diff --git a/.bookignore b/.bookignore new file mode 100644 index 00000000000..7e458990f2f --- /dev/null +++ b/.bookignore @@ -0,0 +1,6 @@ +.bookignore +.github +.gitignore +crowdin.yaml +package-lock.json +package.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000..ee061951a8b --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,24 @@ +# default: +* @DjangoGirls/committers + +# language PR review teams for the respective translations: +/bg/ @DjangoGirls/bg-pr +/cs/ @DjangoGirls/cs-pr +/de/ @DjangoGirls/de-pr +/el/ @DjangoGirls/el-pr +/en/ @DjangoGirls/en-pr +/es/ @DjangoGirls/es-pr +/fa/ @DjangoGirls/fa-pr +/fr/ @DjangoGirls/fr-pr +/hu/ @DjangoGirls/hu-pr +/hy/ @DjangoGirls/hy-pr +/it/ @DjangoGirls/it-pr +/ja/ @DjangoGirls/ja-pr +/ko/ @DjangoGirls/ko-pr +/pl/ @DjangoGirls/pl-pr +/pt/ @DjangoGirls/pt-pr +/ru/ @DjangoGirls/ru-pr +/sk/ @DjangoGirls/sk-pr +/tr/ @DjangoGirls/tr-pr +/uk/ @DjangoGirls/uk-pr +/zh/ @DjangoGirls/zh-pr diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 00000000000..52373ac3126 --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,11 @@ +### Issue description + +Describe what's the problem here. + +### Language + +Is this related to a specific language of the tutorial? + +### Operating system + +What operating system does this issue relate to? diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000000..741ca75c3e7 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,5 @@ +Changes in this pull request: + +- +- +- diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000000..0f9e33b9a56 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,54 @@ +--- +name: Build and Deploy + +on: + push: + branches: + - master + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: awalsh128/cache-apt-pkgs-action@v1 + with: + packages: calibre + - name: Install and Build + run: | + sudo apt install rename + npm install + npx honkit build + npx honkit epub + rename 's/^book/django-girls-tutorial/' book_*.epub + mv *.epub _book/ + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: _book + + deploy: + needs: build + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-24.04 + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000000..f0bd5c4a811 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,17 @@ +name: Build +on: + - pull_request + +jobs: + build: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Install and Build + run: | + npm install + npx honkit build diff --git a/.gitignore b/.gitignore index 53de980d74a..3045a3d9538 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,8 @@ MANIFEST .DS_Store _book node_modules +package-lock.json +.idea +.swp +.langs +.vscode/ diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000000..e69de29bb2d diff --git a/CNAME b/CNAME new file mode 100644 index 00000000000..e204ba9c9a7 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +tutorial.djangogirls.org \ No newline at end of file diff --git a/LANGS.md b/LANGS.md index 40edb26daeb..751d6faf913 100644 --- a/LANGS.md +++ b/LANGS.md @@ -1,14 +1,20 @@ * [🇺🇸 English](en/) -* [🇨🇿 Czech (beta)](cs/) +* [🇧🇬 Български (beta)](bg/) +* [🇨🇿 Čeština (beta)](cs/) +* [🇩🇪 Deutsch](de/) +* [🇬🇷 Ελληνικά (beta)](el/) * [🇪🇸 Español (beta)](es/) -* [🇫🇷 Français](fr/) -* [🇮🇹 Italian (beta)](it/) +* [🇮🇷 فارسی (beta)](fa/) +* [🇫🇷 Français (beta)](fr/) * [🇭🇺 Magyar (beta)](hu/) +* [🇦🇲 հայերեն (beta)](hy/) +* [🇮🇹 Italiano (beta)](it/) +* [🇯🇵 日本語](ja/) +* [🇰🇵/🇰🇷 한국어 (beta)](ko/) * [🇵🇱 Polski](pl/) -* [🇵🇹 Português-brasileiro (beta)](pt/) -* [🇹🇷 Türkçe (beta)](tr/) +* [🇧🇷 Português-brasileiro](pt/) * [🇷🇺 Русский (beta)](ru/) +* [🇸🇰 Slovenčina (beta)](sk/) +* [🇹🇷 Türkçe (beta)](tr/) * [🇺🇦 Українська](uk/) * [🇨🇳 简体中文](zh/) -* [🇰🇵/🇰🇷 한국어 (beta)](ko/) -* [🇸🇰 Slovak (beta)](sk) diff --git a/Makefile b/Makefile new file mode 100644 index 00000000000..6a480076486 --- /dev/null +++ b/Makefile @@ -0,0 +1,111 @@ +LANG := en +LANG_FILE := $(shell test -f .langs && echo .langs || echo LANGS.md) +LANG_DATA := $(shell grep "$(LANG)/" $(LANG_FILE)) +LANG_NAME := $(shell echo "$(LANG_DATA)" | sed 's/.*\[\(.*\)\].*/\1/') + +define ebook_support + @if which ebook-convert 1> /dev/null; then\ + npx honkit $(1) ./ ./djangogirls.$(1);\ + else\ + echo "Error: ebook-convert is not found";\ + echo " * Follow the guide at https://honkit.netlify.app/ebook";\ + echo " - For Debian/Ubuntu, Try: sudo apt install calibre";\ + echo " - For MacOS, Try: brew install --cask calibre";\ + echo " - For Windows and any other OS, Download from https://github.com/kovidgoyal/calibre/releases";\ + false;\ + fi +endef + +help: + @echo + @echo "Usage: make command [LANG=]" + @echo + @echo " LANG: Language shortcodes are found in LANGS.md. Default is 'en'(English)." + @echo " ( Refer $(LANG_FILE) for shortcodes of Languages available. )" + @echo + @echo "Commands:" + @echo " help - Display make command list." + @echo " dev - Setup the project and start the development server with debugging enabled." + @echo " check - Check for the root directory for various dependencies." + @echo " setup - Setup the temporary language and install node dependencies for the development." + @echo " build - Build the honkit project." + @echo " build-dev - Build the honkit project with debug log." + @echo " serve - Start honkit server locally for development." + @echo " pdf - Generate the PDF version of DjangoGirls tutorial." + @echo " epub - Generate the EPUB version of DjangoGirls tutorial." + @echo " mobi - Generate the MOBI version of DjangoGirls tutorial." + @echo " mode - Shows the development mode status." + @echo " exit - Exit development mode." + @echo + @echo "Example:" + @echo + @echo "$$ make dev LANG=es" + @echo + @echo "The above command will start the development server using the language Español." + @echo "'LANG' argument is only required the first time until the exit command is executed." + @echo + +.git/hooks/pre-commit: + @echo "#!/bin/sh\n\ +\n\ +if test -f \"./.langs\"; then\n\ + echo \"Error: You can't commit without exiting development mode.\\\n\\\n\\\\\ +\nTry the following command to exit development mode:\\\n\\\n\\\\\ +\n$$ make exit\\\n\" 1>&2;\n\ + exit 1\n\ +fi\n" > ./.git/hooks/pre-commit + @chmod u+x ./.git/hooks/pre-commit + +node_modules: + @npm install + +check: package.json book.json LANGS.md + @if ! which node 1> /dev/null; then\ + echo "Error: Node.js not found";\ + echo " * Please install/reinstall NodeJS on your system.";\ + echo " * NVM is recommended for installation (https://github.com/nvm-sh/nvm).";\ + false;\ + fi + +setup: node_modules check .git/hooks/pre-commit + @if ! test -f ".langs"; then\ + cp LANGS.md .langs && \ + echo "$(LANG_DATA)" > LANGS.md && \ + echo "You are set to $(LANG_NAME) for development";\ + fi + +build: setup + @npx honkit build + +build-dev: setup + @npx honkit build --log=debug + +serve: setup + @npx honkit serve + +dev: setup + @npx honkit serve --log=debug + +mode: + @if test -f ".langs"; then\ + echo "You are in development mode using the language $(LANG_NAME)";\ + else\ + echo "You are not in development mode";\ + fi + +exit: + @if test -f ".langs"; then\ + mv -f .langs LANGS.md && echo "Language file is restored";\ + rm -rf node_modules _book .git/hooks/pre-commit && echo "The project exited development mode.";\ + fi + +pdf: + $(call ebook_support,pdf) + +epub: + $(call ebook_support,epub) + +mobi: + $(call ebook_support,mobi) + +.PHONY: help check setup build build-dev serve dev pdf epub mobi mode exit diff --git a/README.md b/README.md index 3df1c7b95fe..75f6f9c1f29 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,27 @@ +[![Open in Codeanywhere](https://img.shields.io/badge/Open%20in-Codeanywhere-7f3f97)](https://app.codeanywhere.com/#https://github.com/DjangoGirls/tutorial) + # Django Girls Tutorial -This is the source code repository for the Django Girls Tutorial. Django Girls Tutorial is used on [tutorial.djangogirls.org](http://tutorial.djangogirls.org) so if you want to read it, please go there. If you want to contribute please do go further with this file. +~ 🖥 Source Code 🖥 ~ + +**NOT** intended for reading here. To read go to: [📖 tutorial.djangogirls.org 📖](https://tutorial.djangogirls.org) + +# Contribution QUICKSTART + +1. Fork this repo [[fork](#fork-the-repository)] + +> 2. **[Small changes](#simple-changes)**: you can now edit your fork on the github website, do this! Make a change, then [create a pull request](#making-a-pull-request)! +2. **[Big changes](#new-content-and-complex-changes)**: clone your fork locally. +3. [CLI](#cli-for-development) run `make dev` in repo. + +``` +$ make dev +... +Serving book on http://localhost:4000 +``` + +Note: we have many changes under way we maybe working on your request already! Refer to existing [Pull requests](https://github.com/DjangoGirls/tutorial/pulls). # How to contribute @@ -9,13 +29,13 @@ The Django Girls Tutorial is licensed under a [*Creative Commons Attribution-Sha # Editing basics -The source code of the tutorial is [hosted on Github](https://github.com/DjangoGirls/tutorial). The Github [Fork & Pull workflow](https://help.github.com/articles/using-pull-requests) is used to accept and review changes. +The source code of the tutorial is [hosted on GitHub](https://github.com/DjangoGirls/tutorial). The GitHub [Fork & Pull workflow](https://help.github.com/articles/using-pull-requests) is used to accept and review changes. -The tutorial uses the [GitBook](https://www.gitbook.com/) service for publishing its documentation. [See more information about how Gitbook works](https://help.gitbook.com/). +The tutorial uses the [HonKit](https://github.com/honkit/honkit) project for publishing its documentation. [See more information about how HonKit works](https://honkit.netlify.app/). The tutorial is written in [Markdown mark up language](https://help.github.com/articles/markdown-basics). -You can find any discussions about the contents of the tutorial on the [Github issue tracker](https://github.com/DjangoGirls/tutorial/issues). +You can find any discussions about the contents of the tutorial on the [GitHub issue tracker](https://github.com/DjangoGirls/tutorial/issues). [Crowdin](https://crowdin.com/project/django-girls-tutorial) platform is used to manage translations. If you want to join an existing translation team or launch a new translation, send an email to the [translation managers](mailto:translations@djangogirls.org) or contact [support team](mailto:hello@djangogirls.org). If you want to propose some small changes or fix typos in existing translations, please create a Pull Request. @@ -23,22 +43,30 @@ You can find any discussions about the contents of the tutorial on the [Github i For contributing to the tutorial the following is needed to get started: -* a [Github account](https://github.com) -* in the case of complex edits familiarity with [Git command line basics](https://help.github.com/articles/set-up-git) or familiarity with an app ([Windows](https://windows.github.com/), [Mac](https://mac.github.com/)) to push your edits made on your computer to Github. +* a [GitHub account](https://github.com) +* in the case of complex edits familiarity with [Git command line basics](https://help.github.com/articles/set-up-git) or familiarity with an app ([Windows](https://windows.github.com/), [Mac](https://mac.github.com/)) to push your edits made on your computer to GitHub. -## Fork the repository +## Fork the repository {#fork-the-repository} -First fork the [DjangoGirls/tutorial](https://github.com/DjangoGirls/tutorial) repository to your personal Github account: +First fork the [DjangoGirls/tutorial](https://github.com/DjangoGirls/tutorial) repository to your personal GitHub account: ![Fork button](contributing/images/fork.png) +## CLI for Development + +This command line tool use `make` to create development environment. It is optional to use this tool. While building the document, it builds the document for every language. The build process can be limited to any one language using this tool and reduce build time considerably. Afterwards, the translation to other languages are done from crowdin localization process. + +Usage instructions are available though `make help` command. + +Try the command `make dev` to start development process. + # Editing chapter content ## Simple changes -For simple changes like typo corrections you can use the Github online editor: +For simple changes like typo corrections you can use the GitHub online editor: -* Open your local fork page on Github, +* Open your local fork page on GitHub, * go to *README.md* file in any chapter, * press the *Edit* icon (pen) @@ -48,29 +76,38 @@ and you can edit the chapter directly on github.com. Markdown syntax is used to edit the individual pages of the tutorial. -![Github editor](contributing/images/github_editor.png) +![GitHub editor](contributing/images/github_editor.png) Save your changes and create a pull request as explained below. -## New content and complex changes +## New content and complex changes {#new-content-and-complex-changes} For adding new chapters, writing longer snippets of text or adding images, you need to get a copy of the tutorial to your local computer. -Either use the Github app for your operating system (mentioned above) or `git` command line to get the repository locally. You get the repository address from the front page of your own Github repository fork: +Either use the GitHub app for your operating system (mentioned above) or `git` command line to get the repository locally. You get the repository address from the front page of your own GitHub repository fork: git clone git@github.com:yourgithubusername/tutorial.git +Move to the folder containing the project, to run the following commands. + + cd tutorial + Then, create a branch for your new changes to sit in. It helps to call the branch something related to the changes you are going to make. git checkout -b contributing -Download the [Gitbook Editor](https://www.gitbook.com/editor) app to your computer. +Install the project's requirements using [`npm`](https://docs.npmjs.com/cli/v8/configuring-npm/install). + + npm install + +To preview and serve local files, with auto-reload capabilities, run HonKit using: -Then you can open the tutorial in Gitbook Editor (*File* > *Open book*). + npx honkit serve -Make any changes in the tutorial using Gitbook and then save changes (*Book* > *Save all*). +The local server will be available at http://localhost:4000. +If auto-reload is slow, you can temporarily remove unwanted languages from `LANGS.md`, to speed up the process. -Then commit the changes using `git` and push the changes to your remote Github repository. +Then commit the changes using `git` and push the changes to your remote GitHub repository. Example: @@ -97,21 +134,39 @@ Example: To git@github.com:miohtama/tutorial.git b37ca59..fe36152 contributing -> contributing -If you don't want to download the Gitbook Editor app you can also go to the [Gitbook website](https://www.gitbook.com/), sign up for free and work directly in your browser. +# Restructuring the tutorial {#restructuring-the-tutorial} +Restructuring the tutorial is a major change that takes time so we have created a separate branch for these changes. + +To make contributions that address issues +[1777](https://github.com/DjangoGirls/tutorial/issues/1777) and [1792](https://github.com/DjangoGirls/tutorial/issues/1792), +[fork](#fork-the-repository) the repository your repository. + +Next you need to follow instructions for [cloning and setting up locally given in the section above](#new-content-and-complex-changes). + +Please make use of ["semantic linefeeds"](https://rhodesmill.org/brandon/2012/one-sentence-per-line/) a.k.a. +["semantic line breaks"](https://sembr.org/) for all paragraphs. +Though most of the Django Girls tutorial wasn't originally written that way, placing source line breaks at semantically meaningful spots in the text (and especially between sentences) facilitates both, commenting on individual statements or thoughts in the text as part of the review process, as well as future editing and diff-ing. + +As we restructure the tutorial, this would be a great change to introduce to the tutorial so please make sure the chapter you work on follow this pattern. + +All pull requests for changes aimed at restructuring the tutorial which address the issues +[1777](https://github.com/DjangoGirls/tutorial/issues/1777) and [1792](https://github.com/DjangoGirls/tutorial/issues/1792) +should be made to the `restructure-tutorial`. -# Making a pull request +All other steps for creating a pull request are the same as those outlined in the section on [making a pull request below](#making-a-pull-request), just make sure you make the pull request against the `restructure-tutorial` branch. -After you have finished your changes you need to create [a pull request](https://help.github.com/articles/using-pull-requests) on Github. DjangoGirls will get notified about the pull request, review your changes, suggest any corrections if needed and then *pull* your changes to the master version. +# Making a pull request {#making-a-pull-request} +After you have finished your changes you need to [create a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) on GitHub. DjangoGirls will get notified about the pull request, review your changes, suggest any corrections if needed and then *pull* your changes to the master version. -In your own repository on Github press do *Compare & pull request* +In your own repository on GitHub press do *Compare & pull request* -![Gitbook](contributing/images/pull_request.png) +![Compare & pull request](contributing/images/pull_request.png) Fill in the information *why* this change is being made. The reviewer can see the details of the actual change, so you don't need repeat the content of the change. Then press *Create pull request*. -Github emails will notify you for the follow up process. +GitHub emails will notify you for the follow up process. # Further information and help diff --git a/SUMMARY.md b/SUMMARY.md deleted file mode 100644 index 25a519ca198..00000000000 --- a/SUMMARY.md +++ /dev/null @@ -1,2 +0,0 @@ -# Summary - diff --git a/bg/GLOSSARY.md b/bg/GLOSSARY.md new file mode 100644 index 00000000000..92a2c38234c --- /dev/null +++ b/bg/GLOSSARY.md @@ -0,0 +1,3 @@ +# редактор на код + +Редакторът на код е приложение, което ти позволява да съхраняваш своя код за да можеш да продължиш с него по-късно. Може да научиш откъде да свалиш от [главата Редактор на код](./code_editor/README.md) \ No newline at end of file diff --git a/bg/README.md b/bg/README.md new file mode 100644 index 00000000000..43886769177 --- /dev/null +++ b/bg/README.md @@ -0,0 +1,51 @@ +# Django Girls ръководство + +[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial) + +> Тази работа е лицензирана под Creative Commons Attribution-ShareAlike 4.0 International License. За да видите копие на този лиценз, посетете https://creativecommons.org/licenses/by-sa/4.0/ + +## Добре дошли + +Добре дошли в ръководството на Django Girls! Щастливи сме да те видим тук :) Ще те отведем на приключение зад кулисите на уеб-технологиите, като хвърлим бегъл поглед на всичко, което е необходимо за да накараме мрежата да проработи, така както я знаем. + +Както с всички непознати неща, това може да бъде малко трудно. Но не се притеснявай, вече имаш кураж да бъдеш тука, всичко ще бъде наред :) + +## Въведение + +Някога имал ли си чувтвото, че светът е свързан все повече и повече с технологиите и ти не си още част от него? Чудил ли си се как да създадеш уеб-сайт, но никога си нямал достатъчно мотивация да започнеш? Струвало ли ти се, че светът на софтуера е прекалено сложен за да започнеш да правиш нещо сам? + +Имаме добра новина за теб! Програмиране не е толкова трудно, колкото изглежда, и ние искаме да ти покажем колко лесно може да бъде това. + +Това ръководство няма магически да те превърне в програмист. Ако искаш да си добър ще ти трябват месеци или даже години учене и упражняване. Но ние искаме да покажем, че програмиране или създаване на уеб-сайтове не е толкова сложно, колкото изглежда. Ще се постараем да обясним в детайли, колкото се може по-добре, за да не се чувстваш уплашен от технологията. + +Надяваме се да те накараме да заобичаш технология толкова, колкото и ние я обичаме! + +## Какво ще научиш от това ръководство? + +След като приключиш с ръководството, ще имаш малко работещо уеб-приложение: твой собствен блог. Ще ти покажем как да го пуснеш в мрежата, така че другите да ти видят работата! + +Това ще изглежда (горе-долу) ето така: + +![Фигура 0.1](images/application.png) + +> Ако работиш с ръкводството сам, и нямаш инструктор който да ти помага в случай на някой проблем, имаме чат система за теб: [![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial). Помолихме нашите инструктори и миналите участници да са там от време на време и да помагат на другите с ръководството! Не се страхувай да задаваш въпроси тука! + +Добре, [хайде да започнем от начало...](./how_the_internet_works/README.md) + +## Следвайки ръководството вкъщи + +Изумително е да си част от занятията на Django Girls, но също разбираме, че не винаги е възможно да присъстваш на някое от тях. Затова ние те насърчаваме да пробваш да следиш ръководството вкъщи. За читатели у дома, понастоящем приготвяме видеа, които ще улеснят следването на ръководството само по себе си. Проектът е все още в процес на обработка, но все повече и повече неща скоро ще бъдат покрити на [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed) YouTube канал. + +Във всяка вече покрита глава има линк, препращащ към съответното видео. + +## Относно и допринасяне + +Това ръководство е поддържано от [Django Girls](https://djangogirls.org/). Ако си намерил някакви грешки или искаш да актуализираш ръководството, моля, [следвай насоките за допринасяне](https://github.com/DjangoGirls/tutorial/blob/master/README.md). + +## Би ли искал да ни помогнеш да преведем ръководството на друг език? + +Понастоящем, преводите се съхраняват на платформа crowdin.com на този адрес: + +https://crowdin.com/project/django-girls-tutorial + +Ако твоят език не е изброен на [crowdin](https://crowdin.com/), моля [оставете заявка](https://github.com/DjangoGirls/tutorial/issues/new), информирайки ни за езика, за да можем да го добавим. \ No newline at end of file diff --git a/bg/SUMMARY.md b/bg/SUMMARY.md new file mode 100644 index 00000000000..c6859e9e51b --- /dev/null +++ b/bg/SUMMARY.md @@ -0,0 +1,35 @@ +# Обобщение + +* [Въведение](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) + * [PythonAnywhere](installation/README.md#pythonanywhere) +* [Инсталиране (chromebook)](chromebook_setup/README.md) +* [Как работи интернет](how_the_internet_works/README.md) +* [Въведение в команден ред](intro_to_command_line/README.md) +* [Инсталиране на Python](python_installation/README.md) +* [Редактор на код](code_editor/README.md) +* [Въведение в Python](python_introduction/README.md) +* [Какво е Django?](django/README.md) +* [Инсталиране на Django](django_installation/README.md) +* [Вашият първи проект с Django!](django_start_project/README.md) +* [Django модели](django_models/README.md) +* [Администриране на Django](django_admin/README.md) +* [Внедряване!](deploy/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) +* [Разшири своето приложение](extend_your_application/README.md) +* [Django Форми](django_forms/README.md) +* [Какво следва?](whats_next/README.md) \ No newline at end of file diff --git a/bg/chromebook_setup/README.md b/bg/chromebook_setup/README.md new file mode 100644 index 00000000000..d21dc1f556d --- /dev/null +++ b/bg/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# Настройка на Chromebook + +> **Бележка** Ако вече сте минали през стъпките за инсталиране, няма нужда да правите това отново - можете да прескочите направо към [Въведение в Python](../python_introduction/README.md). + +{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/bg/chromebook_setup/instructions.md b/bg/chromebook_setup/instructions.md new file mode 100644 index 00000000000..5befa2aaec6 --- /dev/null +++ b/bg/chromebook_setup/instructions.md @@ -0,0 +1,73 @@ +Можеш да [пропуснеш този раздел](http://tutorial.djangogirls.org/en/installation/#install-python), ако не използваш Chromebook. Ако използвате, опитът ви в инсталацията ще бъде малко по-различен. Можете да игнорирате останалата част от инструкциите за инсталиране. + +### Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9) + +Cloud IDE е инструмент, който ти дава редактор на код и достъп до компютър, работещ с Интернет, където можеш да инсталираш, пишеш и пускаш софтуер. За продължителността на ръководството, cloud IDE ще ти служи като твоя *локална машина*. Все пак ще пишеш команди в терминал, също като твоите съученици на macOS, Ubuntu или Windows, но той ще бъде свързан с компютър, работещ някъде другаде, който cloud IDE прави за теб. Ето инструкциите за cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9). Можете да изберете един от cloud IDE интерфейси и да следвате инструкциите за cloud IDE. + +#### PaizaCloud Cloud IDE + +1. Отиди на [PaizaCloud Cloud IDE](https://paiza.cloud/) +2. Направи акаунт +3. Натисни *New Server* и избери Django приложение +4. Натисни бутон на Терминал (от лявата страна на прозореца) + +Сега трябва да виждаш интерфейс със странична лента, бутони са отляво. Натисни бутона "Terminal" за да ви отвори прозорец със следния надпис: + +{% filename %}Terminal{% endfilename %} + + $ + + +Терминалът на PaizaCloud Cloud IDE е готов за твоите инструции. Можеш да увеличиш прозореца за да го направиш малко по-голям. + +#### AWS Cloud9 + +Понастоящем, Cloud 9 изисква от теб да се регистрираш с AWS и да въведеш информация за кредитната си карта. + +1. Инсталирай Cloud 9 от [Chrome web store](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. В Cloud 9 таблото, натисни *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 $ + + +Тази долна зона е вашият терминал. Можете да използвате терминала за изпращане на инструкции до отдалечения компютър Cloud 9. Можете да промените размера на прозореца, за да го направите малко по-голям. + +### Виртуална среда + +Виртуална среда (наричана още virtualenv) е като частна кутия, в която можем да запълним полезен компютърен код за проект, над който работим. Ние ги използваме, за да държим различните части от код, които искаме за отделните ни проекти, разделени, така че нещата да не се смесват между проектите. + +Пусни: + +{% filename %}Cloud 9{% endfilename %} + + mkdir djangogirls + cd djangogirls + python3.6 -mvenv 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/bg/code_editor/README.md b/bg/code_editor/README.md new file mode 100644 index 00000000000..8d3daf476a1 --- /dev/null +++ b/bg/code_editor/README.md @@ -0,0 +1,11 @@ +# Редактор на код + +> За читателите у дома: тази глава е разгледана във видеото [Инсталиране на Python & Редактор на код](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s). + +На път сте да напишете първия си ред код, така че е време да изтеглите редактор на код! + +> **Забележка** Ако използвате Chromebook, пропуснете тази глава и се уверете, че следвате инструкциите [Настройка на Chromebook](../chromebook_setup/README.md). Облачният IDE, който сте избрали (PaizaCloud Cloud IDE или AWS Cloud9) включва редактор на код и когато отворите файл във вашия IDE от менюто File, автоматично ще използвате редактора. +> +> ** Забележка ** Може да сте направили това по-рано в главата за инсталиране - ако е така, можете да прескочите веднага до следващата глава! + +{% include "/code_editor/instructions.md" %} \ No newline at end of file diff --git a/bg/code_editor/instructions.md b/bg/code_editor/instructions.md new file mode 100644 index 00000000000..1d57820cc32 --- /dev/null +++ b/bg/code_editor/instructions.md @@ -0,0 +1,37 @@ +Има много различни редактори и това до голяма степен се свежда до личните предпочитания. Повечето програмисти на Python използват сложни, но изключително мощни IDE (интегрирани среди за разработка), като PyCharm. Като начинаещ обаче това вероятно е по-малко подходящо; нашите препоръки са еднакво мощни, но много по-прости. + +Нашите предложения са по-долу, но не се колебайте да попитате ментора си какви са техните предпочитания - по-лесно ще получите помощ от тях. + +## Visual Studio Code + +Visual Studio Code е редактор за програмен код, разработен от Microsoft за Windows, Linux и macOS. Той включва поддръжка за отстраняване на грешки, вграден Git контрол, подчертаване на синтаксис, интелигентно попълване на код, фрагменти и рефакторинг на код. + +[Изтеглете го тук](https://code.visualstudio.com/) + +## Gedit + +Gedit е безплатен редактор с отворен код, достъпен за всички операционни системи. + +[Изтеглете го тук](https://wiki.gnome.org/Apps/Gedit#Download) + +## Sublime Text + +Sublime Text е много популярен редактор с безплатен период за ползване и е достъпен за всички операционни системи. + +[Изтеглете го тук](https://www.sublimetext.com/) + +## Atom + +Atom е друг популярен редактор. Той е безплатен, с отворен код и се предлага за Windows, macOS и Linux. Atom е разработен от [GitHub](https://github.com/). + +[Изтеглете го тук](https://atom.io/) + +## Защо инсталираме редактор на код? + +Може би се чудите защо инсталираме този специален софтуер за редактиране на код, вместо да използваме нещо като Word или Notepad. + +Първата причина е, че кодът трябва да бъде **обикновен текст**, а проблемът с програми като Word и Textedit е, че те всъщност не произвеждат обикновен текст, те създават богат текст (с шрифтове и форматиране), използвайки персонализирани формати като [RTF (формат на обогатен текст)](https://en.wikipedia.org/wiki/Rich_Text_Format). + +Втората причина е, че редакторите на код са специализирани за редактиране на код, така че те могат да предоставят полезни функции като подчертаване на код с цвят според значението му или автоматично затваряне на кавички. + +Ще видим всичко това в действие по-късно. Скоро ще помислите за надеждния си стар редактор на код като за един от любимите си инструменти. :) diff --git a/bg/css/README.md b/bg/css/README.md new file mode 100644 index 00000000000..f73e52a41be --- /dev/null +++ b/bg/css/README.md @@ -0,0 +1,305 @@ +# CSS - направи го красиво! + +Блогът ни все още изглежда доста грозен, нали? Време е да го направите хубав! За това ще използваме CSS. + +## Какво е CSS? + +Cascading Style Sheets (CSS) е език, използван за описание на външния вид и форматирането на уебсайт, написан на език за маркиране (като HTML). Отнасяйте се към него като грим за вашата уеб страница. ;) + +Но не искаме отново да започнем от нулата, нали? Още веднъж ще използваме нещо, което програмистите пуснаха в интернет безплатно. Преосмислянето на колелото не е забавно. + +## Нека използваме Bootstrap! + +Bootstrap е една от най-популярните фреймуорки за HTML и CSS за разработване на красиви уебсайтове: https://getbootstrap.com/ + +Той е написан от програмисти, които са работили за Twitter. Сега тя е разработена от доброволци от цял свят! + +## Инсталирайте Bootstrap + +За да инсталирате Bootstrap, отворете вашия файл `.html` в редактора на кода и го добавете в секцията ``: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + +``` + +Това не добавя никакви файлове към вашия проект. Той просто сочи файлове, които съществуват в Интернет. Затова продължете напред, отворете уебсайта си и актуализирайте страницата. Ето го! + +![Фигура 14.1](images/bootstrap1.png) + +Вече изглежда по-хубав! + +## Статични файлове в Django + +Накрая ще разгледаме по-подробно тези неща, които наричахме **статични файлове**. Статичните файлове са всички ваши CSS и изображения. Съдържанието им не зависи от контекста на заявката и ще бъде едно и също за всеки потребител. + +### Къде да сложа статични файлове за Django + +Django вече знае къде да намери статичните файлове за вграденото приложение "admin". Сега трябва да добавим статични файлове за нашето собствено приложение, `blog`. + +Правим това, като създаваме папка, наречена `static` в блог приложението: + + djangogirls + ├── blog + │ ├── migrations + │ ├── static + │ └── templates + └── mysite + + +Django автоматично ще открива всички папки, наречени 'static', в която и да е от папките на вашите приложения. Тогава той ще може да използва тяхното съдържание като статични файлове. + +## Вашият първи CSS файл! + +Нека сега създадем CSS файл, за да добавим свой собствен стил към вашата уеб страница. Създайте нова директория, наречена `css` във вашата `static` директория. След това създайте нов файл, наречен `blog.css` вътре в тази директория `css`. Готови? + + djangogirls + └─── blog + └─── static + └─── css + └─── blog.css + + +Време е да напишете малко CSS! Отворете файла `blog/static/css/blog.css` във вашия редактор на код. + +Тук няма да навлизаме твърде дълбоко в персонализирането и научаването на CSS. Има препоръка за безплатен CSS курс в края на тази страница, ако искате да научите повече. + +Но нека направим поне малко. Може би бихме могли да променим цвета на заглавията си? За да разберат цветовете, компютрите използват специални кодове. Тези кодове започват с `#`, последвани от 6 букви (A–F) и цифри (0–9). Например кодът за синьо е `#0000FF`. Можете да намерите цветовите кодове за много от цветовете тук: http://www.colorpicker.com/. Можете също така да използвате [предварително определени цветове](http://www.w3schools.com/colors/colors_names.asp), като ` red ` и ` green `. + +Във вашия `blog/static/css/blog.css` файл трябва да добавите следния код: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +h1 a, h2 a { + color: #C25100; +} + +``` + +`h1 a` е CSS селектор. Това означава, че прилагаме стиловете си към всеки `a` елемент вътре в елемент `h1`; селекторът `h2 a` прави същото за елементи `h2`. Така че, когато имаме нещо като `

връзка

`, ще се прилага стилът `h1 a`. В този случай ние му казваме да промени цвета си на `#C25100`, което е тъмно оранжево. Или можете да поставите свой собствен цвят тук, но се уверете, че той има добър контраст на бял фон! + +Във CSS файл определяме стилове за елементи в HTML файла. Първият начин да идентифицираме елементите е с името на елемента. Може да ги запомните като тагове от секцията HTML. Неща като `a`, `h1` и `body` са примери за имена на елементи. Ние също така идентифицираме елементи по атрибут `class` или атрибут `id`. Class и id са имена, които сами давате на елемента. Класовете определят групи от елементи, а идентификаторите сочат конкретни елементи. Например, можете да идентифицирате следния маркер, като използвате името на тага `a`, класа `external_link` или id `link_to_wiki_page`: + +```html + +``` + +Можете да прочетете повече за [CSS селектори в w3schools](http://www.w3schools.com/cssref/css_selectors.asp). + +Трябва също така да кажем на нашия HTML шаблон, че добавихме някои CSS. Отворете файла `blog/templates/blog/post_list.html` в редактора на кода и добавете този ред в самото начало: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% load static %} +``` + +Тук просто зареждаме статични файлове. :) Между таговете `` и ``, след връзките към CSS файловете на Bootstrap, добавете този ред: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +Браузърът чете файловете в реда, в който са зададени, така че трябва да се уверим, че това е на правилното място. В противен случай кодът в нашия файл може да бъде редактиран от кода във файловете на 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.text|linebreaksbr }}

+
+ {% endfor %} + + +``` + +ОК, запазете файла и актуализирайте сайта! + +![Фигура 14.2](images/color2.png) + +Добра работа! Може би също бихме искали да дадем на нашия уебсайт малко въздух и да увеличим полето от лявата страна? Нека опитаме това! + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +body { + padding-left: 15px; +} +``` + +Добавете това към вашия CSS, запишете файла и вижте как работи! + +![Фигура 14.3](images/margin2.png) + +Може би можем да персонализираме шрифта в заглавието ни? Поставете това във вашия `` в `blog/templates/blog/post_list.html` файл: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +Както и преди, проверете поръчката и поставете преди връзката към `blog/static/css/blog.css`. Този ред ще импортира шрифт, наречен *Lobster* от Google Fonts (https://www.google.com/fonts). + +Намерете блока за деклариране `h1 a` (кодът между скобите `{` и `}`) в CSS файла `blog/static/css/blog.css`. Сега добавете ред `font-family: 'Lobster';` между скобите и актуализирайте страницата: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +h1 a, h2 a { + color: #C25100; + font-family: 'Lobster'; +} +``` + +![Фигура 14.3](images/font.png) + +Страхотно! + +Както бе споменато по-горе, CSS има концепция за класове. Те ви позволяват да назовете част от HTML кода и да приложите стилове само към тази част, без да засягате други части. Това може да бъде супер полезно! Може би имате два divs (участъка), които правят нещо различно (като заглавието и публикацията ви). Един клас може да ви помогне да ги направите да изглеждат различно. + +Продължете и дайте име на някои части от HTML кода. Добавете клас, наречен `page-header`, към вашия `div`, който съдържа заглавието ви, като този: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +И сега добавете клас `post` към вашия `div` съдържащ публикация в блог. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+``` + +Сега ще добавим декларационни блокове към различни селектори. Селектори, започващи с `. `, се отнасят за класове. Има много страхотни уроци и обяснения за CSS в мрежата, които могат да ви помогнат да разберете следния код. Засега го копирайте и поставете във вашия `blog/static/css/blog.css` файл: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +.page-header { + background-color: #C25100; + margin-top: 0; + padding: 20px 20px 20px 40px; +} + +.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 { + font-family: 'Lobster', cursive; +} + +.date { + color: #828282; +} + +.save { + float: right; +} + +.post-form textarea, .post-form input { + width: 100%; +} + +.top-menu, .top-menu:hover, .top-menu:visited { + color: #ffffff; + float: right; + font-size: 26pt; + margin-right: 20px; +} + +.post { + margin-bottom: 70px; +} + +.post h2 a, .post h2 a:visited { + color: #000000; +} +``` + +След това заобиколете HTML кода, който показва публикациите с декларации за класове. Заменете това: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} +
+

published: {{ post.published_date }}

+

{{ 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.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
+``` + +Запазете тези файлове и актуализирайте уебсайта си. + +![Фигура 14.4](images/final.png) + +Ура! Изглежда страхотно, нали? Вижте кода, който току-що поставихме, за да намерите местата, където добавихме класове в HTML и ги използвахме в CSS. Къде бихте направили промяната, ако искате датата да е тюркоазена? + +Не се страхувайте да се поинтересувате с този CSS малко и се опитайте да промените някои неща. Играта с CSS може да ви помогне да разберете какво правят различните неща. Ако счупите нещо, не се притеснявайте - винаги можете да го отмените! + +Наистина препоръчваме да вземете безплатните онлайн курсове "Basic HTML & HTML5" и "Basic CSS" на [freeCodeCamp](https://learn.freecodecamp.org/). Те могат да ви помогнат да научите всичко за правенето на уебсайтовете ви по-красиви с HTML и CSS. + +Готови ли сте за следващата глава?! :) \ No newline at end of file diff --git a/bg/css/images/bootstrap1.png b/bg/css/images/bootstrap1.png new file mode 100644 index 00000000000..bd81cd14373 Binary files /dev/null and b/bg/css/images/bootstrap1.png differ diff --git a/bg/css/images/color2.png b/bg/css/images/color2.png new file mode 100644 index 00000000000..3f82e7d3922 Binary files /dev/null and b/bg/css/images/color2.png differ diff --git a/bg/css/images/final.png b/bg/css/images/final.png new file mode 100644 index 00000000000..067c83d36cc Binary files /dev/null and b/bg/css/images/final.png differ diff --git a/bg/css/images/font.png b/bg/css/images/font.png new file mode 100644 index 00000000000..310f9e85f18 Binary files /dev/null and b/bg/css/images/font.png differ diff --git a/bg/css/images/margin2.png b/bg/css/images/margin2.png new file mode 100644 index 00000000000..895828b688d Binary files /dev/null and b/bg/css/images/margin2.png differ diff --git a/bg/deploy/README.md b/bg/deploy/README.md new file mode 100644 index 00000000000..fc814929882 --- /dev/null +++ b/bg/deploy/README.md @@ -0,0 +1,222 @@ +# Внедряване! + +> **Забележка** Следващата глава понякога може да бъде малко трудна за преминаване. Продължете и я завършете; внедряването е важна част от процеса на разработване на уебсайтове. Тази глава е поставена в средата на урока, така че вашият ментор да ви помогне с малко по-сложния процес на вдигане на уебсайта ви онлайн. Това означава, че все още можете да завършите урока самостоятелно, ако ви липсва време. + +Досега вашият уебсайт беше достъпен само на вашия компютър. Сега ще научите как да го прехвърлите в онлайн пространството! Разгръщането е процесът на публикуване на приложението ви в Интернет, така че хората най-накрая да могат да отидат и да видят приложението ви. :) + +Както научихте, уебсайт трябва да бъде разположен на сървър. В интернет има много доставчици на сървъри, ще използваме [PythonAnywhere](https://www.pythonanywhere.com/). PythonAnywhere е безплатен за малки приложения, които нямат твърде много посетители, така че определено засега ще ви бъде достатъчно. + +Другата външна услуга, която ще използваме е [GitHub](https://www.github.com), която е услуга за хостинг на код. Има и други, но почти всички програмисти имат GitHub акаунт в наши дни, а сега и вие! + +Тези три места ще бъдат важни за вас. Вашият локален компютър ще бъде мястото, където правите разработка и тестване. Когато сте доволни от промените, ще поставите копие на програмата си в GitHub. Вашият уебсайт ще бъде на PythonAnywhere и ще го актуализирате, като получите ново копие на вашия код от GitHub. + +# Git + +> **Забележка** Ако вече сте направили стъпките за инсталиране, няма нужда да правите това отново - можете да преминете към следващия раздел и да започнете да създавате вашето Git хранилище. + +{% include "/deploy/install_git.md" %} + +## Стартираме нашето Git хранилище + +Git проследява промените в определен набор от файлове в т.нар. склад (или за кратко "репо"). Нека започнем еднo за нашия проект. Отворете конзолата и стартирайте тези команди в директорията `djangogirls`: + +> **Забележка** Проверете текущата си работна директория с команда `pwd` (macOS / Linux) или `cd` (Windows), преди да инициализирате хранилището. Трябва да сте в папката `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 хранилището е нещо, което трябва да направим само веднъж за всеки проект (и няма да се налага да въвеждате отново потребителското име и имейла). + +Git ще проследи промените във всички файлове и папки в тази директория, но има някои файлове, които искаме да игнорира. Правим това чрез създаване на файл, наречен `.gitignore` в основната директория. Отворете редактора си и създайте нов файл със следното съдържание: + +{% filename %}.gitignore{% endfilename %} + + *.pyc + *~ + /.vscode + __pycache__ + myvenv + db.sqlite3 + /static + .DS_Store + + +И го запишете като `.gitignore` в папката "djangogirls". + +> **Забележка** Точката в началото на името на файла е важна! Ако имате проблеми с създаването му (Macs не харесва да създавате файлове, които започват с точка чрез Finder, например), след това използвайте функцията "Save As" в редактора си; това е бронеустойчиво. И не забравяйте да добавите `.txt`, `.py` или друго разширение към името на файла - той ще бъде разпознат от Git само ако името е просто `.gitignore`. +> +> **Забележка** Един от файловете, които сте посочили във вашия `.gitignore` файл е `db.sqlite3`. Този файл е вашата локална база данни, където се съхраняват всички ваши потребители и публикации. Ще следваме стандартната практика за уеб програмиране, което означава, че ще използваме отделни бази данни за вашия локален тестващ сайт и вашия уеб сайт на живо в PythonAnywhere. Базата данни на PythonAnywhere може да бъде SQLite, като вашата разработваща машина, но обикновено ще използвате такава, наречена MySQL, която може да се справи с много повече посетители на сайта, отколкото SQLite. Така или иначе, като игнорирате вашата SQLite база данни за копието на GitHub, това означава, че всички публикувани досега публикации и superuser ще бъдат достъпни само локално и ще трябва да създавате нови в производството. Трябва да мислите за вашата локална база данни като за добра площадка, където можете да тествате различни неща и да не се страхувате, че ще изтриете истинските си публикации от блога. + +Добра идея е да използвате команда `git status` преди `git add` или винаги, когато се окажете несигурни какво се е променило. Това ще ви помогне да предотвратите появата на изненади, като например добавяне или поемане на грешни файлове. Командата `git status` връща информация за всички непроследени/модифицирани/поетапни файлове, състоянието на клона и много други. Изходът трябва да бъде подобен на следното: + +{% filename %}command-line{% endfilename %} + + $ git status + On branch master + + 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) + + +И накрая спестяваме промените си. Отидете на конзолата си и изпълнете следните команди: + +{% filename %}command-line{% endfilename %} + + $ git add --all . + $ git commit -m "My Django Girls app, first commit" + [...] + 13 files changed, 200 insertions(+) + create mode 100644 .gitignore + [...] + create mode 100644 mysite/wsgi.py + + +## Избутване на кода ви към GitHub + +Отидете на [GitHub.com](https://www.github.com) и се регистрирайте за нов безплатен потребителски акаунт. (Ако вече сте го направили в подготвителната работилница, това е чудесно!) Не забравяйте да запомните паролата си (добавете я към вашия мениджър на пароли, ако използвате такъв). + +След това създайте ново хранилище, като му дадете името "my-first-blog". Оставете квадратчето за „инициализация с README“ отместено, оставете опцията .gitignore празна (направихме това ръчно) и оставете лиценза като None. + +![](images/new_github_repo.png) + +> **Забележка** Името `my-first-blog` е важно - бихте могли да изберете нещо друго, но това ще се случва много пъти в инструкциите по-долу и ще трябва да го замествате всеки път. Вероятно е по-лесно да се придържаме към името `my-first-blog`. + +На следващия екран ще се покаже URL за клониране на вашия склад, което ще използвате в някои от следващите команди: + +![](images/github_get_repo_url_screenshot.png) + +Сега трябва да свържем Git хранилището на вашия компютър към това в GitHub. + +Въведете следното в конзолата си (заменете `` с потребителското име, което сте въвели, когато сте създали акаунта си в GitHub, но без скобите - URL адресът трябва да съответства на клонирания URL адрес, който току-що видяхте): + +{% filename %}command-line{% endfilename %} + + $ git remote add origin https://github.com//my-first-blog.git + $ git push -u origin master + + +Когато избутате кода към GitHub, ще бъдете попитани за вашето потребителско име и парола за GitHub (било то в прозореца на командния ред или в изскачащ прозорец), а след въвеждане на идентификационни данни трябва да видите нещо подобно: + +{% filename %}command-line{% endfilename %} + + 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/ola/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), [Django Girls Tutorial](https://github.com/DjangoGirls/tutorial) и много други страхотни софтуерни проекти с отворен код също са домакини на кода си в GitHub. :) + +# Настройване на нашия блог на PythonAnywhere + +## Регистрирайте се за акаунт в PythonAnywhere + +> **Забележка** Може би вече сте създали акаунт в PythonAnywhere по-рано по време на стъпките за инсталиране - ако е така, няма нужда да го правите отново. + +{% include "/deploy/signup_pythonanywhere.md" %} + +## Конфигуриране на нашия сайт на PythonAnywhere + +Върнете се към главното меню [PythonAnywhere Dashboard](https://www.pythonanywhere.com/), като кликнете върху логото и изберете опцията за стартиране на конзола "Bash" - това е версията на командния ред PythonAnywhere, точно като тази на вашия компютър. + +![Секцията 'Нова конзола' в уеб интерфейса на PythonAnywhere, с бутон за 'bash'](images/pythonanywhere_bash_console.png) + +> **Забележка** PythonAnywhere е базиран на Linux, така че ако сте на Windows, конзолата ще изглежда малко по-различна от тази на вашия компютър. + +Внедряването на уеб приложение в PythonAnywhere включва сваляне на кода от GitHub и конфигуриране на PythonAnywhere да го разпознае и да започне да го обслужва като уеб приложение. Има ръчни начини за това, но PythonAnywhere предоставя помощен инструмент, който ще свърши всичко за вас. Нека го инсталираме първо: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ pip3.6 install --user pythonanywhere + + +Това трябва да отпечата някои неща като `Collecting pythonanywhere` и в крайна сметка да завърши с ред, който казва `Successfully installed (...) pythonanywhere- (...)`. + +Сега стартираме помощника за автоматично конфигуриране на приложението ви от GitHub. Въведете следното в конзолата на PythonAnywhere (не забравяйте да използвате потребителското си име на GitHub вместо ``, така че URL адресът да съответства на клонираният URL от GitHub): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ pa_autoconfigure_django.py --python=3.6 https://github.com//my-first-blog.git + + +Докато гледате това да работи, ще можете да видите какво прави: + +- Изтегляне на вашия код от GitHub +- Създаване на virtualenv на PythonAnywhere, точно като този на вашия собствен компютър +- Актуализиране на вашия файл с настройки с някои настройки за внедряване +- Настройка на база данни на PythonAnywhere с помощта на командата `manage.py migrate` +- Настройка на статичните ви файлове (за тях ще научим по-късно) +- И конфигуриране на PythonAnywhere да обслужва вашето уеб приложение чрез неговия API + +На PythonAnywhere всички тези стъпки са автоматизирани, но те са същите стъпки, които би трябвало да преминете с всеки друг доставчик на сървъри. + +Основното, което трябва да забележите в момента, е, че вашата база данни в PythonAnywhere всъщност е напълно отделена от вашата база данни на вашия собствен компютър, така че може да има различни публикации и администраторски акаунти. В резултат на това, точно както направихме на вашия собствен компютър, трябва да инициализираме администраторския акаунт с `createsuperuser`. PythonAnywhere автоматично активира вашия virtualenv за вас, така че всичко, което трябва да направите, е да стартирате: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + (ola.pythonanywhere.com) $ python manage.py createsuperuser + + +Въведете данните за вашия администратор потребител. Най-добре е да използвате същите, които използвате на собствения си компютър, за да избегнете объркване, освен ако не искате да направите паролата на PythonAnywhere по-сигурна. + +Сега, ако желаете, можете също да разгледате кода си на PythonAnywhere, като използвате `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 + + +Можете също да отидете на страницата „Файлове“ и да се придвижвате наоколо, използвайки вградения файлов браузър на PythonAnywhere. (От страницата на конзолата можете да стигнете до други страници на PythonAnywhere от бутона на менюто в горния десен ъгъл. След като сте на една от страниците, има връзки към другите в горната част.) + +## Вече сте на живо! + +Сега вашият сайт трябва да бъде на живо в публичния Интернет! Кликнете върху страницата „Уеб“ на PythonAnywhere, за да получите линк към нея. Можете да споделите това с всеки, който искате :) + +> **Забележка** Това е урок за начинаещи и при разгръщането на този сайт взехме няколко преки пътища, които не са идеални от гледна точка на сигурността. Ако и когато решите да надградите този проект или да започнете нов проект, трябва да прегледате [контролния списък за разгръщане на Django](https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/) за някои съвети относно осигуряването на вашия сайт. + +## Съвети за отстраняване на грешки + +Ако видите грешка при изпълнение на скрипта `pa_autoconfigure_django.py`, ето няколко често срещани причини: + +- Забравяйки да създадете своя маркер за API на PythonAnywhere API. +- Грешка в URL адреса ви в GitHub +- Ако видите грешка, която казва *"Could not find your settings.py"*, вероятно защото не успяхте да добавите всичките си файлове в Git и/или не ги избутахте до GitHub успешно. Погледнете още един път раздела Git по-горе +- Ако преди това сте се регистрирали за акаунт в PythonAnywhere и имате грешка с collectstatic, вероятно имате по-стара версия на SQLite (например 3.8.2) за вашия акаунт. В такъв случай се регистрирайте за нов акаунт и опитайте командите в секцията PythonAnywhere по-горе. + +Ако видите грешка, когато се опитвате да посетите вашия сайт, първото място за търсене на информация за отстраняване на грешки е във вашия **error log**. Ще намерите линк към това на страницата на PythonAnywhere ["Web"](https://www.pythonanywhere.com/web_app_setup/). Вижте дали има съобщения за грешки там; най-новите са най-отдолу. + +Също така има някои [общи съвети за отстраняване на грешки на помощния сайт на PythonAnywhere](http://help.pythonanywhere.com/pages/DebuggingImportError). + +И не забравяйте, че вашият ментор е тук, за да ви помогне! + +# Вижте вашия сайт! + +Страницата по подразбиране за вашия сайт трябва да гласи „It worked!“, точно както прави на вашия локален компютър. Опитайте да добавите `/admin/` в края на URL адреса и ще бъдете отведени до администраторския сайт. Влезте с потребителското име и паролата и ще видите, че можете да добавяте нови публикации на сървъра - не забравяйте, че публикациите от вашата локална база данни за тестове не бяха изпратени във вашия блог на живо. + +След като създадете няколко публикации, можете да се върнете към вашата локална настройка (не PythonAnywhere). От тук трябва да работите върху вашата локална настройка, за да направите промени. Това е често срещан работен процес в уеб разработката - правете промени локално, бутате тези промени в GitHub и изтегляте промените надолу към вашия уеб сървър на живо. Това ви позволява да работите и да експериментирате, без да нарушавате уеб сайта си на живо. Доста готино, а? + +Заслужавате *огромни* похвали! Сървърните внедрения са едни от най-трудните части на уеб разработката и често отнемат на хората няколко дни, преди да ги накарат да работят. Но вие имате своя сайт на живо, в реалния Интернет! \ No newline at end of file diff --git a/bg/deploy/images/github_get_repo_url_screenshot.png b/bg/deploy/images/github_get_repo_url_screenshot.png new file mode 100644 index 00000000000..ee1560b1e85 Binary files /dev/null and b/bg/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/bg/deploy/images/new_github_repo.png b/bg/deploy/images/new_github_repo.png new file mode 100644 index 00000000000..d1f82e5d863 Binary files /dev/null and b/bg/deploy/images/new_github_repo.png differ diff --git a/bg/deploy/images/pythonanywhere_account.png b/bg/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/bg/deploy/images/pythonanywhere_account.png differ diff --git a/bg/deploy/images/pythonanywhere_bash_console.png b/bg/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..68eb2a030e1 Binary files /dev/null and b/bg/deploy/images/pythonanywhere_bash_console.png differ diff --git a/bg/deploy/images/pythonanywhere_beginner_account_button.png b/bg/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/bg/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/bg/deploy/images/pythonanywhere_create_api_token.png b/bg/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..abae45ae37a Binary files /dev/null and b/bg/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/bg/deploy/install_git.md b/bg/deploy/install_git.md new file mode 100644 index 00000000000..4ea1d93e174 --- /dev/null +++ b/bg/deploy/install_git.md @@ -0,0 +1,52 @@ +Git е "система за контрол на версиите", използвана от много програмисти. Този софтуер може да проследява промените във файловете с течение на времето, така че да можете да заредите конкретни версии по-късно. Нещо като функцията „проследяване на промените“ в програми за текстообработка (например, Microsoft Word или LibreOffice Writer), но много по-мощна. + +## Инсталиране на Git + + + +Можете да свалите Git от [git-scm.com](https://git-scm.com/). Можете да натиснете „ next“ на всички стъпки, с изключение на две: в стъпката, където се изисква да изберете вашия редактор, трябва да изберете Nano, и в стъпката, озаглавена „Настройка на вашата PATH среда“, изберете „Използване на Git и незадължителни инструменти на Unix от командния ред на Windows " (най-долната опция). Освен това, настройките по подразбиране са добре. Разгледайте Windows стил, Unix стил за окончанията на редовете е добре. + +Не забравяйте да рестартирате командния ред или PowerShell, след като инсталацията приключи успешно. + + + +Свалете Git от [git-scm.com](https://git-scm.com/) и следвайте инструкцията. + +> **Забележка** Ако използвате OS X 10.6, 10.7 или 10.8, ще трябва да инсталирате версията на git от тук: [Инсталатор на Git за OS X Snow Leopard](https://sourceforge.net/projects/git-osx-installer/files/git-2.3.5-intel-universal-snow-leopard.dmg/download) + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo apt install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo dnf install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo zypper install git +``` + + \ No newline at end of file diff --git a/bg/deploy/signup_pythonanywhere.md b/bg/deploy/signup_pythonanywhere.md new file mode 100644 index 00000000000..007eba2cfe2 --- /dev/null +++ b/bg/deploy/signup_pythonanywhere.md @@ -0,0 +1,19 @@ +PythonAnywhere е услуга за ползване на Python код на сървъри „в облака“. Ще използваме нея за хостинг на нашия сайт, на живо и в интернет. + +Ще направим блог, който изграждаме на PythonAnywhere. Регистрирайте се за акаунт за начинаещи в PythonAnywhere (безплатното ниво е добре, нямате нужда от кредитна карта). + +* [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +![Страницата за регистрация в PythonAnywhere показва бутон за създаване на безплатен акаунт за начинаещи](../deploy/images/pythonanywhere_beginner_account_button.png) + +> **Забележка** Когато избирате вашето потребителско име тук, имайте предвид, че URL адресът на вашия блог ще приеме формата `yourusername.pythonanywhere.com`, така че изберете свой собствен прякор или име на блога. Също така, запомнете вашата парола (добавете я към вашия мениджър на пароли, ако използвате такъв). + +## Създаване на PythonAnywhere API токен + +Това е нещо, което трябва да направите само веднъж. Когато се регистрирате за PythonAnywhere, ще бъдете отведени до таблото си за управление. Намерете линка в горния десен ъгъл до страницата си „ Account“: + +![Връзка към акаунта в горния десен ъгъл на страницата](../deploy/images/pythonanywhere_account.png) + +след това изберете раздела, наречен "API token", и натиснете бутона с надпис "Create new API token". + +![Раздел на API токен на страницата „Акаунт“](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/bg/django/README.md b/bg/django/README.md new file mode 100644 index 00000000000..b6f4ebe0064 --- /dev/null +++ b/bg/django/README.md @@ -0,0 +1,27 @@ +# Какво е Django? + +Django (/ ˈdʒæŋɡoʊ / *jang-goh*) е безплатна и отворена уеб рамка, написана на Python. Уеб рамката е набор от компоненти, които ви помагат да развивате уеб сайтове по-бързо и по-лесно. + +Когато създавате уебсайт, винаги се нуждаете от подобен набор от компоненти: начин за справяне с удостоверяването на потребителя (регистрация, влизане, излизане), панел за управление на вашия уебсайт, формуляри, начин за качване на файлове и т. н. + +За ваше щастие, други хора отдавна забелязаха, че уеб разработчиците са изправени пред подобни проблеми при изграждането на нов сайт, така че те се обединиха и създадоха рамки (Django е една от тях), които ви дават готови компоненти за използване. + +Рамките съществуват за да ви спестяват нуждата да преоткривате колелото и да помогнат за облекчаване на част от разходи, когато създавате нов сайт. + +## Защо имате нужда от рамка? + +За да разберем за какво всъщност е Django, трябва да разгледаме по-отблизо сървърите. Първото нещо е, че сървърът трябва да знае, че искате той да ви обслужва уеб страница. + +Представете си пощенска кутия (порт), която се следи за входящи писма (заявки). Това се прави от уеб сървър. Уеб сървърът чете писмото и след това изпраща отговор с уеб страница. Но когато искате да изпратите нещо, трябва да имате някакво съдържание. А Django е нещо, което ви помага да създавате съдържанието. + +## Какво се случва, когато някой поиска уебсайт от вашия сървър? + +Когато заявката стигне до уеб сървър, тя се предава на Django, който се опитва да разбере какво всъщност се иска. Първо взема адреса на уеб страница и се опитва да разбере какво да прави. Тази част се прави от **urlresolver** на Django (обърнете внимание, че адресът на уебсайт се нарича URL - Uniform Resource Locator - така че името *urlresolver* има смисъл). Не е много умно - взема списък от модели и се опитва да съответства на URL адреса. Django проверява шаблоните отгоре надолу и ако нещо съвпада, Django предава заявката на свързаната функция (която се нарича *view*). + +Представете си пощенски превозвач с писмо. Тя върви по улицата и проверява всеки домашен номер спрямо този на писмото. Ако съвпада, тя поставя писмото там. Ето как работи urlresolver! + +Във функцията *view* се правят всички интересни неща: можем да разгледаме база данни, за да потърсим някаква информация. Може би потребителят иска да промени нещо в данните? Като писмо, в което се казва: „Моля, променете описанието на моята работа“. *view* може да провери дали ви е позволено да го направите, след това актуализира описанието на работата за вас и изпраща обратно съобщение: „Готово!“ Тогава *view* генерира отговор и Django може да го изпрати до уеб браузъра на потребителя. + +Описанието по-горе е малко опростено, но все още не е необходимо да знаете всички технически неща. Наличието на обща идея е достатъчно. + +Така че вместо да се гмурнем твърде много в детайли, ще започнем да създаваме нещо с Django и ще научим всички важни части по пътя! \ No newline at end of file diff --git a/bg/django_admin/README.md b/bg/django_admin/README.md new file mode 100644 index 00000000000..205ab964b48 --- /dev/null +++ b/bg/django_admin/README.md @@ -0,0 +1,57 @@ +# Администратор на Django + +За добавяне, редактиране и изтриване на публикациите, които току-що моделирахме, ще използваме администратора на Django. + +Нека отворим файла `blog/admin.py` в редактора на кода и заменим съдържанието му с това: + +{% filename %}blog/admin.py{% endfilename %} + +```python +from django.contrib import admin +from .models import Post + +admin.site.register(Post) +``` + +Както можете да видите, ние импортираме (включваме) модела Post, дефиниран в предишната глава. За да направим модела ни видим на страницата на администратора, трябва да регистрираме модела с `admin.site.register(Post)`. + +Добре, време да разгледаме нашия модел Post. Не забравяйте да стартирате `python manage.py runserver` в конзолата, за да стартирате уеб сървъра. Отидете до вашия браузър и напишете адреса http://127.0.0.1:8000/admin/. Ще видите страница за вход като тази: + +![Страница за вход](images/login_page2.png) + +За да влезете, трябва да създадете *superuser* - потребителски акаунт, който има контрол върху всичко в сайта. Върнете се в командния ред, напишете `python manage.py createsuperuser` и натиснете enter. + +> Не забравяйте, че за да пишете нови команди, докато уеб сървърът работи, отворете нов прозорец на терминала и активирайте своя virtualenv. Прегледахме как да пишете нови команди във **Вашия първи проект на Django!**, в секцията **Стартиране на уеб сървъра**. + +{% filename %}macOS or Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py createsuperuser + + +{% 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. + + +Върнете се в браузъра си. Влезте с избраните от вас име и парола на superuser; трябва да видите таблото за управление на Django. + +![Django администратор](images/django_admin3.png) + +Отидете на постове и експериментирайте малко с тях. Добавете пет или шест публикации в блога. Не се притеснявайте за съдържанието - вижда се само на вашия локален компютър - можете да копирате и поставите някакъв текст от този урок, за да спестите време. :) + +Уверете се, че поне две или три публикации (но не всички) имат зададена дата на публикуване. По-късно ще бъде полезно. + +![Django администратор](images/edit_post3.png) + +Ако искате да знаете повече за администратора на Django, трябва да проверите документацията на Django: https://docs.djangoproject.com/en/2.2/ref/contrib/admin/ + +Това вероятно е подходящ момент да вземете кафе (или чай) или нещо за хапване, за да се "заредите". Създадохте първия си модел Django - заслужавате малка почивка! \ No newline at end of file diff --git a/bg/django_admin/images/django_admin3.png b/bg/django_admin/images/django_admin3.png new file mode 100644 index 00000000000..fb221bd18e1 Binary files /dev/null and b/bg/django_admin/images/django_admin3.png differ diff --git a/bg/django_admin/images/edit_post3.png b/bg/django_admin/images/edit_post3.png new file mode 100644 index 00000000000..57299b6f5af Binary files /dev/null and b/bg/django_admin/images/edit_post3.png differ diff --git a/bg/django_admin/images/login_page2.png b/bg/django_admin/images/login_page2.png new file mode 100644 index 00000000000..c16d1aa4289 Binary files /dev/null and b/bg/django_admin/images/login_page2.png differ diff --git a/bg/django_forms/README.md b/bg/django_forms/README.md new file mode 100644 index 00000000000..eca45d6389a --- /dev/null +++ b/bg/django_forms/README.md @@ -0,0 +1,452 @@ +# Django форми + +Последното нещо, което искаме да направим в нашия уеб сайт е да създадем начин за добавяне и редактиране на публикации в блога. Django администратора е супер, но е по-трудно да се персонализира и направи приятно на външен вид. С формите ще имаме абсолютно надмощие над нашия изглед - можем да правим почти всичко което може да си представим! + +Хубавото на Django формите е, че може да дефинираме форма от самото начало или да създадем ModelForm, в която ще съхраняваме резултатът от формата на модела. + +Точно това искаме да направим: ще създадем форма за нашия `Post` модел. + +Като всяка важна част от Django, формите също имат собствен файл: `forms.py`. + +Трябва да създадем файл с това наименование в директорията на `blog`. + + blog + └── forms.py + + +И така, нека да отворим IDE и напишем следният код: + +{% filename %}blog/forms.py{% endfilename %} + +```python +from django import forms + +from .models import Post + +class PostForm(forms.ModelForm): + + class Meta: + model = Post + fields = ('title', 'text',) +``` + +Първо трябва да въведем Django формите (`from django import forms`) и нашия `Post` модел (`from .models import Post`). + +`PostForm`, както забелязахте е името на нашата форма. Трябва да кажем на Django, че тази форма е `ModelForm` (така че Django да направи малко магия за нас) - `forms.ModelForm` отговаря за това. + +След това с `class Meta`, казваме на Django кой модел трябва да се използва за да се създаде тази форма (`model = Post`). + +Най-накрая трябва да кажем с какви полета ще разполагаме в нашата форма. При този сценарий искаме само title и text да бъдат показани – author ще бъде този, който в момента е влязъл с профила си (ти!) и created_date трябва автоматично да се създаде, когато започнем нова публикация (като в кода), нали? + +И това е! Всичко от което имаме нужда в момента е да използваме формата във изгледа и да я покажем в шаблона. + +И така още веднъж, ще създадем връзка до страницата чрез URL, view и template. + +## Връзка до страницата чрез формата + +Време е да отворим `blog/templates/blog/base.html` в редактора. В `div` наречен `page-header` ще добавим връзка: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + +``` + +Забележете, че искаме да извикаме нашия нов изглед `post_new`. Класът `"glyphicon glyphicon-plus"` е предоставен от темата на bootstrap, която използваме и ще покаже знака плюс. + +След добаване на този ред, вашия HTML файл трябва да изглежда ето така: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% load static %} + + + Django Girls blog + + + + + + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ + + +``` + +След запазване и обновяване на страницата http://127.0.0.1:8000 трябва да виждате познатата грешка `NoReverseMatch`. Така ли е? Добре! + +## URL + +Отваряме файла `blog/urls.py` в редактора и добавяме ред: + +{% filename %}blog/urls.py{% endfilename %} + +```python +path('post/new/', views.post_new, name='post_new'), +``` + +И последния код трябва да изглежда така: + +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views + +urlpatterns = [ + 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`. Нека го добавим сега. + +## post_new изглед + +Време е да отворим файлът `blog/views.py` в редактора и да добавим следните няколко реда от код при останалите във формата + +{% filename %}blog/views.py{% endfilename %} + +```python +from .forms import PostForm +``` + +И след това нашия изглед: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +За да създадем нова форма `Post`, трябва да извикаме `PostForm()` и да я препратим към шаблона (template). Ще се върнем отново на този изглед (view), но сега нека бързо да създадем шаблон (template) за формата. + +## Шаблон (Template) + +Трябва да създадем файл `post_edit.html` в директория `blog/templates/blog` и да го отворим в редактора ни за код. За да направим така, че формата да работи са ни нужни няколко неща: + +* Трябва да покажем формата. Можем да направим това чрез (например) {% raw %}`{{ form.as_p }}`{% endraw %}. +* Горният ред трябва да бъде обвит с HTML form tag: `
...
`. +* Трябва ни бутон `Save`. Това правим с HTML button: ``. +* И най-накрая, точно след отварящия `
` tag трябва да добавим {% raw %}`{% csrf_token %}`{% endraw %}. Това е много важно, тъй като прави нашата форма надеждна! Ако забравите за това, Django ще се оплаче когато се опитате да запазите формата. + +![CSFR Забранена страница](images/csrf2.png) + +Добре, нека видим сега как трябва да изглежда HTML кода в `post_edit.html`: + +{% filename %}blog/templates/blog/post_edit.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} +

New post

+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} +``` + +Време е да обновим страницата! Иха! Формата се показа! + +![Нова форма](images/new_form2.png) + +Но, чакай малко! Когато напишеш нещо в полетата `title` и `text` и се опиташ да го запазиш, какво ще стане? + +Нищо! Пак сме на същата страница и нашият текст изчезна... и няма нова публикация. Какво се обърка? + +Отговорът е: нищо. Трябва още малко да поработим върху нашия изглед (*view*). + +## Запазване на формата + +Отворете пак `blog/views.py` в редактора. В момента всичко, което имаме в изгледа на `post_new` е следното: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Когато изпратим форматата се връщаме пак на същият изглед, но този път имаме повече данни в запитването (`request`) или по-точно в `request.POST` (наименованието няма нищо общо с блога "post", а с факта, че "публикуваме" информация). Помните ли как в нашия HTML файл при дефинирането на `
` имахме променлива `method="POST"`? Всички тези полета са сега в `request.POST`. Не трябва да преименувате `POST` (друга валидна стойност за `method` е `GET`, но нямаме време да обясним каква е разликата). + +И така в нашия изглед (*view*) имаме две отделни ситуации да разрешим: първо, когато достъпваме страницата за първи път и искаме празна форма, и второ, когато се върнем назад към изгледа (*view*) с всичките данни които сме въвели във формата. Тоест трябва да добавим условие (ще използваме `if` за тази цел): + +{% filename %}blog/views.py{% endfilename %} + +```python +if request.method == "POST": + [...] +else: + form = PostForm() +``` + +Време е да попълним празното място `[...]`. Ако `method`-а е `POST` тогава искаме да изградим `PostForm` с данни от формата, нали? Ще направим това както следва: + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(request.POST) +``` + +Следващото нещо е да проверим дали формата е вярна (всики полета които се изискват да са определени и да няма неправилно въведени стойности). Правим това чрез `form.is_valid()`. + +Проверяваме дали формата е валидна и ако да в запазваме! + +{% filename %}blog/views.py{% endfilename %} + +```python +if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() +``` + +Основно имаме две неща: запазваме формата с `form.save` и добавяме автор (тъй като няма поле `author` във формата `PostForm` а това поле се изисква). `commit=False` означава, че не искаме все още да запазим моделът `Post` - искаме да добавим първо автора. През повечето време ще използвате `form.save()` без `commit=False`, но в този случай трябва да се снабдим с него. `post.save()` ще запази промените (добавяне на автора) и новата публикация в блога е създадена! + +Накрая, би било добре ако можем веднага да отидем на страницата `post_detail` за нашата новосъздадена блог публикация, нали? За да направим това трябва ни трябва още едно въвеждане: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import redirect + +``` + +Добавете го в самото начало на вашия файл. И сега можем да кажем "отиди на страница `post_detail` за новосъздадената публикация": + +{% filename %}blog/views.py{% endfilename %} + +```python +return redirect('post_detail', pk=post.pk) + +``` + +`post_detail` е името на изгледа, на който искаме да отидем. Помните ли, че този изглед (*view*) изискваше стойност `pk`? За да го предадем на изгледа използваме `pk=post.pk`, където `post` е новосъздадена публикация! + +И така, говорихме много, но може би искаме да видим как изглежда всичко, нали? + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + if request.method == "POST": + form = PostForm(request.POST) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Нека видим дали работи. Отидете на страница http://127.0.0.1:8000/post/new, добвавете `title` и `text`, запазете..и voilà! Новата публикация е добавена и сме пренасочени към страница `post_detail`! + +Може би забелязахте, че избираме датата на публикуване преди да запазим публикацията. По-късно ще се запознаем с *publish button* in **Django Girls Tutorial: Extensions**. + +Това е страхотно! + +> Тъй като наскоро ползвахме административния интерфейс на Django, системата в момента си мисли, че сме влезнали в акаунта си. Има няколко ситуации, които могат да доведат до излизане от акаунта (затваряне на търсачката, рестартиране на базата данни, и др.). Ако при създаване на нова публикация получавате грешки свързани с потребител, който не е влязал в акаунта си, отидете на администраторската страница http://127.0.0.1:8000/admin и влезте пак в акаунта си. Това ще реши проблема временно. Има дълготрайно решение на проблема, което ви очаква в раздела **Домашна работа: добавяне на сигурност към уеб страницата ви!** намиращ се след главното ръководство. + +![Грешка при влизане](images/post_create_error.png) + +## Проверка на формите (Form validation) + +Сега ще ви покажем колко са готини формите на Django. Една публикация трябва да има полета за `title` и `text`. В нашия `Post` модел не казахме дали тези полета се изискват (както при `published_date`), така че Django очаква те да са нагласени по подразбиране. + +Опитайте се да запазите формата без `title` и `text`. Познайте какво ще стане! + +![Проверка на форма](images/form_validation2.png) + +Django се грижи за проверката дали всички полета във формата ни са правилни. Не е ли готино? + +## Редактиране на формата + +Сега знаем как да добавим нова публикация. Но какво ако искаме да променим вече съществуваща? Това много прилича на това, което тъкмо направихме. Нека набързо да създадем няколко важни неща. (Ако не разбирате нещо, попитайте инструктора си или вижте в предходните глави, тъй като вече минахме врез всичко това.) + +Отворете `blog/templates/blog/post_detail.html` в редактора и добавете реда + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + +``` + +така че шаблона (template) да изглежда така: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} + +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endblock %} +``` + +Отворете `blog/urls.py` в редактора и добавете този ред: + +{% filename %}blog/urls.py{% endfilename %} + +```python + path('post//edit/', views.post_edit, name='post_edit'), +``` + +Ще използваме пак шаблона `blog/templates/blog/post_edit.html`, така че последното липсващо нещо е изгледа (*view*). + +Нека отворим `blog/views.py` в редактора и да добваим това накрая на файла: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_edit(request, pk): + post = get_object_or_404(Post, pk=pk) + if request.method == "POST": + form = PostForm(request.POST, instance=post) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm(instance=post) + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Това изглежда почти еднакво с нашия изглед `post_new`, нали? Но не изцяло. Първо зададохме допълнителен `pk` параметър от `urls`. После взехме `Post` модела, който искаме да променим с `get_object_or_404(Post, pk=pk)` и накрая, когато създаваме форма, подаваме тази публикация като инстанция (`instance`), когето запазваме формата... + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(request.POST, instance=post) +``` + +... и когато отваряме формата с публикацията, която искаме да променим: + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(instance=post) +``` + +Добре! Нека проверим дали работи! Да отидем на страница `post_detail`. Трябва да има бутон за редактиране в горния десен ъгъл: + +![Бутон за редактиране](images/edit_button2.png) + +Когато го натиснете, ще видите формата с нашата публикация: + +![Форма на редактиране](images/edit_form2.png) + +Можете да промените заглавието или текста и да запазите промените! + +Поздравления! Вашата апликация изглежда все по- и по-завършена! + +Ако искате повече информация относно Django формите, трябва да прочетете документацията: https://docs.djangoproject.com/en/2.2/topics/forms/ + +## Сигурност + +Да можете да създадете нови публикация чрез един клие е страхотно! Но сега всеки, който посети вашата страница ще може да създаде нова публикация и това е нещо, което може би не искате. Нека направим така, че бутонът да се показва за вас, но не и за останалите. + +Отворете `blog/templates/blog/base.html` в редактора и намерете `page-header` `div` и реда посочващ anchor tag, който по-рано сложихте там. Трябва да изглежда така: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + +``` + +Ще добавим още един `{% if %}` към това, което ще накара връзката да се показва само за потребители, които са влезнали в административния панел. В момента това си само ти! Променете `` да изглежда така: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% if user.is_authenticated %} + +{% endif %} +``` + +Този `{% if %}` ще накара връзката да се изпраща до търсачката, само ако потребителят, който изисква страницата е влязъл в акаунта си. Това не предпазва напълно от създаване на нови публикации, но е добре като за начало. Ще покрием повече относно сигурността в продължението на уроците. + +Помните ли иконата за редактиране, която тъкмо добавихме в страницата ни с детайли? Ще добавим същата промяна и там, така че други хора да не могат да променят съществуващи публикации. + +Отворете `blog/templates/blog/post_detail.html` в редактрора и намерете този ред: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + +``` + +Променете го на това: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% if user.is_authenticated %} + +{% endif %} +``` + +Тъй като най-вероятно сте в акаунта си, ако опресните страницата, няма да видите разликата. Заредете страницата в друга търсачка или в инкогнито прозорец (наречен още "InPrivate" в Windows Edge) и ще видите, че връзката не се показва и иконата също не се появява на екрана! + +## Още едно нещо: време за deploy + +Нека видим дали всичко работи на PythonAnywhere. Време е за още един deploy! + +* Първо съхранете новия си код и го пратете към GitHub: + +{% filename %}command-line{% endfilename %} + + $ git status + $ git add --all . + $ git status + $ git commit -m "Added views to create/edit blog post inside the site." + $ git push + + +* След това в [PythonAnywhere Bash конзолата](https://www.pythonanywhere.com/consoles/): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Не забравяйте да замените `` с вашият PythonAnywhere субдомейн без скобите.) + +* Накрая отидете на ["Web" страница](https://www.pythonanywhere.com/web_app_setup/), използвайте бутона от менюто в горният десен ъгъл на конзолата) и натиснете **Reload**. Опреснете блога си https://subdomain.pythonanywhere.com за да видите промените. + +Това е! Поздравления :) \ No newline at end of file diff --git a/bg/django_forms/images/csrf2.png b/bg/django_forms/images/csrf2.png new file mode 100644 index 00000000000..ee946324f92 Binary files /dev/null and b/bg/django_forms/images/csrf2.png differ diff --git a/bg/django_forms/images/drafts.png b/bg/django_forms/images/drafts.png new file mode 100644 index 00000000000..1d62f8866f4 Binary files /dev/null and b/bg/django_forms/images/drafts.png differ diff --git a/bg/django_forms/images/edit_button2.png b/bg/django_forms/images/edit_button2.png new file mode 100644 index 00000000000..804674f0965 Binary files /dev/null and b/bg/django_forms/images/edit_button2.png differ diff --git a/bg/django_forms/images/edit_form2.png b/bg/django_forms/images/edit_form2.png new file mode 100644 index 00000000000..3d4e525d5d0 Binary files /dev/null and b/bg/django_forms/images/edit_form2.png differ diff --git a/bg/django_forms/images/form_validation2.png b/bg/django_forms/images/form_validation2.png new file mode 100644 index 00000000000..6e333af3077 Binary files /dev/null and b/bg/django_forms/images/form_validation2.png differ diff --git a/bg/django_forms/images/new_form2.png b/bg/django_forms/images/new_form2.png new file mode 100644 index 00000000000..8f2a1088070 Binary files /dev/null and b/bg/django_forms/images/new_form2.png differ diff --git a/bg/django_forms/images/post_create_error.png b/bg/django_forms/images/post_create_error.png new file mode 100644 index 00000000000..d140e8e2419 Binary files /dev/null and b/bg/django_forms/images/post_create_error.png differ diff --git a/bg/django_installation/README.md b/bg/django_installation/README.md new file mode 100644 index 00000000000..8101319c259 --- /dev/null +++ b/bg/django_installation/README.md @@ -0,0 +1,7 @@ +# Инсталиране на Django + +> **Забележка** Ако използвате Chromebook, пропуснете тази глава и се уверете, че следвате инструкциите [Настройка на Chromebook](../chromebook_setup/README.md). +> +> **Забележка** Ако вече сте минали през стъпките за инсталиране, тогава вече сте направили това - можете да преминете направо към следващата глава! + +{% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/bg/django_installation/instructions.md b/bg/django_installation/instructions.md new file mode 100644 index 00000000000..e2497a8518e --- /dev/null +++ b/bg/django_installation/instructions.md @@ -0,0 +1,231 @@ +> Част от този раздел е базиран на уроци от Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> +> Част от този раздел е базиран на [ django-marcador    урок ](http://django-marcador.keimlink.de/) лицензиран съгласно Creative Commons    Attribution-ShareAlike 4.0 международен лиценз. Урокът за джанго-маркадор е защитен с авторско право от Markus Zapke-Gründemann et al. + +## Виртуална среда + +Преди да инсталираме Django, ще ви накараме да инсталирате изключително полезен инструмент, който да ви помогне да поддържате средата си на кодиране подредена на вашия компютър. Възможно е да пропуснете тази стъпка, но силно се препоръчва. Като започнете с възможно най-добрата настройка, ще ви спести много проблеми в бъдеще! + +Така че, нека създадем **виртуална среда** (наричана още *virtualenv*). Virtualenv ще изолира вашата настройка на Python/Django на база проект. Това означава, че всички промени, които правите в един уебсайт, няма да засегнат други, които също разработвате. Яко, нали? + +Всичко, което трябва да направите, е да намерите директория, в която искате да създадете `virtualenv`; вашата начална директория, например. В Windows може да изглежда като `C:\Users\Name` (където `Name` е името на вашия логин). + +> **ЗАБЕЛЕЖКА:** В Windows се уверете, че тази директория не съдържа акцентирани или специални знаци; ако вашето потребителско име съдържа символи с ударение, използвайте друга директория, например, `C:\djangogirls`. + +За този урок ще използваме нова директория `djangogirls` от вашата домашна директория: + +{% filename %}command-line{% endfilename %} + + $ mkdir djangogirls + $ cd djangogirls + + +Ще направим virtualenv, наречен `myvenv`. Общата команда ще бъде във формата: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + + + +За да създадете нов `virtualenv `, трябва да отворите командния ред и да стартирате `python -m venv myvenv`. Ще изглежда така: + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls> python -m venv myvenv + + +Където `myvenv` е името на вашата `virtualenv`. Можете да използвате всяко друго име, но се придържайте към малки букви и не използвайте интервали, ударения или специални знаци. Също така е добре името да бъде кратко - ще го препращате много! + + + + + +Можем да създадем `virtualenv` и в Linux и macOS, като пуснем `python3 -m venv myvenv`. Ще изглежда така: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + +`myvenv` е името на вашата `virtualenv`. Можете да използвате всяко друго име, но се придържайте към малки букви и не използвайте интервали. Също така е добре името да бъде кратко, понеже ще го използвате често! + +> **ЗАБЕЛЕЖКА:** В някои версии на 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=python3.6 myvenv +> +> +> **ЗАБЕЛЕЖКА:** Ако получите грешка като +> +> {% filename %}command-line{% endfilename %} +> +> E: Unable to locate package python3-venv +> +> +> вместо това стартирайте: +> +> {% filename %}command-line{% endfilename %} +> +> sudo apt install python3.6-venv +> + + + +## Работа с virtualenv + +Командата по-горе ще създаде директория с име `myvenv` (или каквото име сте си избрали), която съдържа нашата виртуална среда (по същество куп директории и файлове). + + + +Стартирайте виртуалната си среда като напишете: + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls> myvenv\Scripts\activate + + +> **Забележка:** При Windows 10 можете да получите грешка в прозореца на PowerShell `execution of scripts is disabled on this system`. В този случай трябва да отворите нов прозорец на PowerShell като изберете "Run as Administrator." След това напишете следната команда преди да стартирате виртуалната си среда: +> +> {% filename %}command-line{% endfilename %} +> +> C:\WINDOWS\system32> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned +> Промяна при политиката на изпълнението +> Политиката на изпълнението ви предпазва от скриптове на които нямате доверие. При промяна на политиката на изпълнение може да бъдете изложени на опасен риск описан в темата about_Execution_Policies help в http://go.microsoft.com/fwlink/?LinkID=135170. Искате ли да промените политиката на изпълнението? [Y] ДА [A] Да на всичко [N] Не [L] Не на всичко [S] Прекрати [?] Помощ (по подразбиране е "N"): A +> + + + +> **Забележка:** За потребителите на популярният редактор VS Code, който идва с интегриран терминал базиран на windows PowerShell, и ако искате да се придържате към интегрирания терминал, трябва да напишете следната команда за да активирате виртуалната си среда: +> +> $ . myvenv\Scripts\activate.ps1 +> +> +> Предимството е, че не трябва да сменяте прозорците между IDE и command-line. + + + + + +Стартирайте виртуалната си среда като напишете: + +{% filename %}command-line{% endfilename %} + + $ source myvenv/bin/activate + + +Помнете, че трябва да заместите `myvenv` с името на вашата избрана `virtualenv`. + +> **Забележка:** понякога `source` може да не е на лице. В тези случаи трябва да направите следното: +> +> {% filename %}command-line{% endfilename %} +> +> $ . myvenv/bin/activate +> +> + + + +Ще разберете, че виртуалната ви среда е стартирана като видите подсказването в конзолата ви, което започва с `(myvenv)`. + +Когато работите от виртуална среда, `python` автоматично ще се насочи към правилната версия, така че може да използвате команда `python` вместо `python3`. + +Добре, сега имаме всичкo необходимо на едно място. Най-накрая може да инсталираме Django! + +## Инсталиране на Django {#django} + +Сега след като имате стартирана `virtualenv` може да инсталирате Django. + +Преди да направим това обаче ще проверим дали имаме инсталирана последната версия на `pip`, софтуерът, който използваме да инсталираме Django: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~$ python -m pip install --upgrade pip + + + +### Инсталиране на пакети с изисквания + +Файла съдържа лист от зависимости, които да се инсталират с командата `pip install`: + +Първо създайте файл с име `requirements.txt` в папка `djangogirls`, като използвате IDE инсталиран по-рано. Това става като отворите нов файл в редактора и след това го запазите като `requirements.txt` в папка `djangogirls/`. Вашата директория трябва да изглежда така: + + djangogirls + ├── myvenv + │ └── ... + └───requirements.txt + + +Във вашият `djangogirls/requirements.txt` файл трябва да добавите следното: + +{% filename %}djangogirls/requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +Сега напишете команда `pip install -r requirements.txt` за да инсталирате Django. + +{% filename %}command-line{% endfilename %} + + (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.1MB) + Installing collected packages: Django + Successfully installed Django-{{ book.django_version }} + + + + +> Ако се появи грешка когато извикате команда pip на Windows платформа, проверете дали името на пътя на проекта ви съдържа празно място, знак за ударение или други специални знаци. (например , `C:\Users\User Name\djangogirls`). Ако съдържа, моля помислете за друго място без разстояние, знак за ударение или други специални знаци (предложение: `C:\djangogirls`). Създайте нова виртуална среда в новата директория, след това изтрийте старата и опитайте отново командата. (Преместването на папката с виртуална среда няма да работи, тъй като виртуалната среда използва абсолютни пътеки.) + + + + + +> Вашият command line може да забие след като се опитате да инсталирате Django. Ако това се случи напишете следната команда вместо горната: +> +> {% filename %}command-line{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> + + + + + +> Ако получите грешка при извикване на pip при Ubuntu 12.04 напишете следната команда `python -m pip install -U --force-reinstall pip` за да оправите инсталацията на pip във виртуалната среда. + + + +Това е! Сега вече (най-накрая) сте готови да създадете Django апликация! \ No newline at end of file diff --git a/bg/django_models/README.md b/bg/django_models/README.md new file mode 100644 index 00000000000..05c4135d206 --- /dev/null +++ b/bg/django_models/README.md @@ -0,0 +1,201 @@ +# Модели на Django + +Това, което искаме да създадем сега, е нещо, което ще съхранява всички публикации в нашия блог. Но за да можем да направим това, трябва да поговорим малко за неща, наречени `обекти`. + +## Обекти + +Има концепция в програмирането, наречена `обектно-ориентирано програмиране`. Идеята е, че вместо да пишем всичко като скучна последователност от инструкции за програмиране, можем да моделираме нещата и да определим как те си взаимодействат помежду си. + +И така, какво е обект? Това е съвкупност от свойства и действия. Звучи странно, но ще ви дадем пример. + +Ако искаме да моделираме котка, ще създадем обект `Cat`, който има някои свойства като `color`, `age`, `mood` (като добър, лош или сънен;)) и `owner` (на който може да бъде назначен обект `Person` - или може би в случай на бездомна котка, този свойство може да бъде празно). + +Тогава `Cat` има някои действия: `purr`, `scratch` или `feed` (в този случай ще дадем на котката `CatFood`, който може да бъде отделен обект със свойства, като `taste`). + + Cat + -------- + color + age + mood + owner + purr() + scratch() + feed(cat_food) + + + CatFood + -------- + taste + + +Така че в общи линии идеята е да се опишат реални неща в код със свойства (наречени `свойства на обекта`) и действия (наречени `методи`). + +Как ще моделираме публикации в блогове тогава? Искаме да изградим блог, нали? + +Трябва да отговорим на въпроса: Какво е публикация в блога? Какви свойства трябва да има? + +Е, със сигурност нашата публикация в блога се нуждае от текст с нейното съдържание и заглавие, нали? Също така би било хубаво да знаем кой го е написал - така че се нуждаем от автор. И накрая, искаме да знаем кога публикацията е създадена и публикувана. + + Post + -------- + title + text + author + created_date + published_date + + +Какви неща могат да се направят с публикация в блог? Би било хубаво да има някакъв `метод`, който публикува публикацията, нали? + +Така че ще се нуждаем от метод `publish`. + +Тъй като вече знаем какво искаме да постигнем, нека започнем да го моделираме в Django! + +## Django model + +Знаейки какво е обект, можем да създадем модел на Django за нашата публикация в блога. + +Моделът в Django е специален вид обект - той се записва в `database`. База данни е съвкупност от данни. Това е място, на което ще съхранявате информация за потребители, публикации в блога си и т.н. Ще използваме база данни SQLite, за да съхраняваме нашите данни. Това е адаптерът за база данни Django по подразбиране - това ще ни бъде достатъчно в момента. + +Можете да мислите за модел в базата данни като електронна таблица с колони (полета) и редове (данни). + +### Създаване на приложение + +За да поддържаме всичко подредено, ние ще създадем отделно приложение вътре в нашия проект. Много е хубаво да се организира всичко от самото начало. За да създадем приложение, трябва да стартираме следната команда в конзолата (от директорията `djangogirls`, където е файлът ` manage.py`): + +{% filename %}macOS и Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py startapp blog + + +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + + +Ще забележите, че се създава нова директория `blog` и сега съдържа редица файлове. Директориите и файловете в нашия проект трябва да изглеждат така: + + djangogirls + ├── blog + │ ├── admin.py + │ ├── apps.py + │ ├── __init__.py + │ ├── migrations + │ │ └── __init__.py + │ ├── models.py + │ ├── tests.py + │ └── views.py + ├── db.sqlite3 + ├── manage.py + ├── mysite + │ ├── __init__.py + │ ├── settings.py + │ ├── urls.py + │ └── wsgi.py + ├── myvenv + │ └── ... + └── requirements.txt + + + +След създаването на приложение също трябва да кажем на Django, че трябва да го използва. Правим това във файла `mysite/settings.py` -- отваряме го във вашия редактор на кодове. Трябва да намерим `INSTALLED_APPS` и да добавим ред, съдържащ `'blog.apps.BlogConfig'`. Така че крайният продукт трябва да изглежда така: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog.apps.BlogConfig', +] +``` + +### Създаване на модел на блог публикация + +Във файла `blog/models.py` дефинираме всички обекти, наречени `Models` - това е място, на което ще дефинираме нашата публикация в блога. + +Нека да отворим `blog/models.py` в редактора на кода, да премахнем всичко от него и да напишем код така: + +{% filename %}blog/models.py{% endfilename %} + +```python +from django.conf import settings +from django.db import models +from django.utils import timezone + + +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) + + def publish(self): + self.published_date = timezone.now() + self.save() + + def __str__(self): + return self.title +``` + +> Проверете двукратно дали използвате два знака за подчертаване (`_`) от всяка страна на `str`. Тази конвенция се използва често в Python и понякога ги наричаме и „dunder“ (съкратено от „двойно-подчертаване“, "double-underscore"). + +Изглежда страшно, нали? Но не се притеснявайте - ще ви обясним какво означават тези редове! + +Всички редове, започващи с `from` или `import`, са редове, които добавят части от други файлове. Така че вместо да копираме и поставяме едни и същи неща във всеки файл, можем да включим някои части с `from ... import ...`. + +`class Post (models.Model):` - този ред дефинира нашия модел (това е `object`). + +- `class` е специална ключова дума, която показва, че дефинираме обект. +- `Post` е името на нашия модел. Можем да му дадем различно име (но трябва да избягваме специални символи и бяло пространство). Винаги започвайте име на клас с главна буква. +- `models.Model` означава, че публикацията е модел на Django, така че Django знае, че трябва да бъде записана в базата данни. + +Сега дефинираме свойствата, за които говорихме: `title`, `text`, `created_date`, `published_date` и `author`. За целта трябва да определим типа на всяко поле (текст ли е? Число? Дата? Отношение към друг обект, като User?) + +- `models.CharField` -- по този начин определяте текст с ограничен брой знаци. +- `models.TextField` -- това е за дълъг текст без ограничение. Звучи идеално за съдържание в блог, нали? +- `models.DateTimeField` -- това е дата и час. +- `models.ForeignKey` -- това е връзка към друг модел. + +Тук няма да обясняваме всяка част от кода, тъй като това ще отнеме твърде много време. Трябва да разгледате документацията на Django, ако искате да знаете повече за моделните полета и как да дефинирате неща, различни от описаните по-горе (https://docs.djangoproject.com/en/2.2/ref/models/fields/#field -types). + +Какво ще кажете за `def publish(self):`? Това е точно методът `publish`, за който говорихме преди. `def` означава, че това е функция/метод и `publish` е името на метода. Можете да промените името на метода, ако искате. Правилото за именуване е, че използваме малки букви и подчертавки вместо интервали (прасни места). Например метод, който изчислява средна цена, може да се нарече `calculate_average_price`. + +Методите често `връщат` нещо. Има пример за това в метода `__str__`. В този сценарий, когато извикаме `__str __ ()`, ще получим текст (**string**) със заглавие на публикацията. + +Също така забележете, че и двете `def publish(self):` и `def __str__(self):` са отредени в нашия клас. Тъй като Python е чувствителен към бялото пространство, трябва да отстъпим методите си вътре в класа. В противен случай методите няма да принадлежат към класа и можете да получите някакво неочаквано поведение. + +Ако нещо все още не е ясно за моделите, не се колебайте да попитате своя ментор! Знаем, че е сложно, особено когато научиш едновременно какво са обекти и функции. Но да се надяваме, че сега изглежда малко по-малко вълшебно за вас! + +### Създайте таблици за модели във вашата база данни + +Последната стъпка тук е да добавим нашия нов модел към базата данни. Първо трябва да накараме Django да разбере, че имаме някои промени в нашия модел. (Току-що го създадохме!) Отидете до прозореца на вашата конзола и напишете `python manage.py makemigrations blog`. Ще изглежда така: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py makemigrations blog + Migrations for 'blog': + blog/migrations/0001_initial.py: + + - Create model Post + + +**Забележка:** Не забравяйте да запазите файловете, които редактирате. В противен случай компютърът ви ще изпълни предишната версия, която може да ви даде неочаквани съобщения за грешка. + +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: + Applying blog.0001_initial... OK + + +Ура! Моделът ни на публикация вече е в нашата база данни! Би било хубаво да го видите, нали? Преминете към следващата глава, за да видите как изглежда вашата публикация! \ No newline at end of file diff --git a/bg/django_orm/README.md b/bg/django_orm/README.md new file mode 100644 index 00000000000..ccb19494aa3 --- /dev/null +++ b/bg/django_orm/README.md @@ -0,0 +1,221 @@ +# Django ORM и QuerySets + +В тази глава ще научите как Django се свързва с базата данни и съхранява данни в нея. Нека се потопим! + +## Какво е QuerySet? + +QuerySet е по същество списък на обекти на даден Модел. QuerySets ви позволяват да четете данните от базата данни, да ги филтрирате и да ги подредите.. + +Най-лесно е да се учи чрез пример. Нека опитаме това, нали? + +## Django shell + +Отворете вашата локална конзола (не на PythonAnywhere) и въведете тази команда: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py shell + + +Ефектът трябва да бъде такъв: + +{% filename %}command-line{% endfilename %} + +```python +(InteractiveConsole) +>>> +``` + +Вече сте в интерактивната конзола на Django. Това е точно като Python конзолата, но с допълнителна магия на Django. :) Тук можете да използвате всички Python команди. + +### Всички обекти + +Нека се опитаме първо да покажем всички наши публикации. Можете да направите това със следната команда: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +Traceback (most recent call last): + File "", line 1, in +NameError: name 'Post' is not defined +``` + +Ами сега! Появи се грешка. Това ни казва, че няма Post. Правилно е - забравихме да го внесем първо! + +{% filename %}command-line{% endfilename %} + +```python +>>> from blog.models import Post +``` + +Импортираме модела `Post` от `blog.models`. Нека опитаме отново да покажем всички публикации: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, ]> +``` + +Това е списък на публикациите, които създадохме по-рано! Създадохме тези публикации чрез администраторския интерфейс на Django. Но сега искаме да създаваме нови публикации с помощта на Python, така че как да направим това? + +### Създаване на обект + +Ето как създавате нов обект Post в базата данни: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') +``` + +Но тук имаме една липсваща съставка: `me`. Трябва да предадем инстанция на модел `User` като автор. Как да направим това? + +Нека първо да импортираме модел User: + +{% filename %}command-line{% endfilename %} + +```python +>>> from django.contrib.auth.models import User +``` + +Какви потребители имаме в нашата база данни? Опитайте това: + +{% filename %}command-line{% endfilename %} + +```python +>>> User.objects.all() +]> +``` + +Това е суперпотребителят, който създадохме по-рано! Нека сега вземем потребителя (коригирайте този ред, за да използвате вашето потребителско име): + +{% filename %}command-line{% endfilename %} + +```python +>>> me = User.objects.get(username='ola') +``` + +Както можете да видите, сега `get` a `User` с `username`, което се равнява на „ola“. Яко! + +Сега най-накрая можем да създадем нашия пост: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') + +``` + +Ура! Искате ли да проверите дали работи? + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, , ]> +``` + +Ето, още една публикация в списъка! + +### Добавете още публикации + +Вече можете да се позабавлявате малко и да добавяте още публикации, за да видите как работи. Добавете още две или три и след това преминете към следващата част. + +### Филтрирайте обекти + +Голяма част от QuerySets е възможността да ги филтрирате. Да речем, че искаме да намерим всички публикации, на които потребителят ola е автор. Ще използваме `filter` вместо `all` в `Post.objects.all()`. В скобите посочваме на кое условие(я) трябва да отговаря блог публикацията, за да се озове в нашия набор от заявки. В нашия случай условието е `author/0> да бъде равен на me`. Начинът да го напишем в Django е `author=me`. Сега нашата част от кода изглежда така: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(author=me) +, , , ]> +``` + +Или може би искаме да видим всички публикации, които съдържат думата 'title' в полето `title`? + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(title__contains='title') +, ]> +``` + +> **Забележка** Има два знака за подчертаване (`_`) между `title` и `contains`. ORM на Django използва това правило за разделяне на имена на полета ("title") и операции или филтри ("contains"). Ако използвате само една долна черта, ще получите грешка като "FieldError: Не може да разреши ключовата дума title_contains". + +Можете също така да получите списък с всички публикувани публикации. Правим това, като филтрираме всички публикации, които имат `published_date` са зададени в миналото: + +{% filename %}command-line{% endfilename %} + +```python +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) + +``` + +За съжаление, публикацията, която добавихме от конзолата Python, все още не е публикувана. Но можем да променим това! Първо получете екземпляр от публикация, която искаме да публикуваме: + +{% filename %}command-line{% endfilename %} + +```python +>>> post = Post.objects.get(title="Sample title") +``` + +И след това го публикувате с нашия метод `publish`: + +{% filename %}command-line{% endfilename %} + +```python +>>> post.publish() +``` + +Сега опитайте отново да получите списък с публикувани публикации (натиснете клавиша със стрелка нагоре три пъти и натиснете `enter`): + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +]> +``` + +### Подреждане на обекти + +QuerySets също ви позволяват да поръчате списъка с обекти. Нека се опитаме да ги поръчаме от полето `created_date`: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.order_by('created_date') +, , , ]> +``` + +Можем също да обърнем подреждането, като добавим `-` в началото: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.order_by('-created_date') +, , , ]> +``` + +### Сложни заявки чрез свързване на методи + +Както видяхте, някои методи на `Post.objects` връщат QuerySet. Същите методи от своя страна могат също да бъдат извикани на QuerySet и след това ще върнат нов QuerySet. По този начин можете да комбинирате ефекта им, като ги **свържете** заедно: + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> +``` + +Това е наистина мощно и ви позволява да пишете доста сложни заявки. + +Готино! Вече сте готови за следващата част! За да затворите конзолата, въведете това: + +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` \ No newline at end of file diff --git a/bg/django_start_project/README.md b/bg/django_start_project/README.md new file mode 100644 index 00000000000..70c8788fcb6 --- /dev/null +++ b/bg/django_start_project/README.md @@ -0,0 +1,207 @@ +# Вашият първи проект с Django! + +> Част от тази глава е базирана на уроци от Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> +> Части от тази глава се основават на [django-marcador tutorial](http://django-marcador.keimlink.de/), лицензиран съгласно лиценза Creative Commons Attribution-ShareAlike 4.0 International. Урокът за django-marcador е защитен с авторско право от Markus Zapke-Gründemann и сие. + +Ще създадем малък блог! + +Първата стъпка е да започнете нов проект на Django. По принцип това означава, че ще изпълним някои скриптове, предоставени от Django, които ще създадат скелета на проект на Django за нас. Това е само куп директории и файлове, които ще използваме по-късно. + +Имената на някои файлове и директории са много важни за Django. Не трябва да преименувате файловете, които предстои да създадем. Преместването им на друго място също не е добра идея. Django трябва да поддържа определена структура, за да може да намери важни неща. + +> Не забравяйте да стартирате всичко във virtualenv (виртуалната среда). Ако не видите префикс `(myvenv)` в конзолата си, трябва да активирате своята virtualenv. Обяснихме как да направим това в главата **Инсталация на Django** в частта **Работа с virtualenv**. Въвеждането `myvenv\Scripts\activate`` в Windows или <0>source myvenv/bin/activate` в macOS или Linux ще направи това вместо вас. + + + +Във вашата macOS или Linux конзола трябва да изпълните следната команда. ** Не забравяйте да добавите точка `.` в края!** + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ django-admin startproject mysite . + + +> Точката `.` е от решаващо значение, тъй като казва на скрипта да инсталира Django във вашата текуща директория (за която точката `.` е препратка). +> +> **Забележка** Когато пишете командата по-горе, не забравяйте, че въвеждате само частта, която започва от `django-admin`. Частта `(myvenv) ~/djangogirls$`, показана тук, е само пример за подкана, която ще покани вашия вход във вашия команден ред. + + + + + +В Windows трябва да изпълните следната команда. **(Не забравяйте да добавите точка `.` в края)**: + +{% filename %}command-line{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . + + +> Точката `.` е от решаващо значение, тъй като казва на скрипта да инсталира Django във вашата текуща директория (за която точката `.` е препратка). +> +> **Забележка** Когато пишете командата по-горе, не забравяйте, че въвеждате само частта, която започва от `django-admin.exe`. Частта `(myvenv) C:\Users\Name\djangogirls>`, показана тук, е само пример за подкана, която ще покани вашия вход във вашия команден ред. + + + +`django-admin.py` е скрипт, който ще създаде директории и файлове за вас. Сега трябва да имате структура на директория, която изглежда така: + + djangogirls + ├── manage.py + ├── mysite + │ ├── __init__.py + │ ├── settings.py + │ ├── urls.py + │ └── wsgi.py + ├── myvenv + │ └── ... + └── requirements.txt + + +> **Забележка**: в структурата на вашата директория ще видите и вашата `myvenv` директория, която създадохме преди. + +`manage.py` е скрипт, който помага при управлението на сайта. С него ще можем (освен всичко друго) да стартираме уеб сървър на нашия компютър, без да инсталираме нищо друго. + +Файлът `settings.py` съдържа конфигурацията на вашия уебсайт. + +Спомняте ли си, когато говорихме за пощенски превозвач, проверяващ къде да достави писмо? `urls.py` файлът съдържа списък от модели, използвани от `urlresolver`. + +За сега игнорираме останалите файлове, тъй като няма да ги променяме. Единственото нещо, което трябва да запомните, е да не ги изтриете случайно! + +## Промяна на настройките + +Нека направим някои промени в `mysite/settings.py`. Отворете файла с помощта на редактора на кода, който сте инсталирали по-рано. + +**Забележка**: Имайте предвид, че `settings.py` е обикновен файл, като всеки друг. Можете да го отворите от редактора на кода, като използвате "file -> open" от менюто. Това трябва да ви изведе обичайния прозорец, в който можете да се придвижите до вашия файл `settings.py` и да го изберете. Освен това можете да отворите файла, като отворите папката djangogirls на вашия работен плот и щракнете с десния бутон върху него. След това изберете редактора на кода от списъка. Изборът на редактора е важен, тъй като може да имате инсталирани други програми, които могат да отворят файла, но няма да ви позволят да го редактирате. + +Би било хубаво да имаме точното време на нашия уебсайт. Отидете в [списъка на часовите зони на Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) и копирайте съответната часова зона (ЧЗ) (напр. `Европа/Берлин`). + +В `settings.py` намерете реда, който съдържа `TIME_ZONE` и го модифицирайте, за да изберете своя собствена часова зона. Например: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +TIME_ZONE = 'Europe/Berlin' +``` + +Езиков код се състои от езика, напр. `en` за английски или `de` за немски, и кодът на държавата, напр. `de` за Германия или `ch` за Швейцария. Ако английският не е вашият роден език, можете да добавите това, за да промените бутоните по подразбиране и известията от Django, за да бъдат на вашия език. Така че ще имате бутон „Отказ“, преведен на езика, който сте дефинирали тук. [Django идва с много подготвени преводи](https://docs.djangoproject.com/en/2.2/ref/settings/#language-code). + +Ако искате друг език, променете езиковия код, като промените следния ред: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +LANGUAGE_CODE = 'de-ch' +``` + +Ще трябва също да добавим път за статични файлове. (Ще разберем всичко за статичните файлове и CSS по-късно в урока.) Слезте до *края* на файла и точно под надписа `STATIC_URL` добавете нов, наречен `STATIC_ROOT`: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +STATIC_URL = '/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 + +## Създаване на база данни + +Има много различни софтуерни бази данни, които могат да съхраняват данни за вашия сайт. Ще използваме тази по подразбиране `sqlite3`. + +Това вече е настроено в тази част на вашия `mysite/settings.py` файл: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.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: + Apply all migrations: auth, admin, 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 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 sessions.0001_initial... ОК + + +И ние сме готови! Време е да стартирате уеб сървъра и да видите дали уебсайтът ни работи! + +## Стартиране на уеб сървъра + +Трябва да сте в директорията, която съдържа файла `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 + + +Ако сте в Windows и това не успее с `UnicodeDecodeError`, използвайте вместо това тази команда: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + + +Сега трябва да проверите дали уебсайтът ви работи. Отворете браузъра си (Firefox, Chrome, Safari, Internet Explorer или каквото използвате) и въведете този адрес: + +{% filename %}browser{% endfilename %} + + http://127.0.0.1:8000/ + + +Ако използвате Chromebook и Cloud9, вместо това щракнете върху URL адреса в изскачащия прозорец, който би трябвало да се появи в горния десен ъгъл на командния прозорец, където работи уеб сървърът. URL адресът ще изглежда като: + +{% filename %}browser{% endfilename %} + + https://.vfs.cloud9.us-west-2.amazonaws.com + + +Честито! Току-що създадохте първия си уебсайт и го стартирате с помощта на уеб сървър! Това не е ли страхотно? + +![Инсталирането работи!](images/install_worked.png) + +Обърнете внимание, че командният прозорец може да стартира само едно по едно и командният прозорец, който отворихте по-рано, работи на уеб сървъра. Докато уеб сървърът работи и чака допълнителни входящи заявки, терминалът ще приема нов текст, но няма да изпълнява нови команди. + +> Прегледахме как работят уеб сървърите в главата **Как работи Интернет**. + +За да въведете допълнителни команди, докато уеб сървърът работи, отворете нов прозорец на терминала и активирайте своята virtualenv - за да прегледате инструкциите как да отворите втори прозорец на терминала, вижте [Въведение в командния ред](../intro_to_command_line/README.md). За да спрете уеб сървъра, върнете се обратно към прозореца, в който работи, и натиснете CTRL + C - Control и C клавиши заедно (във Windows може да се наложи да натиснете Ctrl + Break). + +Готови ли сте за следващата стъпка? Време е да създадете малко съдържание! \ No newline at end of file diff --git a/bg/django_start_project/images/install_worked.png b/bg/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..4354c634ddb Binary files /dev/null and b/bg/django_start_project/images/install_worked.png differ diff --git a/bg/django_templates/README.md b/bg/django_templates/README.md new file mode 100644 index 00000000000..1313ac56932 --- /dev/null +++ b/bg/django_templates/README.md @@ -0,0 +1,108 @@ +# Django шаблони + +Време е да покажем на екран малко данни! Django има вградени **template tags** за тази цел. + +## Какви са тези шаблонни етикети? + +Виждате, в HTML не може наистина да пишете Python код, защото търсачките не го разбират. Те знаят само HTML. Знаем, че HTML е статичен, докато Python е по-динамичен. + +**Django template tags** ни позволяват да прехвърлим Python нещата към HTML, така че да изграждаме динамични сайтове по-бързо. Супер! + +## Показване на шаблон за лист от публикации + +В предишната глава дадохме на нашия шаблон лист от публикации с променливата `posts`. Сега ще го покажем на екран с HTML. + +За да отпечатаме променливата в шаблоните на Django, използваме къдрави скоби с името на променливата вътре ето така: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{{ posts }} +``` + +Пробвайте това във вашия шаблон `blog/templates/blog/post_list.html`. Отворете го в редактора си и заместете всичко от вторият `
` до третият `
` с `{{ posts }}`. Запазете файла и опреснете страницата за да видите резултатите: + +![Фигура 13.1](images/step1.png) + +Както може да видите, всичко което имаме е това: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +, ]> +``` + +Това означава, че Django го разбира като лист от обекти. Помните ли от **Въведение в Python** как показваме листове? Да, с for цикли! При Django шаблоните ги правим така: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} + {{ post }} +{% endfor %} +``` + +Пробвайте това във вашия шаблон. + +![Фигура 13.2](images/step2.png) + +Работи! Но ние искаме публикациите ни да се показват като статичните публикации, които създадохме по-рано в главата **Въведение в HTML**. Можете да смесвате HTML с шаблони. Нашето `body` ще изглежда така: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+ +{% for post in posts %} +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` + +{% raw %}Всичко, което сложите между `{% for %}` и `{% endfor %}` ще се повтаря за всеки обект в листа. Опреснете страницата си: {% endraw %} + +![Фигура 13.3](images/step3.png) + +Забелязахте ли, че този път използвахме малко по-различно означение (`{{ post.title }}` или `{{ post.text }}`)? Достъпваме данните във всяко едно поле дефинирано в нашия `Post` модел. Също така `|linebreaksbr` изпраща текста на публикациите през филтър и превръща в абзаци. + +## Още едно нещо + +Ще е хубаво да видим дали уеб страницата ви работи в Internet, нали? Нека го прехвърлим отново на PythonAnywhere. Ето преглед на стъпките: + +* Първо, изпратете кода си към GitHub + +{% filename %}command-line{% endfilename %} + + $ git status + [...] + $ git add --all . + $ git status + [...] + $ git commit -m "Modified templates to display posts from database." + [...] + $ git push + + +* След това влезте пак в [PythonAnywhere](https://www.pythonanywhere.com/consoles/) акаунта си и отидете на **Bash console** (или стартирайте нова) и напишете командите: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd .pythonanywhere.com + $ git pull + [...] + + +(Не забравяйте да заместите `` с вашия актуален PythonAnywhere субдомейн, без скобите.) + +* Накрая отидете на ["Web" страница](https://www.pythonanywhere.com/web_app_setup/) и натиснете **Reload** на вашата апликация. (За да достигнете други PythonAnywhere страници от конзолата, използвайте бутона от менюто в горния десен ъгъл.) Вашете обновление трябва да съществува на https://subdomain.pythonanywhere.com -- проверете в търсачката си! Ако публикациите на вашата PythonAnywhere страница не съвпадат с тези, които се появяват на локалния ви сървър, това е нормално. Базата от данни на локалния ви компютър не са синхронизирани с останалите ви файлове на PythonAnywhere. + +Поздравления! Сега добавете нова публикация в администрацията на Django (помнете да добавите published_date!) Бъдете сигурни, че сте администрацията на Django на своята страница в pythonanywhere, https://subdomain.pythonanywhere.com/admin. След това презаредете страницата за да видите дали публикациите са налице. + +Работи безупречно? Горди сме с теб! Сега отстъпи от компютъра си за малко – заслужи си почивка. :) + +![Фигура 13.4](images/donut.png) \ No newline at end of file diff --git a/bg/django_templates/images/donut.png b/bg/django_templates/images/donut.png new file mode 100644 index 00000000000..f31cebdc8a3 Binary files /dev/null and b/bg/django_templates/images/donut.png differ diff --git a/bg/django_templates/images/step1.png b/bg/django_templates/images/step1.png new file mode 100644 index 00000000000..cbf6420360a Binary files /dev/null and b/bg/django_templates/images/step1.png differ diff --git a/bg/django_templates/images/step2.png b/bg/django_templates/images/step2.png new file mode 100644 index 00000000000..fd6269c837c Binary files /dev/null and b/bg/django_templates/images/step2.png differ diff --git a/bg/django_templates/images/step3.png b/bg/django_templates/images/step3.png new file mode 100644 index 00000000000..b471fdd4d7b Binary files /dev/null and b/bg/django_templates/images/step3.png differ diff --git a/bg/django_urls/README.md b/bg/django_urls/README.md new file mode 100644 index 00000000000..be16809c102 --- /dev/null +++ b/bg/django_urls/README.md @@ -0,0 +1,103 @@ +# Django URLs + +Готови сме да създадем нашата първа уеб страница: начална страница на твоя блог! Но първо нека научим малко повече за Django URLs. + +## Какво е URL? + +URL е уеб адрес. Може да видиш URL всеки път когато посещаваш уебсайт – видимо е в полето за адрес на твоята търсачка. (Да! `127.0.0.1:8000` е URL! И `https://djangogirls.org` също е URL.) + +![URL](images/url.png) + +Всяка страница в Internet има нужда от собствен URL. По този начин твоето приложение знае какво трябва да покаже на потребителя, който отваря този URL. В Django използваме нещо наречено `URLconf` (URL конфигурация). URLconf е пакет от примери, които Django се опитва да съпостави със запитания URL за да намери правилния изглед. + +## Как работят URL в Django? + +Нека отворим файла `mysite/urls.py` в редактора си и видим как изглежда: + +{% filename %}mysite/urls.py{% endfilename %} + +```python +"""mysite URL Configuration + +[...] +""" +from django.contrib import admin +from django.urls import path + +urlpatterns = [ + path('admin/', admin.site.urls), +] +``` + +Както може да видите, Django вече е сложил нещо за нас тук. + +Редовете между трите кавички (`'''` or `"""`) се наричат docstrings – може да ги изписвате в началото на файла, класове или методи за да обясните какво прави кода - като коментар. Те няма да се изпълнят от Python. + +Администртивния URL, който посетихте в предната глава е вече тук: + +{% filename %}mysite/urls.py{% endfilename %} + +```python + path('admin/', admin.site.urls), +``` + +Този ред означава, че за всеки URL, който започва с `admin/`, Django ще намери съответстващ изглед *view*. В този случай въвеждаме много администраторски URL, така че да не е претъпкано в този малък файл – по-четимо и по-чисто. + +## Твоя първи Django URL! + +Време е да създадете вашия първи URL! Искаме 'http://127.0.0.1:8000/' да бъде началната страница на нашия блог и да показва лист от публикации. + +Също така искаме да задържим файла `mysite/urls.py` чист, така че да въведем URL от нашата `blog` апликация към главният файл `mysite/urls.py`. + +Давайте напред, като добавите ред с който ще въведете `blog.urls`. Също ще искате да направите промени в `from django.urls…` реда, защото използваме функция `include`, така че вие трябва да добавите `import` към този ред. + +Вашият файл `mysite/urls.py` трябва да изглежда ето така: + +{% filename %}mysite/urls.py{% endfilename %} + +```python +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('blog.urls')), +] +``` + +Django сега ще пренасочва всичко, което идва към 'http://127.0.0.1:8000/' до `blog.urls` и търси за следващи инструкции тук. + +## blog.urls + +Създайте нов файл с име `urls.py` в директория на `blog` и го отворете с редактора си. И така! Добавете следните два реда: + +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views +``` + +Тук въвеждаме функцията на Django `path` и всички наши изгледи ( `views`) от `blog` апликацията. (Все още нямаме никакви, но ще стигнем до там след минута!) + +След това можем да добавим наши първи URL образец: + +{% filename %}blog/urls.py{% endfilename %} + +```python +urlpatterns = [ + path('', views.post_list, name='post_list'), +] +``` + +Както виждате, сега приписваме изгледа наречен `post_list` към началния (root) URL. Този URL образец ще съвпадне с празен низ и преобразувателя в Django URL ще игнорира домейн името (т.е.,http://127.0.0.1:8000/), което започва с пълния път на URL. Този образец казва на Django, че `views.post_list` е правилното място да отиде, ако някой влезе в сайта ви на адрес 'http://127.0.0.1:8000/'. + +Последната част, `name='post_list' + +

Ако сега се опитате да посетите http://127.0.0.1:8000/, ще видите съобщение от рода на 'web page not available' . Това е така, защото сървърът (помните командата runserver`?) вече не е активен. Погледнете в конзолата на сървъра си и разберете защо. + +![Error (Грешка)](images/error1.png) + +Конзолата ви показва грешка, но не се тревожете – това всъщност е много полезно: Казва ви, **че няма атрибут с име 'post_list'**. Това е името на изгледа, който Django се опитва да намери и използва, но ние не сме го създали все още. На този етап, вашият `/admin/` също няма да работи. Не се тревожете – ще стигнем и до там. Ако виждате съобщение с друга греша, опитайте се да презаредите уеб сървъра. За да направите това, в конзолния прозорец, където сте пуснали сървъра, натиснете Ctrl+C за да го спрете (Ctrl + C заедно). На Windows може би трябва да натиснете Ctrl+Break. След това трябва да презаредите уеб сървъра като напишете командата `python manage.py runserver`. + +> Ако искате да научите повече за Django URLconfs, вижте в официалната документация: https://docs.djangoproject.com/en/2.2/topics/http/urls/ \ No newline at end of file diff --git a/bg/django_urls/images/error1.png b/bg/django_urls/images/error1.png new file mode 100644 index 00000000000..50618fca3fe Binary files /dev/null and b/bg/django_urls/images/error1.png differ diff --git a/bg/django_urls/images/url.png b/bg/django_urls/images/url.png new file mode 100644 index 00000000000..c22441e930e Binary files /dev/null and b/bg/django_urls/images/url.png differ diff --git a/bg/django_views/README.md b/bg/django_views/README.md new file mode 100644 index 00000000000..02efa058ccc --- /dev/null +++ b/bg/django_views/README.md @@ -0,0 +1,44 @@ +# Django views - време за създаване! + +Време е да премахнем пречката, която създадохме в последната глава! :) + +*view* е мястото, където поставяме "логиката" на приложението ни. Ще изиска информация от моделът, който създадохме по-рано и ще го подаде на шаблона. Ще създадем шаблон в следващата глава. Изгледите са просто Python фукнции, които са малко по-сложни от тези, които написахме в главата **Въведение в Python**. + +Изгледите са във файла `views.py`. Ние ще добавим първи си изглед към файла `blog/views.py`. + +## blog/views.py + +И така, нека отворим файла в редактора си видим какво има в него: + +{% filename %}blog/views.py{% endfilename %} + +```python +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`, която взима за стойност `request` ще върне друга функция `render`, взимайки стойността, шаблона и контекста. + +Запазете файла и отидете на http://127.0.0.1:8000/ за да видите какво имаме там. + +Друга грешка! Прочетете какво се случва сега: + +![Error (Грешка)](images/error.png) + +Това показва, че сървърът отново работи, но все още не изглежда както трябва, нали? Не се тревожете. Това е само страница с грешка, няма от какво да се страхувате! Също като съобщение с грешка в конзолата, тези са всъщност от голяма полза. Можете да прочетете, че *TemplateDoesNotExist*. Нека отстраним тази грешка и създадем шаблон в следващата глава! + +> Научете повече за Django изгледите като прочетете официалната документация: https://docs.djangoproject.com/en/2.2/topics/http/views/ \ No newline at end of file diff --git a/bg/django_views/images/error.png b/bg/django_views/images/error.png new file mode 100644 index 00000000000..1530c879cb5 Binary files /dev/null and b/bg/django_views/images/error.png differ diff --git a/bg/dynamic_data_in_templates/README.md b/bg/dynamic_data_in_templates/README.md new file mode 100644 index 00000000000..7268cc70b0b --- /dev/null +++ b/bg/dynamic_data_in_templates/README.md @@ -0,0 +1,81 @@ +# Динамични данни в шаблоните + +Имаме различни парчета на места: `Post` моделът е дефиниран в `models.py`, имаме `post_list` във `views.py` и добавен шаблон. Но как всъщност ще направим, така че нашите публикации да се показват на HMTL шаблон? Защото това е, което искаме да направим – да вземем някакво съдържание (запазените модели в базата от данни) и да се показват хубаво на нашия шаблон, нали? + +Това е точно, което *views* трябва да правят: свързват моделите с шаблоните. В нашия изглед за `post_list` ще трябва да вземем моделите, които искаме да показваме и да ги предадем на шаблоните. В изгледа ние определяме какво (модел) ще се изобразява в шаблона. + +Добре, как ще го постигнем? + +Трябва да отворим `blog/views.py` в редактора си. До момента `post_list` изгледа е такъв: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render + +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` + +Помните ли когато говорихме за вмъкване на код написан в различни файлове? Сега е моментът, в който трябва да вмъкнем модела, който създадохме в `models.py`. Ще добавим реда `from .models import Post` така: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from .models import Post +``` + +Точката преди `models` означава настояща директория или настояща апликация. Двата файла `views.py` и `models.py` са в една и съща директория. Това означава, че можем да използваме `.` и името на файла (без разширението `.py`). Тогава въвеждаме името на модела (`Post`). + +Но след това какво? За да вземем всъщност публикация от `Post` модела ни трябва нещо наречено `QuerySet`. + +## QuerySet + +Вече трябва да сте запознати как работят QuerySets. Говорихме за тях в главата [Django ORM (QuerySets)](../django_orm/README.md). + +Сега искаме публикуваните ни блог постове сортирани по дата на публикуване, нали? Вече направихме това в главата QuerySets! + +{% filename %}blog/views.py{% endfilename %} + +```python +Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +``` + +И така, нека да отворим файла `blog/views.py` в редактора и добавим този код към функцията `def post_list(request)` -- но нека не забравяме първо да добавим `from django.utils import timezone`: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from django.utils import timezone +from .models import Post + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {}) +``` + +Последната липсваща част е подаването на QuerySet постове към контекста на шаблона. Не се притеснявайте -- ще обясним как става в по-следваща глава. + +Моля забележете, че създадохме променлива за нашия QuerySet: `posts`. Ползвайте това като име на нашия QuerySet. От сега нататък можем да се отнасяме към него с това име. + +В `render` функцията имаме един параметър `request` (всичко се получава от потребителят чрез Internet) и друг даващ файла на шаблона (`'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 +from .models import Post + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {'posts': posts}) +``` + +Това е! Време е да се върнем към нашия шаблон и да покажем на екрана QuerySet! + +Искате да прочетете малко повече за QuerySets в Django? Трябва да погледнете тук: https://docs.djangoproject.com/en/2.2/ref/models/querysets/ \ No newline at end of file diff --git a/bg/extend_your_application/README.md b/bg/extend_your_application/README.md new file mode 100644 index 00000000000..923f2555b66 --- /dev/null +++ b/bg/extend_your_application/README.md @@ -0,0 +1,215 @@ +{% set warning_icon = '' %} + +# Продължете апликацията си + +Вече завършихме всички различни стъпки необходими за създаването на нашия уеб сайт: знаем как да напишем модел, URL, изглед и шаблон. Знаем също и как да направим сайта ни хубав. + +Време е за практика! + +Първото нешо, което ни е необходимо за блога е очевидно страница, която да показва една публикация, нали така? + +Вече разполагаме с `Post` модел, така че няма нужда да правим промени в `models.py`. + +## Създайте връзка към шаблона със съдържанието на поста. + +Ще започнем като добавим връзка във файла `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.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +{% raw %} Искаме да имаме връзка от заглавието на поста в листа с публикациите до страницата със съдържанието на поста. Нека променим `

{{ post.title }}

`, така че да се свързва със съдържанието на страницата:{% endraw %} + +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} + +```html +

{{ post.title }}

+``` + +{% raw %} Време е да обясним мистериозния код `{% url 'post_detail' pk=post.pk %}`. Може би забелязахте, че означението `{% %}` означава, че използваме Django шаблонни етикети. Този път ще изполваме такъв, който създава URL за нас! {% endraw %} + +`post_detail` частта означава, че Django трябва да очаква URL в `blog/urls.py` с име name=post_detail + +А какво за `pk=post.pk`? `pk` идва накратко от primary key, което е уникален идентификатор за всеки един запис в базата данни. Всеки Django модел има поле, което служи за негов първоначален код (primary key), и каквото и друго име да има, то може също да се съотнесе като "pk". Тъй като не уточнихме първоначалната стойност в нашия `Post` модел, Django създава един за нас (по подразбиране, полето "id" , съдържащо номер, който се увеличава при всеки запис, т.е. 1, 2, 3) и го добавя към полето на всеки от нашите постове. Можем да достигнем primary key като напишем `post.pk`, по същия начин достъпваме други полета (`title`, `author`, и т.н.) в нашия `Post` обект! + +Сега като отидем на http://127.0.0.1:8000/ ще видим грешка ( както се очаквкаше, тъй като все още нямаме URL или *view* за `post_detail`). Ще изглежда така: + +![NoReverseMatch грешка](images/no_reverse_match2.png) + +## Създаване на URL към съдържанието на поста + +Нека създадем URL в `urls.py` за нашия `post_detail` *view*! + +Искаме първия ни пост да бъде показван на този **URL**: http://127.0.0.1:8000/post/1/ + +Сега да направим URL във файла `blog/urls.py`, който да насочва Django към *view* наречен `post_detail`, който ще показва целия блог пост. Отворете файла `blog/urls.py` в редактора си и добавете следния ред `path('post//', views.post_detail, name='post_detail'),`, така че файлът да изглежда по този начин: + +{% filename %}{{ warning_icon }} blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), +] +``` + +Тази част `post//` уточнява URL образеца -- ще ви го обясним: + +- `post/` означава, че URL трябва да започва с думата **post** последвана от **/**. Дотук добре. +- `` -- тази част е по-сложна. Означава, че Django очаква стойност цяло число и ще го преведе към изгледа (view) като променлива наречена `pk`. +- `/` – след това ни е необходима **/** преди да завършим URL. + +Това означава, че когато напишем в търсачката си `http://127.0.0.1:8000/post/5/`, Django ще разбере, че търсите за *view* наречен `post_detail` и изпраща информацията, че този `pk` съответства на `5` спрямо този *view* (изглед). + +И така, добавихме нов URL образец към `blog/urls.py`! Нека презаредим страницата: http://127.0.0.1:8000/ Бум! Сървърът отново спря да работи. Погледнете в конзолата -- както се очакваше, има нова грешка! + +![AttributeError](images/attribute_error2.png) + +Помните ли каква е следващата стъпка? Добавяне на нов изглед (view)! + +## Добавяне на изглед за съдържанието на поста + +Този път на нашето *view* даваме допълнителен параметър, `pk`. Нашето *view* трябва да го прихване, нали? Така, ще дефинираме нашата функция като `def post_detail(request, pk):`. Забележете, че този параметър трябва да има точно същото име като на `urls` (`pk`), който уточнихме по-рано. Също така забележете, че пропускането на тази променлива е неправилно и в резултат ще доведе до грешка! + +Сега, искаме да вземем само и единствено една публикация. За да направим това, можем да използваме querysets ето така: + +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} + +```python +Post.objects.get(pk=pk) +``` + +Но този код има проблем. Ако нямаме `Post` с даден `primary key` (`pk`) ще имаме много грозна грешка! + +![DoesNotExist грешка](images/does_not_exist2.png) + +Ние не искаме това! За щастие Django идва с нещо, с което да се справи вместо нас: `get_object_or_404`. В случай, че няма `Post` със зададен `pk`, ще се покаже на екрана много по-добре, `Page Not Found 404` страница. + +![Page not found](images/404_2.png) + +Хубавото е, че всъщност и вие можете да си създадете такава страница `Page not found` и да я направите колкото си искате хубава. Но не е чак толкова важно в момента, затова ще го пропуснем. + +ОК, време е да добавим *view* към нашия файл `views.py`! + +В 0>blog/urls.py
създадохме URL правило наречено `post_detail`, което се отнася до изглед с име `views.post_detail`. Това означава, че Django ще очаква изглед функция наречена `post_detail` вътре в `blog/views.py`. + +Трябва да отворим `blog/views.py` в редактора и да добавим следния код близо до другите редове `from` : + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render, get_object_or_404 + +``` + +И накрая на файла ще добавим нашия изглед (*view*): + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) +``` + +Да. Време е да презаредим страницата: http://127.0.0.1:8000/ + +![Post list view (Изглед с лист от постове)](images/post_list2.png) + +Работи! Но сега какво става, когато кликнете върху връзката със заглавието на поста? + +![TemplateDoesNotExist грешка](images/template_does_not_exist2.png) + +Оо, не! Друга грешка! Но вече знаем как да се справим с това, нали? Трябва да добавим нов шаблон! + +## Създайте шаблон за съдържанието на поста + +Ще създадем файл в `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 %} +
+ {{ post.published_date }} +
+ {% endif %} +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endblock %} +``` + +Още веднъж удължаваме `base.html`. В блока `content` искаме да покажем датата на публикуване на поста (ако същестрвува), заглавието и текста. Но трябва да обсъдим други важни работи, нали? + +{% raw %}`{% if ... %} ... {% endif %}` е шаблонен етикет, който използваме, когато искаме да проверим нещо. (Помните ли `if ... else ...` от главата ** Въведение в Python**?) В този случай искаме да проверим дали `published_date` (датата на публикване) на поста не е празна.{% endraw %} + +ОК, можем да отворим страницата ни наново и ще видим, че `TemplateDoesNotExist` сега го няма. + +![Post detail page (Страница със съдържанието на поста)](images/post_detail2.png) + +Ихаа! Работи! + +# Време за прехвърляне на файловете! + +Би било добре да видите дали сайта ви работи на PythonAnywhere нали? Нека опитаме да прехвърлим всичко отново. + +{% filename %}command-line{% endfilename %} + + $ 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 + + +Тогава, в [PythonAnywhere Bash конзолата](https://www.pythonanywhere.com/consoles/): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Не забравяйте да замените `` с вашият актуален PythonAnywhere субдомейн, без скобите.) + +## Обновяване на статичните файлове на сървърът: + +Сървъри като PythonAnywhere обичат да се отнасят към "статичните файлове" (като CSS файлове) различно от Python файловете, защото те могат да оптимизират зареждането им по-бързо. В резултат, когато правим промени на нашите CSS файлове трябва да напишем допълнителни команди на сървъра за да му кажем да ги обнови. Командата се казва `collectstatic`. + +Започнете като активирате виртуалната си среда, ако не е активна от преди това (PythonAnywhere използва команда наречена `workon` да направи това, същото е както когато използваме команда `source myenv/bin/activate` на своя компютър. + +{% filename %}PythonAnywhere command-line{% 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://subdomain.pythonanywhere.com за да видите резултата. + +Та това е! Поздравления :) \ No newline at end of file diff --git a/bg/extend_your_application/images/404_2.png b/bg/extend_your_application/images/404_2.png new file mode 100644 index 00000000000..0a6fdf3234e Binary files /dev/null and b/bg/extend_your_application/images/404_2.png differ diff --git a/bg/extend_your_application/images/attribute_error2.png b/bg/extend_your_application/images/attribute_error2.png new file mode 100644 index 00000000000..4b8262476d9 Binary files /dev/null and b/bg/extend_your_application/images/attribute_error2.png differ diff --git a/bg/extend_your_application/images/does_not_exist2.png b/bg/extend_your_application/images/does_not_exist2.png new file mode 100644 index 00000000000..e7015f2c80d Binary files /dev/null and b/bg/extend_your_application/images/does_not_exist2.png differ diff --git a/bg/extend_your_application/images/no_reverse_match2.png b/bg/extend_your_application/images/no_reverse_match2.png new file mode 100644 index 00000000000..aba1c9c8980 Binary files /dev/null and b/bg/extend_your_application/images/no_reverse_match2.png differ diff --git a/bg/extend_your_application/images/post_detail2.png b/bg/extend_your_application/images/post_detail2.png new file mode 100644 index 00000000000..b40c92efb8c Binary files /dev/null and b/bg/extend_your_application/images/post_detail2.png differ diff --git a/bg/extend_your_application/images/post_list2.png b/bg/extend_your_application/images/post_list2.png new file mode 100644 index 00000000000..dd0a0d67a6f Binary files /dev/null and b/bg/extend_your_application/images/post_list2.png differ diff --git a/bg/extend_your_application/images/template_does_not_exist2.png b/bg/extend_your_application/images/template_does_not_exist2.png new file mode 100644 index 00000000000..c856abeda31 Binary files /dev/null and b/bg/extend_your_application/images/template_does_not_exist2.png differ diff --git a/bg/how_the_internet_works/README.md b/bg/how_the_internet_works/README.md new file mode 100644 index 00000000000..a1f0d1818bf --- /dev/null +++ b/bg/how_the_internet_works/README.md @@ -0,0 +1,47 @@ +# Как работи интернет + +> За читателите у дома: тази глава е разгледана във видеото [Как работи интернет](https://www.youtube.com/watch?v=oM9yAA09wdc). +> +> Тази глава е вдъхновена от беседата "Как работи Интернет" от Джесика Маккелар (http://web.mit.edu/jesstess/www/). + +Обзалагаме се, че използвате интернет всеки ден. Но всъщност знаете ли какво се случва, когато въведете адрес като https://djangogirls.org в браузъра си и натиснете `enter`? + +Първото нещо, което трябва да разберете е, че уебсайтът се състои от куп файлове, записани на твърд диск - точно като вашите филми, музика или снимки. Има обаче една част, която е уникална за уебсайтовете: те включват компютърен код, наречен HTML. + +Ако не сте запознати с програмирането, в началото може да е трудно да разберете HTML, но вашите уеб браузъри (като Chrome, Safari, Firefox и др.) го харесват. Уеб браузърите са създадени да разбират този код, да следват неговите инструкции и да представят тези файлове, от които е направен уебсайтът ви, точно по начина, по който искате. + +Както при всеки файл, ние трябва да съхраняваме HTML файлове някъде на твърд диск. За интернет използваме специални, мощни компютри, наречени *сървъри*. Те нямат екран, мишка или клавиатура, защото основната им цел е да съхраняват данни и да ги предоставят. Ето защо те се наричат *сървъри* - защото те *предоставят* вашите данни. + +Добре, но искате да знаете как изглежда интернет, нали? + +Нарисувахме ви снимка! Изглежда така: + +![Фигура 1.1](images/internet_1.png) + +Прилича на каша, нали? Всъщност това е мрежа от свързани машини (гореспоменатите *сървъри*). Стотици хиляди машини! Много, много километри кабели по света! Можете да посетите уебсайта на Submarine Cable Map (http://submarinecablemap.com), за да видите колко сложна е мрежата. Ето екранна снимка от уебсайта: + +![Фигура 1.2](images/internet_3.png) + +Очарователно е, нали? Но не е възможно да има жица между всяка машина, свързана към Интернет. И така, за да достигнем машина (например тази, на която е записан https://djangogirls.org), трябва да предадем заявка през много, много различни машини. + +Изглежда така: + +![Фигура 1.3](images/internet_2.png) + +Представете си, че когато въвеждате https://djangogirls.org, изпращате писмо, което гласи: "Скъпи момичета на Django, искам да видя уебсайта djangogirls.org. Изпратете ми го, моля!" + +Вашето писмо отива до най-близката до вас поща. След това преминава към друга, която е малко по-близо до вашия адресат, след това към друга и друга, докато не бъде доставено до местоназначението си. Единственото уникално нещо е, че ако изпратите много писма (*пакети данни*) на едно и също място, те могат да преминат през напълно различни пощенски станции (*рутери*). Това зависи от начина, по който се разпределят във всеки офис. + +![Фигура 1.4](images/internet_4.png) + +Така става - изпращате съобщения и очаквате някакъв отговор. Вместо хартия и химикалка използвате байтове с данни, но идеята е същата! + +Вместо адреси с име на улица, град, пощенски код и име на държавата, използваме IP адреси. Вашият компютър първо пита DNS (система за имена на домейни) да преведе djangogirls.org в IP адрес. Тя работи малко като старомодни телефонни книжки, където можете да потърсите името на човека, с когото искате да се свържете, и да намерите техния телефонен номер и адрес. + +Когато изпращате писмо, то трябва да има определени функции, за да бъде доставено правилно: адрес, печат и т.н. Използвате и език, който приемникът разбира, нали? Същото се отнася и за *пакетите данни*, които изпращате, за да видите уебсайт. Ние използваме протокол, наречен HTTP (Hypertext Transfer Protocol). + +Така че, когато имате уебсайт, трябва да имате *сървър* (машина), където живее. Когато *сървърът* получи входяща *заявка* (с писмо), той изпраща обратно вашия уебсайт (с друго писмо). + +Тъй като това е урок за Django, може да попитате какво прави Django. Когато изпращате отговор, не винаги искате да изпращате едно и също нещо на всички. Много по-добре е, ако вашите писма са персонализирани, особено за човека, който току-що ви е писал, нали? Django ви помага при създаването на тези персонализирани, интересни писма. :) + +Достатъчно беседа - време за създаване! \ No newline at end of file diff --git a/bg/how_the_internet_works/images/internet_1.png b/bg/how_the_internet_works/images/internet_1.png new file mode 100644 index 00000000000..e289eac2b23 Binary files /dev/null and b/bg/how_the_internet_works/images/internet_1.png differ diff --git a/bg/how_the_internet_works/images/internet_2.png b/bg/how_the_internet_works/images/internet_2.png new file mode 100644 index 00000000000..e8cf8b77999 Binary files /dev/null and b/bg/how_the_internet_works/images/internet_2.png differ diff --git a/bg/how_the_internet_works/images/internet_3.png b/bg/how_the_internet_works/images/internet_3.png new file mode 100644 index 00000000000..6f5d95dec80 Binary files /dev/null and b/bg/how_the_internet_works/images/internet_3.png differ diff --git a/bg/how_the_internet_works/images/internet_4.png b/bg/how_the_internet_works/images/internet_4.png new file mode 100644 index 00000000000..d4748ac48ef Binary files /dev/null and b/bg/how_the_internet_works/images/internet_4.png differ diff --git a/bg/html/README.md b/bg/html/README.md new file mode 100644 index 00000000000..3f3a61de3dc --- /dev/null +++ b/bg/html/README.md @@ -0,0 +1,217 @@ +# Въвeдение в HTML + +Може би се питате какво е шаблон (template)? + +Шаблонът е файл който, можем да използваме неколкократно за да представим различна информация в последователен формат -- например, можете да използвате шаблон, който да ви помага да напишете писмо, защото макар че всяко писмо да може да съдържа различно съобщение и да бъде адресирано до различен човек, те ще споделят същия формат. + +Django формат шаблона е описан в език наречен HTML (Това е HTML, който споменахме в главата **Как работи Internet**). + +## Какво е HTML? + +HTML е код, който се интерпретира от търсачките -- като Chrome, Firefox, Safari -- за да покаже на екран страницата на потребителя. + +HTML идва от "HyperText Markup Language". **HyperText** означава, че е тип от текст който подпомага хипервръзки между страници. **Markup** означава, че сме взели документа и сме го означили с код за да кажем нещо (в този случай, търсачка) как да подразбира страницата. HTML кода е изграден от **tags** (етикети), всеки от които стартира с `<` и завършва с `>`. Тези етикети представляват маркирани елементи (**elements**). + +## Първият ви шаблон! + +Създаване на шаблон означава създаване на шаблонен файл. Всичко е файл, нали? Може би вече забелязахте това. + +Шаблоните се запазват в директория `blog/templates/blog`. Така че, първо създайте директория наречена `templates` в директорията на блога ви. След това създайте друга директория наречена `blog` вътре при вашите шаблони: + + blog + └───templates + └───blog + + +(Може би се чудите защо са ни нужни две директории наречени `blog` -- както ще откриете по-късно, това е много лесно установена практика, която прави живота ни по-лесен, когато нещата започват да стават по-сложни.) + +И сега създайте файл `post_list.html` (оставете го празен засега) в директорията `blog/templates/blog`. + +Вижте как изглежда сайта ви: http://127.0.0.1:8000/ + +> Ако все още имате грешка `TemplateDoesNotExist`, опитайте се да заредите сървъра си отново. Отидете в конзолата си, спрете сървъра като натиснете едновременно Ctrl+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/ за да разберете + +![Фигура 11.2](images/step3.png) + +Работи! Добра работа :) + +* Най-простия етикет `` е винаги в началото на една страница и `` е винаги в края и. Както може да видите, цялото съдържание на страницата е между отварящият `` и затварящият етикет `` +* `

` е етикет за абзацни елементи; `

` затваря всеки един абзац + +## Глава и тяло на страницата (head и body) + +Всяка HTML страница е разделена на два елемена: **head** и **body**. + +* **head** е елемент, който съдържа информация относно документа, който е показан на екрана. + +* **body** е елемент, който съдържа всичко, което е показано като част от уеб страницата. + +Използваме `` за да кажем на търсачката за конфигурацията на страницата и `` какво точно е на страницата. + +Например, може да сложите заглавие на елемента вътре в `` ето така: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + Ola's blog + + +

Hi there!

+

It works!

+ + +``` + +Запазете файла и презаредете страницата. + +![Фигура 11.3](images/step4.png) + +Забелязахте ли как търсачката ви разбра, че заглавието на блога е "Ola's blog"? Тълкува `Ola's blog` и показва текст с името на заглавието в лентата на търсачката (също така ще се използва за отметка (bookmarks) и т.н.). + +Вероятно забелязахте и, че отварящия етикет съвпада със затварящия с `/`, като тези елементи са вложени (например не можете да затворите определен етикет, докато не затворите всички, които са преди него). + +Също като да слагаме неща в кутии. Имате една голяма кутия, ``; в нея е `` и това съдържа други по-малки кутии: `

`. + +Трябва да следвате тези правила със затварящите етикети и вложените елементи - ако ли не, търсачката ви може и да не ги представи както трябва и страницата ви ще изглежда неправилно. + +## Персонализиране на шаблон + +Може малко да се позабавлявате и да опитате да направите свой шаблон! Ето няколко полезни етикета за целта: + +* `

Заглавие

` за най-важното ви заглавие +* `

Подзаглавие

` за заглавие от следващо ниво +* `

Под-подзаглавие

` …и т.н. до `
` +* `

Абзац

` +* `текст` набляга на текста +* `текст` удебелява текста +* `
` отива на нов ред (не може да сложите нищо в br, както и няма затварящ етикет ) +* `връзка` създава връзка +* `
  • първи елемент
  • втори елемент
` прави лист, точно като този! +* `
` дефинира секция от страницата + +Ето пример на пълен шаблон, копирайте и пренесете в `blog/templates/blog/post_list.html`: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + 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`-елемента (абзаца) от текст, единия за датата, а другия за нашия пост. + +Дава ни този ефект: + +![Фигура 11.4](images/step6.png) + +Ихаа! Но дотук, нашият шаблон показва точно **същата информация** -- там където говорихме по-рано за шаблоните, които ни позволяват да показваме **различна** информация в **същия формат**. + +Това, което искаме е да показва истински публикации добавени в администратора на Django -- и там е където отиваме след това. + +## Още нещо: прехвърляне на файловете (deploy)! + +Би било добре да видим всичко това на живо в Internet, нали? Нека направим още едно прехвърляне на файлове към PythonAnywhere: + +### Запазете, and избутайте кода си към GitHub + +Първо, нека видим кои файлове се промениха след последното прехвърляне (напишете следните команди на локалния компютър, не на PythonAnywhere): + +{% filename %}command-line{% endfilename %} + + $ git status + + +Бъдете сигурни, че сте в директорията на `djangogirls` и нека кажем на git да включи всички промени в тази директория: + +{% filename %}command-line{% endfilename %} + + $ git add --all . + + +> **Забележка** `--all` означава, че `git` ще разпознае и файлове, които сте изтрили (по подразбиране, разпознава нови/модифицирани файлове). Също помните (от 3-та глава), че `.` означава настоящата директория. + +Преди да качим всички файлове, нека проверим какво ще качи `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: + +{% filename %}command-line{% endfilename %} + + $ git push + + +### Издърпайте новия код на PythonAnywhere и презаредете страницата + +* Отворете [PythonAnywhere страницата](https://www.pythonanywhere.com/consoles/) и отидете на **Bash конзолата** (или стартирайте нова). След това напишете команда: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +Трябва да заместите `` с актуалния си PythonAnywhere субдомейн без скобите. Вашият субдомейн е потребителско ви име в PythonAnywhere, но в някои случай може да е различно (като например ако потребителското ви име съдържа главни букви). Така че, ако тази команда не работи, използвайте команда `ls` (показване на лист от файлове) за да намерите вашия субдомейн/име на папката, и след това да отидете в нея `cd`. + +Сега гледайте как се сваля кода ви. Ако искате да проверите дали е пристигнал, отидете на **"Files" страница** и вижте кода си на PythonAnywhere (може да достигнете други страници на PythonAnywhere от бутона на менюто в страницата на конзолата). + +* Накрая, отидете на ["Web" страницата](https://www.pythonanywhere.com/web_app_setup/) и натиснете **Reload** на вашата апликация. + +Обновлението трябва да е на живо! Отидете и презаредете страницата си в търсачката. Промените трябва да са видими. :) \ No newline at end of file diff --git a/bg/html/images/step1.png b/bg/html/images/step1.png new file mode 100644 index 00000000000..eb474aaeddd Binary files /dev/null and b/bg/html/images/step1.png differ diff --git a/bg/html/images/step3.png b/bg/html/images/step3.png new file mode 100644 index 00000000000..47ede3f9993 Binary files /dev/null and b/bg/html/images/step3.png differ diff --git a/bg/html/images/step4.png b/bg/html/images/step4.png new file mode 100644 index 00000000000..0e6b48ec4a5 Binary files /dev/null and b/bg/html/images/step4.png differ diff --git a/bg/html/images/step6.png b/bg/html/images/step6.png new file mode 100644 index 00000000000..f044389de53 Binary files /dev/null and b/bg/html/images/step6.png differ diff --git a/bg/images/application.png b/bg/images/application.png new file mode 100644 index 00000000000..79071fe8d1b Binary files /dev/null and b/bg/images/application.png differ diff --git a/bg/installation/README.md b/bg/installation/README.md new file mode 100644 index 00000000000..1976d4722a6 --- /dev/null +++ b/bg/installation/README.md @@ -0,0 +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). Ще инсталирате всичко необходимо, докато работите през урока. + +# Инсталиране + +В този урок ще изграждате блог. За да направите това, докато преминавате през урока, ще бъдете инструктирани как да инсталирате различен софтуер на вашия компютър и да настроите някои онлайн акаунти, тъй като са необходими. Тази страница събира на едно място всички инструкции за инсталиране и регистрация (което е полезно за някои формати на работилницата). + + +{% include "/chromebook_setup/instructions.md" %} + + +# Кратко въведение в командния прозорец {#command-line} + +Много от стъпките по-долу се позовават на "конзолата", "терминала", "командния прозорец" или "командния ред" - всичко това означава едно и също нещо: прозорец на вашия компютър, в който можете да въведете команди. Когато стигнете до главния урок, ще научите повече за командния ред. Засега основното, което трябва да знаете, е как да отворите команден прозорец и как изглежда: +{% include "/intro_to_command_line/open_instructions.md" %} + +# Инсталиране на Python {#python} + +{% include "/python_installation/instructions.md" %} + +# Инсталиране на редактор на код {#code-editor} + +{% include "/code_editor/instructions.md" %} + +# Настройте virtualenv и инсталирайте Django {#virtualenv} + +{% include "/django_installation/instructions.md" %} + +# Инсталиране на Git {#git} + +{% include "/deploy/install_git.md" %} + +# Създаване на акаунт в GitHub {#github} + +Отидете на [GitHub.com](https://www.github.com) и се регистрирайте за нов безплатен потребителски акаунт. Не забравяйте да запомните паролата си (добавете я към вашия мениджър на пароли, ако използвате такъв). + +# Създаване на акаунт в PythonAnywhere {#pythonanywhere} + +{% include "/deploy/signup_pythonanywhere.md" %} + +# Започнете да четете + +Поздравления, вече сте подготвени и готови да продължите! Ако все още имате известно време преди уъркшопа, би било полезно да започнете да четете няколко от началните глави: + +* [Как работи интернет](../how_the_internet_works/README.md) + +* [Въведение в командния ред](../intro_to_command_line/README.md) + +* [Въведение в Python](../python_introduction/README.md) + +* [Какво е Django?](../django/README.md) + +# Насладете се на уъркшопа! + +Когато започнете семинара, ще можете да преминете направо към [първия си проект на Django!](../django_start_project/README.md), защото вече сте обхванали материала в по-ранните глави. diff --git a/bg/intro_to_command_line/README.md b/bg/intro_to_command_line/README.md new file mode 100644 index 00000000000..d3883fa0b32 --- /dev/null +++ b/bg/intro_to_command_line/README.md @@ -0,0 +1,441 @@ +# Въведение в интерфейса на командния ред + +> За читателите у дома: тази глава е разгледана във видеото [Вашият нов приятел: Командният ред](https://www.youtube.com/watch?v=jvZLWhkzX-8). + +Вълнуващо е, нали ?! Ще напишете първия си ред код само за няколко минути! :) + +**Нека ви запознаем с първия ви нов приятел: командният ред!** + +Следващите стъпки ще ви покажат как да използвате черния прозорец, който използват всички хакери. В началото може да изглежда малко страшно, но всъщност тази подкана просто чака команди от вас. + +> **Забележка** Моля, имайте предвид, че в тази книга използваме взаимозаменяемите термини „директория“ и „папка“, но те са едно и също нещо. + +## Какво е командният ред? + +Прозорецът, който обикновено се нарича **команден ред** or **интерфеса на командния ред**, е текстово приложение за преглед, обработка и манипулиране на файлове на вашия компютър. Прилича много на Windows Explorer или Finder на Mac, но без графичния интерфейс. Други имена на командния ред са: *cmd*, *CLI*, * prompt *, * console * или * terminal *. + +## Отворете интерфейса на командния ред + +За да започнем някои експерименти, първо трябва да отворим интерфейса на командния ред. + +{% include "/intro_to_command_line/open_instructions.md" %} + +## Prompt + +Сега трябва да видите бял или черен прозорец, който чака вашите команди. + + + +Ако сте на Mac или Linux, вероятно виждате `$`, ето така: + +{% filename %}command-line{% endfilename %} + + $ + + + + + + +На Windows, вероятно виждате `>`, ето така: + +{% filename %}command-line{% endfilename %} + + > + + +Погледнете раздела за Linux малко по-горе - ще видите нещо повече от това, когато стигнете до PythonAnywhere по-късно в урока. + + + +Всяка команда ще бъде предварително обозначена с `$` или `>` и един интервал, но не бива да го въвеждате. Вашият компютър ще го направи вместо вас. :) + +> Само малка забележка: във вашия случай може да има нещо като `C:\Users\ola>` или `Olas-MacBook-Air:~ ola$` преди знака на подкана и това е 100% ОК. + +Частта до и включително `$` или `>` се нарича *командния ред* или *подкана* за кратко. То ви подканва да въведете нещо там. + +В ръковдството, когато искаме да въведете команда, ще включим `$` или `>`, а понякога и повече вляво. Игнорирайте лявата част и въведете само командата, която започва след подкана. + +## Вашата първа команда (УРА!) + +Нека започнем с въвеждането на тази команда: + + + +{% filename %}command-line{% endfilename %} + + $ whoami + + + + + + +{% filename %}command-line{% endfilename %} + + > whoami + + + + +И след това натиснете `enter`. Това е нашият резултат: + +{% filename %}command-line{% endfilename %} + + $ whoami + olasitarska + + +Както можете да видите, компютърът току-що отпечата вашето потребителско име. Яко, а? :) + +> Опитайте да въведете всяка команда; не копирайте-поставете. Ще запомните повече по този начин! + +## Основи + +Всяка операционна система има малко по-различен набор от команди за командния ред, така че не забравяйте да следвате инструкциите за вашата операционна система. Нека опитаме това, става ли? + +### Текуща директория + +Би било хубаво да знаем къде сме сега, нали? Да видим. Въведете тази команда и натиснете `enter`: + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska + + +> Забележка: 'pwd' означава 'print working directory' (принтиране работна директория). + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska + + +> Забележка: 'cd' означава 'change directory' (промяна на директория). С PowerShell можете да използвате pwd точно както в Linux или macOS. + + + +Вероятно ще видите нещо подобно на вашата машина. След като отворите командния ред, обикновено стартирате в домашната директория на вашия потребител. + +* * * + +### Научете повече за команда + +Много команди, които можете да въведете в командния ред, имат вградена помощ, която можете да показвате и четете! Например, за да научите повече за текущата команда на директория: + + + +macOS и Linux имат команда `man`, която ви предоставя помощ за команди. Опитайте `man pwd` и вижте какво пише, или поставете `man` преди други команди, за да видите помощта им. Изходът на `man` обикновено се изписва на страницата. Използвайте интервала, за да преминете към следващата страница, и `q`, за да прекратите прегледа на помощта. + + + + + +Добавянето на `/?` суфикс към повечето команди ще отпечата помощната страница. Може да се наложи да превъртите прозореца на вашата команда нагоре, за да видите всичко. Опитайте `cd /?`. + + + +### Списък на файлове и директории + +И така, какво има в него? Ще е готино да разберем. Да видим: + + + +{% filename %}command-line{% endfilename %} + + $ ls + Applications + Desktop + Downloads + Music + ... + + + + + + +{% 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 + ... + + +> Забележка: В PowerShell можете също да използвате 'ls' като в Linux и macOS. + +* * * + +### Промяна на текущата директория + +Сега, нека да отидем на вашата директория Desktop: + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + +Отбележи, че името на директорията "Desktop" може да се преведе на езика на вашия Linux акаунт. В такъв случай ще трябва да замените ` Desktop ` с преведеното име; например, `Работен плот` за български език. + + + + + +{% filename %}command-line{% endfilename %} + + > cd Desktop + + + + +Проверете дали наистина е променена: + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + + +Ето го! + +> PRO съвет: ако напишете `cd D` и след това натиснете `tab` на клавиатурата си, командният ред автоматично ще попълни останалото име, за да можете да навигирате по-бързо. Ако има повече от една папка, започваща с „D“, натиснете два пъти клавиша `tab`, за да получите списък с опции. + +* * * + +### Създаване на директория + +Какво ще кажете за създаването на тестова директория на вашия работен плот? Можете да го направите по този начин: + + + +{% filename %}command-line{% endfilename %} + + $ mkdir practice + + + + + + +{% filename %}command-line{% endfilename %} + + > mkdir practice + + + + +Тази малка команда ще създаде папка с името `practice` на вашия работен плот. Можете да проверите дали е там, като погледнете на работния си плот или като изпълните команда `ls` или `dir`! Опитайте. :) + +> PRO съвет: Ако не искате да въвеждате едни и същи команди отново и отново, опитайте да натиснете `стрелката нагоре` и `стрелка надолу` на клавиатурата си, за да преминете през последните използвани команди. + +* * * + +### Упражнение! + +Малко предизвикателство за вас: в новосъздадената си директория `practice` създайте директория, наречена `test`. (Използвайте командите `cd` и `mkdir`.) + +#### Решение: + + + +{% filename %}command-line{% endfilename %} + + $ cd practice + $ mkdir test + $ ls + test + + + + + + +{% filename %}command-line{% endfilename %} + + > cd practice + > mkdir test + > dir + 05/08/2014 07:28 PM test + + + + +Поздравления! :) + +* * * + +### Почистване + +Не искаме да оставим бъркотия, така че нека премахнем всичко, което направихме до този момент. + +Първо, трябва да се върнем към Desktop: + + + +{% filename %}command-line{% endfilename %} + + $ cd .. + + + + + + +{% filename %}command-line{% endfilename %} + + > cd .. + + + + +Използването на `..` с командата `cd` ще промени текущата ви директория на родителската директория (тоест директорията, която съдържа текущата ви директория). + +Проверете къде се намирате: + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + + +Сега е време за изтриване на директорията `practice`: + +> **Внимание**: Изтриването на файлове с помощта на `del`, `rmdir` или `rm` е безвъзвратно, което означава, че *изтритите файлове ще изчезнат завинаги*! Затова бъдете много внимателни с тази команда. + + + +{% filename %}command-line{% endfilename %} + + $ rm -r practice + + + + + + +{% filename %}command-line{% endfilename %} + + > rmdir /S practice + practice, Are you sure ? Y + + + + +Готово! За да сме сигурни, че е действително изтрита, нека проверим: + + + +{% filename %}command-line{% endfilename %} + + $ ls + + + + + + +{% filename %}command-line{% endfilename %} + + > dir + + + + +### Изход + +Това е засега! Можете спокойно да затворите командния ред. Да го направим по хакерския начин, съгласни? :) + + + +{% filename %}command-line{% endfilename %} + + $ exit + + + + + + +{% filename %}command-line{% endfilename %} + + > exit + + + + +Готино, а? :) + +## Обобщение + +Ето обобщение на някои полезни команди: + +| Команда (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** | +| rmdir (или 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) съдържа пълна справка с команди за всички операционни системи. + +## Готови? + +Нека се потопим в Python! \ No newline at end of file diff --git a/bg/intro_to_command_line/open_instructions.md b/bg/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..88c032d04dc --- /dev/null +++ b/bg/intro_to_command_line/open_instructions.md @@ -0,0 +1,29 @@ + + + +В зависимост от вашата версия на Windows и клавиатурата ви, едно от следните трябва да отвори команден прозорец (може да се наложи да експериментирате малко, но не е нужно да изпробвате всички тези предложения): + +- Отидете в менюто или екрана "Старт" и въведете "Команден ред" в полето за търсене. +- Отидете в менюто "Старт" → Windows System → Команден ред. +- Отидете в менюто Старт → Всички програми → Аксесоари → Команден ред. +- Отидете на стартовия екран, задръжте мишката в долния ляв ъгъл на екрана и щракнете върху стрелката надолу, която се появява (на сензорен екран, вместо това натиснете нагоре от долната част на екрана). Страницата с приложения трябва да се отвори. Кликнете върху командния ред в секцията Windows. +- Задръжте специалния клавиш Windows на клавиатурата си и натиснете клавиша "X". Изберете „Команден ред“ от изскачащото меню. +- Задръжте клавиша на Windows и натиснете клавиша "R", за да получите прозорец "Изпълнение". Въведете "cmd" в полето и щракнете върху бутона OK. + +![Напишете "cmd" в прозореца "Изпълнение"](../python_installation/images/windows-plus-r.png) + +По-късно в този урок ще трябва да имате отворени два командни прозореца едновременно. Въпреки това, при някои версии на Windows, ако вече имате един отворен команден прозорец и се опитате да отворите втори, използвайки същия метод, той вместо това ще ви насочи към командния прозорец, който вече имате отворен. Опитайте го сега на вашия компютър и вижте какво ще се случи! Ако получите само един команден прозорец, опитайте някой от другите методи в списъка по-горе. Поне един от тях трябва да доведе до отваряне на нов команден прозорец. + + + + + +Отидете на Launchpad → Other → Terminal. + + + + + +Вероятно е под Applications → Accessories → Terminal или Applications → System → Terminal, но това може да зависи от вашата система. Ако не е там, можете да опитате да го потърсите в Google. :) + + diff --git a/bg/python_installation/README.md b/bg/python_installation/README.md new file mode 100644 index 00000000000..23ef41cb47f --- /dev/null +++ b/bg/python_installation/README.md @@ -0,0 +1,15 @@ +# Да започнем с Python + +Най-накрая сме тук! + +Но първо нека ви разкажем какво е Python. Python е много популярен език за програмиране, който може да се използва за създаване на уебсайтове, игри, научен софтуер, графика и много, много други. + +Python възниква в края на 80-те години и основната му цел е да бъде четен от хора (не само от машини!). Ето защо той изглежда по-прост от другите езици за програмиране, но не се притеснявайте - Python също е наистина мощен! + +# Инсталиране на Python + +> **Забележка** Ако използвате Chromebook, пропуснете тази глава и се уверете, че следвате инструкциите [Настройка на Chromebook](../chromebook_setup/README.md). +> +> **Забележка** Ако вече сте минали през стъпките за инсталиране, не е нужно да правите това отново - можете да преминете направо към следващата глава! + +{% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/bg/python_installation/images/add_python_to_windows_path.png b/bg/python_installation/images/add_python_to_windows_path.png new file mode 100644 index 00000000000..3266efb6177 Binary files /dev/null and b/bg/python_installation/images/add_python_to_windows_path.png differ diff --git a/bg/python_installation/images/python-installation-options.png b/bg/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..a0a6c65d81d Binary files /dev/null and b/bg/python_installation/images/python-installation-options.png differ diff --git a/bg/python_installation/images/windows-plus-r.png b/bg/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/bg/python_installation/images/windows-plus-r.png differ diff --git a/bg/python_installation/instructions.md b/bg/python_installation/instructions.md new file mode 100644 index 00000000000..f01564c391f --- /dev/null +++ b/bg/python_installation/instructions.md @@ -0,0 +1,121 @@ +> За читателите у дома: тази глава е разгледана във видеото [Инсталиране на Python & Редактор на код](https://www.youtube.com/watch?v=pVTaqzKZCdA). +> +> Този раздел е базиран на урок от Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) + +Django е написан на Python. Имаме нужда от Python, за да направим нещо в Django. Нека започнем с инсталирането му! Искаме да инсталирате най-новата версия на Python 3, така че ако имате някоя по-ранна версия, ще трябва да я актуализирате. Ако вече имате версия 3.4 или по-нова, трябва да се оправите. + +Моля, инсталирайте нормален Python по следния начин, дори когато на вашия компютър е инсталиран Anaconda. + + + +Първо проверете дали вашият компютър използва 32-битова версия или 64-битова версия на Windows, в реда "Тип система" на страницата Информация за системата. За да стигнете до тази страница, опитайте един от следните методи: + +* Натиснете едновременно клавиша Windows и клавиша за Пауза/Прекъсване +* Отворете контролния панел от менюто на Windows, след което отворете Система & Сигурност, след това Система +* Натиснете бутона на Windows, след това отворете Настройки> Система> Информация + +Можете да изтеглите Python за Windows от уебсайта https://www.python.org/downloads/windows/. Кликнете върху връзката "Последно издание на Python 3 - Python x.x.x“. Ако вашият компютър работи с **64-битова** версия на Windows, изтеглете **изпълнителния инсталатор Windows x86-64**. В противен случай изтеглете **изпълнителния инсталатор Windows x86**. След като изтеглите инсталатора, трябва да го стартирате (щракнете двукратно върху него) и следвайте инструкциите там. + +Едно нещо, за което трябва да внимавате: По време на инсталацията ще забележите прозорец с надпис „Настройка“. Уверете се, че поставяте отметка в квадратчето „Добавяне на Python 3.6 към PATH“ или „Добавяне на Python към променливите на вашата среда“ и кликнете върху „Инсталиране сега“, както е показано тук (може да изглежда малко по-различно, ако инсталирате друга версия): + +![Не забравяйте да добавите Python към Path](../python_installation/images/python-installation-options.png) + +Когато инсталацията приключи, може да видите диалогов прозорец с връзка, която можете да следвате, за да научите повече за Python или за версията, която сте инсталирали. Затворете или отменете този диалог - в този урок ще научите повече! + +Забележка: Ако използвате по-стара версия на Windows (7, Vista или някоя по-стара версия) и инсталатора на Python 3.6.x не успее с грешка, можете да опитате или: + +1. да инсталирате всички актуализации на Windows и да опитате отново да инсталирате Python; или +2. да инсталирате [по-стара версия на Python](https://www.python.org/downloads/windows/), например, [3.4.6](https://www.python.org/downloads/release/python-346/). + +Ако инсталирате по-стара версия на Python, екранът за инсталиране може да изглежда малко по-различно от показаното по-горе. Уверете се, че сте стигнали до най-долу, за да видите „Добавяне на python.exe към Path“, след това щракнете върху бутона вляво и изберете „Ще бъде инсталиран на локален твърд диск“: + +![Добавете Python към Path, по-стари версии](../python_installation/images/add_python_to_windows_path.png) + + + + + +> **Забележка** Преди да инсталирате Python в macOS, трябва да се уверите, че настройките ви за Mac позволяват инсталиране на пакети, които не са от App Store. Отидете на System Preferences (това е в папката Applications), щракнете върху "Security & Privacy", и след това върху раздела "General". Ако "Allow apps downloaded from:" е зададен на "Mac App Store,", променете го на "Mac App Store and identified developers". + +Трябва да отидете на уебсайта https://www.python.org/downloads/release/python-361/ и да изтеглите инсталатора на Python: + +* Изтеглете *macOS 64-битов/32-битов инсталатор* файл, +* Щракнете два пъти * python-3.6.1-macosx10.6.pkg *, за да стартирате инсталатора. + + + + + +Много е вероятно вече да имате инсталиран Python извън кутията. За да проверите дали сте го инсталирали (и коя версия е), отворете конзола и въведете следната команда: + +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python 3.6.1 + + +Ако имате инсталирана друга версия на Python, поне 3.4.0 (например 3.6.0), тогава не е нужно да актуализирате. Ако нямате инсталиран Python или искате друга версия, първо проверете каква дистрибуция на Linux използвате със следната команда: + +{% filename %}command-line{% endfilename %} + + $ grep '^NAME=' /etc/os-release + + +След това, в зависимост от резултата, следвайте едно от следните ръководства за инсталиране под този раздел. + + + + + +Въведете тази команда в конзолата си: + +{% filename %}command-line{% endfilename %} + + $ sudo apt install python3 + + + + + + +Използвайте тази команда в конзолата си: + +{% filename %}command-line{% endfilename %} + + $ sudo dnf install python3 + + +Ако сте на по-стари версии на Fedora, може да получите грешка, че командата `dnf` не е намерена. В такъв случай трябва да използвате вместо `yum`. + + + + + +Използвайте тази команда в конзолата си: + +{% filename %}command-line{% endfilename %} + + $ sudo zypper install python3 + + + + +Проверете дали инсталацията е била успешна, като отворите командния ред и изпълните командата `python3`: + +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python 3.6.1 + + +Показаната версия може да се различава от 3.6.1 - тя трябва да съответства на инсталираната от вас версия. + +**ЗАБЕЛЕЖКА:** Ако сте в Windows и получите съобщение за грешка, че `python3` не е намерен, опитайте да използвате `python` (без `3`) и проверете дали все още може да е версия на Python, която е 3.4.0 или по-нова. Ако и това не работи, можете да отворите нов команден ред и да опитате отново; това се случва, ако използвате командния ред, оставен отворен преди инсталирането на Python. + +* * * + +Ако имате някакви съмнения или ако нещо се обърка и нямате идея какво да правите по-нататък, моля, попитайте вашия ментор! Понякога нещата не вървят гладко и е по-добре да поискате помощ от някого с повече опит. \ No newline at end of file diff --git a/bg/python_introduction/README.md b/bg/python_introduction/README.md new file mode 100644 index 00000000000..02952d2f6db --- /dev/null +++ b/bg/python_introduction/README.md @@ -0,0 +1,1070 @@ +{% set warning_icon = '' %} + +# Въведение в Python + +> Част от тази глава е базирана на уроци от Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). + +Да напишем малко код! + +## Python запитване + +> За читателите у дома: тази част е разгледана във видеото [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U). + +За да започнем да играем с Python, трябва да отворим *команден ред* на вашия компютър. Вече трябва да знаете как да го направите - научихте го в главата [Въведение в командния ред](../intro_to_command_line/README.md). + +След като сте готови, следвайте инструкциите по-долу. + +Искаме да отворим конзола на Python, затова въведете `python` в Windows или `python3` в Mac OS/Linux и натиснете `enter`. + +{% filename %}command-line{% endfilename %} + + $ python3 + Python 3.6.1 (...) + Type "help", "copyright", "credits" or "license" for more information. + >>> + + +## Вашата първа Python команда! + +След като изпълните командата Python, подканата се промени в `>>>`. За нас това означава, че засега можем да използваме само команди на езика Python. Не е нужно да пишете `>>>` - Python ще направи това вместо вас. + +Ако искате да излезете от конзолата на Python във всеки момент, напишете `exit()` или използвайте прекия път `Ctrl + Z` за Windows и `Ctrl + D` за Mac/Linux. Тогава вече няма да виждате `>>>`. + +Засега не искаме да излизаме от конзолата Python. Искаме да научим повече за него. Нека започнем с въвеждане на някаква математика, като `2 + 3` и натискане на `enter`. + +{% filename %}command-line{% endfilename %} + +```python +>>> 2 + 3 +5 +``` + +Хубаво! Вижте как отговорът изскочи? Python знае математика! Можете да опитате и други команди като: + +- `4 * 5` +- `5 - 1` +- `40 / 2` + +За да извършим експоненциално изчисление, да кажем 2 на степен 3, пишем в конзолата: {% filename %}command-line{% endfilename %} + +```python +>>> 2 ** 3 +8 +``` + +Забавлявайте се с това за малко и след това се върнете тук. :) + +Както можете да видите, Python е чудесен калкулатор. Ако се чудите какво още можете да направите... + +## Низове + +Какво ще кажете за вашето име? Въведете първото си име в кавички така: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" +'Ola' +``` + +Сега създадохте първия си низ! Това е поредица от знаци, които могат да бъдат обработени от компютър. Низът винаги трябва да започва и завършва с един и същ символ. Това могат да бъдат единични (`'`) или двойни (`"`) кавички (няма разлика!) Кавичките казват на Python, че това, което е вътре в тях, е низ. + +Низовете могат да бъдат нанизани заедно. Опитайте това: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Hi there " + "Ola" +'Hi there Ola' +``` + +Можете също да умножите низове с число: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` + +Ако трябва да поставите апостроф във вашия низ, имате два начина да го направите. + +Използвайки двойни кавички: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Runnin' down the hill" +"Runnin' down the hill" +``` + +или да избягате от апострофа с обратна черта (``): + +{% filename %}command-line{% endfilename %} + +```python +>>> 'Runnin\' down the hill' +"Runnin' down the hill" +``` + +Хубаво, а? За да видите името си с главни букви, напишете: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola".upper() +'OLA' +``` + +Току що използвахте метода `upper` върху вашия низ! Методът (като `upper()`) е поредица от инструкции, които Python изпълнява върху даден обект (`"Ola"`) след като е повикан. + +Ако искате да знаете, от колко на брой букви е вашето име, има функция и за това! + +{% filename %}command-line{% endfilename %} + +```python +>>> len("Ola") +3 +``` + +Чудите ли се понякога защо, когато извиквате функции с `.` на края на низа (като `"Ola".upper()`), като понякога извиквате първо функцията и поставяте низа в скоби? Е, в някой случаи функциите принадлежат на обекти, като `upper()`, които могат да се използва само върху низове. В този случай, наричам функцията метод. В други случаи, функциите които не принадлежат към определени типове и могат да бъдат използвани при различни обекти, също като `len()`. Затова даваме `"Ola"` като параметър на функцията `len`. + +### Обобщение + +Добре, достатъчно за низове. Досега научихте за: + +- **запитване** -- писане на команди (код) в Python среда в резултат дава отговори на Python език. +- **числа и низове** -- в Python числата се използват за математически операции а низовете за текстови обекти. +- **оператори** – като `+` и `*`, събират стойности за да получат нова +- **функции** – като `upper()` и `len()`, извършващи се върху обектите. + +Това са основите на всеки програмен език, който учите. Готови ли сте за нещо по-сложно? Залагаме, че сте! + +## Грешки + +Нека опитаме нещо ново. Можем ли да вземем дължината на числото по същият начин, по който взехме дължината на нашето име? Напишете `len(304023)` и натиснете `enter`: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` + +Показа се първата ни грешка! {{ warning_icon }} е начина, по който ще ви показваме, че кода който се опитвате да пуснете няма да работи както се очаква. Грешките (дори и тези, които правим нарочно) са важна част от процеса на учене! + +Казва, че обектът от тип "int" (integers, или още цели числа) нямат дължина. Какво можем да направим сега? Може би да напишем числото ни като низ? Низовете имат дължина, нали така? + +{% filename %}command-line{% endfilename %} + +```python +>>> len(str(304023)) +6 +``` + +Работи! Използвахме функцията `str` във функцията `len`. `str()` преобразува всичко в низове. + +- Функцията `str` преобразува нещата като **низове** +- Функцията `int` преобразува нещата като **цели числа** + +> Важно: можем да преобразуваме числа в текст, но не можем да направим обратното -- както и да е какво би било `int('hello')`? + +## Променливи + +Важно понятие в програмирането са променливите. Променливата е нищо повече от име, което може да се използва по-късно в програмата. Програмистите ползват тези променливи да запазват данни. Това прави кода им по-четлив, така че не се налага да запомнят какви са тези неща. + +Нека кажем, че искаме да създаде променлива с име `name`: + +{% filename %}command-line{% endfilename %} + +```python +>>> name = "Ola" +``` + +Пишем name равно на Ola. + +Ако забелязахте, програмата ви не върна нищо както преди това. Как да разберем, че променливата съществува? Напишете `name` и натиснете бутона `enter`: + +{% filename %}command-line{% endfilename %} + +```python +>>> name +'Ola' +``` + +Ихууу! Първата ти променлива! :) Винаги може да я промениш към какво се отнася: + +{% filename %}command-line{% endfilename %} + +```python +>>> name = "Sonja" +>>> name +'Sonja' +``` + +Може да я използвате и във функции: + +{% filename %}command-line{% endfilename %} + +```python +>>> len(name) +5 +``` + +Страхотно, нали? Сега, променливите могат да са какво ли не -- също така и числа! Пробвайте това: + +{% filename %}command-line{% endfilename %} + +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` + +Но какво ако използваме грешното име Можете ли да отгатнете какво ще се случи? Нека опитаме! + +{% 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 +``` + +Грешка! Както виждате, Python има различни видове грешки, като тази се казва **NameError**. Python винаги ще ви дава тази грешка, ако се опитвате да използвате променлива, която все още не е дефинирана. Ако попаднете на тази грешка по-късно, вижте дали не сте сбъркали при писането на някое от имената. + +Поиграйте се малко с това и вижте какво може да правите! + +## Фунцкията print + +Пробвайте това: + +{% filename %}command-line{% endfilename %} + +```python +>>> name = 'Maria' +>>> name +'Maria' +>>> print(name) +Maria +``` + +Когато напишете `name`, Python интерпретатора отговаря със низово *изображение* на променливата 'name', където буквите 'M-a-r-i-a' са обградени от единични кавички. Когато кажем `print(name)`, Python ще "отпечата" съдържанието на променливата на екрана, без кавичките, което е по-прилежно. + +Както ще видим по-късно `print()` също е полезен, когато искаме да отпечатаме неща от функциите, или когато искаме да отпечатаме неща на няколко реда. + +## Листове + +Освен низовете и целите числа, Python има всякакви видове типове от обекти. Сега ще въведем една от тях наречена **list**. Листоверте са точно това, което си мислите, че са: обекти, които са листове от други обекти. :) + +Давайте нататък и създайте лист: + +{% filename %}command-line{% endfilename %} + +```python +>>> [] +[] +``` + +Да, това е празен лист. Не е много полезен нали? Нека създадем лист с лотарийни номера. Не искаме да се повтаряме постоянно, така че ще използваме променлива: + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery = [3, 42, 12, 19, 30, 59] +``` + +И така, имаме лист! Какво можем да правим с него? Нека видим колко лотарийни числа има в листа? Имате ли си на идея коя функция може да се използва за това? Това вече го знаете! + +{% filename %}command-line{% endfilename %} + +```python +>>> len(lottery) +6 +``` + +Да! `len()` може да ви даде броя на обектите в листа. Много удобно, нали? Може би и ще го сортираме: + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.sort() +``` + +Това не връща нищо, само променя реда, в който числата са показани в листа. Нека го отпечатаме отново и видим какво се случва: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery) +[3, 12, 19, 30, 42, 59] +``` + +Както се вижда, числата в листа са вече подредени от по-малката към по-голямата стойност. Поздравления! + +Може би искаме да направим обратното? + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.reverse() +>>> print(lottery) +[59, 42, 30, 19, 12, 3] +``` + +Ако искате да добавите нещо към вашия лист, може да го направите като напишете следната команда: + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.append(199) +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +``` + +Ако искате да покажете само първото число, може да направите това като използвате **индекси**. Индекса е номерът, който казва къде в листа се появява елемента. Програмистите предпочитат да започват броенето от 0, така че първият обект в листа е с индекс 0, следващия е с 1 и т.н. Опитайте това: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery[0]) +59 +>>> print(lottery[1]) +42 +``` + +Както може да видите, можете да достъпите различни обекти от листа си като използвате името на листа и индекс със квадратни скоби. + +За да премахнете нещо от листа си ще трябва да използвате **индексите**, които научихме по-горе и метода `pop()`. Нека пробваме пример и затвърдим това, което научихме до момента: ще отстраним първото число от листа ни. + +{% filename %}command-line{% 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] +``` + +Работи безупречно! + +За повече веселба, пробвайте други индекси: 6, 7, 1000, -1, -6 or -1000. Пробвайте се да предположите какъв би могъл да е резултата от командата. Имат ли смисъл резултатите? + +Можете да намерите лист с всички възможни методи в тази глава от документацията на Python: https://docs.python.org/3/tutorial/datastructures.html + +## Речници + +> За читателите у дома: тази част е показана във видеото [Python Basics: Dictionaries](https://www.youtube.com/watch?v=ZX1CVvZLE6c). + +Речника е подобен на листа, но можете да достъпвате стойностите му като погледнете за ключа вместо числения индекс. Синтаксисът за дефиниране на празен речник е: + +{% filename %}command-line{% endfilename %} + +```python +>>> {} +{} +``` + +Това показва, че в момента създадохте празен речник. Ура! + +Сега, опитайте се да напишете следната команда (опитайте се да заместите със своя информация): + +{% filename %}command-line{% endfilename %} + +```python +>>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} +``` + +С тази команда, току що създадохте променлива с име `participant` с три елемент-стойност (keys-value) двойки. + +- Елементът `name` се отнася за стойността `'Ola'` (`низ` обект), +- `country` се отнася за `'Poland'` (друг `низ`), +- and `favorite_numbers` се отнася за `[7, 42, 92]` (`лист` с три числа в него). + +Може да проверите съдържанието на всеки от елементите с този синтаксис: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(participant['name']) +Ola +``` + +Виждате ли, подобно е на лист. Но не е необходимо да помните индекса -- само името. + +Какво се случва, когато попитаме Python за стойността на елемент, който не съществува? Можете ли да познаете? Нека опитаме и видим: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> participant['age'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'age' +``` + +Вижте, друга грешка! Тази е **KeyError**. Python е много услужлив и ти казва, че елемент `'age'` не съществува в този речник. + +Кога да използвате речник и кога лист? Това е добър въпрос. Помислете за отговор преди да видите следващия ред. + +- Ако имате нужда просто от подредена последователност от елементи? Ползвайте лист. +- Ако трабва да асоциирате стойности с елементи, които искате да може да ги видите на по-късен етап (чрез елемент - by key)? Използвайте речник. + +Речниците са като листове, но *непостоянни*, което означава, че могат да бъдат променени след като бъдат създадени. Може да добавяте нови двойки елемент-стойност към речника след като е създаден ето така: + +{% filename %}command-line{% endfilename %} + +```python +>>> participant['favorite_language'] = 'Python' +``` + +Като при листовете, използването на метода `len()` върху речника връща броя на двойката елемент-стойност в речника. Продължете и напишете тази команда: + +{% filename %}command-line{% endfilename %} + +```python +>>> len(participant) +4 +``` + +Надявам се да има смисъл това което правим досега. :) Готови ли сте за още веселба с речниците? Прочетете някои невероятни неща. + +Можете да използвате метода `pop()` да изтриете елемент от речника. Да кажем, че искаме да премахнем въведението, което се отанся за елемента `'favorite_numbers'`, напишете следната команда: + +{% filename %}command-line{% endfilename %} + +```python +>>> participant.pop('favorite_numbers') +[7, 42, 92] +>>> participant +{'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +Както се вижда, двойката елемент-стойност отнасяща се за 'favorite_numbers' беше премахната. + +Както и това, можете да промените стойността, която отговаря на вече създаден елемент в речника. Напишете това: + +{% filename %}command-line{% endfilename %} + +```python +>>> participant['country'] = 'Germany' +>>> participant +{'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +Както виждате, стойността на елемента `'country'` беше променен от `'Poland'` на `'Germany'`. :) Вълнуващо? Ураа! Току що научихте още едно невероятно нещо. + +### Обобщение + +Страхотно! Вече знаете много за програмирането. В тази последна част научихте за: + +- **грешки** -- знаете как да четете и разбирате грешките които се показват, ако Python не разбира командата която сте задали +- **променливи** – имена на обектите, които ви позволяват да пишете код по-лесно и да правят кода ви по-четлив +- **листове** –листовете са обекти запазени в определен ред +- **речници** – обекти запазени като двойки от елемент-стойност (key-value pairs) + +Вълнувате ли се за следващата част? :) + +## Сравняване на неща + +> За читателите у вома: тази част е показана във видеото [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4). + +Голяма част от програмирането включва сравняване на неща. Какво е най-лесното нещо което може да се сравни? Числата! Нека видим как работи: + +{% filename %}command-line{% endfilename %} + +```python +>>> 5 > 2 +True +>>> 3 < 1 +False +>>> 5 > 2 * 2 +True +>>> 1 == 1 +True +>>> 5 != 2 +True +``` + +Дадохме на Python да сравни няколко числа. Както може да видите, Python не само че може да сравни числата, но може също така да сравнява и резултатите от метода. Супер, нали? + +Чудите ли се защо използвахме два знака за равно `==` един до друг за да сравним дали числата са равни? Използваме едно равно `=` за да причислим стойност на променливите. Винаги, ама **винаги** трябва да иползваме две от тях – `==` – ако искаме да проверим дали две неща са равни едно на друго. Можем също така да кажем, че не искаме двете неща да са равни едно на друго. Затова, използваме символа `!=`, както е показано в примера по-горе. + +Дайте на Python още две задачки: + +{% filename %}command-line{% endfilename %} + +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` + +Виждали сме `>` и `<`, но какво означават `>=` и `<=`? Четем ги по този начин: + +- x `>` y означава: x е по-голямо от y +- x `>` y означава: x е по-малко от y +- x `<=` y означава: x е по-малко или равно на y +- x `>=` y означава: x е по-голямо или равно на y + +Страхотно! Искате ли да направите още нещо? Пробвайте това: + +{% filename %}command-line{% endfilename %} + +```python +>>> 6 > 2 and 2 < 3 +True +>>> 3 > 2 and 2 < 1 +False +>>> 3 > 2 or 2 < 1 +True +``` + +Може да дадете на Python колкото си искате числа да сравнява и ще ви даде отговор! Много умно, нали? + +- **and** – ако използвате оператора `and`, двете сравнения трябва да са True за да бъде цялата команда True +- **or** – ако използвате оператора `or`, само едното сравнение трябва да е True за да бъде цялата команда True + +Чували ли сте за израза "сравнение на ябълки и портокали"? Нека пробваме подобно нещо в Python: + +{% 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' +``` + +Тук виждате, както при израза, Python не е способен да сравни число (`int`) и низ (`str`). Вместо това ни показва грешка **TypeError** и ни казва, че двата типа не могат да бъдат сравнени. + +## Булеви променливи + +По между другото, току що научихте за нов тип обект в Python. Нарича се **Булев (Boolean)**. + +Има само два вида булеви променливи: + +- True +- False + +Но за Python да разбере това, винаги трябва да пишете 'True' (като първата буква е главна, а следващите малки). **true, TRUE, and tRUE няма да работят – само True е правилно.** (Същото се отнася и до 'False'.) + +Булевите стойности могат също да са променливи! Вижте тук: + +{% filename %}command-line{% endfilename %} + +```python +>>> a = True +>>> a +True +``` + +Може също да го направите по този начин: + +{% filename %}command-line{% endfilename %} + +```python +>>> a = 2 > 5 +>>> a +False +``` + +Практикувайте и се повеселете с булевите стойности като се опитате да напишете следните команди: + +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` + +Поздраления! Булевите стойности са едни от най-готините неща в програмирането, и ти току що се научи как да ги използваш! + +# Запази! + +> За читателите у дома: тази част е показана във видеото [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk) + +До тук писахме всичкия си python код в интерпретатора, който ни ограничава да използваме само едни ред да впишем кода. Обикновено програмите са запазени във файлове и после изпълнени от **интерпретатора** или **компилатора** ни. Досега пускахме нашите програми по една на ред в Python интерпретатора. Ще са ни необходими малко повече редове от код за следващите няколко задачи, затова бързо ще направим това: + +- Излезем от Python интерпретатора +- Отворим редактор за текс по избор +- Запазим малко код в нов python файл +- Пуснете го! + +За да излезнем от Python интерпретатора, който използвахме, пише следната функция `exit()` + +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` + +Това ще ви върне в началното състояние на конзолата (терминала). + +По-рано избрахме нашия редактор от секцията за [code editor](../code_editor/README.md). Сега трябва да го отворим и да напишем малко код в нов файл (ако използвате Chromebook, създайте нов файл в cloud IDE и отворете файла, който ще е в редактора): + +{% filename %}editor{% endfilename %} + +```python +print('Hello, Django girls!') +``` + +Очевидно, вече сте по-обиграни Python разработчици, така че напишете код, който научихте днес. + +Сега трябва да запазим файла и да му дадем описателно име. Нека наречем файла **python_intro.py** и го запазим на началния си екран. Можем да именуваме файла си както пожелаем, но е важно да сме сигурни, че завършва на **.py**. Разширението **.py** казва на операционната система, че това е **Python executable file** и Python може да го обработи. + +> **Забележка:** Трябва да забелязахте, че едни от най-готините неща в редактора са: цветовете! В конзолата на Python всичко беше един цват; сега трябва да виждате, че `print` функцията е с различен цвят от цвета на низа. Това се нарича "syntax highlighting", и е много полезна добавка когато пишем код. Цвета на нещата ще ви подсказва, например ако имате незатворени низове или сте объркали ключова дума (като при писането на функцията `def`, както ще видим по-долу). Това е една от причините да изполваме редактор за писане на код. :) :) + +С вече запазения файл е време да го пуснем! Да използваме това, което научихме от секцията с командите. Ползвайте терминала (конзолата) за да смените директорията до началния си екран (desktop). + + + +На Mac, командата ще излгежда по този начин: + +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop + + + + + + +На Linux, ще изглежда така: + +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop + + +(Помнете, че думата "Desktop" може да е преведена на вашия език.) + + + + + +На Windows Command Prompt ще изглежда така: + +{% filename %}command-line{% endfilename %} + + > cd %HomePath%\Desktop + + + + + + +И на Windows Powershell ще изглежда така: + +{% filename %}command-line{% endfilename %} + + > cd $Home\Desktop + + + + +Ако се затруднявате, поискайте помощ. Затова са менторите! + +Сега ползвайте Python за да изпълни кода във файла ето така: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hello, Django girls! + + +Забележка: на Windows 'python3' не е разпознат като команда. Вместо това, използвайте 'python' за да стартирате файла: + +{% filename %}command-line{% endfilename %} + +```python +> python python_intro.py +``` + +Браво! Току що пуснахте първата си програма на Python, която беше запазена на файл. Чувствате ли се страхотно? + +Сега може да се прехвърлим на по-важно средство в програмирането: + +## If … elif … else + +Много неща в кода трябва да се изпълнят само ако са преминали определени условия. Затова Python има нещо, наречено **if условна конструкция**. + +Заместете кода във файла си **python_intro.py** с това: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 3 > 2: +``` + +Ако запазим и стартираме файла ще видим грешка като тази: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + + $ python3 python_intro.py + File "python_intro.py", line 2 + ^ + SyntaxError: unexpected EOF while parsing + + +Python очаква от нас да дадем следващи инсктрукции какво да се изпълни в условието `3 > 2` за да бъде вярно (или `True` за същата цел). Нека накараме Python да отпечата “It works!”. Променете кода си във файла с това: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 3 > 2: + print('It works!') +``` + +Забелязахте ли как изписахме следващия ред от код с 4 празни места навътре? Трябва да направим това за да може Python да знае, кой код да изпълни в случай, че е вярно условието. Може да използвате едно празно място, но почти всеки Python програмист използва 4, тъй като изглежда по-прилежно. Използването на бутона Tab също се равнява на 4 места, ако сте направили редактора си да прави така. Когато направите избор не го променяйте! Ако вече сте използвали 4 места за в бъдеще ползвайте 4 места - в противен случай може да попаднете на затруднения. + +Запазете и го стартирайте отново: + +{% filename %}command-line{% endfilename %} + +```python +$ python3 python_intro.py +It works! +``` + +Забележка: Помнете, че на Windows, 'python3' не се разпознава като команда. От сега нататък, заместете 'python3' с 'python' за да изпълните файла. + +### Какво ако условието не е вярно (True)? + +В предходните примери, кода се изпълняваше само ако условието е вярно (True). Но Python има също `elif` и `else` условия: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 5 > 2: + print('5 is indeed greater than 2') +else: + print('5 is not greater than 2') +``` + +Когато това се изпълни ще се отпечата: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + 5 is indeed greater than 2 + + +Ако 2 беше по-голямо число от 5, тогава втората команда щеше да се изпълни. Нека видим как работи `elif` : + +{% filename %}python_intro.py{% endfilename %} + +```python +name = 'Sonja' +if name == 'Ola': + print('Hey Ola!') +elif name == 'Sonja': + print('Hey Sonja!') +else: + print('Hey anonymous!') +``` + +и се изпълнява: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hey Sonja! + + +Видяхте ли какво се случи там? `elif` ви даде възможност да добавите още едно условие в случай, че предното се провали. + +Може да добавяте колкото си искате `elif` условия след първоначалното `if` условие. Например: + +{% filename %}python_intro.py{% endfilename %} + +```python +volume = 57 +if volume < 20: + print("It's kinda quiet.") +elif 20 <= volume < 40: + print("It's nice for background music") +elif 40 <= volume < 60: + print("Perfect, I can hear all the details") +elif 60 <= volume < 80: + print("Nice for parties") +elif 80 <= volume < 100: + print("A bit loud!") +else: + print("My ears are hurting! :(") +``` + +Python преминава и тества през всеки ред и отпечатва: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Perfect, I can hear all the details + + +## Коментари + +Коментрите са редове, започващи с `#`. Може да пишете каквото искате след `#` и Python ще го игнорира. Коментарите са направени да правят кода по-лесен за четене и разбиране от другите хора. + +Нека видим как изглежда: + +{% 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!") +``` + +Не е необходимо да пишете коментар за всеки ред от код, но те са много подходящи да обяснят какво прави самия код, или да дадат обобщение, когато се прави нещо сложно. + +### Обобщение + +В последните няколко упражнения научихте как да: + +- **сравнявате** – в Python може да сравнявате като използвате `>`, `>=`, `==`, `<=`, `<` и `and`, `or` оператори +- използвате **булеви променливи** – типа на обекта може да приема само две стойности: `True` или `False` +- **запазвате файлове** – запазване на кода във файлове, така че да могат да се изпълняват по-големи програми. +- използвате **if … elif … else** – условна конструкция, която ви позволява да изпълнявате код когато определени условия се изпълнят. +- пишете **коментари** - редовете в Python, които не се изпълняват и дават пояснения за кода ви + +Време е за последната част от тази глава! + +## Вашите собствени функции! + +> За читателите у дома: тази част е показана във видеото [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0). + +Помните ли функциите като `len()`, които изпълнихте в Python? Така, добри новини - сега ще научите как да напишете свои фукции! + +Функцията е последователност от инструкции, така че Python да може да я изпълнин. Всяка функция в Python започяа с ключовата дума `def`, с което се дава име на функцията и може да има няколко параметъра. Нека пробваме. Заместете кода във файла **python_intro.py** със следното: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(): + print('Hi there!') + print('How are you?') + +hi() +``` + +Добре, първата ви функция е готова! + +Може би се чудите защо написахме името на функцията в края на файла. Когато пишем `def hi():` и следващите редове започват по-навътре, това оказва какво трябва да направи функцията `hi()`. Python ще прочете и запомни тези инструкции, но няма да изпълни все още функцията. За да кажем на Python да изпълни функцията, трябва да извикаме вункцията с `hi()`. Python чете файла и изпълнява от горе до долу, затова трябва да дефинираме функцията преди да сме я повикали. + +Нека го стартираме и видим какво се случва: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi there! + How are you? + + +Забележка: ако не работи не се паникьосвайте! Резултатът ще ви помогне да разберете защо: + +- Ако получите грешка `NameError`, това най-вероятно означава, че сте направили грешка при писането, такаче трябва да проверите дали имената са същите при създаването на функцията `def hi():` и когато я извиквате `hi()`. +- Ако получите грешка `IndentationError`, вижте дали двата реда с функцията `print` са отместени на едно и също растояние: python иска кода във функцията да бъде безупречно подреден. +- Ако на изхода няма нищо, проверете дали последното `hi()` *не е* отместено - ако е , тази част също ще се превърне в част от функцията и никога няма да се изпълни + +Нека съставим първата си функция с параметри. Ще променим предния пример - функцията, която казва 'hi' на човека, който пуска програмата - с име: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): +``` + +Както се вижда, дадохме на функцията си стойност, която нарекохме `name`: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + if name == 'Ola': + print('Hi Ola!') + elif name == 'Sonja': + print('Hi Sonja!') + else: + print('Hi anonymous!') + +hi() +``` + +Запомнете: `print` функцията е поместена 4 места навътре спрямо `if` условието. Това е така, защото функцията се изпълнява, ако е изпълнено условието. Нека видим как работи: + +{% 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' + + +Опаа, грешка. За щастие, Python ни показва много полезно съобщение за грешката. Казва ни, че фукнцията `hi()` (която ние дефинирахме) има аргумент, който се изисква (с име `name`) и че сме забравили да го приложим, когато извикваме фунцкията. Нека оправим това в края на файла: + +{% filename %}python_intro.py{% endfilename %} + +```python +hi("Ola") +``` + +И да стартираме отначало: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Ola! + + +А ако сменим името? + +{% filename %}python_intro.py{% endfilename %} + +```python +hi("Sonja") +``` + +И стартираме отново: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Sonja! + + +Сега, какво мислите, че ще стане ако напишете ново име? (Не Ola или Sonja.) Опитайте и вижте дали сте прави. Трябва да отпечата това: + +{% filename %}command-line{% endfilename %} + + Hi anonymous! + + +Това е страхотно, нали? При това не трбва да се повтаряте всеки път, когато смените името на човека, който функцията трябва да поздрави. Затова са ни необходими функциите - никога да не повтаряш кода си! + +Нека опитаме нещо по-хитро - имаме повече от две имена и писането на условия за всяко едно от тях ще отнеме много време, нали така? Заместете съдържание на файла си със следното: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + print('Hi ' + name + '!') + +hi("Rachel") +``` + +Нека извикаме кода: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Rachel! + + +Поздравления! Току що научихте как да пишете функции! :) + +## Цикли + +> За читателите у дома: тази част е показана във видеото [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0) + +Това вече е последната част. Мина бързо, нали? :) + +Програмистите не обичат да е повтарят. Програмирането се отнася до автоматизация, така че не искаме да поздравяваме всеки човек по име като изписваме за всеки по отделно, нали? Ето къде циклите идват в употреба. + +Все още си спомняте листовете? Нека направим лист с момичета: + +{% filename %}python_intro.py{% endfilename %} + +```python +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +``` + +Искаме да поздравим всяка една от тях по име. Имаме функцията `hi` да направи това, така че нека я използваме в цикъл: + +{% filename %}python_intro.py{% endfilename %} + +```python +for name in girls: +``` + +Конструкцията `for` се държи подобно на конструкцията `if`; кода под него трябва да е отместен с четири места навътре. + +Ето целия код, който трябва да е във файла: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + print('Hi ' + name + '!') + +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +for name in girls: + hi(name) + print('Next girl') +``` + +И когато го стартираме: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Rachel! + Next girl + Hi Monica! + Next girl + Hi Phoebe! + Next girl + Hi Ola! + Next girl + Hi You! + Next girl + + +Както виждате всичко, което сложите вътре във `for` конструкцията с отместването ще бъде повторено за всеки елемент от листа `girls`. + +Може също да използвате `for` цикъл за числа като използвате фунцкията `range` : + +{% filename %}python_intro.py{% endfilename %} + +```python +for i in range(1, 6): + print(i) +``` + +Което ще отпечата: + +{% filename %}command-line{% endfilename %} + + 1 + 2 + 3 + 4 + 5 + + +`range` е функция, която създава лист от номера едно след друго (тези номера са дадени от вас като стойности). + +Забележете, че втория параметър, който сте дали не се включва в листа с показаните числа от Python (което означава, че `range(1, 6)` брои от 1 до 5, без да включва числото 6). Това е така, защото "range" е полу-отворена функция, което означава, че включва първата стойност, но не и последната. + +## Обобщение + +Това е! **Ти си върха!** Това беше сложна глава, така че трябва да сте горди със себе си. Ние определено сме горди с това, което постигнахте досега! + +За официалното и пълно ръководство на Python посетете visit https://docs.python.org/3/tutorial/. Това ще ви даде много по-подробни и цялостни знания за езика. Със здраве! :) + +Може би искате да направите нещо друго за кратко - разтягане, разходка, да ви отпочинат очите - преди да отидем към следващата глава. :) + +![Кексче](images/cupcake.png) \ No newline at end of file diff --git a/bg/python_introduction/images/cupcake.png b/bg/python_introduction/images/cupcake.png new file mode 100644 index 00000000000..8c1820adee8 Binary files /dev/null and b/bg/python_introduction/images/cupcake.png differ diff --git a/bg/styles/website.css b/bg/styles/website.css new file mode 100644 index 00000000000..917a9d65a50 --- /dev/null +++ b/bg/styles/website.css @@ -0,0 +1,64 @@ + +/* add text to top menu items */ + +.book-header .fa::after { + text-transform: none; + font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; +} +.book-header .fa-align-justify::after { + content: ' Show Outline'; + text-transform: none; + font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; +} +.book.with-summary .book-header .fa-align-justify::after { + content: ' Hide Outline'; +} +.book-header .fa-globe::after { + content: ' Language'; +} +.book-header .fa-font::after { + content: ' Font Settings'; +} +@media (max-width:600px) { + .book-header .fa-font::after { + content: ' Font'; + } + .book-header .js-toolbar-action.pull-right { /* social sharing links */ + display: none; + } +} + +/* add text to the Next & Prev arrows */ + +.navigation-prev::after { + content: 'Previous'; + font-size: 20pt; + vertical-align: text-bottom; + line-height: 44px; +} +.navigation-next::after { + content: 'Next'; + font-size: 20pt; + vertical-align: text-bottom; + line-height: 44px; +} + +@media (max-width:1240px) { + /* on small viewports, the arrows are shown on the side, so move text around to look better */ + .navigation-next::after { + content: none; + } + .navigation-next::before { + content: 'Next'; + font-size: 20pt; + vertical-align: text-bottom; + line-height: 44px; + } +} + +/* fine tune text size to not overlap main body text on very specific viewport sizes */ +@media (min-width:1241px) and (max-width:1274px) { + .navigation-prev::after { + font-size: 16pt; + } +} diff --git a/bg/template_extending/README.md b/bg/template_extending/README.md new file mode 100644 index 00000000000..d9278924a4d --- /dev/null +++ b/bg/template_extending/README.md @@ -0,0 +1,147 @@ +# Разширяване на шаблона + +Друго хубаво нещо, което Django има за вас, е **разширяване на шаблона**. Какво означава това? Това означава, че можете да използвате същите части на вашия HTML за различни страници на вашия уебсайт. + +Шаблоните помагат, когато искате да използвате една и съща информация или оформление на повече от едно място. Не е нужно да се повтаряте във всеки файл. И ако искате да промените нещо, не е необходимо да го правите във всеки шаблон, само в един! + +## Създайте основен шаблон + +Базовият шаблон е най-основният шаблон, който разширявате на всяка страница от вашия уебсайт. + +Нека създадем `base.html` файл в `blog/templates/blog/`: + + blog + └───templates + └───blog + base.html + post_list.html + + +След това го отворете в редактора на кода и копирайте всичко от `post_list.html` във `base.html` файл, като този: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% load static %} + + + Django Girls blog + + + + + + + + +
+
+
+ {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
+ + +``` + +След това в `base.html` заменете съдържанието в секцията `` (всичко между `` и ``) с това: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ +``` + +{% raw %}Може да забележите, че това замени всичко от `{% for post in posts %}` до `{% endfor %}` с: {% endraw %} + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% block content %} +{% endblock %} +``` + +Но защо? Току-що създадохте `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.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` + +Искаме да използваме това като част от нашия шаблон за всички съдържателни блокове. Време е да добавите блокови тагове към този файл! + +{% raw %}Искате вашият маркер за блока да съвпада с маркера във вашия `base.html` файл. Освен това искате той да включва всички кодове, които принадлежат във вашите блокове на съдържание. За целта поставете всичко между `{% block content %}` и `{% endblock %}`. Ето така:{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ 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.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +Това е! Запазете файла и проверете дали уебсайтът ви все още работи правилно. :) + +> Ако получите грешката `TemplateDoesNotExist`, това означава, че няма `blog/base.html` файл и имате `runserver` работещ в конзолата. Опитайте се да го спрете (като натиснете Ctrl + C - клавишите Control и C заедно) и го рестартирайте, като изпълните команда `python manage.py runserver`. \ No newline at end of file diff --git a/bg/whats_next/README.md b/bg/whats_next/README.md new file mode 100644 index 00000000000..ed55fd3b3b4 --- /dev/null +++ b/bg/whats_next/README.md @@ -0,0 +1,42 @@ +# Какво следва? + +Поздравете се! **Ти си напълно страхотен**. Гордеем се! <3 + +### Какво да правим сега? + +Направете почивка и се отпуснете! Току-що направихте нещо наистина огромно. + +След това, не забравяйте да следвате Django Girls във [ Facebook ](http://facebook.com/djangogirls) или [ Twitter ](https://twitter.com/djangogirls). + +### Можете ли да препоръчате допълнителни ресурси? + +Да! Има *много* онлайн ресурси за научаване на всякакви умения за програмиране - може да бъде доста трудно да разберете как да продължите по-натам, но не се безспокойте. Каквито и да бяха интересите ви преди да дойдете на Django Girls и каквито и интереси сте развили по време на ръководството, ето някои безплатни ресурси (или ресурси с големи безплатни компоненти), които можете да използвате, за да стигнете до това, което искате. + +#### Django + +- Другата ни книга, [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org/) +- [Официалното ръководство на Django](https://docs.djangoproject.com/en/2.2/intro/tutorial01/) +- [Първи стъпки с видео уроци на Django](http://www.gettingstartedwithdjango.com/) + +#### 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) - можете да участвате в повечето курсове безплатно, но ако искате сертификат или по-голяма квалификация, това ще струва пари +- [Python специализация на Coursera](https://www.coursera.org/specializations/python) - можете да участвате в няколко видео лекции безплатно и можете да спечелите сертификат на Coursera, като вземете тези курсове +- [Python for Everybody](https://www.py4e.com/) - безплатна и отворена версия на специализирания Python 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 diff --git a/book.json b/book.json index c667d875bff..819d89ec3ce 100644 --- a/book.json +++ b/book.json @@ -1,22 +1,28 @@ { "gitbook": ">=3.2.0", + "variables": { + "py_version": "3.12", + "py_release": "3.12.3", + "py_min_version": "3.10", + "py_min_release": "3.10.13", + "pa_py_version": "3.10", + "django_version": "5.1.2" + }, "links": { - "sidebar": { - "Need help? Talk to us!": "https://gitter.im/DjangoGirls/tutorial" - } }, "pdf": { - "fontSize": 14 + "fontSize": 16 }, "plugins": [ "heading-anchors@1.0.3", "ga@1.0.1", - "richquotes@0.0.7", + "richquotes@0.0.9", "github@2.0.0", "language-picker", - "sidebar-ad", + "sidebar-ads", "codeblock-label", - "sectionx" + "sectionx-ex", + "collapsible-menu" ], "pluginsConfig": { "ga": { @@ -31,11 +37,66 @@ "language-picker": { "grid-columns": 3 }, - "sidebar-ad": { - "imageUrl": "https://cdn.shopify.com/s/files/1/0992/7712/products/codelikeagirl---mockup4_large.jpg", - "url": "https://store.djangogirls.org/", - "description": "💖 Support our work and buy a Django Girls t-shirt! ✨", - "btnText": "Get a t-shirt!" + "sidebar-ads": { + "ads": [ + { + "imageUrl": "https://djangogirls.org/static/img/global/donate/lagos.jpg", + "url": "https://surveys.jetbrains.com/s3/w-django-girls-survey-2024", + "description": "💖 Celebrate 10 years with us. Fill our survey! ✨", + "btnText": "Fill in now!" + }, + { + "imageUrl": "https://static.djangoproject.com/img/logos/django-logo-negative.png", + "url": "https://www.djangoproject.com/", + "description": "💖 The DSF supports the development of Django! ✨", + "btnText": "Learn more!" + }, + { + "imageUrl": "https://djangogirls.org/static/img/global/supporters/DO_Logo_Vertical_Blue.png", + "url": "https://www.digitalocean.com/", + "description": "💖 DigitalOcean simplifies cloud computing! ✨", + "btnText": "Learn more!" + }, + { + "imageUrl": "https://djangogirls.org/uploads/uploads/posthog.png", + "url": "https://posthog.com/", + "description": "💖 PostHog offers a suite of product analysis tools! ✨", + "btnText": "Learn more!" + }, + { + "imageUrl": "https://djangogirls.org/uploads/uploads/lincolnloop.png", + "url": "https://lincolnloop.com/", + "description": "💖 Lincoln Loop provides scalable content platforms! ✨", + "btnText": "Learn more!" + }, + { + "imageUrl": "https://djangogirls.org/uploads/uploads/torchbox.png", + "url": "https://torchbox.com/", + "description": "💖 Torchbox, the creators of Wagtail! ✨", + "btnText": "Learn more!" + }, + { + "imageUrl": "https://www.pythonanywhere.com/static/anywhere/images/PA-logo.svg", + "url": "https://www.pythonanywhere.com/", + "description": "💖 Host, run, and code Python in the cloud! ✨", + "btnText": "Learn more! " + }, + { + "imageUrl": "https://djangogirls.org/static/img/global/donate/lagos.jpg", + "url": "https://www.patreon.com/djangogirls", + "description": "💖 Support our work and donate to our project! ✨", + "btnText": "Donate now!" + }, + { + "imageUrl": "https://djangogirls.org/static/img/global/donate/tshirt.jpg", + "url": "https://djangogirls.org/en/contact/", + "description": "💖 Want to support our work? ✨", + "btnText": "Contact Us!" + } + ] + }, + "sectionx": { + "tag": "b" } } } diff --git a/contributing/images/edit.png b/contributing/images/edit.png index bd11fe1dc29..bd0bb646924 100644 Binary files a/contributing/images/edit.png and b/contributing/images/edit.png differ diff --git a/contributing/images/fork.png b/contributing/images/fork.png index 8d0cfb439c0..13e52e00097 100644 Binary files a/contributing/images/fork.png and b/contributing/images/fork.png differ diff --git a/contributing/images/gitbook.png b/contributing/images/gitbook.png index 666b4780081..460c2623f58 100644 Binary files a/contributing/images/gitbook.png and b/contributing/images/gitbook.png differ diff --git a/contributing/images/github_editor.png b/contributing/images/github_editor.png index 44af3a6de7b..653f747d491 100644 Binary files a/contributing/images/github_editor.png and b/contributing/images/github_editor.png differ diff --git a/contributing/images/pull_request.png b/contributing/images/pull_request.png index 7af36fe61be..0effe646f72 100644 Binary files a/contributing/images/pull_request.png and b/contributing/images/pull_request.png differ diff --git a/crowdin.yaml b/crowdin.yaml index 6034104a541..da45c696f2b 100644 --- a/crowdin.yaml +++ b/crowdin.yaml @@ -1,19 +1,3 @@ -project_identifier: django-girls-tutorial -api_key: 2be4b1707d0745bc96e9a5c9ffb4ca9b -base_path: /Users/olasitarska/Desktop/Events/Django Girls/tutorial - files: - - - source: "/en/**/*.md" - translation: "/%two_letters_code%/%original_path%/%original_file_name%" - ignore: - - /_book - - /node_modules - - /CONTRIBUTING.md - - - source: "/en/*.md" - translation: "/%two_letters_code%/%original_file_name%" - ignore: - - /_book - - /node_modules - - /CONTRIBUTING.md + - source: /en/**/*.md + translation: '/%locale%/**/%original_file_name%' diff --git a/cs/code_editor/instructions.md b/cs/code_editor/instructions.md index 9666843aff6..a43563481a1 100755 --- a/cs/code_editor/instructions.md +++ b/cs/code_editor/instructions.md @@ -8,15 +8,15 @@ Gedit je open-source editor. Je k dispozici zdarma pro všechny operační syst [Stáhnout si jej můžeš zde](https://wiki.gnome.org/Apps/Gedit#Download) -## Sublime Text 3 +## Sublime Text Sublime Text je velmi oblíbený editor s bezplatnou zkušební dobou. Lze jej snadno nainstalovat a používat. Je k dispozici pro všechny operační systémy. -[Stáhnout si jej můžeš zde](https://www.sublimetext.com/3) +[Stáhnout si jej můžeš zde](https://www.sublimetext.com/) ## Atom -Atom je velmi nový editor kódu vytvořen [GitHub](https://github.com/)em. Je zdarma, je open-source a má snadnou instalaci a snadné použití. Je k dispozici pro Windows, OS X a Linux. +Atom je velmi nový editor kódu vytvořen [GitHub](https://github.com/)em. Je zdarma, je open-source a má snadnou instalaci a snadné použití. Je k dispozici pro Windows, macOS a Linux. [Stáhnout si jej můžeš zde](https://atom.io/) @@ -28,4 +28,4 @@ První důvod je, že kód musí být **prostý text** a programy jako Word a Te Druhým důvodem je, že editory kódu se specializují na editaci kódu, takže mohou poskytovat užitečné funkce, jako je barevné zvýraznění kódu podle jeho významu nebo automatické ukončování uvozovek apod. -Vše to uvidíme v akci později. Brzy ti přijde tvůj oblíbený editor kódu jako jeden z tvých nejlepších nástrojů :) \ No newline at end of file +Vše to uvidíme v akci později. Brzy ti přijde tvůj oblíbený editor kódu jako jeden z tvých nejlepších nástrojů :) diff --git a/cs/css/README.md b/cs/css/README.md index ab915ee6046..acc0961ec20 100755 --- a/cs/css/README.md +++ b/cs/css/README.md @@ -45,7 +45,8 @@ Uděláš to tak, že vytvoříš složku s názvem `static` uvnitř aplikace bl djangogirls ├── blog │ ├── migrations -│ └── static +│ ├── static +│   └── templates └── mysite ``` diff --git a/cs/css/images/bootstrap1.png b/cs/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/cs/css/images/bootstrap1.png and b/cs/css/images/bootstrap1.png differ diff --git a/cs/css/images/color2.png b/cs/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/cs/css/images/color2.png and b/cs/css/images/color2.png differ diff --git a/cs/css/images/final.png b/cs/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/cs/css/images/final.png and b/cs/css/images/final.png differ diff --git a/cs/css/images/font.png b/cs/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/cs/css/images/font.png and b/cs/css/images/font.png differ diff --git a/cs/css/images/margin2.png b/cs/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/cs/css/images/margin2.png and b/cs/css/images/margin2.png differ diff --git a/cs/deploy/README.md b/cs/deploy/README.md index 380ebd21346..6c4d08eaadf 100755 --- a/cs/deploy/README.md +++ b/cs/deploy/README.md @@ -6,7 +6,7 @@ Až dosud byly tvoje webové stránky k dispozici pouze ve tvém počítači, ny Jak jsi se dozvěděla, webové stránky musí být umístěny na serveru. Na internetu existuje mnoho poskytovatelů serverů. My budeme používat jednoho, který má relativně jednoduchý proces nasazení: [PythonAnywhere][1]. PythonAnywhere je zdarma pro malé aplikace, které nemají příliš mnoho návštěvníků, takže to pro tebe bude teď stačit. - [1]: https://pythonanywhere.com/ + [1]: https://www.pythonanywhere.com/ Další externí službu, kterou budeme používat, je [GitHub][2], což je hostingová služba pro zdrojové kódy. Na internetu existují i jiné služby, ale téměř všichni programátoři mají účet na GitHubu. Nyní ho budeš mít také! @@ -28,7 +28,7 @@ Git je "systém pro správu verzí" používaný spoustou programátorů. Tento Git sleduje změny v sadě souborů v takzvaném úložišti kódu/repository (nebo zkráceně "repo"). Založme si jedno repo pro náš projekt. Otevři konzoli a v `djangogirls` adresáři spusť tyto příkazy: -> **Poznámka:** Zkontroluj si svůj aktuální pracovní adresář pomocí `pwd` (OS x/Linux) nebo příkazem `cd` (Windows) před inicializací úložiště. Měla bys být ve složce `djangogirls`. +> **Poznámka:** Zkontroluj si svůj aktuální pracovní adresář pomocí `pwd` (macOS/Linux) nebo příkazem `cd` (Windows) před inicializací úložiště. Měla bys být ve složce `djangogirls`. ``` $ git init @@ -44,8 +44,8 @@ Git bude sledovat změny souborů a složek v tomto adresáři, ale jsou tam ně ``` *.pyc __pycache__ - myvenv - db.sqlite3 +myvenv +db.sqlite3 .DS_Store ``` @@ -59,7 +59,7 @@ Je vhodné použít příkaz `git status` před použitím příkazu `git add`, $ git status On branch master - Initial commit + No commits yet Untracked files: (use "git add ..." to include in what will be committed) diff --git a/cs/deploy/images/github_get_repo_url_screenshot.png b/cs/deploy/images/github_get_repo_url_screenshot.png index 62a29f5f8d7..ee1560b1e85 100644 Binary files a/cs/deploy/images/github_get_repo_url_screenshot.png and b/cs/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/cs/deploy/images/new_github_repo.png b/cs/deploy/images/new_github_repo.png index 64011e59a52..d1f82e5d863 100644 Binary files a/cs/deploy/images/new_github_repo.png and b/cs/deploy/images/new_github_repo.png differ diff --git a/cs/deploy/images/pythonanywhere_web_tab_virtualenv.png b/cs/deploy/images/pythonanywhere_web_tab_virtualenv.png index 97e87e7b07b..6069f6da831 100644 Binary files a/cs/deploy/images/pythonanywhere_web_tab_virtualenv.png and b/cs/deploy/images/pythonanywhere_web_tab_virtualenv.png differ diff --git a/cs/deploy/install_git.md b/cs/deploy/install_git.md index 6cc2682b85d..0e9d9d7c282 100755 --- a/cs/deploy/install_git.md +++ b/cs/deploy/install_git.md @@ -11,7 +11,7 @@ Stáhni Git z [git-scm.com](https://git-scm.com/) a postupuj podle pokynů. Pokud ho již nemáš nainstalovaný, git měl by být k dispozici pomocí Správce balíčků, zkus: ``` -sudo apt-get install git +sudo apt install git # or sudo yum install git # or diff --git a/cs/django_admin/images/django_admin3.png b/cs/django_admin/images/django_admin3.png index a450b4f9630..ea01ab951bf 100644 Binary files a/cs/django_admin/images/django_admin3.png and b/cs/django_admin/images/django_admin3.png differ diff --git a/cs/django_admin/images/edit_post3.png b/cs/django_admin/images/edit_post3.png index c8572a73e7d..d577b111424 100644 Binary files a/cs/django_admin/images/edit_post3.png and b/cs/django_admin/images/edit_post3.png differ diff --git a/cs/django_admin/images/login_page2.png b/cs/django_admin/images/login_page2.png index 47153ef6960..6ae26e9959a 100644 Binary files a/cs/django_admin/images/login_page2.png and b/cs/django_admin/images/login_page2.png differ diff --git a/cs/django_forms/README.md b/cs/django_forms/README.md index a96e2811b36..8ea26f584c1 100755 --- a/cs/django_forms/README.md +++ b/cs/django_forms/README.md @@ -211,10 +211,10 @@ from django.shortcuts import redirect Přidej to na samý začátek souboru. A nyní můžeš říci: Jdi na stránku `post_detail` s nově vytvořeným příspěvkem. ```python -return redirect('blog.views.post_detail', pk=post.pk) +return redirect('post_detail', pk=post.pk) ``` -`blog.views.post_detail` je název pohledu, na který chceme jít. Pamatuj si, že tento *view* vyžaduje proměnnou `pk`. Pro předání do view použijeme `pk=post.pk`, kde `post` je nově vytvořený příspěvek! +`post_detail` je název pohledu, na který chceme jít. Pamatuj si, že tento *view* vyžaduje proměnnou `pk`. Pro předání do view použijeme `pk=post.pk`, kde `post` je nově vytvořený příspěvek! Už jsme si toho řekly hodně, ale pravděpodobně chceš vidět, jak nyní celý *view* vypadá nyní, nemám pravdu? @@ -227,7 +227,7 @@ def post_new(request): post.author = request.user post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) @@ -365,7 +365,7 @@ Vzhledem k tomu, že jsi pravděpodobně přihlášená, neuvidíš žádnou zm Uvidíme, jestli to funguje na PythonAnywhere. Čas na další nasazení! -* Za prvé commitni nový kód a pošli ho na Github +* Za prvé commitni nový kód a pošli ho na GitHub ``` $ git status diff --git a/cs/django_forms/images/csrf2.png b/cs/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/cs/django_forms/images/csrf2.png and b/cs/django_forms/images/csrf2.png differ diff --git a/cs/django_forms/images/drafts.png b/cs/django_forms/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/cs/django_forms/images/drafts.png and b/cs/django_forms/images/drafts.png differ diff --git a/cs/django_forms/images/edit_button2.png b/cs/django_forms/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/cs/django_forms/images/edit_button2.png and b/cs/django_forms/images/edit_button2.png differ diff --git a/cs/django_forms/images/edit_form2.png b/cs/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/cs/django_forms/images/edit_form2.png and b/cs/django_forms/images/edit_form2.png differ diff --git a/cs/django_forms/images/form_validation2.png b/cs/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/cs/django_forms/images/form_validation2.png and b/cs/django_forms/images/form_validation2.png differ diff --git a/cs/django_forms/images/new_form2.png b/cs/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/cs/django_forms/images/new_form2.png and b/cs/django_forms/images/new_form2.png differ diff --git a/cs/django_forms/images/post_create_error.png b/cs/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/cs/django_forms/images/post_create_error.png and b/cs/django_forms/images/post_create_error.png differ diff --git a/cs/django_installation/instructions.md b/cs/django_installation/instructions.md index e8d4352485e..d912a5ed786 100755 --- a/cs/django_installation/instructions.md +++ b/cs/django_installation/instructions.md @@ -33,9 +33,9 @@ C:\Users\Name\djangogirls > C:\Python34\python -m venv myvenv kde `C:\Python34\python` je adresář, kam jsme dříve nainstalovali Python a `myvenv` je název `virtualenv`. Můžeš použít i jiné jméno, ale používej malá písmena a nepoužívej mezery, diakritiku nebo speciální znaky. Je také dobrý nápad, abys zvolila krátké jméno - budeš ho používat častokrát! -### Linux a OS X +### Linux a macOS -Vytvoření `virtualenv` na Linux a OS X je stejně jednoduché - spusť`python3 -m venv myvenv`. Celý příkaz bude vypadat takto: +Vytvoření `virtualenv` na Linux a macOS je stejně jednoduché - spusť`python3 -m venv myvenv`. Celý příkaz bude vypadat takto: ``` ~/djangogirls$ python3 -m venv myvenv @@ -50,7 +50,7 @@ Vytvoření `virtualenv` na Linux a OS X je stejně jednoduché - spusť`python3 > > Chceš-li se tomuto vyhnout, použij tento příkaz `virtualenv`. > -> ~/djangogirls$ sudo apt-get install python-virtualenv +> ~/djangogirls$ sudo apt install python-virtualenv > ~/djangogirls$ virtualenv --python=python3.4 myvenv > @@ -66,7 +66,7 @@ Spusť virtuální prostředí: C:\Users\Name\djangogirls> myvenv\Scripts\activate ``` -#### Linux a OS X +#### Linux a macOS Spusť virtuální prostředí: diff --git a/cs/django_models/README.md b/cs/django_models/README.md index 44977a6ed93..a4c75b25aed 100755 --- a/cs/django_models/README.md +++ b/cs/django_models/README.md @@ -110,12 +110,13 @@ V souboru `blog/models.py` budeme definovat všechny objekty nazývané `modely` Otevři `blog/models.py`, odstraň vše, co v něm je, a vlož následující kód: ```python +from django.conf import settings from django.db import models from django.utils import timezone class Post(models.Model): - author = models.ForeignKey('auth.User') + author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) title = models.CharField(max_length=200) text = models.TextField() created_date = models.DateTimeField( diff --git a/cs/django_orm/README.md b/cs/django_orm/README.md index 82b165f28fb..5f8e383fea2 100755 --- a/cs/django_orm/README.md +++ b/cs/django_orm/README.md @@ -46,7 +46,7 @@ Tohle je jednoduché: importujeme model `Post` z `blog.models`. Pojďme znovu zk ``` >>> Post.objects.all() -[, ] +, ]> ``` To je seznam příspěvků, které jsme dříve vytvořily pomocí Django administrátorského rozhraní. Teď nicméně chceme vytvořit příspěvky použitím Pythonu, tak jak na to? @@ -71,7 +71,7 @@ Jaké uživatele máme v naší databázi? Zkus tohle: ``` >>> User.objects.all() -[] +]> ``` Tohle je superuser, kterého jsme vytvořily dříve! Pojďme si teď vzít instanci tohoto uživatele: @@ -92,7 +92,7 @@ Hurá! Chceš se podívat, jestli to fungovalo? ``` >>> Post.objects.all() -[, , ] +, , ]> ``` A je to tu, další příspěvek v seznamu! @@ -121,7 +121,11 @@ Nebo možná chceme vidět všechny příspěvky, jež mají slovo 'titulek' v p Také můžeš získat seznam všech publikovaných příspěvků. Uděláme to vyfiltrováním všech příspěvků, které mají nastavené `published_date` na nějaké uplynulé datum: -> > > from django.utils import timezone Post.objects.filter(published_date__lte=timezone.now()) [] +``` +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) +[] +``` Bohužel příspěvek, který jsme přidali pomocí Python konzole, ještě není publikován. To můžeme změnit! Nejdřív vezmeme instanci příspěvku, který chceme publikovat: diff --git a/cs/django_start_project/README.md b/cs/django_start_project/README.md index 8210d837237..98bcc2ee0c0 100755 --- a/cs/django_start_project/README.md +++ b/cs/django_start_project/README.md @@ -70,7 +70,7 @@ Budeme také muset přidat cestu pro statické soubory (o statických souborech ```python STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') +STATIC_ROOT = BASE_DIR / 'static' ``` ## Nastavení databáze @@ -83,7 +83,7 @@ Ta je již nastavena v konfiguračním souboru `mysite/settings.py`: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'NAME': BASE_DIR / 'db.sqlite3', } } ``` @@ -114,7 +114,7 @@ Running migrations: A máme hotovo! Čas spustit webový server a měla bys vidět naše fungující webové stránky! -Pro spuštění musíš být v adresáři, který obsahuje soubor `manage.py` (adresář `djangogirls`). V konzoli spustíš webový server zadáním `pythonu manage.py runserver`: +Pro spuštění musíš být v adresáři, který obsahuje soubor `manage.py` (adresář `djangogirls`). V konzoli spustíš webový server zadáním `python manage.py runserver`: ``` (myvenv) ~/djangogirls$ python manage.py runserver diff --git a/cs/django_start_project/images/it_worked2.png b/cs/django_start_project/images/it_worked2.png index 4412ecfc49e..4efa554e567 100644 Binary files a/cs/django_start_project/images/it_worked2.png and b/cs/django_start_project/images/it_worked2.png differ diff --git a/cs/django_templates/README.md b/cs/django_templates/README.md index f9808e0940f..97c487fcdd7 100755 --- a/cs/django_templates/README.md +++ b/cs/django_templates/README.md @@ -27,7 +27,7 @@ Zkus to ve své šabloně `blog/templates/blog/post_list.html`. Nahraď vše od Jak vidíš, dostali jsme toto: ``` -[, ] +, ]> ``` To znamená, že to Django chápe jako seznam objektů. Vzpomínáš si z kapitoly **Úvod do pythonu**, jak můžeme zobrazit seznam? Ano, pomocí for smyček! V Django šabloně je použiješ takto: @@ -72,7 +72,7 @@ Všimla sis, že jsme tentokrát použily lehce odlišnou notaci (`{{ post.title Bylo by dobré vidět, jestli tvá webová stránka bude stále fungovat i na webu, že? Pojďme zkusit další nasazení/deploy na PythonAnywhere. Tady je rekapitulace postupu... -* Nejdřív hoď svůj kód na Github +* Nejdřív hoď svůj kód na GitHub ``` $ git status diff --git a/cs/django_templates/images/donut.png b/cs/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/cs/django_templates/images/donut.png and b/cs/django_templates/images/donut.png differ diff --git a/cs/django_templates/images/step1.png b/cs/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/cs/django_templates/images/step1.png and b/cs/django_templates/images/step1.png differ diff --git a/cs/django_templates/images/step2.png b/cs/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/cs/django_templates/images/step2.png and b/cs/django_templates/images/step2.png differ diff --git a/cs/django_templates/images/step3.png b/cs/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/cs/django_templates/images/step3.png and b/cs/django_templates/images/step3.png differ diff --git a/cs/django_urls/images/error1.png b/cs/django_urls/images/error1.png index cc17593d19d..250028e996b 100644 Binary files a/cs/django_urls/images/error1.png and b/cs/django_urls/images/error1.png differ diff --git a/cs/django_urls/images/url.png b/cs/django_urls/images/url.png index 6cd1bd96291..b59f9dce992 100644 Binary files a/cs/django_urls/images/url.png and b/cs/django_urls/images/url.png differ diff --git a/cs/django_views/images/error.png b/cs/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/cs/django_views/images/error.png and b/cs/django_views/images/error.png differ diff --git a/cs/extend_your_application/README.md b/cs/extend_your_application/README.md index 25678e931cb..55c33681cff 100755 --- a/cs/extend_your_application/README.md +++ b/cs/extend_your_application/README.md @@ -25,7 +25,7 @@ Začneme s přidáním odkazu do `blog/templates/blog/post_list.html` souboru. Z

{{ post.text|linebreaksbr }}

{% endfor %} -{% endblock content %} +{% endblock %} ``` diff --git a/cs/extend_your_application/images/404_2.png b/cs/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/cs/extend_your_application/images/404_2.png and b/cs/extend_your_application/images/404_2.png differ diff --git a/cs/extend_your_application/images/attribute_error2.png b/cs/extend_your_application/images/attribute_error2.png index 6edcd9933c3..33a3b36b1d3 100644 Binary files a/cs/extend_your_application/images/attribute_error2.png and b/cs/extend_your_application/images/attribute_error2.png differ diff --git a/cs/extend_your_application/images/does_not_exist2.png b/cs/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/cs/extend_your_application/images/does_not_exist2.png and b/cs/extend_your_application/images/does_not_exist2.png differ diff --git a/cs/extend_your_application/images/no_reverse_match2.png b/cs/extend_your_application/images/no_reverse_match2.png index 306926206f8..aba1c9c8980 100644 Binary files a/cs/extend_your_application/images/no_reverse_match2.png and b/cs/extend_your_application/images/no_reverse_match2.png differ diff --git a/cs/extend_your_application/images/post_detail2.png b/cs/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/cs/extend_your_application/images/post_detail2.png and b/cs/extend_your_application/images/post_detail2.png differ diff --git a/cs/extend_your_application/images/post_list2.png b/cs/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/cs/extend_your_application/images/post_list2.png and b/cs/extend_your_application/images/post_list2.png differ diff --git a/cs/extend_your_application/images/template_does_not_exist2.png b/cs/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/cs/extend_your_application/images/template_does_not_exist2.png and b/cs/extend_your_application/images/template_does_not_exist2.png differ diff --git a/cs/how_the_internet_works/images/internet_1.png b/cs/how_the_internet_works/images/internet_1.png index 9c5bcf0b003..e289eac2b23 100644 Binary files a/cs/how_the_internet_works/images/internet_1.png and b/cs/how_the_internet_works/images/internet_1.png differ diff --git a/cs/how_the_internet_works/images/internet_2.png b/cs/how_the_internet_works/images/internet_2.png index dd5861f376f..e8cf8b77999 100644 Binary files a/cs/how_the_internet_works/images/internet_2.png and b/cs/how_the_internet_works/images/internet_2.png differ diff --git a/cs/how_the_internet_works/images/internet_3.png b/cs/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/cs/how_the_internet_works/images/internet_3.png and b/cs/how_the_internet_works/images/internet_3.png differ diff --git a/cs/how_the_internet_works/images/internet_4.png b/cs/how_the_internet_works/images/internet_4.png index 2661cec1b61..d4748ac48ef 100644 Binary files a/cs/how_the_internet_works/images/internet_4.png and b/cs/how_the_internet_works/images/internet_4.png differ diff --git a/cs/html/README.md b/cs/html/README.md index 503feb1e10e..929acd7ff9b 100755 --- a/cs/html/README.md +++ b/cs/html/README.md @@ -156,7 +156,7 @@ Co ve skutečnosti chceme, je zobrazit opravdové příspěvky přidané v naše Bylo by fajn vidět všecho tohle venku a živě na internetu, že ano? Pojďme udělat další PythonAnywhere nasazení (deploy): -### Commitni a hoď svůj kód na Github +### Commitni a hoď svůj kód na GitHub Nejdříve se podívejme, které soubory se změnily od posledního nasazení (deploy). Zadej tyto příkazy lokálně (ne na PythonAnywhere): @@ -186,7 +186,7 @@ $ git commit -m "Změněn HTML kód stránek." > **Poznámka** Ujisti se, že používáš dvojité uvozovky kolem zprávy. -Jakmile jsme s tímto hotovy, nahrajeme (push) naše změny na Github: +Jakmile jsme s tímto hotovy, nahrajeme (push) naše změny na GitHub: ``` git push diff --git a/cs/html/images/step1.png b/cs/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/cs/html/images/step1.png and b/cs/html/images/step1.png differ diff --git a/cs/html/images/step3.png b/cs/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/cs/html/images/step3.png and b/cs/html/images/step3.png differ diff --git a/cs/html/images/step4.png b/cs/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/cs/html/images/step4.png and b/cs/html/images/step4.png differ diff --git a/cs/html/images/step6.png b/cs/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/cs/html/images/step6.png and b/cs/html/images/step6.png differ diff --git a/cs/images/application.png b/cs/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/cs/images/application.png and b/cs/images/application.png differ diff --git a/cs/installation/README.md b/cs/installation/README.md index bb9faf25871..cdd38b9c502 100755 --- a/cs/installation/README.md +++ b/cs/installation/README.md @@ -1,6 +1,6 @@ # Pokud děláš tutoriál doma -Pokud děláš tento tutorial doma, ne na jedné z [Django girls akcí](https://djangogirls.org/events/), můžeš zcela vynechat tuto kapitolu a jít rovnou na kapitolu [jak funguje Internet?](../how_the_internet_works/README.md). +Pokud děláš tento tutorial doma, ne na jedné z [Django girls akcí](https://djangogirls.org/events/), můžeš zcela vynechat tuto kapitolu a jít rovnou na kapitolu [jak funguje Internet](../how_the_internet_works/README.md). To proto, že zde uvedené věci stejně vysvětlíme v průběhu celého kurzu a tato stránka pouze shromažďuje všechny pokyny pro instalaci na jednom místě. Jedna z Django Girls událostí "Instalační večer" se zaobírá instalováním všeho, co budeme potřebovat, což nás už nebude zdržovat během samotného worshopu. To je pro nás užitečná úspora času. @@ -44,6 +44,6 @@ Gratulujeme, právě sis zřídila všechny účty a nastavila vše, co potřebu * [Úvod do příkazového řádku](../intro_to_command_line/README.md) - * [Úvod do Pythonu](../intro_to_command_line/README.md) + * [Úvod do Pythonu](../python_introduction/README.md) * [Co je Django?](../django/README.md) diff --git a/cs/intro_to_command_line/README.md b/cs/intro_to_command_line/README.md index 2bdd6c0f5de..e736738bc1b 100755 --- a/cs/intro_to_command_line/README.md +++ b/cs/intro_to_command_line/README.md @@ -20,7 +20,7 @@ Chceš-li začít experimentovat, je třeba nejprve otevřít naše rozhraní p Jdi na menu Start → Všechny programy → Příslušenství → Příkazová řádka. -### Mac OS X +### macOS Aplikace → Nástroje → Terminál. diff --git a/cs/python_installation/images/add_python_to_windows_path.png b/cs/python_installation/images/add_python_to_windows_path.png index 9510d6f2176..3266efb6177 100644 Binary files a/cs/python_installation/images/add_python_to_windows_path.png and b/cs/python_installation/images/add_python_to_windows_path.png differ diff --git a/cs/python_installation/instructions.md b/cs/python_installation/instructions.md index 207e1f1c0a4..316d6845eab 100755 --- a/cs/python_installation/instructions.md +++ b/cs/python_installation/instructions.md @@ -26,18 +26,10 @@ Pokud Python nemáš nainstalovaný nebo pokud chceš nainstalovat jinou verzi, Použij tento příkaz v konzoli: ``` -sudo apt-get install python3.4 +sudo apt install python3.4 ``` -#### Fedora (do verze 21) - -Použij tento příkaz v konzoli: - -``` -sudo yum install python3.4 -``` - -#### Fedora (22 +) +#### Fedora Použij tento příkaz v konzoli: @@ -53,11 +45,11 @@ Použij tento příkaz v konzoli: $ sudo zypper install python3 ``` -### OS X +### macOS Musíš jít na web https://www.python.org/downloads/release/python-342/ a stáhnout si instalátor Python: - * Stáhni *Mac OS X 64-bit/32-bit installer* soubor, + * Stáhni *macOS 64-bit/32-bit installer* soubor, * Poklepej na *python-3.4.3-macosx10.6.pkg*, chceš-li spustit instalační program. Ověř, zda instalace proběhla úspěšně, otevři aplikaci *Terminal* a spusť příkaz `python3`: diff --git a/cs/python_introduction/README.md b/cs/python_introduction/README.md index 3448c09a381..6a197344f9d 100755 --- a/cs/python_introduction/README.md +++ b/cs/python_introduction/README.md @@ -444,7 +444,7 @@ Už jsi někdy slyšela výraz "srovnávat jablka a hrušky"? Zkusme v Pythonu e >>> 1 > 'django' Traceback (most recent call last): File "", line 1, in -TypeError: unorderable types: int() > str() +TypeError: '>' not supported between instances of 'int' and 'str' ``` Zde vidíš, že stejně jako nelze srovnávat "jablka a hrušky", Python není schopen porovnávat řetězce (`str`) a čísla (`int`). Místo toho zobrazí **TypeError** a říká nám, že tyto dva typy nelze srovnávat společně. diff --git a/cs/python_introduction/images/cupcake.png b/cs/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/cs/python_introduction/images/cupcake.png and b/cs/python_introduction/images/cupcake.png differ diff --git a/cs/template_extending/README.md b/cs/template_extending/README.md index b7fb7c5e3c2..184c85aa05b 100755 --- a/cs/template_extending/README.md +++ b/cs/template_extending/README.md @@ -100,7 +100,7 @@ A teď přidej na začátek souboru tento řádek: {% extends 'blog/base.html' %} ``` -{% raw %} to znamená, že nyní rozšiřujeme šablonu `base.html` v `post_list.html`. Jen jedna věc zbývá: vše dát (kromě řádku, který jsme právě přidaly) mezi `{% block content %}` a `{% endblock content %}`. Takto: {% endraw %} +{% raw %} to znamená, že nyní rozšiřujeme šablonu `base.html` v `post_list.html`. Jen jedna věc zbývá: vše dát (kromě řádku, který jsme právě přidaly) mezi `{% block content %}` a `{% endblock %}`. Takto: {% endraw %} ```html {% extends 'blog/base.html' %} @@ -115,7 +115,7 @@ A teď přidej na začátek souboru tento řádek:

{{ post.text|linebreaksbr }}

{% endfor %} -{% endblock content %} +{% endblock %} ``` To je ono! Zkontroluj, zda tvoje stránky stále správně fungují :) diff --git a/cs/whats_next/README.md b/cs/whats_next/README.md index f00eee800f1..5c52f3bfb88 100755 --- a/cs/whats_next/README.md +++ b/cs/whats_next/README.md @@ -17,7 +17,7 @@ Poté nezapomeň: Ano! Zaprvé, jdi a zkus naši další knihu, jmenuje se [Django Girls Tutorial: Extensions][3]. - [3]: http://djangogirls.gitbooks.io/django-girls-tutorial-extensions/ + [3]: https://tutorial-extensions.djangogirls.org Později můžeš zkusit, některý ze zdrojů uvedených níže. Všechny můžeme velmi doporučit! @@ -36,5 +36,5 @@ Později můžeš zkusit, některý ze zdrojů uvedených níže. Všechny můž [7]: https://www.codecademy.com/tracks/web [8]: https://github.com/ggcarrots/django-carrots/ [9]: http://learnpythonthehardway.org/book/ - [10]: http://gettingstartedwithdjango.com/ + [10]: http://www.gettingstartedwithdjango.com/ [11]: https://twoscoopspress.com/products/two-scoops-of-django-1-8 diff --git a/de/GLOSSARY.md b/de/GLOSSARY.md new file mode 100644 index 00000000000..26a8c07100e --- /dev/null +++ b/de/GLOSSARY.md @@ -0,0 +1,3 @@ +# Code-Editor + +Ein Code-Editor ist eine Anwendung, die es dir erlaubt, deinen Code zu speichern, um später daran weiterzuarbeiten. Du kannst in dem [Code-Editor Kapitel](./code_editor/README.md) erfahren, woher du einen bekommst. \ No newline at end of file diff --git a/de/README.md b/de/README.md new file mode 100644 index 00000000000..db87ba0c460 --- /dev/null +++ b/de/README.md @@ -0,0 +1,51 @@ +# Django Girls Tutorial + +[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial) + +> Dieses Werk ist unter der Creative Commons Attribution-ShareAlike 4.0 International License lizensiert. Eine Kopie dieser Lizenz finden Sie auf http://creativecommons.org/licenses/by-sa/4.0/ + +## Willkommen + +Willkommen beim Django Girls Tutorial! Wir freuen uns, dass du hier bist. :) In diesem Tutorial schauen wir gemeinsam unter die Haube der Technologien im Internet, geben dir einen Einblick in die Bits und Bytes, die zusammen das Internet bilden, wie wir es heute kennen. + +Wie alles Unbekannte wird das ein Abenteuer sein – aber keine Sorge: Da du bereits den Mut aufgebracht hast, hier zu sein, wirst du das schon meistern. :) + +## Einleitung + +Hattest du auch schon einmal das Gefühl, dass Technik in der Welt immer wichtiger wird und du da nicht ganz mithalten kannst? Wolltest du schon immer einmal eine Website bauen, aber hattest dann nicht genug Motivation, damit anzufangen? Hast du dir irgendwann schon einmal gedacht, dass die Computerwelt zu kompliziert für dich ist, so dass du noch nicht einmal den Versuch unternommen hast, dort selbst etwas zu tun? + +Dann haben wir hier gute Neuigkeiten für dich! Programmieren ist nicht so schwer, wie du denkst, und wir zeigen dir hier, wie viel Spaß es machen kann. + +Dieses Tutorial wird dich nicht auf zauberhafte Weise in eine Programmiererin verwandeln. Wenn du gut darin sein willst, brauchst du Monate oder sogar Jahre des Lernens und Übens. Aber wir wollen dir zeigen, dass Programmieren oder Webseitenerstellen nicht so kompliziert ist, wie es scheint. Wir versuchen, dir auf einfache Art verschiedene, kleine Teile zu zeigen, so dass du davon nicht eingeschüchtert wirst. + +Wir hoffen, dass du danach diese Technik und Technologien so sehr mögen wirst wie wir! + +## Was lernst du in diesem Tutorial? + +Wenn du mit dem Tutorial fertig bist, hast du eine einfache, aber funktionierende Webanwendung: deinen eigenen Blog. Wir zeigen dir, wie man ihn online stellt, andere können dein Werk also sehen! + +Es wird (in etwa) so aussehen: + +![Abbildung 0.1](images/application.png) + +> Wenn du allein mit diesem Tutorial arbeitest und keinen Coach in der Nähe hast, kannst du in diesem Chat nachfragen, wenn du ein Problem hast: [![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial). Wir haben unsere Coaches und frühere Teilnehmer unserer Workshops gebeten, hin und wieder dort vorbei zu schauen und anderen mit dem Tutorial zu helfen! Hab keine Angst, dort deine Fragen zu stellen! + +Okay, [lass uns ganz am Anfang starten...](./how_the_internet_works/README.md) + +## Das Tutorial daheim durcharbeiten + +An einem Django-Girls-Workshop teilzunehmen ist toll, aber uns ist klar, dass das nicht immer allen möglich ist. Darum wollen wir dich ermutigen, das Tutorial auch zu Hause zu erarbeiten. Für Leser zu Hause erstellen wir gerade Video-Tutorials, die es erleichtern sollen, diesem Tutorial zu folgen. Diese Arbeit ist noch nicht abgeschlossen, aber mehr und mehr Themen werden als Video erfasst und können im [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed)-YouTube-Kanal angesehen werden. + +In jedem Kapitel, das bereits mit Video unterstützt wird, gibt es einen Link auf das jeweilige Video dazu. + +## Über uns und wie du mithelfen kannst + +Dieses Tutorial wird von [DjangoGirls](https://djangogirls.org/) betreut. Solltest du Fehler finden oder das Tutorial aktualisieren wollen, dann folge den [Richtlinien zum Mitarbeiten](https://github.com/DjangoGirls/tutorial/blob/master/README.md). + +## Möchtest du uns helfen, das Tutorial in andere Sprachen zu übersetzen? + +Zur Zeit haben wir die Übersetzungen auf der crowdin.com Plattform: + +https://crowdin.com/project/django-girls-tutorial + +Sollte deine Sprache nicht aufgeführt sein, dann öffne ein neues [Issue](https://github.com/DjangoGirls/tutorial/issues/new), mit der betreffenden Sprache, dann können wir sie hinzufügen. \ No newline at end of file diff --git a/de/SUMMARY.md b/de/SUMMARY.md new file mode 100644 index 00000000000..28b069b3a29 --- /dev/null +++ b/de/SUMMARY.md @@ -0,0 +1,35 @@ +# Zusammenfassung + +* [Einleitung](README.md) +* [Installation](installation/README.md) + * [Kommandozeile](installation/README.md#command-line) + * [Python](installation/README.md#python) + * [Code-Editor](installation/README.md#code-editor) + * [Virtuelle Umgebung](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) +* [Installation (Chromebook)](chromebook_setup/README.md) +* [Wie das Internet funktioniert](how_the_internet_works/README.md) +* [Einführung in die Kommandozeile](intro_to_command_line/README.md) +* [Python-Installation](python_installation/README.md) +* [Der Code-Editor](code_editor/README.md) +* [Einführung in Python](python_introduction/README.md) +* [Django - Was ist das?](django/README.md) +* [Django-Installation](django_installation/README.md) +* [Dein erstes Django-Projekt!](django_start_project/README.md) +* [Django-Models](django_models/README.md) +* [Django-Administration](django_admin/README.md) +* [Veröffentlichen!](deploy/README.md) +* [Django-URLs](django_urls/README.md) +* [Django-Views - leg los!](django_views/README.md) +* [Einführung in HTML](html/README.md) +* [Django-ORM und QuerySets](django_orm/README.md) +* [Dynamische Daten in Templates](dynamic_data_in_templates/README.md) +* [Django-Templates](django_templates/README.md) +* [CSS - mach es hübsch!](css/README.md) +* [Erweiterung der Templates](template_extending/README.md) +* [Erweitere deine Anwendung](extend_your_application/README.md) +* [Django-Formulare](django_forms/README.md) +* [Wie geht es weiter?](whats_next/README.md) \ No newline at end of file diff --git a/de/chromebook_setup/README.md b/de/chromebook_setup/README.md new file mode 100644 index 00000000000..4e1c50d4085 --- /dev/null +++ b/de/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# Chromebook-Installation + +> **Hinweis** Wenn du die [Installation bereits gemacht](../installation/README.md) hast, kannst du direkt zur [Einführung in Python](../python_introduction/README.md) gehen. + +{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/de/chromebook_setup/instructions.md b/de/chromebook_setup/instructions.md new file mode 100644 index 00000000000..990e3144929 --- /dev/null +++ b/de/chromebook_setup/instructions.md @@ -0,0 +1,158 @@ +Du kannst [diesen Abschnitt einfach](http://tutorial.djangogirls.org/en/installation/#install-python) überspringen, falls du kein Chromebook benutzt. Wenn du eins benutzt, wird deine Installation ein wenig anders sein. Du kannst den Rest der Installationsanweisungen ignorieren. + +### Cloud-IDE (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com) + +Eine Cloud-IDE ist ein Werkzeug, dass dir einen Code-Editor und Zugang zu einem Rechner im Internet bereitstellt, auf dem du die Software installieren, anpassen und ausführen kannst. Für die Dauer des Tutorials wird Cloud IDE zu deinem *lokalen Rechner*. Auch du wirst Befehle in einer Kommandozeilen-Oberfläche ausführen können, genau wie die anderen Teilnehmerinnen, die mit macOS, Ubuntu oder Windows arbeiten. Dein Terminal wird jedoch mit einem Rechner verbunden sein, den Cloud IDE dir bereitstellt. Hier sind die Anleitungen für die Cloud-IDEs (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com). Wähle eine der Cloud-IDEs aus und folge den Anweisungen der gewählten Cloud IDE. + +#### PaizaCloud Cloud IDE + +1. Gehe zu [PaizaCloud Cloud IDE](https://paiza.cloud/) +2. Lege dir dort ein Benutzerkonto an +3. Klicke auf *New Server* und wähle die Django-App +4. Klicke auf die Schaltfläche "Terminal" (links im Browserfenster) + +Jetzt solltest du links eine Schnittstelle mit einer Seitenleiste und Schaltflächen sehen. Klicke auf den "Terminal"-Button und öffne das Terminal-Fenster mit einer Eingabeaufforderung wie folgt: + +{% filename %}browser{% endfilename %} + + $ + + +Das Terminal auf der PaizaCloud Cloud IDE steht für deine Anweisungen bereit. Du kannst die Größe des Fensters frei einstellen. + +#### AWS Cloud9 + +Zur Zeit verlangt Cloud 9, dass du dich mit AWS anmeldest und Kreditkarten-Informationen angibst. + +1. Installiere Cloud 9 aus dem [Chrome web store](https://chrome.google.com/webstore/detail/cloud9/nbdmccoknlfggadpfkmcpnamfnbkmkcp) +2. Gehe zu [c9.io](https://c9.io) und klicke auf *Get started with AWS Cloud9* +3. Erstelle ein AWS-Benutzerkonto (benötigt Angabe der Kreditkarte, kann aber kostenlos verwendet werden) +4. Gib im AWS-Dashboard *Cloud9* in die Suchzeile ein und klicke es an +5. Klicke im Cloud-9-Dashboard *Create environment* an +6. Gib ihm den Namen *django-girls* +7. Wähle beim Konfigurieren der Einstellungen *Create a new instance for environment (EC2)* als "Environment Type" und den "Instance type" *t2.micro* ("Free-tier eligible." sollte angezeigt werden). Die Voreinstellung bzgl. "cost-saving" ist in Ordnung und auch die anderen Voreinstellungen kannst du belassen. +8. Klicke auf *Next step* +9. Klicke auf *Create environment* + +Jetzt solltest du eine Benutzeroberfläche mit Seitenleiste, ein grosses Fenster mit Text und am unteren Rand ein Feld sehen, das wie folgt aussieht: + +{% filename %}bash{% endfilename %} + + deinbenutzername:~/workspace $ + + +Dieser untere Bereich ist dein Terminal. Dort kannst du Kommandos für den Computer eingeben, den dir Cloud 9 zur Verfügung stellt. Du kannst dieses Fenster vergrößern oder verkleinern. + +#### Glitch.com Cloud-IDE + +1. Gehe auf [Glitch.com](https://glitch.com/) +2. Melde dich für einen Account an (https://glitch.com/signup) oder nutze deinen GitHub-Account, falls du einen hast. (Siehe GitHub-Anweisungen unten.) +3. Klicke auf *Neues Projekt* und wähle *hello-webpage* +4. Klicke auf die Dropdown-Liste Tools (unten links im Fenster) und dann auf den Knopf Terminal, um einen Kommandozeilen-Tab mit einem Prompt wie dem folgenden zu öffnen: + +{% filename %}Terminal{% endfilename %} + + app@name-deines-glitch-projects:~ + + +Wenn du Glitch.com als Cloud-IDE verwendest, musst du keine virtuelle Umgebung erstellen. Erstelle stattdessen die folgenden Dateien manuell: + +{% 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 +``` + +Gehe nach dem Erstellen der Dateien zum Terminal und führe die folgenden Befehle aus, um dein erstes Django-Projekt zu erstellen: + +{% filename %}Terminal{% endfilename %} + + django-admin.py startproject mysite . + refresh + + +Um detaillierte Fehlermeldungen zu sehen, kannst du Django Debug-Logs für deine Glitch-Anwendung aktivieren. Füge einfach folgendes am Ende der Datei `mysite/settings.py` hinzu. + +{% 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, + }, + }, +} +``` + +Dadurch wird eine Datei namens `debug.log` erzeugt, die aufgetretene Django-Operationen und Fehlermeldungen detailliert aufgeführen wird, was die Fehlersuche und -behebung sehr erleichtern kann, wenn deine Website nicht funktioniert. + +Der erste Neustart des Glitch-Projekts sollte fehlschlagen. (Wenn du auf die oberste Dropdown-Schaltfläche `Show` klickst und dann auf `In a New Window`, erhältst du die Fehlermeldung `DisallowedHost`.) Mach dir jetzt keine Sorgen darüber. Das Tutorial wird dies beheben, sobald du die Django-Einstellungen deines Projekts in der Datei `mysite/settings.py` aktualisierst + +### Virtuelle Umgebung + +Eine virtuelle Umgebung (auch virtualenv genannt) ist wie ein privater Behälter, in den wir nützlichen Code für ein Projekt packen können, an dem wir arbeiten. Wir benutzen sie, um Code für verschiedene Projekte getrennt aufzubewahren, damit dieser nicht vermischt wird. + +Führe Folgendes aus: + +{% filename %}Cloud 9{% endfilename %} + + mkdir djangogirls + cd djangogirls + python3 -m venv myvenv + source myvenv/bin/activate + pip install django~={{ book.django_version }} + + +(Beachte, dass wir im letzten Befehl eine Tilde gefolgt von einem Gleichheitssymbol benutzen: `~=`). + +### GitHub + +Erstelle einen [GitHub](https://github.com)-Account. + +### PythonAnywhere + +Das Django Girls-Tutorial enthält ein Kapitel zum Thema Deployment. Beim Deployment nimmst du den Code, der deiner Web-Anwendung zu Grunde liegt, und packst ihn auf einen öffentlich zugänglichen Computer (Server), damit auch andere Leute deine Arbeit sehen können. + +Es mag seltsam scheinen, das auf einem Chromebook zu tun. Denn wir sind mit Cloud 9 ja bereits auf einem anderen Computer im Internet (anstatt z.B. auf einem lokalen Laptop). Es ist aber trotzdem sinnvoll, denn wir können uns unseren Cloud-9-Arbeitsplatz als Ort für "Dinge in Arbeit" vorstellen und PythonAnywhere als Ort, wo wir unser "fertiges" Projekt der Öffentlichkeit zeigen. + +Melde dich deshalb auf [www.pythonanywhere.com](https://www.pythonanywhere.com) für ein PythonAnywhere-Benutzerkonto an. \ No newline at end of file diff --git a/de/code_editor/README.md b/de/code_editor/README.md new file mode 100644 index 00000000000..9ff0e2c9c79 --- /dev/null +++ b/de/code_editor/README.md @@ -0,0 +1,11 @@ +# Der Code-Editor + +> Für die Leser zu Hause: Dieses Kapitel wird im Video [Installing Python & Code Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s) behandelt. + +Gleich geht's los! Du wirst deine erste Zeile Programmcode schreiben! Daher ist es jetzt an der Zeit, einen entsprechenden Editor herunterzuladen! + +> **Hinweis** Wenn du ein Chromebook benutzt, dann überspringe dieses Kapitel und folge den [Chromebook Installations](../chromebook_setup/README.md)-Anweisungen. Deine Cloud-IDE (PaizaCloud Cloud IDE oder AWS Cloud9) enthält einen Code-Editor und wenn du eine Datei in deiner Entwicklungsumgebung öffnest, wirst du automatisch den Editor benutzen. +> +> **Hinweis:** Es kann sein, dass du diesen Schritt bereits im [Kapitel "Installation"](../installation/README.md) erledigt hast. In diesem Fall kannst du direkt zum nächsten Kapitel übergehen! + +{% include "/code_editor/instructions.md" %} \ No newline at end of file diff --git a/de/code_editor/instructions.md b/de/code_editor/instructions.md new file mode 100644 index 00000000000..82af5539f5b --- /dev/null +++ b/de/code_editor/instructions.md @@ -0,0 +1,37 @@ +Es gibt viele verschiedene Editoren. Welcher für dich am besten ist, ist weitestgehend Geschmackssache. Die meisten Python-Programmiererinnen verwenden komplexe, aber extrem leistungsfähige IDEs (Integrated Development Environments), z. B. PyCharm. Für Anfängerinnen sind diese jedoch weniger gut geeignet. Unsere Empfehlungen sind ebenso leistungsfähig, aber viel einfacher zu bedienen. + +Unsere Vorschläge siehst du unten. Aber fühl dich ganz frei, deine Trainerin zu fragen, was ihre Vorlieben sind - wenn sie sich mit dem Editor auskennt, wird es leichter sein, Hilfe zu erhalten. + +## Visual Studio Code + +Visual Studio Code ist ein von Microsoft entwickelter Quellcode-Editor für Windows, Linux und Mac. Es enthält Unterstützung für Debugging, eingebaute Git-Steuerung, Syntax-Highlighting, intelligente Code-Vervollständigung, Snippets und Code-Refactoring. + +[Du kannst ihn hier herunterladen](https://code.visualstudio.com/) + +## Gedit + +Gedit ist ein kostenloser Open-Source-Editor. Es gibt ihn für alle Betriebssysteme. + +[Du kannst ihn hier herunterladen](https://wiki.gnome.org/Apps/Gedit#Download) + +## Sublime Text + +Sublime Text ist ein sehr beliebter Editor, nutzbar für einen kostenlosen Testzeitraum. Er ist einfach zu installieren und zu verwenden, und er ist für alle Betriebssysteme verfügbar. + +[Du kannst ihn hier herunterladen](https://www.sublimetext.com/) + +## Atom + +Atom ist ein weiterer beliebter Editor. Er ist gratis, Open-Source und für Windows, macOS und Linux verfügbar. Atom wird von [GitHub](https://github.com/) entwickelt. + +[Du kannst ihn hier herunterladen](https://atom.io/) + +## Warum installieren wir einen Code-Editor? + +Vielleicht wunderst du dich, warum wir so spezielle Code-Editor-Software installieren, statt einfach etwas wie Word oder Notepad zu benutzen. + +Erstens muss Code "plain text" (unformatierter Text) sein. Das Problem mit Programmen wie Word und Textedit ist, dass sie nicht "plain text" sondern "rich text" (mit Schriftarten und Formatierungen) produzieren und besondere Formate wie RTF (Rich Text Format) verwenden. + +Ein weiterer Grund ist, dass Code-Editoren (bisweilen auch Programmier- oder Text-Editoren genannt) auf das Bearbeiten von Programm-Code spezialisiert sind und Funktionen aufweisen, die normale Textverarbeitungen nicht haben. Beispielsweise sogenanntes "Syntax-Highlighting", also farbliches Hervorheben bestimmter Code-Stellen, oder auch das automatische Schließen von Klammern und vieles mehr. + +Einiges davon werden wir später in Aktion sehen. Glaub uns: es wird nicht lange dauern, bis du deinen Code-Editor nicht mehr missen möchtest. :) diff --git a/de/css/README.md b/de/css/README.md new file mode 100644 index 00000000000..f439d56e9e9 --- /dev/null +++ b/de/css/README.md @@ -0,0 +1,330 @@ +# CSS - mach es hübsch! + +Unser Blog sieht immer noch ziemlich unfertig aus, oder? Zeit, das zu ändern! Dafür nutzen wir CSS. + +## Was ist CSS? + +Cascading Style Sheets (CSS) ist eine Sprache, die das Aussehen und die Formatierung einer Website beschreibt. Es handelt sich wie bei HTML um eine Auszeichnungssprache (Markup Language). Sie ist sowas wie das "Make-up" unserer Website. ;) + +Aber wir wollen nicht nochmal bei Null anfangen, oder? Einmal mehr werden wir etwas verwenden, dass ProgrammiererInnen entwickelt haben und gratis im Internet zur Verfügung stellen. Wir wollen ja nicht das Rad neu erfinden. + +## Lass uns Bootstrap verwenden! + +Bootstrap ist eines der bekanntesten HTML- und CSS-Frameworks für die Entwicklung von schönen Webseiten: https://getbootstrap.com/ + +Es wurde ursprünglich von ProgrammiererInnen bei Twitter geschrieben. Heute wird es von Freiwilligen aus der ganzen Welt weiterentwickelt! + +## Bootstrap installieren + +Öffne deine `.html`-Datei in deinem Code-Editor und füge Folgendes zum ``-Abschnitt hinzu, um Bootstrap zu installieren: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +Dadurch werden deinem Projekt keine Dateien hinzugefügt. Der Code verweist nur auf Dateien, die im Internet vorhanden sind. Öffne und aktualisiere also deine Webseite. Da ist sie! + +![Abbildung 14.1](images/bootstrap1.png) + +Sie sieht jetzt schon viel schöner aus! + +## Statische Dateien in Django + +Endlich werden wir einen genaueren Blick auf die Dinge werfen, die wir bisher **statische Dateien** genannt haben. Statische Dateien sind alle deine CSS- und Bilddateien. Ihr Inhalt hängt nicht vom Requestkontext ab, sondern gilt für alle Benutzer gleichermaßen. + +### Wohin kommen die statischen Dateien für Django + +Django weiss schon, wo die statischen Dateien für die integrierte "admin"-App zu finden sind. Wir müssen noch die statischen Dateien für unsere `blog`-App hinzufügen. + +Dies tun wir, indem wir einen Ordner namens `static` in der Blog-App erstellen: + + djangogirls + ├── blog + │ ├── migrations + │ ├── static + │ └── templates + └── mysite + + +Django findet automatisch alle Ordner mit dem Namen "static" in all unseren App-Ordnern. So ist es in der Lage, ihre Inhalte als statische Dateien zu nutzen. + +## Deine erste CSS-Datei! + +Erstellen wir nun eine CSS-Datei, um deiner Website deinen eigenen Stil zu verleihen. Erstelle ein neues Verzeichnis namens `css` in deinem `static`-Verzeichnis. Dann erstelle eine neue Datei namens `blog.css` in diesem `css`-Verzeichnis. Fertig? + + djangogirls + └─── blog + └─── static + └─── css + └─── blog.css + + +Zeit, ein wenig CSS zu schreiben! Öffne die `blog/static/css/blog.css` Datei in Deinem Code-Editor. + +Wir gehen nicht zu sehr auf die Details von CSS ein. Für diejenigen, die mehr über CSS lernen möchten, haben wir am Ende des Kapitels einen Link auf eine Empfehlung für einen kostenlosen CSS-Kurs angefügt. + +Aber lass uns wenigstens etwas Kleines probieren. Beispielsweise könnten wir die Farbe unserer Kopfzeile ändern. Computer benutzen spezielle Codes, um Farben zu verstehen. Diese Codes starten immer mit `#`, danach folgen sechs Buchstaben (A-F) und Zahlen (0-9). Blau zum Beispiel ist `#0000FF`. Beispiele für solche Farbcodes findest du hier: http://www.colorpicker.com/. Du kannst auch [vordefinierte Farben](http://www.w3schools.com/colors/colors_names.asp) wie `red` und `green` benutzen. + +In deiner `blog/static/css/blog.css` Datei änderst du den folgenden Code: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +h1 a, h2 a { + color: #C25100; +} + +``` + +`h1 a` ist ein CSS-Selektor. Das bedeutet, dass wir für ein `a`-Element innerhalb eines `h1`-Elements einen Style hinzufügen; der `h2 a`-Selektor macht das selbe für `h2`-Elemente. Wenn wir also etwas haben wie: `

link

` wird der `h1 a` Style angewandt. In diesem Fall sagen wir, dass die Farbe in `#C25100` geändert werden soll. Das ist ein dunkles Orange. Du kannst hier auch deine eigene Farbe verwenden, aber stelle sicher, dass sie einen guten Kontrast zum weißen Hintergrund hat! + +In einer CSS-Datei werden Stile für Elemente der HTML-Datei festgelegt. Ein Weg, HTML-Elemente zu identifizieren, ist der Name des Elements. Du erinnerst dich vielleicht an diese Namen, die wir als 'Tags' im HTML Kapitel bezeichnet haben. Zum Beispiel sind `a`, `h1` und `body` solche Elementnamen. Wir identifizieren Elemente auch über die Attribute `class` oder `id`. Klassen (`class`) und IDs (`id`) sind Namen, die du den Elementen selbst gibst. Klassen definieren dabei Gruppen von Elementen und IDs verweisen auf bestimmte Elemente. Du könntest zum Beispiel das folgende Element anhand des Elementnamens `a`, anhand der Klasse `external_link` oder anhand der ID `link_to_wiki_page` identifizieren: + +```html + +``` + +[Auf w3schools](http://www.w3schools.com/cssref/css_selectors.asp) erfährst du mehr über CSS-Selektoren. + +Wir müssen der HTML-Vorlage noch sagen, dass wir CSS eingefügt haben. Öffne die Datei `blog/templates/blog/post_list.html` im Code-Editor und füge diese Zeile ganz oben ein: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% load static %} +``` + +Wir laden hier die statischen Dateien. :) Füge zwischen den Tags `` und ``, direkt nach den Links zu den Bootstrap-Dateien, noch diese Zeile ein: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +Der Browser liest die Dateien in der Reihenfolge, in der sie aufgeschrieben wurden. Darum müssen wir sicherstellen, dass die Zeile am richtigen Ort steht. Sonst könnte der Code der Bootstrap-Dateien den Code aus unserer Datei überschreiben. Wir haben also unserem Template gerade gesagt, wo sich die CSS-Datei befindet. + +Deine Datei sollte jetzt so aussehen: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% load static %} + + + + Django Girls blog + + + + +
+

Django Girls Blog

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

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} + + +``` + +OK, speichere die Datei und lade die Seite neu! + +![Abbildung 14.2](images/color2.png) + +Gut gemacht! Vielleicht wollen wir unserer Webseite etwas mehr Luft geben, indem wir den Abstand auf der linken Seite vergrößern? Probieren wir es aus! + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +body { + padding-left: 15px; +} +``` + +Füge dies zu deinem CSS hinzu, speichere die Datei und schau dir an, was passiert. + +![Abbildung 14.3](images/margin2.png) + +Vielleicht können wir auch die Schrift in unserem HTML-Kopf anpassen? Füge dies zu `` in `blog/templates/blog/post_list.html` hinzu: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +Wie eben bereits gemacht, prüfe die Reihenfolge und platziere die Anweisung vor dem Link `blog/static/css/blog.css`. Sie importiert eine Schriftart (engl. "Font") namens *Lobster* von Google Fonts (https://www.google.com/fonts). + +Suche den Anweisungsblock: `h1 a` (der Code zwischen den geschweiften Klammern `{` und `}`) in der CSS Datei `blog/static/css/blog.css`. Nun füge die Zeile `font-family: 'Lobster';` zwischen den geschweiften Klammern hinzu und aktualisiere die Seite: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +h1 a, h2 a { + color: #C25100; + font-family: 'Lobster'; +} +``` + +![Abbildung 14.3](images/font.png) + +Super! + +Wie oben erwähnt, basiert CSS auf dem Konzept von Klassen. Diese erlauben dir, einen Teil des HTML-Codes mit einem Namen zu versehen und die Darstellung dieses Teils separat von anderen Teilen mit einem Stil zu steuern. Das kann sehr hilfreich sein! Eventuell hast Du zwei 'div's die etwas vollkommen Verschiedenes auszeichnen (wie einen Seitentitel oder Post Beitrag). Die Klasse hilft dir, sie unterschiedlich aussehen zu lassen. + +Geben wir also einigen Teilen deines HTML-Codes solche Namen. Ersetze den `header`, der deine Kopfzeile enthält, mit folgendem: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +Jetzt fügen wir dem `article` für den Blog-Inhalt (Post) noch eine Klasse `post` hinzu. + +{% filename %}blog/templates/blog/post_list{% endfilename %} + +```html +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+``` + +Wir erweitern jetzt unser CSS mit entsprechenden Selektoren. Selektoren, die mit `.` anfangen, beziehen sich auf Klassen im HTML. Es gibt im Internet viele gute Tutorials und Informationen über CSS, die dir helfen können, den folgenden Code besser zu verstehen. Kopiere zunächst folgenden Text in deine `blog/static/css/blog.css`-Datei: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +.page-header { + 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 { + color: #ffffff; + font-size: 36pt; + text-decoration: none; +} + +h1, +h2, +h3, +h4 { + font-family: 'Lobster', cursive; +} + +.date { + color: #828282; +} + +.save { + float: right; +} + +.post-form textarea, +.post-form input { + width: 100%; +} + +.top-menu, +.top-menu:hover, +.top-menu:visited { + color: #ffffff; + float: right; + font-size: 26pt; + margin-right: 20px; +} + +.post { + margin-bottom: 70px; +} + +.post h2 a, +.post h2 a:visited { + color: #000000; +} + +.post > .date, +.post > .actions { + float: right; +} + +.btn-default, +.btn-default:visited { + color: #C25100; + background: none; + border-color: #C25100; +} + +.btn-default:hover { + color: #FFFFFF; + background-color: #C25100; +} +``` + +Der HTML-Code, der für die Anzeige der Blogposts verantwortlich ist, soll durch Klassen erweitert werden. Ersetze den folgenden Code: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` + +in `blog/templates/blog/post_list.html` durch diesen: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+
+
+ {% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
+``` + +Speichere die geänderten Dateien und aktualisiere die Webseite. + +![Abbildung 14.4](images/final.png) + +Juhuu! Sieht super aus, oder? Schau dir den Code an, den wir gerade eingefügt haben. Da siehst du, wo wir überall Klassen zu den HTML-Objekten hinzugefügt haben, um sie in CSS zu referenzieren. Wo würdest du eine Änderung machen, um das Datum in Türkis anzuzeigen? + +Hab keine Angst, etwas mit dieser CSS-Datei herumzuspielen, und versuche, ein paar Dinge zu ändern. Mit CSS herumzuspielen, kann dir helfen zu verstehen, was die verschiedenen Dinge genau machen. Mach dir keine Sorgen, wenn etwas kaputt geht, du kannst deine Änderungen immer rückgängig machen! + +Wir empfehlen die kostenlosen online-Kurse "Basic HTML & HTML5" und "Basic CSS" auf [freeCodeCamp](https://learn.freecodecamp.org/). Sie werden dir helfen, deine Webseiten mit HTML und CSS schöner zu gestalten. + +Bereit für das nächste Kapitel? :) \ No newline at end of file diff --git a/de/css/images/bootstrap1.png b/de/css/images/bootstrap1.png new file mode 100644 index 00000000000..bd81cd14373 Binary files /dev/null and b/de/css/images/bootstrap1.png differ diff --git a/de/css/images/color2.png b/de/css/images/color2.png new file mode 100644 index 00000000000..3f82e7d3922 Binary files /dev/null and b/de/css/images/color2.png differ diff --git a/de/css/images/final.png b/de/css/images/final.png new file mode 100644 index 00000000000..067c83d36cc Binary files /dev/null and b/de/css/images/final.png differ diff --git a/de/css/images/font.png b/de/css/images/font.png new file mode 100644 index 00000000000..310f9e85f18 Binary files /dev/null and b/de/css/images/font.png differ diff --git a/de/css/images/margin2.png b/de/css/images/margin2.png new file mode 100644 index 00000000000..895828b688d Binary files /dev/null and b/de/css/images/margin2.png differ diff --git a/de/deploy/README.md b/de/deploy/README.md new file mode 100644 index 00000000000..9657fab70d0 --- /dev/null +++ b/de/deploy/README.md @@ -0,0 +1,246 @@ +# Veröffentlichen! + +> **Hinweis:** Durch das folgende Kapitel muss man sich manchmal durchbeißen. Bleib dran und gib nicht auf; die Website zu veröffentlichen, ist ein sehr wichtiger Schritt. Dieses Kapitel ist in der Mitte des Tutorials platziert, damit dir dein Mentor mit dem etwas anspruchsvolleren Vorgang der Veröffentlichung deiner Website helfen kann. Den Rest des Tutorials kannst du dann auch alleine beenden, sollte die Zeit nicht ausreichen. + +Bis jetzt war deine Webseite nur auf deinem Computer verfügbar. Jetzt wirst du lernen wie du sie 'deployst'! Deployen bedeutet, dass du deine Anwendung im Internet veröffentlichst, so dass endlich jeder darauf zugreifen kann. :) + +Wie du schon gelernt hast, muss eine Webseite auf einem Server liegen. Es gibt eine Vielzahl von Hosting (Server)-Anbietern im Internet, wir werden [PythonAnywhere](https://www.pythonanywhere.com/) verwenden. PythonAnywhere ist kostenlos für kleine Anwendungen, die nicht von vielen Besuchern aufgerufen werden. Also erstmal genau das Richtige für dich. + +Als weiteren externen Dienst werden wir [GitHub](https://www.github.com) nutzen, einen "Code Hosting"-Dienst. Es gibt noch andere solcher Dienste, aber die meisten Programmierer haben heute ein Konto bei GitHub, und du auch gleich! + +Diese drei Orte werden für dich wichtig sein. Die Entwicklung und das Testen wirst du auf deinem lokalen Rechner durchführen. Wenn du mit deinen Änderungen zufrieden bist, wirst du eine Kopie deines Programms auf GitHub veröffentlichen. Deine Website wird auf PythonAnywhere gehostet werden. Ändern kannst du sie, indem du eine neue Version deines Codes von GitHub herunter lädst. + +# Git + +> **Hinweis:** Falls du die [Installationsschritte](../installation/README.md) bereits durchgeführt hast, kannst du mit dem nächsten Abschnitt fortfahren und anfangen, dein Git-Repository zu erstellen. + +{% include "/deploy/install_git.md" %} + +## Unser Git-Repository + +Git verwaltet die Veränderungen an einer Sammlung von Dateien in einem sogenannten Repository (oder kurz "Repo"). Legen wir eines für unser Projekt an. Öffne deine Konsole und gibt folgende Kommandos im `djangogirls`-Verzeichnis ein: + +> **Hinweis:** Überprüfe dein aktuelles Arbeitsverzeichnis mit dem Befehl `pwd` (OSX/Linux) oder `cd` (Windows) bevor du das Repository initialisierst. Du musst dich im `djangogirls`-Verzeichnis befinden, bevor du fortfährst. + +{% filename %}command-line{% endfilename %} + + $ git init + Initialized empty Git repository in ~/djangogirls/.git/ + $ git config --global user.name "Dein Name" + $ git config --global user.email du@example.com + + +Die Initialisierung des Git-Repositorys müssen wir für jedes Projekt nur einmal machen (danach musst Du Benutzernamen und Mail-Adresse nie wieder eingeben). + +Git wird die Änderungen an all den Dateien und Ordnern in diesem Verzeichnis aufzeichnen. Wir wollen aber, dass einige Dateien ignoriert werden. Dazu legen wir eine Datei `.gitignore` im Hauptordner (`djangogirls`) des Repos an. Öffne deinen Editor und erstelle eine neue Datei mit dem folgenden Inhalt: + +{% filename %}.gitignore{% endfilename %} + + # Python + *.pyc + *~ + __pycache__ + + # Env + .env + myvenv/ + venv/ + + # Datenbank + db.sqlite3 + + # Static Ordner im Projektverzeichnis + /static/ + + # macOS + ._* + .DS_Store + .fseventsd + .Spotlight-V100 + + # Windows + Thumbs.db* + ehthumbs*.db + [Dd]esktop.ini + $RECYCLE.BIN/ + + # Visual Studio + .vscode/ + .history/ + *.code-workspace + + +Speichere die Datei mit dem Namen `.gitignore` im "djangogirls"-Root-Verzeichnis. + +> **Hinweis:** Der Punkt vor dem Dateinamen ist wichtig! Wenn du Schwierigkeiten beim Erstellen hast (z.B. lassen Macs im Finder keine Dateien mit Punkt am Anfang erzeugen, Punkt-Dateien sind auf Linux und macOS "versteckte Dateien"), dann verwende die "Speichern unter"-Funktion im Editor, das sollte immer funktionieren. Wichtig ist, dass du den Dateinamen nicht mit `.txt`, `.py` oder einer anderen Dateinamen-Erweiterung ergänzt -- die Datei wird von Git nur erkannt, wenn ihr Name exakt nur `.gitignore` ist. Linux und MacOS behandeln Dateien mit Namen, die mit `.` beginnen (wie `.gitignore`), als versteckt und der normale `ls`-Befehl zeigt diese Dateien nicht an. Verwende stattdessen `ls -a` um die Datei `.gitignore` anzuzeigen. +> +> **Hinweis:** Eine der Dateien, die du in deiner `.gitignore`-Datei defniniert hast, ist `db.sqlite3`. Diese Datei ist deine lokale Datenbank, in welcher alle deine Benutzer und Posts gespeichert werden. Wir werden die gängige Web-Entwicklungs-Praxis befolgen, was heißt, dass wir separate Datenbanken für unsere lokale Test-Website und unsere öffentliche Website auf PythonAnywhere verwenden werden. Die Datenbank für letztere könnte SQLite sein, wie auf deiner Entwicklungsmaschine, aber normalerweise wirst du eine sogenannte MySQL-Datenbank nutzen, welche mit viel mehr Besuchern umgehen kann als SQLite. So oder so, dadurch, dass du deine SQLite-Datenbank für die GitHub-Kopie nicht verwendest, werden alle deine bisherigen Posts der Superuser nur lokal zur Verfügung stehen und du musst in der produktiven Umgebung neue hinzufügen. Betrachte deine lokale Datenbank als tollen Spielplatz, auf welchem du verschiedene Dinge ausprobieren kannst, ohne Angst zu haben, dass du deine wirklichen Post auf deinem Blog löschst. + +Es ist hilfreich den Befehl `git status` vor `git add` auszuführen oder immer dann, wenn du dir unsicher bist, was geändert wurde. Das schützt vor manchen Überraschungen, wie z. B. das falsche Hinzufügen oder Übertragen von Dateien. Das `git status`-Kommando gibt Informationen über unbeobachtete/veränderte/hinzugefügte Dateien, den Status der Verzweigung und einiges mehr wieder. Deine Ausgabe sollte dem hier ähneln: + +{% filename %}command-line{% endfilename %} + + $ git status + On branch master + + 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) + + +Nun speichern wir unsere Änderungen durch folgende Eingabe in der Konsole: + +{% filename %}command-line{% endfilename %} + + $ git add . + $ git commit -m "Meine Django-Girls-App, erster Commit" + [...] + 13 files changed, 200 insertions(+) + create mode 100644 .gitignore + [...] + create mode 100644 mysite/wsgi.py + + +## Den Code auf GitHub veröffentlichen + +Gehe auf [GitHub.com](https://www.github.com) eröffne ein neues, kostenloses Nutzerkonto. (Falls Du es bereits während der Workshop-Vorbereitung eingerichtet hast, ist das großartig!) Stelle sicher, dass Du Dein Passwort nicht vergisst (füge es zu zu Deinem Passwort-Manager hinzu, falls Du einen solchen verwendest). + +Erstelle dann ein neues Repository und gib ihm den Namen "my-first-blog". Lass das Kontrollkästchen "initialise with a README" deaktiviert und die Einstellung der Option .gitignore leer (das haben wir schon von Hand gemacht) und lass die Lizenz auf "None". + +![](images/new_github_repo.png) + +> **Achtung:** Der Name `my-first-blog` ist wichtig -- du kannst auch einen anderen wählen, aber er wird im Folgenden noch sehr oft vorkommen und du wirst immer daran denken müssen, ihn in den Anweisungen entsprechend anzupassen. Es ist wahrscheinlich einfacher, bei `my-first-blog` zu bleiben. + +In der nächsten Ansicht wirst du die clone-URL deines Repositorys sehen, die du in manchen der folgenden Kommandozeilenbefehlen verwenden wirst: + +![](images/github_get_repo_url_screenshot.png) + +Nun müssen wir das Git-Repository auf deinem Computer mit dem auf GitHub verbinden. + +Gib das Folgende auf der Kommandozeile ein (ersetzte `` mit dem Benutzernamen, den du beim Erstellen deines GitHub-Accounts gewählt hast, aber ohne die spitzen Klammern -- die URL sollte der clone-URL entsprechen, die du vorhin gerade gesehen hast): + +{% filename %}command-line{% endfilename %} + + $ git remote add origin https://github.com//my-first-blog.git + $ git push -u origin master + + +Wenn du zu GitHub pushst, wirst du nach deinem Benutzernamen und Passwort gefragt (entweder direkt im Kommandozeilen-Fenster oder in einem Pop-Up-Fenster), und nach der Eingabe deiner Zugangsdaten solltest du etwas Ähnliches wie das hier sehen: + +{% filename %}command-line{% endfilename %} + + 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/ola/my-first-blog.git + + * [new branch] master -> master + Branch master set up to track remote branch master from origin. + + + + +Dein Code ist jetzt auf GitHub. Schau gleich mal nach! Dort ist dein Code in guter Gesellschaft - [Django](https://github.com/django/django), das [Django Girls Tutorial](https://github.com/DjangoGirls/tutorial) und viele andere großartige Open Source Software-Projekte haben ihren Code auf GitHub. :) + +# Deinen Blog auf PythonAnywhere einrichten + +## Registriere dich für ein PythonAnywhere Konto + +> **Hinweis:** Es ist möglich, dass du bereits ein PythonAnywhere Konto angelegt hast. Wenn ja, dann brauchst du das nicht noch einmal zu tun. + +{% include "/deploy/signup_pythonanywhere.md" %} + +## Unsere Site auf PythonAnywhere konfigurieren + +Gehe zurück zum [Haupt-Dashboard PythonAnywhere](https://www.pythonanywhere.com/), indem du auf das Logo klickst. Dann wähle die Option zum Start einer "Bash"-Konsole – die PythonAnywhere Version einer Kommandozeile wie du sie auf deinen Computer hast. + +![Der 'New Console"-Abschnitt auf der PythonAnywhere-Weboberfläche, mit einem Knopf für 'bash'](images/pythonanywhere_bash_console.png) + +> **Hinweis:** PythonAnywhere basiert auf Linux. Wenn du Windows benutzt, dann sieht die Konsole etwas anders aus als die Konsole auf deinem Computer. + +Um eine Web App auf PythonAnywhere publizieren zu können, muss dein Code von GitHub heruntergeladen und PythonAnyhwere dazu gebracht werden, diesen zu erkennen und als Web Applikation anzubieten. Du kannst das auch manuell machen. Aber PythonAnywhere stellt ein Hilfstool zur Verfügung, das das alles für dich erledigt. Lass es uns installieren: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ pip install --user pythonanywhere + + +Nach diesem Befehl solltest du in etwa Folgendes sehen: `Collecting pythonanywhere`, und irgendwann den Schluss `Successfully installed (...) pythonanywhere- (...)`. + +Nun können wir mit dem Hilfstool unsere App von GitHub automatisch konfigurieren. Gib das Folgende in der Konsole auf PythonAnywhere ein (vergiss nicht, deinen GitHub-Benutzernamen an Stelle von `` zu benutzen, so dass die URL der clone-URL von GitHub entspricht): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ pa_autoconfigure_django.py --python=3.10 https://github.com//my-first-blog.git + + +Während du die Ausführung verfolgst, wirst du sehen, was passiert: + +- Den Code von GitHub herunterladen +- Eine virtuelle Umgebung auf PythonAnywhere einrichten, genau wie die auf deinem eigenen Computer +- Deine Einstellungen mit ein paar Veröffentlichungseinstellungen aktualisieren +- Eine Datenbank auf PythonAnywhere einrichten mit dem Befehl `manage.py migrate` +- Deine statischen Dateien einrichten (darüber lernen wir später etwas) +- PythonAnywhere so einrichten, dass es deine Web-App über seine Schnittstelle (API) präsentieren kann + +Diese Schritte wurden auf PythonAnywhere automatisiert, aber es sind die selben Schritte, die du bei jedem anderen Server-Provider machen müsstest. + +Das Wichtigste im Moment ist, dass du weißt, dass Deine Datenbank auf PythonAnywhere vollständig unabhängig von deiner Datenbank auf deinem eigenen PC ist, so dass sie unterschiedliche Posts und Administratorenkonten haben kann. Aus diesem Grund müssen wir das Administratorenkonto mittels `createsuperuser` initialisieren - wie wir das auf deinem eigenen Computer getan haben. PythonAnywhere hat deine virtualenv automatisch für dich aktiviert. Du musst nur noch Folgendes ausführen: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + (ola.pythonanywhere.com) $ python manage.py createsuperuser + + +Trage die Informationen für deinen Administrator ein. Am Besten verwendest du die selben Daten wie auf deinem eigenen Computer, um Verwechslungen zu vermeiden - es sei denn, du willst das Passwort auf PythonAnywhere sicherer machen. + +Nun kannst auch einen Blick auf deinen Code auf PythonAnywhere werfen mittels `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 + + +Du kannst auch auf die "Files"-Seite gehen und mit PythonAnywheres eingebautem Datei-Manager navigieren. (Von der "Console"-Seite gelangst du über das Menü in der rechten oberen Ecke zu anderen PythonAnywhere-Seiten. Sobald du auf einer dieser Seiten bist, findest du die Links zu den anderen Seiten oben über dem Seiteninhalt.) + +## Du bist jetzt live! + +Nun ist deine Site also live im öffentlichen Internet! Klick dich zur PythonAnywhere "Web"-Seite durch und hole dir den Link. Teile ihn, mit wem du willst. :) + +> **Hinweis:** Da es sich hier um ein Anfänger-Tutorial handelt, haben wir ein paar Abkürzungen genommen, um die Site zu veröffentlichen, welche sicherheitstechnisch nicht ideal sind. Falls du dich entscheidest, dieses Projekt weiterzubauen oder ein neues Projekt anzufangen, dann solltest du die [Django deployment checklist](https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/) durchgehen, um einige Tipps zur Absicherung deiner Seite zu erhalten. + +## Debugging Tipps + +Solltest du beim Ausführen des `pa_autoconfigure_django.py` Skripts eine Fehlermeldung erhalten, findest du folgend ein paar bekannte Gründe hierfür: + +- Du hast vergessen deinen PythonAnywhere API-Token zu erstellen. +- Du hast in deiner GitHub-URL einen Fehler gemacht. +- Falls du die Fehlermeldung *"Could not find your settings.py"* erhältst, liegt das wahrscheinlich daran, dass du nicht alle Files zum Git hinzugefügt und/oder diese nicht erfolgreich auf GitHub veröffentlicht hast. Schau dir nochmals den Git-Abschnitt weiter oben an. +- Falls du ein bestehendes PythonAnywhere-Benutzerkonto verwendest und eine Fehlermeldung bzgl. collectstatic erhalten hast, hast du dort vermutlich eine alte SQLite-Version (z.B. 3.8.2). Wenn das der Fall ist, erstelle ein neues Benutzerkonto und versuche dort, die Kommandos aus dem obenstehenden PythonAnywhere-Abschnitt erneut auszuführen. + +Falls du eine Fehlermeldung erhältst, wenn du versuchst, deine Site aufzurufen, solltest du als Erstes die Debugging-Informationen im **error log** anschauen. Den Link dazu findest du über [die PythonAnywhere-Seite "Web"](https://www.pythonanywhere.com/web_app_setup/). Schau nach, ob darin Fehlermeldungen enthalten sind; die neuesten findest du ganz unten. + +Du findest einige [Allgemeine Debugging Tipps im PythonAnywhere Wiki](http://help.pythonanywhere.com/pages/DebuggingImportError). + +Und denke daran, dein Coach ist da, um zu helfen! + +# Schau dir deine Website an! + +Auf der Defaultseite deiner Site sollte "It worked!" stehen - genau so wie auf deinem lokalen Computer. Füge nun `/admin/` ans Ende deiner URL an und du kommst auf die Admin-Site. Logge dich mit Benutzername und Passwort ein, und du wirst sehen, dass du auf dem Server neue Posts hinzufügen kannst -- die Posts aus deiner lokalen Test-Datenbank wurden ja nicht auf deinen öffentlichen Blog geschickt. + +Wenn du ein paar Posts erstellt hast, kannst du zurück auf dein lokales Setup (nicht PythonAnywhere) wechseln. Ab jetzt solltest du für Änderungen auf deinem lokalen Setup arbeiten. So wird in der Web-Entwicklung gearbeitet - Änderungen lokal machen und diese dann auf GitHub veröffentlichen und dann deine Änderungen auf den produktiven Webserver ziehen. So kannst du Sachen ausprobieren, ohne deine produktive Website kaputt zu machen. Ziemlich cool, oder? + +Klopf dir *kräftig* auf die Schulter! Server-Deployment ist eines der kompliziertesten Dinge der Web-Entwicklung und es dauert oftmals mehrere Tage, bis alles läuft. Aber du hast deine Site jetzt live, im echten Internet! \ No newline at end of file diff --git a/de/deploy/images/github_get_repo_url_screenshot.png b/de/deploy/images/github_get_repo_url_screenshot.png new file mode 100644 index 00000000000..ee1560b1e85 Binary files /dev/null and b/de/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/de/deploy/images/new_github_repo.png b/de/deploy/images/new_github_repo.png new file mode 100644 index 00000000000..d1f82e5d863 Binary files /dev/null and b/de/deploy/images/new_github_repo.png differ diff --git a/de/deploy/images/pythonanywhere_account.png b/de/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/de/deploy/images/pythonanywhere_account.png differ diff --git a/de/deploy/images/pythonanywhere_bash_console.png b/de/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..68eb2a030e1 Binary files /dev/null and b/de/deploy/images/pythonanywhere_bash_console.png differ diff --git a/de/deploy/images/pythonanywhere_beginner_account_button.png b/de/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/de/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/de/deploy/images/pythonanywhere_create_api_token.png b/de/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..abae45ae37a Binary files /dev/null and b/de/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/de/deploy/install_git.md b/de/deploy/install_git.md new file mode 100644 index 00000000000..31aa6536ebb --- /dev/null +++ b/de/deploy/install_git.md @@ -0,0 +1,52 @@ +Git ist ein "Versionsverwaltungssystem" für Dateien und Code, das von vielen Programmierern benutzt wird. Diese Software kann Änderungen an Dateien über die Zeit verfolgen, so dass du bestimmte Versionen im Nachhinein wieder aufrufen kannst. Sie hat Ähnlichkeit mit der Funktion "Änderungen nachverfolgen" in Textverarbeitungsprogrammen (z. B. Microsoft Word oder LibreOffice Writer), ist jedoch weitaus leistungsfähiger. + +## Git installieren + + + +Du kannst Git von [git-scm.com](https://git-scm.com/) herunterladen. Du kannst bei allen Schritten außer zweien "next" klicken: Wähle im Schritt, in dem du einen Editor aussuchen sollst, "Nano"; und bei der Anweisung "Adjusting your PATH environment", wähle die Einstellung "Run Git and associated Unix tools from the Windows command-line" (die letzte Option). Die anderen Voreinstellungen sind ok. "Checkout"-Stil "Windows" und "Commit" mit "Unix line endings" (Zeilenende im Unix-Format) sind die richtigen Einstellungen. + +Vergiss nicht, die Eingabeaufforderung oder PowerShell nach erfolgreicher Installation neu zu starten. + + + +Lade Git von [git-scm.com](https://git-scm.com/) herunter und folge dann den Anweisungen. + +> **Hinweis:** Falls du OS X 10.6, 10.7, oder 10.8 verwendest, muss du die Git-Version unter folgendem Link installieren: [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) + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo apt install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo dnf install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo zypper install git +``` + + \ No newline at end of file diff --git a/de/deploy/signup_pythonanywhere.md b/de/deploy/signup_pythonanywhere.md new file mode 100644 index 00000000000..b94d9d975a9 --- /dev/null +++ b/de/deploy/signup_pythonanywhere.md @@ -0,0 +1,19 @@ +PythonAnywhere ist ein Dienst, mittels dem Python auf Servern "in der Cloud" ausgeführt werden kann. Wir werden ihn verwenden, um unsere Seite zu hosten, live und im Internet. + +Wir werden den Blog, den wir bauen, auf PythonAnywhere hosten. Registriere dich auf PythonAnywhere für ein "Beginner"-Konto (die kostenfreie Stufe ist ausreichend, du brauchst keine Kreditkarte). + +* [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +![Die PythonAnywhere-Anmelde-Seite mit einem Knopf, um ein kostenloses 'Beginner'-Benutzerkonto anzulegen](../deploy/images/pythonanywhere_beginner_account_button.png) + +> **Hinweis** Beachte bei der Wahl deines PythonAnywhere-Benutzernamens, dass die URL deines Blogs die Form `deinbenutzername.pythonanywhere.com` haben wird. Wähle also einen Namen, unter dem du veröffentlichen willst, oder einen Namen, der den Inhalt deines Blogs beschreibt. Und vergiss dein Passwort nicht (füge es deinem Passwortmanager hinzu, wenn du einen benutzt). + +## Erstellen eines PythonAnywhere API-Tokens + +Das Folgende musst du nur einmal machen. Wenn du dich auf PythonAnywhere angemeldet hast, kommst du aufs "Dashboard". Oben rechts findest du den Link zu deiner "Account"-Seite: + +!["Account"-Link oben rechts auf der Seite](../deploy/images/pythonanywhere_account.png) + +Klicke dort auf den Reiter namens "API token" und dann auf den Knopf, der mit "Create new API token" beschriftet ist. + +![Der API-Token-Reiter auf der "Account"-Seite](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/de/django/README.md b/de/django/README.md new file mode 100644 index 00000000000..5238cee1750 --- /dev/null +++ b/de/django/README.md @@ -0,0 +1,27 @@ +# Django - Was ist das? + +Django (*/ˈdʒæŋɡoʊ/*) ist ein freies, quelloffenes Web-Anwendungs-Framework, geschrieben in Python. Ein Web-(Anwendungs-)Framework ist eine Art Baukastensystem, das dir mit vielen vorgefertigten Teilen die Entwicklung von Web-Anwendungen stark erleichtert. + +Wenn du eine Website entwickelst, brauchst du immer wieder sehr ähnliche Elemente: Einen Weg, Benutzer zu verwalten (Registrierung, Anmeldung, Abmeldung etc.), einen Administrationsbereich, Formulare, Upload von Dateien usw. + +Glücklicherweise wurde schon vor einiger Zeit erkannt, dass Web-Entwickler immer wieder die gleichen Probleme zu lösen haben. Gemeinsam entstanden so verschiedene Frameworks (Django ist so eines), welche die Web-Entwicklung durch vorgefertigte Elemente erleichtern. + +Frameworks sind dazu da, damit du das Rad nicht neu erfinden musst. Du kannst dich auf die konkret zu erfüllenden Anforderungen der Webseite kümmern. Die grundlegende Basis der Webseite stellt dir das Framework zur Verfügung. + +## Warum brauchst du ein Framework? + +Um besser zu verstehen, welche Vorteile dir Django bietet, werfen wir einen Blick auf Server im Allgemeinen. Als Erstes muss der Server wissen, dass er eine Webseite ausliefern soll. + +Der Server hat mehrere "Ports". Ein Port ist vergleichbar mit einem Briefkasten, der auf eingehende Briefe ("Anfragen", "requests") überwacht wird. Das macht der Webserver. Der Webserver liest die eingeworfenen Briefe (requests) und beantwortet sie mit der Webseite (response). Um etwas ausliefern zu können, brauchen wir Inhalte. Und Django hilft dir dabei, diese Inhalte zu erstellen. + +## Was passiert, wenn jemand eine Webseite beim Server anfordert? + +Wenn die Anfrage beim Web-Server ankommt, reicht er diese an Django weiter. Und Django versucht herauszufinden, welche Seite genau angefordert wurde. Django wertet zuerst die Adresse der Webseite aus und versucht herauszufinden, was getan werden soll. Dafür ist der **urlresolver** von Django verantwortlich (Hinweis: URL - Uniform Resource Locator ist ein anderer Name für die Web-Adresse, daher der Name *urlresolver*). Sehr schlau ist er aber nicht. Er hat eine Musterliste und vergleicht diese mit der URL. Der Vergleich der Muster erfolgt von oben nach unten. Wenn ein Muster auf die URL zutrifft, wird der damit verknüpften Funktion (der sogenannten *view*) der Request/die Anfrage übergeben. + +Stell dir eine Postbotin mit einem Brief vor. Sie geht die Straße entlang und prüft jede Hausnummer mit der Adresse auf dem Brief. Wenn beide passen, dann steckt sie den Brief in den Briefkasten. So funktioniert der urlresolver! + +In der *view* Funktion passieren all die interessanten Dinge: wir können in eine Datenbank gucken und dort nach Informationen suchen. Vielleicht wollte die Benutzerin irgendetwas in den Daten ändern? So, als ob der Brief sagen würde: "Bitte ändere meine Stellenbeschreibung!" Die Funktion *view* kann nun prüfen, ob du dazu berechtigt bist, im positiven Fall die Änderungen durchführen und im Anschluss eine Bestätigungs-Nachricht zurücksenden. Die *view* generiert dann eine Antwort und Django kann diese an den Webbrowser der Benutzerin senden. + +Die Beschreibung oben ist ein wenig vereinfacht, aber du musst noch nicht all die technischen Details wissen. Eine generelle Vorstellung zu haben, reicht erstmal. + +Anstatt zu sehr ins Detail zu gehen, fangen wir lieber an, mit Django etwas zu erschaffen, und du wirst dabei alles Wichtige lernen! \ No newline at end of file diff --git a/de/django_admin/README.md b/de/django_admin/README.md new file mode 100644 index 00000000000..6a57b9d2a66 --- /dev/null +++ b/de/django_admin/README.md @@ -0,0 +1,57 @@ +# Django-Administration + +Wir benutzen den Django-Admin, um die soeben modellierten Posts hinzuzufügen, zu ändern oder zu löschen. + +Öffne die Datei `blog/admin.py` im Code-Editor und ersetze den Inhalt wie folgt: + +{% filename %}blog/admin.py{% endfilename %} + +```python +from django.contrib import admin +from .models import Post + +admin.site.register(Post) +``` + +Wie du siehst, importieren wir hier das Model "Post", das wir im vorherigen Kapitel erstellt haben. Damit unser Model auf der Admin-Seite sichtbar wird, müssen wir es mit `admin.site.register(Post)` registrieren. + +Okay, wir sehen uns nun unser Post-Model an. Denk daran, `python manage.py runserver` in die Konsole einzugeben, um den Webserver zu starten. Öffne deinen Browser und gib die Adresse http://127.0.0.1:8000/admin/ ein. Du siehst eine Anmeldeseite: + +![Login Seite](images/login_page2.png) + +Um dich einloggen zu können, musst du zunächst einen *superuser* erstellen - einen User, der alles auf der Website steuern darf. Geh zurück zur Kommandozeile, tippe `python manage.py createsuperuser` und drücke Enter. + +> Denke daran, damit du neue Kommandos eingeben kannst während der Webserver läuft, musst du ein neues Terminal öffnen und deine virtualenv aktivieren. Wie man neue Kommandos eingeben kann, haben wir im Kapitel **Dein erstes Django-Projekt!** unter **Den Webserver starten** behandelt. + +{% filename %}macOS oder Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py createsuperuser + + +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py createsuperuser + + +Wenn du dazu aufgefordert wirst, gib einen Benutzernamen (Kleinbuchstaben, keine Leerzeichen), eine Mailadresse und ein Passwort ein. **Mach dir keine Gedanken, wenn du das Passwort bei der Eingabe nicht sehen kannst - so soll es sein.** Tippe weiter und drücke `Enter`, um weiterzumachen. Du solltest nun Folgendes sehen (wobei Benutzername und Email deine eigenen sein sollten): + + Username: ola + Email address: ola@example.com + Password: + Password (again): + Superuser created successfully. + + +Geh nochmal in deinen Browser und log dich mit den Daten des Superusers ein, den du gerade erstellt hast. Du solltest nun das Django-Admin-Dashboard sehen. + +!["Django Admin"-Weboberfläche](images/django_admin3.png) + +Gehe auf Posts und experimentiere ein bisschen damit. Füge fünf oder sechs Blogeinträge hinzu. Mach dir keine Sorgen wegen des Inhalts -- der ist nur auf deinem lokalen Computer sichtbar. Um Zeit zu sparen kannst du etwas Text aus diesem Tutorial kopieren und einfügen. :-) + +Achte darauf, dass bei wenigstens zwei oder drei Posts (aber nicht bei allen) das Veröffentlichungsdatum (publish date) eingetragen ist. Das werden wir später noch brauchen. + +!["Django Admin"-Weboberfläche](images/edit_post3.png) + +Mehr zum Django-Admin-Dashboard kannst du in der Django-Dokumentation erfahren: https://docs.djangoproject.com/en/2.2/ref/contrib/admin/ + +Jetzt ist wahrscheinlich ein guter Moment, um dir einen Kaffee (oder Tee) zu gönnen und neue Kraft zu tanken. Du hast dein erstes Django-Model erstellt - du hast dir eine kleine Pause verdient! \ No newline at end of file diff --git a/de/django_admin/images/django_admin3.png b/de/django_admin/images/django_admin3.png new file mode 100644 index 00000000000..fb221bd18e1 Binary files /dev/null and b/de/django_admin/images/django_admin3.png differ diff --git a/de/django_admin/images/edit_post3.png b/de/django_admin/images/edit_post3.png new file mode 100644 index 00000000000..57299b6f5af Binary files /dev/null and b/de/django_admin/images/edit_post3.png differ diff --git a/de/django_admin/images/login_page2.png b/de/django_admin/images/login_page2.png new file mode 100644 index 00000000000..c16d1aa4289 Binary files /dev/null and b/de/django_admin/images/login_page2.png differ diff --git a/de/django_forms/README.md b/de/django_forms/README.md new file mode 100644 index 00000000000..eaaea05d302 --- /dev/null +++ b/de/django_forms/README.md @@ -0,0 +1,478 @@ +# Django-Formulare + +Als Letztes möchten wir auf unserer Website noch die Möglichkeit haben, Blogposts hinzuzufügen und zu editieren. Die Django `admin`-Oberfläche ist cool, aber eher schwierig anzupassen und hübsch zu machen. Mit Formularen, `forms`, haben wir die absolute Kontrolle über unser Interface - wir können fast alles machen, was man sich vorstellen kann! + +Das Gute an Django-Forms ist, dass man sie entweder vollständig selbst definieren oder eine `ModelForm` erstellen kann, welche den Inhalt des Formulars in das Model speichert. + +Genau das wollen wir jetzt machen: Wir erstellen ein Formular für unser `Post`-Model. + +So wie die anderen wichtigen Django-Komponenten haben auch die Forms ihre eigene Datei: `forms.py`. + +Wir erstellen nun eine Datei mit diesem Namen im `blog`-Verzeichnis. + + blog + └── forms.py + + +So, jetzt lass uns diese im Code-Editor öffnen und folgenden Code hinzufügen: + +{% filename %}blog/forms.py{% endfilename %} + +```python +from django import forms + +from .models import Post + +class PostForm(forms.ModelForm): + + class Meta: + model = Post + fields = ('title', 'text',) +``` + +Zuerst müssen wir die Django-Forms importieren (`from django import forms`) und auch unser `Post`-Model (`from .models import Post`). + +Wie du wahrscheinlich schon vermutet hast, `PostForm` ist der Name unseres Formulars. Wir müssen Django mitteilen, dass unser Formular ein `ModelForm` ist (so kann Django ein bisschen für uns zaubern) - `forms.ModelForm` ist dafür verantwortlich. + +Als Nächstes sehen wir uns `class Meta` an, damit sagen wir Django, welches Model benutzt werden soll, um das Formular zu erstellen (`model = Post`). + +Nun können wir bestimmen, welche(s) Feld(er) unser Formular besitzen soll. Wir wollen hier nur den `title` und `text` sichtbar machen - der `author` sollte die Person sein, die gerade eingeloggt ist (Du!) und `created_date` sollte automatisch generiert werden, wenn der Post erstellt wird (also im Code). Stimmt's? + +Und das war's schon! Jetzt müssen wir das Formular nur noch in einem *view* benutzen und im Template darstellen. + +Also erstellen wir hier auch wieder einen Link auf die Seite, eine URL, eine View und ein Template. + +## Link auf eine Seite mit dem Formular + +Bevor wir den Link hinzufügen, benötigen wir einige Icons als Buttons für den Link. Lade für dieses Tutorial [file-earmark-plus.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/file-earmark-plus.svg) herunter und speicher es im Ordner `blog/templates/blog/blog/icons/` + +> Hinweis: Um das SVG-Bild herunterzuladen, öffne das Kontextmenü auf dem Link (normalerweise durch einen Rechtsklick darauf) und wähle "Link speichern unter". Im Dialog, in dem du gefragt wirst, wo du die Datei speichern willst, navigiere zum `djangogirls`-Verzeichnis deines Django-Projekts und innerhalb davon in das Unterverzeichnis `blog/templates/blog/icons/` und speicher die Datei dort. + +Es ist an der Zeit, `blog/templates/blog/base.html` im Code-Editor zu öffnen. Jetzt können wir diese Icon-Datei im Basis-Template wie folgt verwenden. Im `div`-Element innerhalb des `header`-Abschnitts werden wir einen Link vor dem `h1`-Element hinzufügen: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + {% include './icons/file-earmark-plus.svg' %} + +``` + +Beachte, dass wir unsere neue View `post_new` nennen wollen. Das [SVG-Icon](https://icons.getbootstrap.com/icons/file-earmark-plus/) wird von [Bootstrap Icons](https://icons.getbootstrap.com/) zur Verfügung gestellt und zeigt ein Seitensymbol mit Pluszeichen an. Wir verwenden eine Django-Template-Direktive namens `include`. Dadurch wird der Inhalt der Datei in das Django-Template eingefügt. Der Web-Browser weiß, wie man diese Art von Inhalt ohne weitere Verarbeitung handhabt. + +> Alle Bootstrap-Icons kannst du [hier herunterladen](https://github.com/twbs/icons/releases/download/v1.11.3/bootstrap-icons-1.11.3.zip). Entpacke die Datei und kopiere alle SVG-Bilddateien in einen neuen Ordner namens `icons` innerhalb von `blog/templates/blog/`. So kannst du auf ein Symbol wie `pencil-fill.svg` mit dem Dateipfad `blog/templates/blog/icons/pencil-fill.svg` zugreifen + +Nach dem Bearbeiten der Zeile sieht deine HTML-Datei so aus: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% load static %} + + + + Django Girls blog + + + + + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ + +``` + +Nach dem Speichern und Neuladen von http://127.0.0.1:8000 solltest du den bereits bekannten `NoReverseMatch`-Fehler sehen. Ist dem so? Gut! + +## URL + +Wir öffnen `blog/urls.py` im Code-Editor und fügen eine Zeile hinzu: + +{% filename %}blog/urls.py{% endfilename %} + +```python +path('post/new/', views.post_new, name='post_new'), +``` + +Der finale Code sieht dann so aus: + +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views +urlpatterns = [ + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), + path('post/new/', views.post_new, name='post_new'), +] +``` + +Nach dem Neuladen der Site sehen wir einen `AttributeError`, weil wir noch keine `post_new`-View eingefügt haben. Fügen wir sie gleich hinzu! + +## Die post_new-View + +Jetzt wird es Zeit, die Datei `blog/views.py` im Code-Editor zu öffnen und die folgenden Zeilen zu den anderen `from` Zeilen hinzuzufügen: + +{% filename %}blog/views.py{% endfilename %} + +```python +from .forms import PostForm +``` + +Und dann unsere *View*: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Um ein neues `PostForm` zu erstellen, rufen wir `PostForm()` auf und übergeben es an das Template. Wir kommen gleich nochmal zu dem *View* zurück, aber jetzt erstellen wir schnell ein Template für das Form. + +## Template + +Wir müssen eine Datei `post_edit.html` im Verzeichnis `blog/templates/blog` erstellen und im Code-Editor öffnen. Damit ein Formular funktioniert, benötigen wir einige Dinge: + +* Wir müssen das Formular anzeigen. Wir können das zum Beispiel mit einem einfachen `{{ form.as_p }}` tun. +* Die Zeile oben muss von einem HTML-Formular-Element eingeschlossen werden `...`. +* Wir benötigen einen `Save`-Button. Wir erstellen diesen mit einem HTML-Button: ``. +* Und schließlich fügen wir nach dem öffnenden `
` Tag `{% raw %}{% csrf_token %}{% endraw %}` hinzu. Das ist sehr wichtig, da es deine Formulare sicher macht! Wenn du diesen Teil vergisst, wird sich Django beim Speichern des Formulars beschweren. + +![CSFR Forbidden page](images/csrf2.png) + +Ok, also schauen wir mal, wie der HTML-Code in `post_edit.html` aussehen sollte: + +{% filename %}blog/templates/blog/post_edit.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} +

New post

+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} +``` + +So, jetzt aktualisieren wir die Seite! Yay! Das Formular wird angezeigt! + +![Neues Formular](images/new_form2.png) + +Aber Moment! Wenn du in das `title`- oder `text`-Feld etwas eintippst und versuchst es zu speichern - was wird wohl passieren? + +Nichts! Wir landen wieder auf der selben Seite und unser Text ist verschwunden... und kein neuer Post wurde hinzugefügt. Was lief denn hier schief? + +Die Antwort ist: nichts. Wir müssen einfach noch etwas mehr Arbeit in unsere *View* stecken. + +## Speichern des Formulars + +Öffne `blog/views.py` erneut im Code-Editor. Derzeit ist alles, was wir in der View `post_new` haben, das hier: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Wenn wir das Formular übermitteln, werden wir zur selben Ansicht weitergeleitet, aber dieses Mal haben wir mehr Daten in `request`, genauer in `request.POST` (der Name hat nichts zu tun mit einem "Blogpost", sondern damit, dass wir Daten "posten"). Erinnerst du dich daran, dass in der HTML-Datei unsere `
` Definition die Variable `method="POST"` hatte? Alle Felder aus dem Formular sind jetzt in `request.POST`. Du solltest `POST` nicht umbenennen (der einzige andere gültige Wert für `method` ist `GET`, wir wollen hier jetzt aber nicht auf den Unterschied eingehen). + +Somit müssen wir uns in unserer *View* mit zwei verschiedenen Situationen befassen: erstens, wenn wir das erste Mal auf die Seite zugreifen und ein leeres Formular wollen und zweitens, wenn wir zur *View* mit allen soeben ausgefüllten Formular-Daten zurück wollen. Wir müssen also eine Bedingung hinzufügen (dafür verwenden wir `if`): + +{% filename %}blog/views.py{% endfilename %} + +```python +if request.method == "POST": + [...] +else: + form = PostForm() +``` + +Es wird Zeit, die Lücken zu füllen `[...]`. Falls die `Methode` `POST` ist, wollen wir das `PostForm` mit Daten vom Formular erstellen. Oder? Das machen wir folgendermaßen: + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(request.POST) +``` + +Als Nächstes müssen wir testen, ob das Formular korrekt ist (alle benötigten Felder sind ausgefüllt und keine ungültigen Werte werden gespeichert). Wir tun das mit `form.is_valid()`. + +Wir überprüfen also, ob das Formular gültig ist und wenn ja, können wir es speichern! + +{% filename %}blog/views.py{% endfilename %} + +```python +if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() +``` + +Im Grunde passieren hier zwei Dinge: Wir speichern das Formular mit `form.save` und wir fügen einen Autor hinzu (da es bislang kein `author` Feld in der `PostForm` gab und dieses Feld notwendig ist). `commit=False` bedeutet, dass wir das `Post` Model noch nicht speichern wollen - wir wollen erst noch den Autor hinzufügen. Meistens wirst du `form.save()` ohne `commit=False` benutzen, aber in diesem Fall müssen wir es so tun. `post.save()` wird die Änderungen sichern (den Autor hinzufügen) und ein neuer Blogpost wurde erstellt! + +Wäre es nicht grossartig, wenn wir direkt zu der `post_detail` Seite des neu erzeugten Blogposts gehen könnten? Um dies zu tun, benötigen wir noch einen zusätzlichen Import: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import redirect +``` + +Füge dies direkt am Anfang der Datei hinzu. Jetzt können wir endlich sagen: "Gehe zu der `post_detail` Seite unseres neu erstellten Posts": + +{% filename %}blog/views.py{% endfilename %} + +```python +return redirect('post_detail', pk=post.pk) +``` + +`post_detail` ist der Name der View, zu der wir springen wollen. Erinnerst du dich daran, dass diese *view* einen `pk` benötigt? Um diesen an die View weiterzugeben, benutzen wir `pk=post.pk`, wobei `post` unser neu erstellter Blogpost ist! + +Ok, wir haben jetzt eine ganze Menge geredet, aber du willst bestimmt sehen, wie die gesamte *View* aussieht, richtig? + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + if request.method == "POST": + form = PostForm(request.POST) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Schauen wir mal, ob es funktioniert. Gehe zur Seite http://127.0.0.1:8000/post/new/, füge einen `title` und `text` hinzu und speichere es...voilà! Der neue Blogpost wird hinzugefügt und wir werden auf die `post_detail` Seite umgeleitet! + +Du hast vielleicht bemerkt, dass wir das Veröffentlichungsdatum festlegen, bevor wir den Post veröffentlichen. Später werden wir einen *publish button* in **Django Girls Tutorial: Extensions** einführen. + +Das ist genial! + +> Da wir vor Kurzem das Django-Admin-Interface benutzt haben, denkt das System, dass wir noch angemeldet sind. Es gibt einige Situationen, welche dazu führen können, dass wir ausgeloggt werden (Schließen des Browsers, Neustarten der Datenbank etc). Wenn du feststellst, dass du bei dem Erstellen von Posts Fehlermeldungen bekommst, die auf nicht angemeldete Nutzer zurückzuführen sind, dann gehe zur Admin Seite http://127.0.0.1:8000/admin und logge dich erneut ein. Dies wird das Problem vorübergehend lösen. Es gibt eine permanente Lösung dafür, die im Kapitel **Homework: add security to your website!** nach dem Haupttutorial auf dich wartet. + +![Anmeldefehler](images/post_create_error.png) + +## Formularvalidierung + +Jetzt zeigen wir dir, wie cool Django-Formulare sind. Ein Blogpost muss `title`- und `text`-Felder besitzen. In unserem `Post`-Model haben wir (im Gegensatz zu dem `published_date`) nicht festgelegt, dass diese Felder nicht benötigt werden, also nimmt Django standardmäßig an, dass sie definiert werden. + +Versuch, das Formular ohne `title` und `text` zu speichern. Rate, was passieren wird! + +![Formularvalidierung](images/form_validation2.png) + +Django kümmert sich darum sicherzustellen, dass alle Felder in unserem Formular richtig sind. Ist das nicht großartig? + +## "Bearbeiten"-Formular + +Jetzt wissen wir, wie ein neuer Blogpost hinzugefügt wird. Aber was ist, wenn wir einen bereits bestehenden bearbeiten wollen? Das funktioniert so ähnlich wie das, was wir gerade getan haben. Lass uns schnell ein paar wichtige Dinge erstellen. (Falls du etwas nicht verstehst, solltest du deinen Coach fragen oder in den vorherigen Kapiteln nachschlagen, da wir all die Schritte bereits behandelt haben.) + +Lass uns zunächst das Symbol speichern, das den Bearbeiten-Button darstellt. Lade [pencil-fill.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/pencil-fill.svg) herunter und speichere es in `blog/templates/blog/icons/`. + +Öffne `blog/templates/blog/post_detail.html` im Code-Editor und füge folgenden Code innerhalb des Elements `article` hinzu: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + +``` + +damit die Vorlage so aussieht: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} + +{% endblock %} +``` + +Öffne `blog/urls.py` im Code-Editor und fügen diese Zeile hinzu: + +{% filename %}blog/urls.py{% endfilename %} + +```python + path('post//edit/', views.post_edit, name='post_edit'), +``` + +Wir werden die Vorlage `blog/templates/blog/post_edit.html` wiederverwenden, daher ist das einzig Fehlende eine neue *View*. + +Öffne `blog/views.py` im Code-Editor und füge ganz am Ende der Datei Folgendes hinzu: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_edit(request, pk): + post = get_object_or_404(Post, pk=pk) + if request.method == "POST": + form = PostForm(request.POST, instance=post) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm(instance=post) + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Sieht genauso aus wie unsere `post_new`-View, oder? Aber nicht ganz. Zum einen übergeben wir einen zusätzliche `pk`-Parameter aus `urls`. Und: Wir bekommen das `Post`-Model, welches wir bearbeiten wollen, mit `get_object_or_404(Post, pk=pk)` und wenn wir dann ein Formular erstellen, übergeben wir diesen Post als `instance`, wenn wir das Formular speichern… + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(request.POST, instance=post) +``` + +als auch, wenn wir ein Formular mit post zum Editieren öffnen: + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(instance=post) +``` + +Ok, lass uns mal schauen, ob das funktioniert! Geh auf die `post_detail`-Seite. Dort sollte sich ein Editier-Button in der oberen rechten Ecke befinden: + +![Schaltfläche "Bearbeiten"](images/edit_button2.png) + +Wenn du darauf klickst, siehst du das Formular mit unserem Blogpost: + +!["Bearbeiten"-Formular](images/edit_form2.png) + +Probier doch einmal, den Titel oder den Text zu ändern und die Änderungen zu speichern! + +Herzlichen Glückwunsch! Deine Anwendung nimmt immer mehr Gestalt an! + +Falls du mehr Informationen über Django-Formulare benötigst, solltest du die offizielle Dokumentation lesen: https://docs.djangoproject.com/en/2.2/topics/forms/ + +## Sicherheit + +Neue Posts durch Klick auf einen Link zu erstellen ist großartig! Aber im Moment ist jeder, der deine Seite besucht, in der Lage, einen neuen Blogpost zu veröffentlichen, und das ist etwas, was du garantiert nicht willst. Lass es uns so machen, dass der Button für dich angezeigt wird, aber für niemanden sonst. + +Öffne die Datei `blog/templates/blog/base.html` im Code-Editor, finde darin unseren `header` und das Anchor-Element, welches du zuvor eingefügt hast. Es sollte so aussehen: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + {% include './icons/file-earmark-plus.svg' %} + +``` + +Wir fügen ein weiteres `{% if %}`-Tag ein, was dafür sorgt, dass der Link nur für angemeldete Nutzer angezeigt wird. Im Moment bist das also nur du! Ändere das ``-Element zu Folgendem: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% if user.is_authenticated %} + + {% include './icons/file-earmark-plus.svg' %} + +{% endif %} +``` + +Dieses `{% if %}` sorgt dafür, dass der Link nur zu dem Browser geschickt wird, wenn der anfragende Nutzer auch angemeldet ist. Das verhindert das Erzeugen neuer Posts nicht komplett, ist aber ein sehr guter erster Schritt. In der Erweiterungslektion kümmern wir uns ausgiebiger um Sicherheit. + +Erinnerst du dich an den Editier-Button, den wir gerade zu unserer Seite hinzugefügt haben? Wir wollen dort dieselbe Anpassung machen, damit andere Leute keine existierenden Posts verändern können. + +Öffne `blog/templates/blog/post_detail.html` im Code-Editor und finde folgende Zeile: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + + {% include './icons/pencil-fill.svg' %} + +``` + +Ändere es wie folgt: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% if user.is_authenticated %} + + {% include './icons/pencil-fill.svg' %} + +{% endif %} +``` + +Da du wahrscheinlich angemeldet bist, wirst du beim Refresh der Seite keinen Veränderung feststellen. Lade jedoch die Seite in einem anderen Browser oder einem Inkognito-Fenster ("In Private" im Windows Edge) und du wirst sehen, dass dieser Link nicht auftaucht und das Icon ebenfalls nicht angezeigt wird! + +## Eins noch: Zeit für das Deployment! + +Mal sehen, ob das alles auch auf PythonAnywhere funktioniert. Zeit für ein weiteres Deployment! + +* Commite als Erstes deinen neuen Code und schiebe ihn auf GitHub: + +{% filename %}command-line{% endfilename %} + + $ git status + $ git add . + $ git status + $ git commit -m "Added views to create/edit blog post inside the site." + $ git push + + +* Dann führe Folgendes in der [PythonAnywhere Bash-Konsole](https://www.pythonanywhere.com/consoles/) aus: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Denk daran, `` durch deine tatsächliche PythonAnywhere-Subdomain zu ersetzen - ohne die spitzen Klammern.) + +* Gehe schließlich noch rüber [auf die Seite "Web"](https://www.pythonanywhere.com/web_app_setup/) (benutze den Menü-Knopf in der rechten oberen Ecke der Konsole) und klicke **Reload**. Lade deinen Blog https://subdomain.pythonanywhere.com neu, um die Änderungen zu sehen. + +Und das war's. Glückwunsch! :) \ No newline at end of file diff --git a/de/django_forms/images/csrf2.png b/de/django_forms/images/csrf2.png new file mode 100644 index 00000000000..ee946324f92 Binary files /dev/null and b/de/django_forms/images/csrf2.png differ diff --git a/de/django_forms/images/drafts.png b/de/django_forms/images/drafts.png new file mode 100644 index 00000000000..1d62f8866f4 Binary files /dev/null and b/de/django_forms/images/drafts.png differ diff --git a/de/django_forms/images/edit_button2.png b/de/django_forms/images/edit_button2.png new file mode 100644 index 00000000000..804674f0965 Binary files /dev/null and b/de/django_forms/images/edit_button2.png differ diff --git a/de/django_forms/images/edit_form2.png b/de/django_forms/images/edit_form2.png new file mode 100644 index 00000000000..3d4e525d5d0 Binary files /dev/null and b/de/django_forms/images/edit_form2.png differ diff --git a/de/django_forms/images/form_validation2.png b/de/django_forms/images/form_validation2.png new file mode 100644 index 00000000000..6e333af3077 Binary files /dev/null and b/de/django_forms/images/form_validation2.png differ diff --git a/de/django_forms/images/new_form2.png b/de/django_forms/images/new_form2.png new file mode 100644 index 00000000000..8f2a1088070 Binary files /dev/null and b/de/django_forms/images/new_form2.png differ diff --git a/de/django_forms/images/post_create_error.png b/de/django_forms/images/post_create_error.png new file mode 100644 index 00000000000..d140e8e2419 Binary files /dev/null and b/de/django_forms/images/post_create_error.png differ diff --git a/de/django_installation/README.md b/de/django_installation/README.md new file mode 100644 index 00000000000..e2fe6b6e527 --- /dev/null +++ b/de/django_installation/README.md @@ -0,0 +1,7 @@ +# Django-Installation + +> **Hinweis** Wenn du ein Chromebook verwendest, überspringe bitte dieses Kapitel und folge den Anweisungen im [Chromebook Setup](../chromebook_setup/README.md). +> +> **Hinweis:** Falls du dich bereits durch die [Installationsschritte](../installation/README.md) gearbeitet hast, gibt es keinen Grund dies erneut zu tun – du kannst direkt zum nächsten Kapitel springen! + +{% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/de/django_installation/instructions.md b/de/django_installation/instructions.md new file mode 100644 index 00000000000..3a84565b975 --- /dev/null +++ b/de/django_installation/instructions.md @@ -0,0 +1,229 @@ +> Ein Teil dieses Kapitels basiert auf den Tutorials von Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> +> Teile dieses Kapitels basieren auf dem [django-marcador Tutorial](http://django-marcador.keimlink.de/) lizenziert unter der Creative Commons Attribution-ShareAlike 4.0 International License. Für das "django-marcador Tutorial" liegt das Urheberrecht bei Markus Zapke-Gründemann et al. + +## Virtuelle Umgebung + +Bevor wir mit der Installation von Django beginnen, lernen wir ein sehr hilfreiches Tool kennen, das uns hilft, unsere Arbeitsumgebung zum Coden sauber zu halten. Es ist möglich, diesen Schritt zu überspringen, aber wir legen ihn dir dennoch besonders ans Herz. Mit dem bestmöglichen Setup zu starten, wird dir in der Zukunft eine Menge Frust ersparen! + +Wir erzeugen eine virtuelle Arbeitsumgebung - ein **virtual environment** oder auch *virtualenv*. Das isoliert die Python-/Django-Setups verschiedener Projekte voneinander. Das bedeutet, dass deine Änderungen an einem Website-Projekt keine anderen Projekte beeinträchtigen, an welchen du sonst noch entwickelst. Klingt nützlich, oder? + +Du musst nur das Verzeichnis festlegen, in dem du das `virtualenv` erstellen willst; zum Beispiel dein Home-Verzeichnis. Auf Windows ist dies `C:\Users\Name` (`Name` ist dein Anmeldename/Login). + +> **HINWEIS:** Stelle auf Windows sicher, dass dieser Verzeichnisname keine Umlaute oder Sonderzeichen enthält. Falls dein Benutzername Umlaute enthält, verwende ein anderes Verzeichnis, zum Beispiel `C:\djangogirls`. + +In diesem Tutorial erstellen wir darin ein neues Verzeichnis `djangogirls`: + +{% filename %}command-line{% endfilename %} + + $ mkdir djangogirls + $ cd djangogirls + + +Wir erstellen eine virtuelle Umgebung namens `myvenv`. Das Kommando dazu lautet dann: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + + + +Um ein neues `virtualenv` zu erzeugen, musst du auf der Kommandozeile von Windows `python -m venv myvenv` ausführen. Das wird so aussehen: + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls> python -m venv myvenv + + +wobei `myvenv` der Name deines `virtualenv` ist. Du kannst auch irgend einen anderen Namen wählen, aber bleibe bei Kleinbuchstaben und verwende keine Leerzeichen, Umlaute oder Sonderzeichen. Eine Gute Idee ist, den Namen kurz zu halten. Du wirst ihn oft benutzen bzw. eingeben müssen! + + + + + +Auf Linux oder macOS kann ein `virtualenv` durch das Ausführen von `python3 -m venv myvenv` erzeugt werden. Das wird so aussehen: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + +`myvenv` ist der Name deiner neuen virtuellen Arbeitsumgebung, deines neuen `virtualenv`. Du kannst auch irgend einen anderen Namen wählen, aber bleibe bei Kleinbuchstaben und verwende keine Leerzeichen. Eine Gute Idee ist, den Namen kurz zu halten. Du wirst ihn oft benutzen bzw. eingeben müssen! + +> **Hinweis:** Bei manchen Versionen von Debian/Unbuntu kann folgender Fehler auftreten: +> +> {% 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. +> +> +> Falls das auftritt, folge den Anweisungen in der Fehlermeldung und installiere das `python3-venv`-Paket: {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python3-venv +> +> +> **HINWEIS:** In manchen Debian/Ubuntu-Versionen kann das zu folgendem Fehler führen: +> +> {% filename %}command-line{% endfilename %} +> +> Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 +> +> +> Falls das eintritt, verwende stattdessen den `virtualenv`-Befehl. +> +> {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python-virtualenv +> $ virtualenv --python=python{{ book.py_version }} myvenv +> +> +> **HINWEIS:** Wenn du einen Fehler wie +> +> {% filename %}command-line{% endfilename %} +> +> E: Unable to locate package python3-venv +> +> +> erhältst, führe stattdessen Folgendes aus: +> +> {% filename %}command-line{% endfilename %} +> +> sudo apt install python{{ book.py_version }}-venv +> + + + +## Mit der virtuellen Umgebung arbeiten + +Die obigen Kommandos erstellen ein Verzeichnis `myvenv` (bzw. den von Dir vergebenen Namen). Es enthält unsere virtuelle Arbeitsumgebung (im Wesentlichen ein paar Verzeichnisse und Dateien). + + + +Starte deine virtuelle Umgebung, indem du Folgendes eingibst: + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls> myvenv\Scripts\activate + + +> **HINWEIS:** Auf Windows 10 kannst du in der Windows PowerShell die Fehlermeldung `execution of scripts is disabled on this system` erhalten. Öffne in diesem Fall eine weitere Windows PowerShell über "Als Administrator ausführen". Versuche dann, das folgende Kommando einzugeben, bevor du das virtualenv noch einmal aktivierst: +> +> {% 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 +> + + + +> **Hinweis:** Für Benutzerinnen des populären Editors VS Code, der einen PowerShell-basiertes Terminal eingebaut hat: Wenn du beim eingebauten Terminal bleiben willst, kannst du deine virtuelle Umgebung mit folgendem Befehl aktivieren: +> +> $ . myvenv\Scripts\activate.ps1 +> +> +> Der Vorteil davon ist, dass du nicht zwischen den Editor-Fenstern und den Kommandozeilen-Fenstern wechseln musst + + + + + +Starte deine virtuelle Umgebung, indem du eingibst: + +{% filename %}command-line{% endfilename %} + + $ source myvenv/bin/activate + + +Der Name `myvenv` muss mit dem von Dir gewählten Namen des `virtualenv` übereinstimmen! + +> **Anmerkung:** Manchmal ist das Kommando `source` nicht verfügbar. In diesen Fällen geht es auch so: +> +> {% filename %}command-line{% endfilename %} +> +> $ . myvenv/bin/activate +> + + + +Du erkennst, dass dein `virtualenv` gestartet ist, wenn du vor der Eingabeaufforderung eine Klammer mit dem Namen deiner Umgebung siehst, `(myvenv)`. + +In deiner neuen virtuellen Umgebung wird automatisch die richtige Version von `python` verwendet. Du kannst also `python` statt `python3` eingeben. + +Ok, jetzt ist die erforderliche Umgebung startklar und wir können endlich Django installieren! + +## Django-Installation {#django} + +Da du nun dein `virtualenv` gestartet hast, kannst du Django installieren. + +Bevor wir damit loslegen, sollten wir jedoch sicherstellen, dass wir die neueste Version von `pip` haben, eine Software, mit Hilfe derer wir Django installieren werden: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~$ python -m pip install --upgrade pip + + +### Pakete mittels requirements-Datei installieren + +Eine requirements-Datei enthält eine Liste von Abhängigkeiten, die von `pip install` installiert werden sollen: + +Erstelle mit dem zuvor installierten Code-Editor eine Datei namens `requirements.txt` im Verzeichnis `djangogirls/`. Das machst du, indem du eine neue Datei in deinem Code-Editor öffnest und als `requirements.txt` im Ordner `djangogirls/` abspeicherst. Dein Ordner sieht jetzt so aus: + + djangogirls + ├── myvenv + │ └── ... + └───requirements.txt + + +Schreibe in die Datei `djangogirls/requirements.txt` folgenden Text: + +{% filename %}djangogirls/requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +Führe nun `pip install -r requirements.txt` aus, um Django zu installieren. + +{% filename %}command-line{% endfilename %} + + (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.1MB) + Installing collected packages: Django + Successfully installed Django-{{ book.django_version }} + + + + +> Wenn du einen Fehler auf einem Windowsrechner bekommst, überprüfe, ob der Pfadname deines Projekts Leerzeichen, Umlaute oder Sonderzeichen enthält (z.B. `C:\Users\User Name\djangogirls`). Ist das der Fall, dann verwende bitte einen anderen Ordner ohne Sonderzeichen, Umlaute oder Leerzeichen. (Vorschlag: `C:\djangogirls`). Erstelle ein neues virtualenv in einem neuen Verzeichnis, lösche danach das alte und wiederhohle den oben genannten Befehl. (Das Verzeichnis des virtualenv zu verschieben funktioniert dabei nicht, da virtualenv absolute Pfade verwendet.) + + + + + +> Es kann sein, dass deine Befehlszeile einfriert, wenn du versuchst Django zu installieren. Sollte das passieren, nutze folgenden Befehl anstelle des oben angegebenen: +> +> {% filename %}command-line{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> + + + + + +> Falls der pip-Aufruf auf Ubuntu 12.04 zu einer Fehlermeldung führt, rufe `python -m pip install -U --force-reinstall pip` auf, um die Installation von pip im virtualenv zu reparieren. + + + +Das war's! Du bist nun (endlich) bereit, deine erste Django-Anwendung zu starten! \ No newline at end of file diff --git a/de/django_models/README.md b/de/django_models/README.md new file mode 100644 index 00000000000..a0f1172dd14 --- /dev/null +++ b/de/django_models/README.md @@ -0,0 +1,201 @@ +# Django-Models + +Wir erstellen jetzt etwas, damit wir alle Posts von unserem Blog speichern können. Aber um das zu tun, müssen wir zunächst über `Objekte` sprechen. + +## Objekte + +Eine Herangehensweise an das Programmieren ist das so genannte `objektorientierte Programmieren`. Die Idee dahinter ist, dass wir Dinge und ihre Interaktionen untereinander modellieren können und nicht alles als langweilige Kette von Programmbefehlen hintereinander aufschreiben müssen. + +Was ist denn nun ein Objekt? Ein Objekt ist eine Sammlung von Eigenschaften und Aktionsmöglichkeiten, das anhand einer Vorlage (Klasse) erstellt wird. Das klingt erst einmal komisch, aber hier haben wir gleich ein Beispiel. + +Wenn wir zum Beispiel eine Katze modellieren wollen, erschaffen wir eine Objektvorlage `Katze`, eine Art Blaupause oder Schema, nach welcher zukünftig jedes spezifische Katzenobjekt erstellt werden kann. Die Vorlage beschreibt typische Eigenschaften von Katzen, z.B. `farbe`, `alter`, `stimmung` (also gut, schlecht oder müde ;)), `besitzerin` (die ein `Person`-Objekt ist oder – im Falle einer Streunerkatze – leer bleibt). + +Jedes Objekt einer `Katze` soll natürlich auch einige Aktionsmöglichkeiten besitzen: `schnurren`, `kratzen` oder `füttern` (hier bekäme die Katze ein bisschen `Katzenfutter`, welches wieder durch ein eigenes Objekt mit Eigenschaften wie `Geschmack` repräsentiert sein könnte). + + Katze + -------- + farbe + alter + stimmung + besitzerin + schnurren() + kratzen() + fuettern(katzen_futter) + + + Katzenfutter + -------- + geschmack + + +Der Gedanke dahinter ist also, echte Dinge mit Hilfe von Eigenschaften (genannt `Objekteigenschaften`) und Aktionsmöglichkeiten (genannt `Methoden`) im Programmcode zu beschreiben. + +Wie also modellieren wir Blogposts? Schließlich wollen wir ja einen Blog bauen, nicht wahr? + +Wir müssen folgende Fragen beantworten: Was ist ein Blogpost? Welche Eigenschaften sollte er haben? + +Nun, zum einen braucht unser Blogpost Text mit einem Inhalt und einen Titel, oder? Außerdem wäre es schön zu wissen, wer ihn geschrieben hat – wir brauchen also noch einen Autor. Schließlich wollen wir wissen, wann der Post geschrieben und veröffentlicht wurde. + + Post + -------- + title + text + author + created_date + published_date + + +Was für Dinge könnte man mit einem Blogpost machen? Es wäre schön, wenn wir eine `Methode` hätten, die den Post veröffentlicht, nicht wahr? + +Wir brauchen also eine `veröffentlichen`-Methode. + +Da wir jetzt wissen, was wir erreichen wollen, können wir nun damit anfangen, es in Django zu formulieren! + +## Ein Django-Model erstellen + +Da wir jetzt in etwa wissen, was ein Objekt ist, wollen wir ein Django-Model, eine Vorlage, für unsere Blogposts anlegen, nach welcher wir zukünftig unsere Blogpostobjekte erstellen können. + +Ein "Modell" ist in Django ein Objekt einer speziellen Sorte – eines das in der `Datenbank` gespeichert wird. Eine Datenbank ist eine Sammlung von Daten. Dies ist ein Ort, an dem du Informationen zu Benutzern, deinen Blogposts usw. speichern wirst. Wir benutzen dafür eine SQLite-Datenbank. Das ist die Voreinstellung in Django – für uns wird das erst einmal ausreichen. + +Du kannst dir ein Model wie eine Tabelle mit Spalten ("Feldern", englisch "fields") und Zeilen (Datensätzen) vorstellen. + +### Eine Applikation für unseren Blog + +Um unsere Webseite aufgeräumt zu halten, werden wir eine eigene Anwendung für unser Projekt erstellen, wir nennen das eine Applikation. Wir wollen uns gleich daran gewöhnen, alles ordentlich und sortiert zu halten. Um eine Applikation zu erstellen, müssen wir das folgende Kommando in der Konsole ausführen (wieder in dem `djangogirls`-Verzeichnis, in dem die `manage.py`-Datei liegt): + +{% filename %}macOS und Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py startapp blog + + +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + + +Wie du sehen kannst, wurde ein neues `blog`-Verzeichnis erstellt, welches schon einige Dateien enthält. Das Verzeichnis und die Dateien unseres Projektes sollten jetzt so aussehen: + + djangogirls + ├── blog + │   ├── admin.py + │   ├── apps.py + │   ├── __init__.py + │   ├── migrations + │   │   └── __init__.py + │   ├── models.py + │   ├── tests.py + │   └── views.py + ├── db.sqlite3 + ├── manage.py + ├── mysite + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + + + +Nach dem Erstellen der Applikation müssen wir Django noch sagen, dass diese auch genutzt werden soll. Das tun wir in der Datei `mysite/settings.py` -- öffne diese in deinem Code-Editor. Wir suchen den Eintrag `INSTALLED_APPS` und fügen darin die Zeile `'blog.apps.BlogConfig',` direkt über der schließenden Klammer `]` ein. Danach sollte es also so aussehen: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog.apps.BlogConfig', +] +``` + +### Das Blogpost-Model + +Alle `Models` unserer Applikation werden in der `blog/models.py`-Datei definiert. Dies ist also der richtige Platz für unser Blogpost-Model. + +Öffnen wir also `blog/models.py` im Code-Editor, löschen alles darin und schreiben Code wie diesen: + +{% filename %}blog/models.py{% endfilename %} + +```python +from django.conf import settings +from django.db import models +from django.utils import timezone + + +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) + + def publish(self): + self.published_date = timezone.now() + self.save() + + def __str__(self): + return self.title +``` + +> Kontrolliere nochmal, dass du zwei Unterstriche (`__`) vor und hinter dem `str` gesetzt hast. Diese Konvention wird häufig in Python benutzt und manchmal nennen wir es "dunder" (kurz für "double-underscore"). + +Es sieht kompliziert aus, oder? Aber keine Sorge, wir werden erklären, was diese Zeilen bedeuten! + +Die Zeilen, die mit `from` oder `import` beginnen, sind Anweisungen, um Sachen aus anderen Dateien mitzunutzen. Anstatt häufig genutzten Code in jede Datei einzeln zu kopieren, binden wir ihn ein mit: `from... import ...`. + +`class Post(models.Model):` – Diese Zeile definiert unser Model (eine Objekt-Vorlage). + +- `class` ist ein spezielles Schlüsselwort, das angibt, dass wir hier eine Klasse, eine Vorlage für zukünftige Objekte, definieren wollen. +- `Post` ist der Name unseres Models. Wir können ihm auch einen anderen Namen geben (aber wir müssen Sonderzeichen und Leerzeichen vermeiden). Beginne einen Klassennamen immer mit einem Großbuchstaben. +- `models.Model` gibt an, dass das Post-Model ein Django-Model ist, so weiß Django, dass es in der Datenbank gespeichert werden soll. + +Jetzt definieren wir die Eigenschaften, über welche wir gesprochen haben: `title`, `text`, `created_date`, `published_date` und `author`. Um dies zu tun, müssen wir den Typ jedes Felds definieren. (Ist es Text? Eine Zahl? Ein Datum? Eine Beziehung zu einem anderen Objekt, z.B. einem Benutzer?) + +- `models.CharField` – so definierst du ein Textfeld mit einer limitierten Anzahl von Zeichen. +- `models.TextField` – so definierst du ein langes Textfeld ohne Grössenbeschränkung. Klingt doch perfekt für unsere Blogpostinhalte, oder? +- `models.DateTimeField` – ein Feld für einen Zeitpunkt (ein Datum und eine Uhrzeit). +- `models.ForeignKey` – definiert eine Verknüpfung/Beziehung zu einem anderen Model. + +Wir werden nicht den gesamten Code hier erklären, da das zu lange dauern würde. Du solltest einen Blick in die offizielle Django-Dokumentation werfen, wenn du mehr über Modelfelder und darüber wissen möchtest, wie man auch andere Dinge als die oben beschriebenen definiert (https://docs.djangoproject.com/en/2.2/ref/models/fields/#field-types). + +Was ist mit `def publish(self):`? Das ist genau die `publish`-Methode zum Veröffentlichen unserer Blogposts, über die wir vorher bereits sprachen. `def` zeigt an, dass es sich nachfolgend um eine Funktion/Methode handelt, und `publish` ist der Name der Methode. Du kannst den Namen der Methode auch ändern, wenn du möchtest. Die Benennungsregel ist, dass wir Kleinbuchstaben verwenden, und anstatt Leerzeichen (die in Funktionsnamen nicht vorkommend dürfen) Unterstriche. Eine Methode, die einen Durchschnittspreis berechnet, könnte zum Beispiel `calculate_average_price` genannt werden. + +Oft geben Methoden einen Wert zurück (englisch: `return`). Ein Beispiel dafür ist die Methode `__str__`. In diesem Szenario, wenn wir `__str__()` aufrufen, bekommen wir einen Text (**string**) mit einem Blogpost-Titel zurück. + +Beachte, dass sowohl `def publish(self):` als auch `def __str__(self):` in unserer Klasse eingerückt sind. Mit der Einrückung sagen wir Python, dass diese Methoden Teil der Klasse sind. Ohne die Einrückung wären es für Python Funktionen ausserhalb der Klasse, was zu anderem Verhalten führen würde. + +Wenn dir über Methoden noch etwas nicht klar ist, dann zögere nicht, deinen Coach zu fragen! Wir wissen, dass es kompliziert ist, vor allem, wenn du gleichzeitig lernst, was Objekte und Funktionen sind. Aber hoffentlich sieht es für dich jetzt etwas weniger nach Magie aus! + +### Tabellen für Models in deiner Datenbank erstellen + +Als letzten Schritt wollen wir unser neues Model der Datenbank hinzufügen. Dazu müssen wir Django erst 'mal mitteilen, dass wir einige Änderungen an unserem Model vorgenommen haben. (Wir haben es eben erst erstellt!) Scheibe `python manage.py makemigrations blog` in dein Kommandozeilen-Fenster. Das sieht dann so aus: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py makemigrations blog + Migrations for 'blog': + blog/migrations/0001_initial.py: + + - Create model Post + + +**Hinweis:** Denke daran, die Dateien nach dem Editieren zu speichern. Ansonsten führt dein Computer die vorherige Version aus, was zu unerwarteten Fehlermeldungen führen kann. + +Django hat eine Migrationsdatei für uns vorbereitet, die wir nun auf unsere Datenbank anwenden müssen. Schreibe `python manage.py migrate blog`. Die Ausgabe sollte so aussehen: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py migrate blog + Operations to perform: + Apply all migrations: blog + Running migrations: + Applying blog.0001_initial... OK + + +Hurra! Unser Post-Model ist ab sofort in unserer Datenbank gespeichert! Es wäre doch schön, zu wissen, wie es aussieht, oder? Springe zum nächsten Kapitel, um es dir anzusehen! \ No newline at end of file diff --git a/de/django_orm/README.md b/de/django_orm/README.md new file mode 100644 index 00000000000..6621b90a1d9 --- /dev/null +++ b/de/django_orm/README.md @@ -0,0 +1,219 @@ +# Django-ORM und QuerySets + +In diesem Kapitel lernst du, wie sich Django mit der Datenbank verbindet und Daten darin speichert. Lass uns loslegen! + +## Was ist ein QuerySet? + +Zusammengefasst ist ein QuerySet eine Liste von Objekten eines bestimmten Models. QuerySets erlauben es dir, Daten aus der Datenbank zu lesen, zu filtern und zu sortieren. + +Am besten wir sehen uns das an einem Beispiel an. Versuchen wir's? + +## Django-Shell + +Öffne deine lokale Konsole (nicht in PythonAnywhere) und tippe dieses Kommando ein: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py shell + + +Das sollte angezeigt werden: + +{% filename %}command-line{% endfilename %} + +```python +(InteractiveConsole) >>> +``` + +Nun bist du in der interaktiven Konsole von Django. Die funktioniert wie der Python-Prompt, aber hat noch etwas zusätzliche Django-Magie. :) Du kannst hier auch alle Python-Befehle verwenden. + +### Alle Objekte + +Zunächst wollen wir alle unsere Blogposts ansehen. Das kannst du mit folgendem Kommando erreichen: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +Traceback (most recent call last): + File "", line 1, in +NameError: name 'Post' is not defined +``` + +Hoppla! Eine Fehlermeldung ist erschienen. Sie sagt uns, dass Python "Post" nicht kennt. Und sie hat recht: Wir haben vergessen zu importieren! + +{% filename %}command-line{% endfilename %} + +```python +>>> from blog.models import Post +``` + +Wir importieren das Model `Post` aus `blog.models`. Versuchen wir nochmal, alle Posts anzuzeigen: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, ]> +``` + +Das ist eine Liste all der Posts, die wir zuvor lokal erstellt haben! Wir haben diese Posts mit der Django-Admin-Oberfläche erstellt. Aber nun wollen wir weitere Posts mit Python erstellen! Wie geht das also? + +### Objekt erstellen + +So erstellst du ein neues Post-Objekt in der Datenbank: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') +``` + +Allerdings fehlt noch eine Zutat: `me`. Wir müssen eine Instanz des Models `User` als Autor übergeben. Wie macht man das? + +Als Erstes müssen wir das User-Model importieren: + +{% filename %}command-line{% endfilename %} + +```python +>>> from django.contrib.auth.models import User +``` + +Welche User sind in unserer Datenbank vorhanden? Finde es damit heraus: + +{% filename %}command-line{% endfilename %} + +```python +>>> User.objects.all() +]> +``` + +Das ist der Superuser, den wir vorhin erstellt haben! Lass uns jetzt eine Instanz des Users erstellen (passe diese Zeile an, so dass dein eigener Benutzername verwendet wird): + +{% filename %}command-line{% endfilename %} + +```python +>>> me = User.objects.get(username='ola') +``` + +Wie du siehst, holen (`get`) wir jetzt ein `User`-Objekt mit einem `username` 'ola'. Prima! + +Jetzt können wir schließlich unseren Post erstellen: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') + +``` + +Super! Wollen wir nachsehen, ob es funktioniert hat? + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, , ]> +``` + +Da ist er, ein weiterer Post in der Liste! + +### Mehrere Posts hinzufügen + +Du kann jetzt nach Belieben weitere Blogposts hinzufügen, um ein Gefühl dafür zu bekommen, wie es funktioniert. Füge doch noch zwei, drei hinzu bevor du zum nächsten Teil übergehst. + +### Objekte filtern + +Eine wichtige Eigenschaft von QuerySets ist, dass die Einträge gefiltert werden können. Zum Beispiel wollen wir alle Posts finden, die der User Ola geschrieben hat. Dafür nehmen wir `filter` statt `all` in `Post.objects.all()`. In Klammern schreiben wir die Bedingung(en), die ein Blogpost erfüllen muss, damit ein er in unser Queryset kommt. So soll jetzt z.B. `author` gleich `me` sein, damit nur die Blogposts des Autors "me" herausgefiltert werden. In Django schreiben wir deshalb: `author=me`. Jetzt sieht unser Code folgendermaßen aus: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(author=me) +, , , ]> +``` + +Oder vielleicht wollen wir alle Posts haben, die das Wort "title" im `title`-Feld haben? + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(title__contains='title') +, ]> +``` + +> **Anmerkung:** Zwischen `title` und `contains` befinden sich zwei Unterstriche (`__`). Das ORM von Django nutzt diese Regel, um Feldnamen ("title") und Operationen oder Filter ("contains") voneinander zu trennen. Wenn du nur einen Unterstrich benutzt, bekommst du einen Fehler wie "FieldError: Cannot resolve keyword title_contains". + +Du kannst auch eine Liste aller bereits publizierten Posts erhalten, indem wir nach allen Posts suchen, deren `published_date` in der Vergangenheit liegt: + +{% filename %}command-line{% endfilename %} + +```python +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) + +``` + +Unglücklicherweise ist der Post, den wir über die Python-Konsole hinzugefügt haben, noch nicht veröffentlicht. Aber das können wir ändern! Als Erstes holen wir eine Instanz des Posts, den wir veröffentlichen wollen: + +{% filename %}command-line{% endfilename %} + +```python +>>> post = Post.objects.get(title="Sample title") +``` + +Dann publizieren wir ihn mit unserer `publish`-Methode: + +{% filename %}command-line{% endfilename %} + +```python +>>> post.publish() +``` + +Jetzt versuch nochmal, eine Liste von veröffentlichten Posts zu bekommen (drücke dreimal "Pfeil nach oben" und `enter`): + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +]> +``` + +### Objekte ordnen + +Mit den QuerySets kannst du eine Liste auch nach bestimmten Kriterien ordnen. Lass uns das mit dem `created_date` Feld ausprobieren: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.order_by('created_date') +, , , ]> +``` + +Wir können die Reihenfolge auch umdrehen, indem wir "`-`" davor schreiben: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.order_by('-created_date') +, , , ]> +``` + +### Komplexe Queries durch Methoden-Verkettung + +Wie du gesehen hast, geben einige Methoden auf `Post.objects` ein QuerySet zurück. Die selben Methoden können wiederum auch auf einem QuerySet aufgerufen werden und geben dann ein neues QuerySet zurück. Das ermöglicht es, ihre Wirkung zu kombinieren, indem du die Methoden **verkettest**: + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> +``` + +Dies ist wirklich mächtig und lässt dich ziemlich komplexe Abfragen schreiben. + +Cool! Jetzt bist du bereit für den nächsten Teil! Um die Konsole zu schließen, schreib das: + +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +``` \ No newline at end of file diff --git a/de/django_start_project/README.md b/de/django_start_project/README.md new file mode 100644 index 00000000000..002885116af --- /dev/null +++ b/de/django_start_project/README.md @@ -0,0 +1,260 @@ +# Dein erstes Django-Projekt! + +> Ein Teil dieses Kapitels basiert auf Tutorials der Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> +> Teile dieses Kapitels basieren auf dem [django-marcador Tutorial](http://django-marcador.keimlink.de/) lizenziert unter Creative Commons Attribution-ShareAlike 4.0 International License. Für das "django-marcador Tutorial" liegt das Urheberrecht bei Markus Zapke-Gründemann et al. + +Wir werden einen kleinen Blog erstellen! + +Der erste Schritt ist, ein neues Django-Projekt zu starten. Im Grunde bedeutet das, dass wir einige Skripte ausführen werden, die Django zur Verfügung stellt, um ein Skelett eines Django-Projekts für uns zu erzeugen. Das Projekt beinhaltet einen Haufen von Verzeichnissen und Dateien, die wir später verwenden werden. + +Die Namen einiger Dateien und Verzeichnisse sind sehr wichtig für Django. Die Dateien, die erstellt werden, solltest du nicht umbenennen. Sie an eine andere Stelle zu verschieben, ist auch keine gute Idee. Django muss zwingend eine gewisse Struktur erhalten, um wichtige Dinge wiederzufinden. + +> Denk daran, alles in der "Virtualenv"-Umgebung auszuführen. Wenn du kein Präfix `(myvenv)` in deiner Konsole siehst, musst du deine Virtualenv-Umgebung aktivieren. Wie das gemacht wird, erklären wir im Kapitel **Django-Installation**, im Abschnitt **Arbeiten mit Virtualenv**. Zur Erinnerung: Gib dazu auf Windows `myvenv\Scripts\activate` ein, bzw. auf macOS oder Linux `source myvenv/bin/activate`. + + + +In deiner macOS- oder Linux-Konsole solltest du den folgenden Befehl ausführen; **vergiss den Punkt (`.`) am Ende nicht!** + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ django-admin startproject mysite . + + +> Der Punkt `.` ist sehr wichtig, weil er dem Skript mitteilt, dass Django in deinem aktuellen Verzeichnis installiert werden soll. (Der Punkt `.` ist eine Schnellreferenz dafür.) +> +> **Hinweis:** Wenn du das oben angegebene Kommando eingibst, denk daran, nur das einzutippen, was mit `django-admin` anfängt. Der `(myvenv) ~/djangogirls$`-Teil hier ist nur ein Beispiel für die Eingabeaufforderung (den "Prompt") auf der Kommandozeile. + + + + + +Auf Windows solltest du den folgenden Befehl ausführen. **(Vergiss den Punkt (`.`) am Ende nicht!)**: + +{% filename %}command-line{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . + + +> Der Punkt `.` ist sehr wichtig, weil er dem Skript mitteilt, dass Django in deinem aktuellen Verzeichnis installiert werden soll. (Der Punkt `.` ist eine Schnellreferenz dafür.) +> +> **Hinweis:** Wenn du das oben angegebene Kommando eingibst, denk daran, nur das einzutippen, was mit `django-admin.exe` anfängt. Der `(myvenv) C:\Users\Name\djangogirls>`-Teil hier ist nur ein Beispiel für die Eingabeaufforderung (den "Prompt") auf der Kommandozeile. + + + +`django-admin.py` ist ein Skript, welches Verzeichnisse und Dateien für dich erstellt. Du solltest jetzt eine Verzeichnisstruktur haben, die folgendermaßen aussieht: + + djangogirls + ├── manage.py + ├── mysite + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + + +> **Hinweis:** In deiner Verzeichnisstruktur wirst du auch den `myvenv`-Ordner sehen, den wir vorhin erzeugt haben. + +`manage.py` ist ein Script, das das Management deines Projektes unterstützt. Mit dem Script bist du unter anderem in der Lage, den Webserver auf deinem Rechner zu starten, ohne etwas Weiteres installieren zu müssen. + +Die Datei `settings.py` beinhaltet die Konfiguration deiner Website. + +Erinnerst du dich, als wir über den Postboten gesprochen haben, der überlegt, wohin er den Brief liefern soll? Die `urls.py` Datei beinhaltet eine Liste von Patterns (Mustern), die vom `urlresolver` benutzt werden. + +Lass uns kurz die anderen Dateien vergessen - wir werden sie nicht verändern. Denk aber dran, sie nicht versehentlich zu löschen! + +## Einstellungen anpassen + +Wir machen nun ein paar Änderungen in `mysite/settings.py`. Öffne die Datei mit dem Code-Editor, den du schon installiert hast. + +**Hinweis**: `settings.py` ist eine Datei wie jede andere. Du kannst sie aus deinem Code-Editor heraus öffnen, in dem du im "Datei"-Menü die "Öffnen"-Aktion wählst. So solltest du das normale Fenster zur Dateiauswahl bekommen, in dem du zur `settings.py`-Datei navigieren und sie auswählen kannst. Stattdessen kannst du die Datei aber auch öffnen, in dem du im Dateimanager zum "djangogirls"-Ordner navigierst und auf die Datei rechtsklickst. Wähle dann deinen Code-Editor aus der Liste der "Öffnen mit"-Programme. Das ist wichtig, da du andere Programme installiert haben könntest, die diese Datei zwar öffnen können, aber die dich die Datei nicht editieren lassen würden. + +Es wäre schön, wenn die richtige Zeit auf deiner Webseite eingestellt ist. Gehe zur [Zeitzonen-Liste auf Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) und kopiere die für dich geltende Zeitzone (Spalte "TZ"), z.B. `Europe/Berlin`. + +Suche in `settings.py` die Zeile, die `TIME_ZONE` enthält und ändere sie ab, um deine eigene Zeitzone auszuwählen. Zum Beispiel: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +TIME_ZONE = 'Europe/Berlin' +``` + +Ein Sprachkennung besteht aus einem Kürzel für die Sprache, z.B. `en` für Englisch oder `de` für Deutsch, und einem Länder-Kürzel z.B. `de` für Deutschland oder `ch` für die Schweiz. Falls Englisch nicht deine Muttersprache ist, kannst du damit die Standard-Knöpfe und -Meldungen von Django auf deine Sprache wechseln. Der "Cancel"-Knopf würde dann in diese Sprache übersetzt (und z.B. bei Deutsch mit "Abbrechen" beschriftet). [Django enthält viele fix-fertige Übsersetzungen](https://docs.djangoproject.com/en/2.2/ref/settings/#language-code). + +Wenn du eine andere Sprache als Englisch willst, ändere die Sprachkennung, indem du die folgende Zeile änderst: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +LANGUAGE_CODE = 'de-ch' +``` + +Ausserdem müssen wir einen Pfad für statische Dateien festlegen. (Über statische Dateien und CSS lernst du später in diesem Tutorial etwas.) Geh hinunter zum *Ende* der Datei und füge direkt unter dem `STATIC_URL`-Eintrag einen neuen Eintrag namens `STATIC_ROOT` ein: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +STATIC_URL = '/static/' +STATIC_ROOT = BASE_DIR / 'static' +``` + +Wenn `DEBUG` auf `True` gesetzt ist und `ALLOWED_HOSTS` leer, dann wird der "Host" gegen `['localhost', '127.0.0.1', '[::1]']` validiert. Unser Hostname auf PythonAnywhere, wo wir unsere Anwendung deployen werden, würde da nicht passen. Deswegen ändern wir folgende Einstellung: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +ALLOWED_HOSTS = ['127.0.0.1', '.pythonanywhere.com'] +``` + +> **Hinweis**: Wenn du ein Chromebook verwendest, füge noch diese Zeile am Ende deiner settings.py-Datei hinzu: `MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'` +> +> Falls du Cloud9 benutzt, füge auch `.amazonaws.com` zu den `ALLOWED_HOSTS` hinzu +> +> Wenn du dein Projekt auf `Glitch.com` hostest, dann lass uns den Django-Sekret-Key schützen, der vertraulich bleiben muss (andernfalls könnte jeder, der dein Projekt remixt, diesen sehen): +> +> - Zuerst erstellen wir einen zufälligen geheimen Schlüssel. Öffne erneut das Glitch-Terminal und gib den folgenden Befehl ein: +> +> {% filename %}Kommandozeile{% endfilename %} +> +> ```bash +> python -c 'from django.core.management.utils import get_random_secret_key; \ +> print(get_random_secret_key())' +> ``` +> +> Das sollte einen langen zufälligen String ausgeben, der perfekt für die Verwendung als geheimer Schlüssel für deine brandneue Django-Website geeignet ist. Wir werden diesen Schlüssel jetzt in eine Datei namens `.env` einfügen, die Glitch nur dir als Besitzerin der Website anzeigen wird. +> +> - Erstelle eine Datei namens `.env` im Wurzelverzeichnis deines Projekts und füge folgenden Inhalt ein: +> +> {% filename %}.env{% endfilename %} +> +> ```bash +> # Hier, innerhalb der einfachen Anführungszeichen, kannst den oben erzeugten zufälligen Schlüssel einfügen +> SECRET='3!0k#7ds5mp^-x$lqs2%le6v97h#@xopab&oj5y7d=hxe511jl' +> ``` +> +> - Aktualisiere dann die Django-Einstellungen-Datei, um diesen geheimen Wert einzufügen zu lassen und lege den Django-Webseitennamen fest: +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> SECRET_KEY = os.getenv('SECRET') +> ``` +> +> - Und etwas weiter unten in derselben Datei geben wir den Namen deiner neuen Glitch-Website ein: +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> ALLOWED_HOSTS = [os.getenv('PROJECT_DOMAIN') + ".glitch.me"] +> ``` +> +> Der Wert `PROJECT_DOMAIN` wird automatisch von Glitch generiert. Er wird dem Namen deines Projekts entsprechen. + +## Eine Datenbank erstellen + +Es gibt viele verschiedene Datenbank Programme, welche die Daten unserer Website verwalten können. Wir werden die Standard-Datenbanksoftware nehmen, `sqlite3`. + +Das sollte schon in der `mysite/settings.py`-Datei eingestellt sein: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} +``` + +Um eine Datenbank für unseren Blog zu erstellen, müssen wir folgenden Befehl in der Konsole ausführen (Dazu müssen wir in dem `djangogirls`-Verzeichnis sein, in dem sich auch die `manage.py`-Datei befindet). Wenn alles glatt läuft, sollte das so aussehen: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py migrate + Operations to perform: + Apply all migrations: auth, admin, 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 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 sessions.0001_initial... OK + + +Und wir sind fertig! Zeit, unseren Webserver zu starten, um zu sehen, ob unsere Website funktioniert! + +## Den Webserver starten + +Kontrolliere, dass du in dem Verzeichnis bist, in dem die `manage.py`-Datei liegt (das `djangogirls`-Verzeichnis). Wir starten den Webserver, indem wir in der Konsole `python manage.py runserver` ausführen: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver + + +Wenn du ein Chromebook verwendest, benutze stattdessen diesen Befehl: + +{% filename %}Cloud 9{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0.0.0.0:8080 + + +oder wenn du Glitch verwendest, diesen: + +{% filename %}Glitch.com terminal{% endfilename %} + + $ refresh + + + +Wenn du Windows benutzt und dies mit dem `UnicodeDecodeError` fehlschläft, verwende diesen Befehl: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + + +Jetzt wollen wir schauen, ob unsere Website funktioniert: Öffne deinen Browser (Firefox, Chrome, Safari, Edge oder was du sonst nutzt) und gib diese Adresse ein: + +{% filename %}browser{% endfilename %} + + http://127.0.0.1:8000/ + + +Wenn du ein Chromebook und Cloud9 verwendest, dann klicke stattdessen die URL im erschienenen Fenster in der oberen rechten Ecke des Kommandozeilenfensters, in dem der Webserver läuft. Die URL sollte etwa so aussehen: + +{% filename %}browser{% endfilename %} + + https://.vfs.cloud9.us-west-2.amazonaws.com + + +oder auf Glitch: + + https://name-deines-glitch-projects.glitch.me + + +Glückwunsch! Du hast gerade deine erste Website erstellt und sie auf deinem Webserver laufen! Ist das nicht toll? + +![Installation hat funktioniert!](images/install_worked.png) + +Beachte, dass ein Terminalfenster immer nur eine Sache zur selben Zeit erledigen kann, und in dem Terminalfenster, was du vorhin geöffnet hast, läuft gerade der Webserver. Und solange der Webserver läuft und auf einkommende Anfragen wartet, akzeptiert das Terminal zwar Texteingaben, aber es wird keine neuen Befehle ausführen. + +> Wie Webserver funktionieren, haben wir im Kapitel **"Wie das Internet funktioniert"** angesehen. + +Um weitere Kommandos einzugeben, während der Webserver läuft, öffne ein neues Kommandozeilen-Fenster und aktiviere dort deine Virtualenv-Umgebung. Siehe [Einführung in die Kommandozeile](../intro_to_command_line/README.md), um nachzulesen, wie du ein zweites Kommandozeilen-Fenster öffnen kannst. Um den Webserver zu stoppen, wechsel zurück in das Fenster, in dem er läuft, und drücke STRG+C - Steuerung und C gleichzeitig. (In Windows kann es sein, dass du STRG und "Pause"-Taste drücken musst). + +Bereit für den nächsten Schritt? Es wird Zeit, ein paar Inhalte hinzuzufügen! \ No newline at end of file diff --git a/de/django_start_project/images/install_worked.png b/de/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..4354c634ddb Binary files /dev/null and b/de/django_start_project/images/install_worked.png differ diff --git a/de/django_templates/README.md b/de/django_templates/README.md new file mode 100644 index 00000000000..470a6e09043 --- /dev/null +++ b/de/django_templates/README.md @@ -0,0 +1,108 @@ +# Django-Templates + +Es wird Zeit, ein paar Daten anzuzeigen! Django bringt dafür bereits ein paar sehr hilfreiche **Template-Tags** mit. + +## Was sind Template-Tags? + +Also, in HTML kann man nicht wirklich Python-Code schreiben, weil es der Browser nicht verstehen würde. Denn der kennt nur HTML. Wir wissen, dass HTML ziemlich statisch ist, während Python dynamischer ist. + +Die **Django-Template-Tags** erlauben uns, Python-artige Dinge ins HTML zu bringen, so dass man einfach und schnell dynamische Websites erstellen kann. Super! + +## Anzeigen des Post-List-Templates + +Im vorangegangen Kapitel haben wir unserem Template in der `posts`-Variable eine Liste von Posts übergeben. Diese wollen wir jetzt in HTML anzeigen. + +Um eine Variable in einem Django-Template darzustellen, nutzen wir doppelte, geschweifte Klammern mit dem Namen der Variable darin, so wie hier: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{{ posts }} +``` + +Versuche das in deinem `blog/templates/blog/post_list.html` Template. Öffne es in deinem Code-Editor und ersetze alles vom zweiten `
` bis zum dritten `
` mit `{{ posts }}`. Speichere die Datei und aktualisiere die Seite, um die Ergebnisse anzuzeigen. + +![Abbildung 13.1](images/step1.png) + +Wie du siehst, haben wir nun das: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +, ]> +``` + +Das heißt, Django versteht es als Liste von Objekten. Kannst du dich noch an die Einführung von Python erinnern, wie man Listen anzeigen kann? Ja, mit for-Schleifen! In einem Django-Template benutzt du sie so: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} +    {{ post }} +{% endfor %} +``` + +Versuch das in deinem Template. + +![Abbildung 13.2](images/step2.png) + +Es funktioniert! Aber wir wollen, dass die Posts so wie die statischen Posts angezeigt werden, die wir vorhin im **Einführung in HTML**-Kapitel erstellt haben. Du kannst HTML und Template Tags mischen. Unser `body` sollte dann so aussehen: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+

Django Girls Blog

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

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` + +{% raw %}Alles, was du zwischen `{% for %}`und `{% endfor %}` schreibst, wird für jedes Objekt in der Liste wiederholt. Aktualisiere deine Seite:{% endraw %} + +![Abbildung 13.3](images/step3.png) + +Ist dir aufgefallen, dass wir diesmal eine etwas andere Notation benutzen haben (`{{ post.title }}` oder `{{ post.text }}`)? Wir greifen auf Daten von jedem Feld unseres `Post`-Models zu. Außerdem leitet das `|linebreaksbr` den Text der Posts durch einen Filter, um Zeilenumbrüche in Absätze umzuwandeln. + +## Und zum Schluss + +Es wäre gut zu sehen, ob deine Website noch immer im öffentlichen Internet funktioniert, richtig? Lass uns versuchen, unsere Aktualisierungen wieder zu PythonAnywhere hochzuladen. Hier ist eine Zusammenfassung der Schritte… + +* Schiebe zuerst deinen Code auf GitHub + +{% filename %}command-line{% endfilename %} + + $ git status + [...] + $ git add . + $ git status + [...] + $ git commit -m "Modified templates to display posts from database." + [...] + $ git push + + +* Dann logg dich wieder bei [PythonAnywhere](https://www.pythonanywhere.com/consoles/) ein, geh zu deiner **Bash-Konsole** (oder starte eine neue) und gib ein: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd .pythonanywhere.com + $ git pull + [...] + + +(Denk daran, `` durch deine tatsächliche PythonAnywhere-Subdomain zu ersetzen - ohne die spitzen Klammern.) + +* Spring anschließend rüber zur [Seite "Web"](https://www.pythonanywhere.com/web_app_setup/) und klick auf **Neu laden** in deinem Browser. (Um von der Konsolen-Seite aus zu anderen PythonAnywhere-Seiten zu gelangen, benutze den Menü-Knopf in der rechten oberen Ecke.) Ein Update sollte auf https://subdomain.pythonanywhere.com live sein -- guck's dir im Browser an! Wenn die Blogposts auf deiner PythonAnywhere-Seite anders sind als die auf deinem lokalen Server, ist das in Ordnung so. Die Datenbanken auf deinem lokalen Computer und auf PythonAnywhere werden nicht zusammen mit den restlichen Dateien abgeglichen. + +Glückwunsch! Nun kannst du dich daran machen, neue Posts in deinem Django Admin zu erstellen (denk daran, auch ein published_date einzufügen!). Stell sicher, dass du im Django-Admin der PythonAnywhere-Seite https://subdomain.pythonanywhere.com/admin arbeitest. Dann aktualisiere die Seite und schau nach, ob die Posts dort erscheinen. + +Funktioniert super? Wir sind so stolz auf dich! Steh kurz auf und geh ein Stück weg vom Computer. Du hast dir eine Pause verdient :) + +![Abbildung 13.4](images/donut.png) \ No newline at end of file diff --git a/de/django_templates/images/donut.png b/de/django_templates/images/donut.png new file mode 100644 index 00000000000..f31cebdc8a3 Binary files /dev/null and b/de/django_templates/images/donut.png differ diff --git a/de/django_templates/images/step1.png b/de/django_templates/images/step1.png new file mode 100644 index 00000000000..cbf6420360a Binary files /dev/null and b/de/django_templates/images/step1.png differ diff --git a/de/django_templates/images/step2.png b/de/django_templates/images/step2.png new file mode 100644 index 00000000000..fd6269c837c Binary files /dev/null and b/de/django_templates/images/step2.png differ diff --git a/de/django_templates/images/step3.png b/de/django_templates/images/step3.png new file mode 100644 index 00000000000..b471fdd4d7b Binary files /dev/null and b/de/django_templates/images/step3.png differ diff --git a/de/django_urls/README.md b/de/django_urls/README.md new file mode 100644 index 00000000000..728b50c8461 --- /dev/null +++ b/de/django_urls/README.md @@ -0,0 +1,103 @@ +# Django-URLs + +Gleich werden wir unsere erste Website basteln: eine Homepage für deinen Blog! Zuerst sollten wir uns jedoch mit Django URLs beschäftigen. + +## Was ist eine URL? + +Eine URL ist eine Web-Adresse. Jedes Mal, wenn du eine Website besuchst, kannst du eine URL sehen - sie ist in der Adressleiste des Browsers sichtbar. (Ja! `127.0.0.1:8000` ist eine URL! Und `https://djangogirls.org` ist auch eine URL.) + +![URL](images/url.png) + +Jede Seite im Internet braucht ihre eigene URL. Dadurch weiß deine Applikation, was sie dem Nutzer, der eine URL öffnet, zeigen soll. In Django verwenden wir eine sogenannte `URLconf` (URL-Konfiguration). URLconf ist eine Ansammlung von Mustern, die Django mit der empfangenen URL abgleicht, um die richtige View zu finden, das heißt, um letztlich die richtige Seite für den Nutzer anzuzeigen. + +## Wie funktionieren URLs in Django? + +Öffne die `mysite/urls.py`-Datei in deinem Code-Editor nach Wahl und schaue dir an, wie sie aussieht: + +{% filename %}mysite/urls.py{% endfilename %} + +```python +"""mysite URL Configuration + +[...] +""" +from django.contrib import admin +from django.urls import path + +urlpatterns = [ + path('admin/', admin.site.urls), +] +``` + +Wie du siehst, hat Django hier schon etwas für uns eingefügt. + +Zeilen zwischen dreifachen Gänsefüßchen (`'''` oder `"""`) heißen Docstrings (Kommentare) - man kann sie am Anfang der Datei, Klasse oder Methode platzieren, um zu beschreiben, was sie tut. Sie werden von Python nicht ausgeführt. + +Die admin-URL, die du im vorangegangenen Kapitel bereits besucht hast, ist schon da: + +{% filename %}mysite/urls.py{% endfilename %} + +```python + path('admin/', admin.site.urls), +``` + +Diese Zeile bedeutet, dass Django für jede URL, die mit `admin/` beginnt, die entsprechende *View* finden wird. Hier wird mit admin-site.urls eine ganze Sammlung von admin-URLs referenziert. Dadurch müssen nicht alle in dieser kleinen Datei aufgeführt werden und sie bleibt lesbarer und übersichtlicher. + +## Deine erste Django-URL! + +Es wird Zeit, unsere erste URL zu erstellen! Wir wollen, dass 'http://127.0.0.1:8000/' die Homepage unseres Blogs wird und eine Liste unserer Posts zeigt. + +Wir wollen auch, dass die `mysite/urls.py`-Datei sauber bleibt. Deshalb importieren wir die URLs unserer `Blog`-Applikation in die `mysite/urls.py`-Hauptdatei. + +Also los: Füge eine Zeile hinzu, die `blog.urls` importiert. Ausserdem wirst du die Zeile `from django.urls…` ändern müssen, da wir hier die Funktion `include` verwenden, die du in dieser Zeile noch importieren musst. + +Deine `mysite/urls.py`-Datei sollte jetzt so aussehen: + +{% filename %}mysite/urls.py{% endfilename %} + +```python +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('blog.urls')), +] +``` + +Django wird nun alle Aufrufe von 'http://127.0.0.1:8000/' auf `blog.urls` umleiten und dort nach weiteren Anweisungen schauen. + +## blog.urls + +Erstelle eine neue leere Datei namens `urls.py` im Verzeichnis `blog` und öffne sie im Code-Editor. Alles klar! Füge folgende zwei Zeilen ein: + +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views +``` + +Hier importieren wir die Django-Funktion `path` und alle unsere `views` aus unserer `blog`-Applikation. (Wir haben noch keine, aber dazu kommen wir gleich!) + +Jetzt können wir unser erstes URL-Muster hinzufügen: + +{% filename %}blog/urls.py{% endfilename %} + +```python +urlpatterns = [ + path('', views.post_list, name='post_list'), +] +``` + +Wie du siehst, fügen wir nun eine `view` mit dem Namen `post_list` zur Root-URL hinzu. Leere Zeichenfolgen passen auf dieses Muster und der Django-URL-Resolver ignoriert den Domain-Namen (z.B. http://127.0.0.1:8000/), der im vollständigen Pfad voransteht. Dieses Muster sagt Django also, dass `views.post_list` das gewünschte Ziel ist, wenn jemand deine Website über 'http://127.0.0.1:8000/' aufruft. + +Der letzte Teil `name='post_list'` ist der Name der URL, der genutzt wird, um die View zu identifizieren. Er kann identisch mit dem Namen der View sein, aber es kann auch ein komplett anderer sein. Wir werden später die Namen der URLs im Projekt benutzen. Daher ist es wichtig, jede URL in der App zu benennen. Wir sollten außerdem versuchen, eindeutige und einfach zu merkende URL-Namen zu wählen. + +Wenn du jetzt versuchst, http://127.0.0.1:8000/ aufzurufen, dann erscheint eine Meldung der Art "Webseite nicht verfügbar". Das erscheint deshalb, weil der Server nicht mehr läuft. (Erinnerst du dich noch, `runserver` eingegeben zu haben?) Schau mal in deiner Server-Konsole nach und finde heraus, warum der Server nicht mehr läuft. + +![Error](images/error1.png) + +Die Konsole zeigt einen Fehler, aber keine Sorge – der ist eigentlich ziemlich nützlich: Er sagt dir, dass **kein Attribut 'post_list'** vorhanden ist. Das ist der Name der *View*, die Django zu finden und zu verwenden versucht, aber wir haben sie noch gar nicht erstellt. In diesem Zustand wird dein `/admin/` auch nicht funktionieren. Keine Sorge, das regeln wir gleich. Wenn du eine andere Fehlermeldung siehst, versuche es nochmal nach einem Neustart des Webservers. Stoppe dazu den Webserver, indem du Strg+C drückst (die Strg- bzw. Ctrl- und die C-Taste zusammen). Auf Windows musst du evtl. Strg+Untbr (bzw. Ctrl+Break) drücken. Dann musst du den Webserver mittels des Kommandos `python manage.py runserver` erneut starten. + +> Wenn du mehr über Django-URLconfs lernen willst, dann öffne die offizielle Dokumentation: https://docs.djangoproject.com/en/2.2/topics/http/urls/ \ No newline at end of file diff --git a/de/django_urls/images/error1.png b/de/django_urls/images/error1.png new file mode 100644 index 00000000000..50618fca3fe Binary files /dev/null and b/de/django_urls/images/error1.png differ diff --git a/de/django_urls/images/url.png b/de/django_urls/images/url.png new file mode 100644 index 00000000000..c22441e930e Binary files /dev/null and b/de/django_urls/images/url.png differ diff --git a/de/django_views/README.md b/de/django_views/README.md new file mode 100644 index 00000000000..ac71c660d35 --- /dev/null +++ b/de/django_views/README.md @@ -0,0 +1,44 @@ +# Django-Views - leg los! + +Es wird jetzt Zeit, den Bug, den wir im letzten Kapitel erzeugt haben, zu beheben! :) + +In der *View* schreiben wir die Logik unserer Anwendung. So werden Informationen aus dem `Model` abgefragt werden, welches du zuvor erzeugt hast und diese werden an ein `Template` weitergeben. Ein Template erzeugen wir im nächsten Kapitel. Views sind Python-Funktionen, die ein bisschen komplizierter sind als die, die wir im Kapitel **Einführung in Python** kennengelernt haben. + +Views kommen in die `views.py` Datei. Wir fügen nun also unsere *Views* zur Datei `blog/views.py` hinzu. + +## blog/views.py + +OK, wir öffnen jetzt diese Datei in unserem Code-Editor und schauen, was darin steht: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render + +# Create your views here. +``` + +OK, hier steht noch nicht so viel. + +Denk daran, Zeilen mit einem `#` am Anfang sind Kommentare – das bedeutet, dass diese Zeilen von Python nicht ausgeführt werden. + +Lass uns eine *View* erstellen, wie der Kommentar das vorschlägt. Füge die folgende Mini-View unter dem Kommentar ein: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` + +Wie du siehst, definieren wir eine Funktion (`def`) mit dem Namen `post_list`, die den Parameter `request` entgegen nimmt und die mit `return` den Rückgabewert einer anderen Funktion namens `render` zurück gibt. Letztere wird unser Template `blog/post_list.html` "rendern" (zu einer fertigen HTML-Seite zusammensetzen). + +Speichere die Datei, öffne http://127.0.0.1:8000/ im Browser und schau nach, was wir jetzt haben. + +Einen anderen Fehler! Lies, was da jetzt los ist: + +![Error](images/error.png) + +Das zeigt, dass der Server zumindest wieder läuft, aber es sieht immer noch nicht richtig aus, oder? Mach dir keine Sorgen, es ist nur eine Fehlerseite, nichts zu befürchten! Genau wie die Fehlermeldungen in der Konsole sind auch die hier ziemlich nützlich. Du erhältst den Hinweis *TemplateDoesNotExist*, also dass es das Template nicht gibt. Lass uns diesen Bug beheben, indem wir im nächsten Kapitel ein Template erstellen! + +> Erfahre mehr über Django Views in der offiziellen Dokumentation: https://docs.djangoproject.com/en/2.2/topics/http/views/ \ No newline at end of file diff --git a/de/django_views/images/error.png b/de/django_views/images/error.png new file mode 100644 index 00000000000..1530c879cb5 Binary files /dev/null and b/de/django_views/images/error.png differ diff --git a/de/domain/README.md b/de/domain/README.md new file mode 100644 index 00000000000..da6c9139258 --- /dev/null +++ b/de/domain/README.md @@ -0,0 +1,51 @@ +# Die Domain + +Heroku hat dir eine Domain bereitgestellt, aber sie ist sehr lang, schwer zu merken und einfach nur hässlich. Es wäre doch toll, einen Domainnamen zu haben, der kürzer und einfacher zu merken ist, oder? + +In diesem Kapitel werden wir dir beibringen, wie man eine Domain kauft und sie mit Heroku verknüpft! + +## Wo registriert man eine Domain? + +Eine typische Domain kostet in etwa 15 $ pro Jahr. Es gibt günstigere und teurere Varianten, je nach Provider. Es gibt viele Unternehmen, bei denen du Domains kaufen kannst: eine einfache [Google-Suche](https://www.google.com/search?q=register%20domain) wird dir hunderte Vorschläge liefern. + +Unser Favorit ist [I want my name](https://iwantmyname.com/). Die werben mit "einfachem Domainmanagement" und es ist wirklich simpel. + +## Wie registriert man eine Domain auf IWantMyName? + +Gehe auf [iwantmyname](http://iwantmyname.com) und tippe eine Domain, die du haben möchtest, in das Suchfeld. + +![](images/1.png) + +Du solltest jetzt eine Liste mit all den verfügbaren Domains sehen, die zu deinem Wunschnamen passen. Wie du sehen kannst, zeigt dir ein Smiley an, wenn eine Domain verfügbar ist und ein trauriges Gesicht, wenn sie bereits vergeben ist. + +![](images/2.png) + +Wir haben beschlossen, `djangogirls.in` zu kaufen: + +![](images/3.png) + +Gehe zur Kasse. Du solltest dich jetzt bei IwantMyName anmelden, wenn du nicht bereits ein Konto dort hast. Danach gib deine Kreditkarteninformationen ein und kaufe deine Domain! + +Im Anschluss klickst du auf `Domains` im Menu und wählst deine neu gekaufte Domain aus. Dann suche und klicke auf den `manage DNS records` Link: + +![](images/4.png) + +Jetzt musst du dieses Formular finden: + +![](images/5.png) + +Fülle es mit den folgenden Details aus: - Hostname: www - Type: CNAME - Value: deine Heroku-Domain (z.B. djangogirls.herokuapp.com) - TTL: 3600 + +![](images/6.png) + +Klicke auf "Hinzufügen" und speichere die Änderungen am unteren Ende. + +Es kann einige Stunden dauern, bevor deine Domain lauffähig ist, hab etwas Geduld! + +## Konfigurieren der Domain in Heroku + +Du musst Heroku angeben, dass du deine eigene Domain benutzen möchtest. + +Gehe zum [Heroku Dashboard](https://dashboard.heroku.com/apps), logge dich auf dein Heroku-Konto ein und wähle deine App aus. Dann geh in das Einstellungsmenu und füge deine Domain in der `Domains` Sektion ein und speichere deine Änderungen. + +Das wars! diff --git a/de/dynamic_data_in_templates/README.md b/de/dynamic_data_in_templates/README.md new file mode 100644 index 00000000000..4af9e9bf509 --- /dev/null +++ b/de/dynamic_data_in_templates/README.md @@ -0,0 +1,84 @@ +# Dynamische Daten in Templates + +Wir haben nun schon einige Dinge an verschiedenen Orten fertiggestellt: das `Post`-Model ist in der `models.py` definiert, wir haben die `post_list` in der `views.py` und das Template hinzugefügt. Aber wie schaffen wir es nun, dass unsere Posts wirklich im HTML-Template erscheinen? Denn wir wollen ja erreichen, dass bestimmte Inhalte (die in der Datenbank gespeicherten Models) auf schöne Weise in unserem Template anzeigt werden, richtig? + +Genau dafür sind die *Views* zuständig: die Verbindung zwischen den Models und den Templates. In unserer `post_list`-View müssen wir die Models, die wir anzeigen wollen, hernehmen und diese dem Template übergeben. In einer *View* entscheiden wir, was (welches Model) wir in einem Template anzeigen werden. + +Okay, und wie machen wir das jetzt? + +Wir öffnen unsere Datei `blog/views.py` in unserem Code-Editor. Bisher sieht unsere `post_list`-*View* folgendermaßen aus: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render + +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` + +Erinnerst du dich, als wir davon gesprochen haben, dass wir den Code in verschiedene Dateien einfügen müssen? Jetzt ist es an der Zeit, das Model, dass wir in `models.py` beschrieben haben, einzufügen. Wir fügen den Befehl `from .models import Post` folgendermaßen ein: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from .models import Post +``` + +Der Punkt vor `models` bedeutet *aktuelles Verzeichnis* oder *aktuelle Anwendung*. Die Dateien `views.py` und `models.py` liegen im selben Verzeichnis. Deswegen können wir `.` und den Namen der Datei (ohne `.py`) benutzen. Dann ergänzen wir für den Import den Namen des Models (`Post`). + +Und nun? Um vom `Post`-Model die tatsächlichen Blogposts zu erhalten, brauchen wir etwas, das `QuerySet` heißt. + +## QuerySet + +Dir sollte schon ungefähr klar sein, wie QuerySets funktionieren. Wir haben darüber im Kapitel [Django-ORM und QuerySets](../django_orm/README.md) gesprochen. + +Wir wollen nun also eine Liste von publizierten Blogposts ausgeben, sortiert nach dem `published_date`, oder? Das haben wir bereits im Kapitel QuerySets gemacht! + +{% filename %}blog/views.py{% endfilename %} + +```python +Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +``` + +Öffnen wir also die Datei `blog/views.py` im Code-Editor und setzen wir dieses Stück Code in die Funktion `def post_list(request)` ein. Aber vergiss nicht, zuerst `from django.utils import timezone` hinzufügen: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from django.utils import timezone +from .models import Post + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {}) +``` + +Um unser QuerySet auf der Blogpost-Liste unseres Blogs anzuzeigen, bleiben noch zwei Dinge zu tun: + +1. Das QuerySet `posts` dem Template-Kontext übergeben, in dem wir den `render`-Funktionsaufruf ändern. Das werden wir jetzt tun. +2. Das Template abändern, um das QuerySet `posts` anzuzeigen. Das werden wir in einem späteren Kapitel behandeln. + +Beachte, dass wir eine *Variable* für unser QuerySet erstellt haben: `posts`. Das ist sozusagen der Name unseres QuerySets. Ab jetzt bezeichnen wir das QuerySet mit diesem Namen. + +In der `render`-Funktion haben wir einen Parameter `request` (also alles, was wir vom User über das Internet bekommen) und einen weiteren Parameter, der den Template-Namen (`'blog/post_list.html'`) angibt. Der letzte Parameter, `{}`, ist eine Stelle, in der wir weitere Dinge hinzufügen können, die das Template dann benutzen kann. Wir müssen diesen einen Namen geben (wir verwenden einfach wieder `'posts'`). :) Es sollte nun so aussehen: `{'posts': posts}`. Bitte achte darauf, dass der Teil vor `:` ein String ist; das heißt, du musst ihn mit Anführungszeichen `''` umschliessen. + +Schließlich sollte deine `blog/views.py` Datei folgendermaßen aussehen: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from django.utils import timezone +from .models import Post + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {'posts': posts}) +``` + +Das war's! Zeit, zurück zum Template zu gehen und das QuerySet anzuzeigen! + +Wenn du mehr über QuerySets in Django erfahren willst, dann sieh unter diesem Link nach: https://docs.djangoproject.com/en/2.2/ref/models/querysets/ \ No newline at end of file diff --git a/de/extend_your_application/README.md b/de/extend_your_application/README.md new file mode 100644 index 00000000000..546a3170994 --- /dev/null +++ b/de/extend_your_application/README.md @@ -0,0 +1,214 @@ +{% set warning_icon = '' %} + +# Erweitere deine Anwendung + +Wir haben bereits die verschiedenen Schritte für die Erstellung unserer Website abgeschlossen: Wir wissen, wie man Models, URLs, Views und Templates schreibt. Wir wissen auch, wie wir unsere Website verschönern. + +Zeit zu üben! + +Das erste, was unser Blog braucht, ist eine Seite, auf der ein einzelner Blogpost dargestellt wird, oder? + +Wir haben bereits ein `Post`-Model, deshalb brauchen wir nichts zur `models.py` hinzufügen. + +## Erstelle eine Template-Verknüpfung + +Wir beginnen damit, einen Link in der `blog/templates/blog/post_list.html`-Datei zu erstellen. Öffne sie im Code-Editor, und bisher sollte sie etwa so aussehen: {% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +{% raw %}Wir wollen einen Link vom Titel eines Posts in der Post-Liste zur Detailseite des jeweiligen Posts haben. Ändern wir `

{{ post.title }}

`, so dass es zu der Detailseite verlinkt:{% endraw %} + +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} + +```html +

{{ post.title }}

+``` + +{% raw %}Es ist an der Zeit, das mysteriöse `{% url 'post_detail' pk=post.pk %}` zu erklären. Wie du dir wahrscheinlich schon denkst, bedeutet `{% %}`, dass wir Django-Template-Tags verwenden. Dieses Mal verwenden wir eines, das eine URL für uns erzeugen wird! {% endraw %} + +Der `post_detail`-Teil bedeutet, dass Django eine URL in `blog/urls.py` mit dem Namen name=post_detail erwartet. + +Und was ist mit `pk=post.pk`? `pk` ist die Abkürzung für primary key (zu Deutsch: Primär-Schlüssel), ein eineindeutiges Identifikationsmerkmal zu jedem Eintrag in einer Datenbank. Jedes Django-Modell hat ein Feld, das als Primär-Schlüssel dient. Welchen Namen dieses Feld auch haben mag, es kann ebenfalls als "pk" referenziert werden. Da wir keinen Primär-Schlüssel in unserem `Post`-Modell angelegt haben, erstellt Django einen für uns (standardmäßig ist dies ein Feld namens "id", welches eine Zahl enthält, die mit jedem weiteren Eintrag nach oben gezählt wird, z.B. 1, 2, 3) und fügt ihn als Feld zu jedem unserer Posts hinzu. Wir greifen auf den Primär-Schlüssel zu, indem wir `post.pk` schreiben, genauso wie wir auf andere Felder (`title`, `author`, usw.) in unserem `Post`-Objekt zugreifen! + +Wenn wir jetzt http://127.0.0.1:8000/ aufrufen, erhalten wir einen Fehler (wie erwartet, da wir ja noch keine URL oder *View* für `post_detail` erstellt haben). Er wird so aussehen: + +![NoReverseMatch Error](images/no_reverse_match2.png) + +## Erstelle eine URL für die Post-Detailseite + +Lass uns eine URL in `urls.py` für unsere `post_detail`-*View* erstellen! + +Wir wollen, dass unsere erste Blogpost-Detailseite unter dieser **URL** angezeigt wird: http://127.0.0.1:8000/post/1/ + +Lass uns eine URL in der Datei `blog/urls.py` anlegen, um Django auf die *View* `post_detail` zu verweisen, welche dann den ganzen Blogpost anzeigen wird. Öffne die Datei `blog/urls.py` im Code-Editor und füge die Zeile `path('post//', views.post_detail, name='post_detail'),` hinzu, so dass die Datei wie folgt aussieht: + +{% filename %}{{ warning_icon }} blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), +] +``` + +Der Teil `post//` definiert ein URL-Muster – wir erklären es dir: + +- `post/` heißt, dass die URL mit dem Wort **post** beginnen sollte, gefolgt von einem **/**. So weit, so gut. +- `` – Dieser Teil ist schwieriger. Er bedeutet, dass Django eine Ganzzahl (einen Integer-Wert) erwartet und diese in Form einer Variablen namens `pk` einer View weitergibt. +- `/` – dann brauchen wir vor dem Abschluss der URL wieder einen **/**. + +Wenn du also `http://127.0.0.1:8000/post/5/` in deinen Browser eingibst, wird Django verstehen, dass du nach einer *View* suchst, die `post_detail` heißt, und wird der *View* die Information weitergeben, dass `pk` dabei `5` sein soll. + +So, jetzt haben wir der `blog/urls.py` ein neues URL-Muster hinzugefügt! Lass uns die Seite http://127.0.0.1:8000/ neu laden - Bumm! Der Server läuft wieder nicht mehr. Schau in die Konsole - wie erwartet gibt es noch einen anderen Fehler! + +![AttributeError](images/attribute_error2.png) + +Erinnerst du dich, was der nächste Schritt ist? Eine View hinzufügen! + +## Füge eine View hinzu + +Dieses Mal bekommt unsere *View* den extra Parameter `pk`. Unsere *View* muss diesen entgegennehmen, richtig? Also definieren wir unsere Funktion als `def post_detail(request, pk)`. Beachte, dass der Parameter genau den gleichen Variablennamen haben muss, wie wir in `urls` festgelegt haben (`pk`). Beachte zudem, dass das Weglassen dieser Variable unzulässig ist und zu einem Fehler führt! + +Jetzt benötigen wir also genau einen bestimmten Blogpost. Diesen finden wir, indem wir ein QuerySet folgendermaßen schreiben: + +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} + +```python +Post.objects.get(pk=pk) +``` + +Aber bei diesem Code gibt es ein Problem. Wenn es kein `Post`-Objekt mit diesem `primary key` (`pk`) gibt, bekommen wir einen super-hässlichen Fehler! + +![DoesNotExist Error](images/does_not_exist2.png) + +Das wollen wir nicht! Zum Glück stellt uns Django etwas zur Verfügung, das uns dieses Problem abnimmt: `get_object_or_404`. Wenn es kein `Post`-Objekt mit einem gegebenen `pk` gibt, wird eine schöne Seite angezeigt, die sogenannte `Page Not Found 404`-Seite ("Seite nicht gefunden"-Seite). + +![Page not found](images/404_2.png) + +Die gute Neuigkeit ist, dass du auch deine eigene `Page not found`-Seite erstellen und diese so hübsch gestalten kannst, wie du willst. Aber das ist jetzt gerade nicht so wichtig, deshalb überspringen wir das. + +Okay, es wird Zeit, die *View* zu unserer `views.py`-Datei hinzuzufügen! + +In `blog/urls.py` haben wir eine URL-Regel namens `post_detail` erstellt, die auf eine View namens `views.post_detail` verweist. Das heißt, dass Django eine View-Funktion erwartet, die `post_detail` heißt und in `blog/views.py` angelegt wurde. + +Wir sollten also `blog/views.py` im Code-Editor öffnen und den folgenden Code zu den anderen `from` Zeilen hinzufügen: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render, get_object_or_404 +``` + +Und am Ende der Datei werden wir unsere *View*-Funktion ergänzen: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) +``` + +Super. Lass uns nun http://127.0.0.1:8000/ neu laden. + +![Die post_list-View](images/post_list2.png) + +Es hat funktioniert! Aber was passiert, wenn du auf den Link im Blog-Titel klickst? + +![TemplateDoesNotExist Error](images/template_does_not_exist2.png) + +Oh nein! Ein anderer Fehler! Aber wir wissen ja schon, wie wir mit diesem umgehen, oder? Wir müssen ein Template hinzufügen! + +## Erstelle ein Template für die Post-Detailseite + +Wir erstellen eine Datei in `blog/templates/blog` mit dem Namen `post_detail.html` und öffnen sie im Code-Editor. + +Gib den folgenden Code ein: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} +
+ {% if post.published_date %} + + {% endif %} +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endblock %} +``` + +Wir erweitern wieder `base.html`. Im `content`-Block wollen wir das Publikationsdatum eines Posts (published_date), falls es existiert, anzeigen und auch den Titel und den Text. Aber wir müssen noch ein paar wichtige Dinge klären, oder? + +{% raw %}`{% if ... %} ... {% endif %}` ist ein Template-Tag, das wir benutzen können, wenn wir etwas überprüfen möchten. (Erinnerst du dich an `if ... else ...` vom Kapitel **Einführung in Python**?) In diesem Fall hier wollen wir prüfen, ob das `published_date`-Feld eines Post-Objektes nicht leer ist. {% endraw %} + +OK, aktualisieren wir unsere Seite und sehen, ob `TemplateDoesNotExist` jetzt weg ist. + +![Blogpost-Detailseite](images/post_detail2.png) + +Yay! Es funktioniert! + +# Veröffentlichen! + +Es wäre schön zu sehen, ob deine Website noch auf PythonAnywhere funktioniert, richtig? Lass sie uns erneut veröffentlichen. + +{% filename %}command-line{% endfilename %} + + $ git status + $ git add . + $ git status + $ git commit -m "View und Template für Blogpost-Details sowie CSS für die Website hinzugefügt" + $ git push + + +Dann führe Folgendes in der [PythonAnywhere-Bash-Konsole](https://www.pythonanywhere.com/consoles/) aus: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Denk daran, `` durch deine tatsächliche PythonAnywhere-Subdomain zu ersetzen - ohne die spitzen Klammern.) + +## Die statischen Dateien auf dem Server aktualisieren + +Server wie PythonAnywhere behandeln statische Dateien ("static files", z.B. CSS-Dateien) anders als Python-Dateien, weil statische Dateien noch optimiert und dadurch dann schneller geladen werden können. Deswegen müssen wir, nachdem wir Änderungen an den CSS Dateien vorgenommen haben, einen zusätzlichen Befehl auf dem Server ausführen, um diese Dateien zu aktualisieren. Der Befehl heißt `collectstatic`. + +Aktiviere also deine virtuelle Umgebung, wenn sie nicht vom letzten Mal noch aktiv ist (PythonAnywhere benutzt dazu das Kommando `workon`, das ist ähnlich wie `source myenv/bin/activate`, das du auf deinem Computer verwendest): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ workon .pythonanywhere.com + (ola.pythonanywhere.com)$ python manage.py collectstatic + [...] + + +Der `manage.py collectstatic` Befehl ist ein bisschen wie `manage.py migrate`. Wir machen ein paar Änderungen in unserem Code und dann sagen wir Django, dass es diese übernehmen (*apply*) soll, entweder zu der servereigenen Sammlung von statischen Dateien oder in die Datenbank. + +Auf jeden Fall sind wir nun soweit, dass wir [auf die Seite "Web"](https://www.pythonanywhere.com/web_app_setup/) wechseln können (mittels dem Menü-Knopf in der Ecke oben rechts) und **Reload** klicken können. Schau dir dann die Seite https://subdomain.pythonanywhere.com an, um das Ergebnis zu sehen. + +Und das war's. Glückwunsch! :) \ No newline at end of file diff --git a/de/extend_your_application/images/404_2.png b/de/extend_your_application/images/404_2.png new file mode 100644 index 00000000000..0a6fdf3234e Binary files /dev/null and b/de/extend_your_application/images/404_2.png differ diff --git a/de/extend_your_application/images/attribute_error2.png b/de/extend_your_application/images/attribute_error2.png new file mode 100644 index 00000000000..4b8262476d9 Binary files /dev/null and b/de/extend_your_application/images/attribute_error2.png differ diff --git a/de/extend_your_application/images/does_not_exist2.png b/de/extend_your_application/images/does_not_exist2.png new file mode 100644 index 00000000000..e7015f2c80d Binary files /dev/null and b/de/extend_your_application/images/does_not_exist2.png differ diff --git a/de/extend_your_application/images/no_reverse_match2.png b/de/extend_your_application/images/no_reverse_match2.png new file mode 100644 index 00000000000..aba1c9c8980 Binary files /dev/null and b/de/extend_your_application/images/no_reverse_match2.png differ diff --git a/de/extend_your_application/images/post_detail2.png b/de/extend_your_application/images/post_detail2.png new file mode 100644 index 00000000000..b40c92efb8c Binary files /dev/null and b/de/extend_your_application/images/post_detail2.png differ diff --git a/de/extend_your_application/images/post_list2.png b/de/extend_your_application/images/post_list2.png new file mode 100644 index 00000000000..dd0a0d67a6f Binary files /dev/null and b/de/extend_your_application/images/post_list2.png differ diff --git a/de/extend_your_application/images/template_does_not_exist2.png b/de/extend_your_application/images/template_does_not_exist2.png new file mode 100644 index 00000000000..c856abeda31 Binary files /dev/null and b/de/extend_your_application/images/template_does_not_exist2.png differ diff --git a/de/how_the_internet_works/README.md b/de/how_the_internet_works/README.md new file mode 100644 index 00000000000..ab728a10ce6 --- /dev/null +++ b/de/how_the_internet_works/README.md @@ -0,0 +1,47 @@ +# Wie das Internet funktioniert + +> Für die Leser zu Hause: Dieses Kapitel wird im Video [How the Internet Works](https://www.youtube.com/watch?v=oM9yAA09wdc) behandelt. +> +> Dieses Kapitel wurde inspiriert durch den Vortrag "How the Internet works" von Jessica McKellar (http://web.mit.edu/jesstess/www/). + +Wahrscheinlich nutzt du das Internet jeden Tag. Aber weißt du, was passiert, wenn du eine Adresse wie https://djangogirls.org im Browser eingibst und `enter` drückst? + +Als Erstes solltest du wissen, dass eine Webseite meist nur ein paar Dateien auf der Festplatte sind -- so wie deine Filme, deine Musik oder deine Bilder. Das Besondere an Webseiten ist, dass sie aus speziellem Computer-Code bestehen, das sogenannte HTML. + +Wenn du noch nie etwas mit Programmierung zu tun hattest, kann auch HTML zuerst abschreckend aussehen, aber dein Browser (Chrome, Safari, Firefox, etc.) liebt es. Browser sind so entworfen, dass sie diesen Code verstehen, seinen Anweisungen folgen können und diese Dateien, aus denen deine Website besteht, genau so darstellen, wie du es möchtest. + +Wie jede andere Datei auch, muss die HTML-Datei irgendwo auf einer Festplatte gespeichert werden. Für das Internet verwenden wir spezielle, leistungsstarke Computer, sogenannte *Server*. An ihnen sind normalerweise weder Bildschirm, Maus oder Tastatur angeschlossen, weil der Hauptzweck der Server darin besteht, Daten zu speichern und zur Verfügung zu stellen. Darum nennt man sie *Server* - sie *bedienen* (serve) dich mit Daten. + +OK, aber du willst wissen, wie das Internet aussieht oder? + +Wir haben ein Bild gemalt. So sieht es aus: + +![Abbildung 1.1](images/internet_1.png) + +Ziemliches Durcheinander, oder? Eigentlich ist es ein Netzwerk aus verbundenen Maschinen (den oben genannten *Servern*). Hunderttausende von Rechnern! Kilometer über Kilometer Kabel rund um die Welt. Auf einer Webseite über Unterseekabel (https://submarinecablemap.com/) kannst du dir ein Bild von der Komplexität des Netzes machen. Hier ist ein Screenshot der Seite: + +![Abbildung 1.2](images/internet_3.png) + +Faszinierend, oder? Es ist jedoch nicht möglich, Kabel zwischen allen Servern des Internets zu schalten. Damit wir eine Maschine (z.B. diejenige, auf welcher https://djangogirls.org abgespeichert ist) erreichen können, muss unsere Anfrage über viele verschiedene andere Maschinen weitergeleitet werden. + +Das sieht ungefähr so aus: + +![Abbildung 1.3](images/internet_2.png) + +Stell dir vor, wenn du https://djangogirls.org in den Browser eingibst, würdest du einen Brief versenden, in dem steht; "Hallo Django Girls, ich möchte die djangogirls.org Webseite ansehen. Bitte schickt sie mir!" + +Der Brief kommt ins Postamt in deiner Nähe. Von da aus gelangt er zu einem anderen Postamt näher an der Zieladresse und näher und näher, bis der Brief zugestellt werden kann. Die einzigartige Sache ist, dass, wenn du mehrere Briefe (*Datenpakete*) zu der selben Adresse abschickst, jeder einzelne Brief durch komplett unterschiedliche Poststellen (*Router*) laufen könnte. Dies hängt davon ab, wie sie an jedem Standort verteilt werden. + +![Abbildung 1.4](images/internet_4.png) + +So einfach ist das im Prinzip. Du sendest Nachrichten und erwartest eine Antwort. Anstelle von Papier und Stift verwendest du Daten, aber die Idee ist dieselbe! + +Anstelle von Adressen mit Straße, Ort und Postleitzahl verwenden wir IP-Adressen. IP steht für Internet Protocol. Dein Computer fragt erst das DNS (Domain Name System), um die (von Menschen besser lesbare) Adresse djangogirls.org in die (besser von Maschinen lesbare) IP-Adresse umzuwandeln. Das DNS ist ein bisschen wie ein altmodisches Telefonbuch aus Papier, in dem du den Namen einer Person, die Du kontaktieren willst, suchen und die Telefonnummer und Adresse nachgucken kannst. + +Wenn du einen Brief versenden willst, brauchst du spezielle Eigenschaften wie: Postanschrift, Briefmarke etc. Außerdem musst du eine Sprache verwenden, die der Empfänger versteht. Das gleiche gilt für die *Datenpakete*, die du sendest, um eine Website betrachten zu können. Wir verwenden ein Protokoll namens HTTP (Hypertext Transfer Protocol). + +Grundsätzlich brauchst du also für eine Website auch einen *Server*, auf dem sie abgelegt ist. Wenn der *Server* eine eingehende *Anforderung* (in einem Brief) empfängt, sendet er deine Website zurück (in einem weiteren Brief). + +Da dies hier ein Django-Tutorial ist, fragst du dich vielleicht, was Django in diesem Zusammenhang macht. Wenn dein Server eine Antwort zurück sendet, soll nicht an jeden dasselbe gesendet werden. Es wäre besser, wenn die Antworten individuell personalisiert würden, entsprechend der Anfragen des jeweiligen Briefes, oder? Django hilft dir, diese personalisierten und interessanten Antworten zu erstellen. :) + +Genug der Theorie, lass uns loslegen! \ No newline at end of file diff --git a/de/how_the_internet_works/images/internet_1.png b/de/how_the_internet_works/images/internet_1.png new file mode 100644 index 00000000000..e289eac2b23 Binary files /dev/null and b/de/how_the_internet_works/images/internet_1.png differ diff --git a/de/how_the_internet_works/images/internet_2.png b/de/how_the_internet_works/images/internet_2.png new file mode 100644 index 00000000000..e8cf8b77999 Binary files /dev/null and b/de/how_the_internet_works/images/internet_2.png differ diff --git a/de/how_the_internet_works/images/internet_3.png b/de/how_the_internet_works/images/internet_3.png new file mode 100644 index 00000000000..6f5d95dec80 Binary files /dev/null and b/de/how_the_internet_works/images/internet_3.png differ diff --git a/de/how_the_internet_works/images/internet_4.png b/de/how_the_internet_works/images/internet_4.png new file mode 100644 index 00000000000..d4748ac48ef Binary files /dev/null and b/de/how_the_internet_works/images/internet_4.png differ diff --git a/de/html/README.md b/de/html/README.md new file mode 100644 index 00000000000..6f6cbd62cbb --- /dev/null +++ b/de/html/README.md @@ -0,0 +1,227 @@ +# Einführung in HTML + +Vielleicht fragst du dich, was ein Template (Vorlage) ist? + +Ein Template (zu deutsch "Vorlage") ist eine Textdatei und ermöglicht es uns, verschiedene Inhalte in einer einheitlichen Darstellung zu erzeugen. Eine Vorlage für z.B. einen Brief hilft uns, immer gleich aussehende Nachrichten zu versenden, in denen sich Empfänger, Betreff und Text jeweils ändern, das äußere Format jedoch bestehen bleibt. + +Ein Django-Template wird mit einer Sprache namens HTML beschrieben. (Genau das HTML aus dem ersten Kapitel: **Wie das Internet funktioniert**). + +## Was ist HTML? + +HTML ist recht einfacher Code, der von deinem Browser – z.B. Chrome, Firefox oder Safari – interpretiert wird, um dem Benutzer eine Website darzustellen. + +HTML steht für "HyperText Markup Language". Als **HyperText** wird Text bezeichnet, der über markierte Textstellen, den "Hyperlinks" (die umgangssprachlichen "Links"), auf andere (meist ebenfalls in HTML geschriebene) Seiten verweist. **Markup** bedeutet, dass wir ein Dokument nehmen und mit Code versehen, um einem Empfänger mitzuteilen (in diesem Fall dem Browser), wie diese Seite interpretiert werden muss. HTML-Code besteht aus **Tags**, wovon jeder mit `<` beginnt und mit `>` endet. Diese Tags stellen die Markup-**Elemente** dar. + +## Dein erstes Template! + +Ein Template zu erstellen, heißt, eine entsprechende Datei dafür zu erstellen. Alles ist eine Datei, wie du vielleicht schon bemerkt hast. + +Templates werden im Verzeichnis `blog/templates/blog` gespeichert. Als Erstes erzeugen wir das Verzeichnis `templates` in deinem Blog-Verzeichnis. Im Template-Verzeichnis selbst erstellen wir ein weiteres Verzeichnis `blog`: + + blog + └───templates + └───blog + + +(Falls du dich wunderst, warum wir zwei `blog`-Verzeichnisse brauchen – das hängt mit den nützlichen Namenskonventionen von Django zusammen, die das Leben einfacher machen, wenn deine Projekte immer komplizierter und komplexer werden.) + +Als nächstes erstellen wir eine Datei `post_list.html` (erst mal ohne Inhalt) innerhalb des Verzeichnisses `blog/templates/blog`. + +Kontrolliere deine überarbeitete Webseite unter: http://127.0.0.1:8000 + +> Falls du die Fehlermeldung `TemplateDoesNotExist` angezeigt bekommst, versuche den Server neu zu starten. Auf der Kommandozeile drückst du dafür Strg+C bzw. Ctrl+C (Strg-/Ctrl- und die C-Taste C zusammen) und startest danach den Server erneut mit dem Kommando `python manage.py runserver`. + +![Abbildung 11.1](images/step1.png) + +Der Fehler sollte weg sein! Gratulation! :) Deine Webseite ist allerdings noch leer, weil dein Template leer ist. Das müssen wir ändern. + +Öffne die neue Datei im Code-Editor, und füge Folgendes hinzu: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + +

Halli-Hallo!

+

Es funktioniert!

+ + +``` + +Hat sich die Seite geändert? Besuche http://127.0.0.1:8000/, um nachzusehen. + +![Abbildung 11.2](images/step3.png) + +Es funktioniert. Gute Arbeit! :) + +* Die Zeile `` ist kein HTML-Tag. Es deklariert nur den Dokumententyp. Hier informiert sie den Browser, dass der Dokumententyp [HTML5](https://html.spec.whatwg.org/#the-doctype) ist. Jede HTML5-Datei muss so anfangen. +* Der eigentliche HTML-Teil beginnt immer mit `` und endet immer mit ``. Zwischen den beiden Tags `` und `` steht der gesamte Inhalt der Webseite +* `

` ist der Tag für ein Absatz-Element (paragraph), `

` beendet einen Absatz + +## "Head" und "body" + +Jede HTML-Seite gliedert sich in zwei Teile: **head** und **body**. + +* Das Element **head** speichert im "Kopf" der Seite Informationen über die Seite, die dir nicht angezeigt werden. + +* Das Element **body** enthält den "Körper" - also den dargestellten Inhalt der Seite. + +Im `` informieren wir den Browser über Einstellungen und Konfigurationen der Webseite, z.B. wie sie dargestellt werden soll, und im `` darüber, was tatsächlich dargestellt werden soll. + +In den `` können wir z.B. noch den Titel (title) der Seite mit aufnehmen: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + + Olas blog + + +

Halli-Hallo!

+

Es funktioniert!

+ + +``` + +Speichere die Datei und aktualisiere die Seite im Browser. + +![Abbildung 11.3](images/step4.png) + +Der Titel "Olas Blog" wird nun im Browser angezeigt. Hast du es bemerkt? Der Browser hat `Olas Blog` interpretiert und in die Titelleiste übernommen (dieser Titel wird auch in den Lesezeichen usw. verwendet). + +Wie du vielleicht bemerkt hast, hat jedes Element zu Beginn einen öffnenden Tag und einen zugehörigen *schließenden Tag* mit `/` und innerhalb davon sind Elemente *eingebettet*. Ein innerer Tag kann nicht außerhalb des umschließenden Tags geschlossen werden, die Reihenfolge muss immer stimmen. + +Es ist, wie wenn man Sachen in Kisten steckt. Du hast eine große Kiste, ``. In der ist als weitere, etwas kleinere Kiste `` drin, und in der wiederum weitere kleine Kistchen: `

`. + +Die Regeln und Reihenfolgen von *schließenden* Tags und *Verschachtelung* der Elemente musst du immer einhalten. Anderenfalls können Browser die Seite nicht richtig interpretieren und darstellen. + +## Dein Template anpassen + +Jetzt kannst du ein bisschen rumprobieren und dein Template umgestalten! Hier sind ein paar nützliche Tags dafür: + +* `

Überschrift

` (headline) für wichtigste Überschriften +* `

Unter-Überschrift

` die nächst tiefere Überschiftenebene +* `

Unter-Unter-Überschrift

` ... und so weiter bis `
` +* `

Ein Fliesstext-Absatz

` +* `Text` hebt deinen Text hervor +* `Text` hebt deinen Text stark hervor +* `
` fängt eine neue Zeile an (du kannst nichts in das br schreiben und es gibt keinen schließenden Tag) +* `link` erstellt einen Link +* `
  • Erster Punkt
  • second item
` generiert eine Liste so wie diese hier! +* `
` definiert einen Abschnitt auf einer Seite +* `` definiert eine Reihe von Navigationslinks +* `
` definiert voneinander unabhängige, eigenständige Inhalts-Teile +* `
` definiert einen Abschnitt in einem Dokument +* `
` gibt eine Kopfzeile für ein Dokument oder einen Abschnitt an +* `
` enthält den Hauptinhalt eines Dokuments +* `` definiert eine Nebenbemerkung (wie den Inhalt einer Rand-Leiste) zum Inhaltsteil, in dem es platziert wird +* `
` definiert eine Fußzeile für ein Dokument oder einen Abschnitt +* `` definiert eine bestimmte Zeit (oder einen Zeitpunkt samt Datum) + +Hier ist ein vollständiges Beispiel eines Templates. Kopiere es und füge es in `blog/templates/blog/post_list.html` ein: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + + Django Girls blog + + +
+

Django Girls Blog

+
+ +
+ +

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.

+
+ +
+ +

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.

+        
+     + +``` + +Wir haben hier einen `header`-Abschnitt und zwei `article`-Abschnitte erstellt. + +* Das `header`-Element enthält den Titel unseres Blogs – eine Überschrift und einen Link +* Die beiden `Artikel` Elemente enthalten unsere Blogeinträge mit einem veröffentlichten Datum in einem `time` Element, ein `h2` Element mit einem anklickbaren Beitragstitel und einem `p` (Absatz) Element für den Text unseres Blogeintrags. + +Wir bekommen das Folgende: + +![Abbildung 11.4](images/step6.png) + +Yaaay! Bis jetzt zeigt unser Template aber immer genau die **gleichen Inhalte** – obwohl wir aber vorhin davon gesprochen haben, dass Templates uns erlauben, **verschiedene** Informationen im **gleichen Format** darzustellen. + +Eigentlich wollen wir richtige Posts anzeigen, die in unserer Django-Admin-Oberfläche hinzugefügt wurden – und das wollen wir als Nächstes tun. + +## Noch eine Sache: Deployment! + +Es wäre gut, das alles live draußen im Internet zu sehen, oder? Lass uns noch eine PythonAnywhere-Anwendung erstellen: + +### Committe und pushe deinen Code auf GitHub + +Lass uns nachsehen, welche Dateien sich nach dem letzten Veröffentlichen (Deployment) geändert haben. (Führe diese Befehle lokal aus und nicht auf PythonAnywhere): + +{% filename %}command-line{% endfilename %} + + $ git status + + +Stelle sicher, dass du im `Djangogirls` Verzeichnis bist und sag `git`, dass alle Änderungen in diesem Verzeichnis hinzugefügt werden sollen: + +{% filename %}command-line{% endfilename %} + + $ git add . + + +Bevor wir alle Dateien hochladen, prüfen wir noch einmal, was `git` hochladen will (alle Dateien, die `git` hochladen wird, sind jetzt grün): + +{% filename %}command-line{% endfilename %} + + $ git status + + +Fast fertig, wir sagen nun noch, dass diese Änderung in der Verlaufsübersicht gespeichert werden soll. Wir erstellen eine "Commit Message", die beschreibt, was wir verändert haben. Du kannst an diesem Punkt hier alles reinschreiben, aber es ist sehr nützlich, etwas Sinnvolles einzutragen, damit du dich in Zukunft erinnern kannst, was du geändert hast. + +{% filename %}command-line{% endfilename %} + + $ git commit -m "HTML der Site geändert." + + +> **Beachte:** Du musst Anführungszeichen um den Commit-Kommentar setzen. + +Nachdem wir das gemacht haben, laden (push) wir unsere Änderungen auf GitHub: + +{% filename %}command-line{% endfilename %} + + $ git push + + +### Hol dir den neuen Code auf PythonAnywhere und aktualisiere deinen Browser + +* Öffne die [PythonAnywhere consoles page](https://www.pythonanywhere.com/consoles/) und gehe zu deiner **Bash-Konsole** (oder starte eine neue). Dann, führe Folgendes aus: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +Du musst `` durch deine tatsächliche PythonAnywhere-Subdomain zu ersetzen - ohne die spitzen Klammern. Normalerweise ist deine Subdomain dein PythonAnywhere-Benutzername, aber in manchen Fällen ist sie leicht anders (z.B. wenn dein Benutzername Großbuchstaben enthält). Wenn dieser Befehl also nicht funktioniert, verwende den Befehl `ls` (listet Dateien auf), um den tatsächlichen Subdomain-/Ordner-Name herauszufinden, und verwende dann `cd`, um dorthin zu wechseln. + +Nun sieh zu, wie dein Code heruntergeladen wird. Wenn du überprüfen willst, dass er angekommen ist, geh' hinüber zur **Seite "Files"** and schau deinen Code auf PythonAnywhere an (du kannst andere PythonAnywhere-Seiten über den Menü-Knopf auf der Konsolen-Seite erreichen). + +* Spring anschließend rüber zur [Seite "Web"](https://www.pythonanywhere.com/web_app_setup/) und klick auf **Neu laden** in deinem Browser. + +Dein Update sollte live sein! Lade die Seite neu in deinem Browser. Es sollten nun Änderungen zu sehen sein. :) \ No newline at end of file diff --git a/de/html/images/step1.png b/de/html/images/step1.png new file mode 100644 index 00000000000..eb474aaeddd Binary files /dev/null and b/de/html/images/step1.png differ diff --git a/de/html/images/step3.png b/de/html/images/step3.png new file mode 100644 index 00000000000..47ede3f9993 Binary files /dev/null and b/de/html/images/step3.png differ diff --git a/de/html/images/step4.png b/de/html/images/step4.png new file mode 100644 index 00000000000..0e6b48ec4a5 Binary files /dev/null and b/de/html/images/step4.png differ diff --git a/de/html/images/step6.png b/de/html/images/step6.png new file mode 100644 index 00000000000..f044389de53 Binary files /dev/null and b/de/html/images/step6.png differ diff --git a/de/images/application.png b/de/images/application.png new file mode 100644 index 00000000000..79071fe8d1b Binary files /dev/null and b/de/images/application.png differ diff --git a/de/installation/README.md b/de/installation/README.md new file mode 100644 index 00000000000..0e5fc8537fd --- /dev/null +++ b/de/installation/README.md @@ -0,0 +1,69 @@ +# Wenn du dieses Tutorial zu Hause bearbeitest + +Wenn du das Tutorial zu Hause bearbeitest, und nicht auf einer der [Django Girls Veranstaltungen](https://djangogirls.org/events/), kannst du dieses Kapitel komplett überspringen und direkt mit dem Kapitel [Wie funktioniert das Internet?](../how_the_internet_works/README.md) fortfahren. + +Dem ist so, weil wir die Dinge jeweils installieren werden, wenn sie im Tutorial benötigt werden. Das hier ist nur eine zusätzliche Seite, die alle Installationsanleitungen an einem Ort bündelt (was für manche Veranstaltungsformate nützlich ist). Falls du willst, kannst du alles auf dieser Seite bereits jetzt installieren. Wenn du jedoch mit dem Lernen beginnen willst, bevor du eine Hand voll Sachen auf deinem Computer installierst, überspringe dieses Kapitel und lies unsere Erklärungen zur Installation später im Tutorial. + +Viel Erfolg! + +# Wenn du an einem Workshop teilnimmst + +Wenn du an einer [Django Girls Veranstaltung](https://djangogirls.org/events/) teilnimmst: + +* Vielleicht hat deine Veranstaltung eine "Installationsparty" vor dem eigentlichen Workshoptag. Wenn du gerade auf einer Installationsparty bist, ist das deine Seite! Folge den Anweisungen hier, um alles Notwendige für den Workshop zu installieren. Frage deinen Coach, wenn du Hilfe brauchst. Am Workshoptag kannst du dann die Installationsanweisungen überspringen, auf die du im Tutorial stößt. +* Vielleicht haben die Organisatoren des Workshops dich gebeten, zu versuchen, schon zu Hause möglichst alles Benötigte auf deinem Computer zu installieren. Wenn du dazu aufgefordert wurdest, dann bist du hier auf der richtigen Seite! Folge den Anweisungen hier so gut, wie du kannst. Wenn du am Workshoptag dann im Tutorial auf einen Installationsschritt triffst, der dir zu Hause nicht gelungen ist, frage deinen Coach um Hilfe. +* Wenn dein Workshop keine Installationsparty hat (oder du nicht teilnehmen konntest) und die Organisatorien dich nicht gebeten haben, alles zu Hause zu installieren, dann überspring die Seite und geh direkt zum Kapitel [Wie das Internet funktioniert](../how_the_internet_works/README.md). Denn du wirst dann alles installieren, während du das Tutorial durcharbeitest. + +# Installation + +In diesem Tutorial wirst du einen Blog bauen. Dafür wirst du während des Tutorials aufgefordert, verschiedene Software auf deinem Computer zu installieren und auch einige Online-Konten anzulegen, wenn sie gebraucht werden. Diese Seite fasst alle Installations- und Kontoeinrichtungs-Anweisungen an einer Stelle zusammen (das ist für einige Workshopformate sinnvoll). + + {% include "/chromebook_setup/instructions.md" %} + + + +# Kurze Einführung in die Kommandozeile {#command-line} + +Viele der folgenden Schritte beziehen sich auf die "Konsole", das "Terminal", das "Kommandozeilen-Fenster" oder die "Kommandozeile" -- all diese Begriffe bezeichnen dasselbe: Ein Fenster auf deinem Computer, in das du Kommandos eingeben kannst. Im Hauptteil des Tutorials wirst du mehr über die Kommandozeile lernen. Vorerst musst du nur wissen, wie du ein Kommandozeilenfester öffnen kannst und wie eines aussieht: +{% include "/intro_to_command_line/open_instructions.md" %} + +# Python installieren {#python} + +{% include "/python_installation/instructions.md" %} + +# Einen Code-Editor installieren {#code-editor} + +{% include "/code_editor/instructions.md" %} + +# Virtualenv einrichten und Django installieren {#virtualenv} + +{% include "/django_installation/instructions.md" %} + +# Git installieren {#git} + +{% include "/deploy/install_git.md" %} + +# Einen GitHub-Account erstellen {#github-account} + +Gehe zu [GitHub.com](https://www.github.com) und registriere dich für ein neues, kostenfreies Benutzerkonto. Achte darauf, dass du dein Passwort nicht vergisst (füge es deinem Passwortmanager hinzu, wenn du einen benutzt). + +# Einen PythonAnywhere-Account erstellen {#pythonanywhere-account} + +{% include "/deploy/signup_pythonanywhere.md" %} + +# Fang an zu lesen! + +Herzlichen Glückwunsch, du hast alles eingerichtet und bist nun bereit loszulegen! Wenn du vor dem Workshop noch etwas Zeit hast, wäre es hilfreich, einige der einführenden Kapitel zu lesen: + +* [Wie das Internet funktioniert](../how_the_internet_works/README.md) + +* [Einführung in die Kommandozeile](../intro_to_command_line/README.md) + +* [Einführung in Python](../python_introduction/README.md) + +* [Django - Was ist das?](../django/README.md) + +# Viel Spaß beim Workshop! + +Wenn du mit dem Workshop anfängst, kannst du direkt zum Kapitel [Dein erstes Django-Projekt!](../django_start_project/README.md) gehen, weil du den Inhalt der vorhergehenden Kapitel schon bearbeitet hast. diff --git a/de/intro_to_command_line/README.md b/de/intro_to_command_line/README.md new file mode 100644 index 00000000000..4727d56a9de --- /dev/null +++ b/de/intro_to_command_line/README.md @@ -0,0 +1,441 @@ +# Einführung in die Kommandozeile + +> Für die Leser zu Hause: Dieses Kapitel wird im Video [Your new friend: Command Line](https://www.youtube.com/watch?v=jvZLWhkzX-8) behandelt. + +Aufregend, oder?! In ein paar Minuten wirst du deine erste Zeile Code schreiben! :) + +**Erstmal stellen wir dir deine neue Freundin vor: Die Konsole!** + +Im Folgenden zeigen wir dir, wie du das schwarze Fenster benutzt, das alle Hackerinnen nutzen. Es sieht vielleicht erstmal etwas unheimlich aus, aber es ist nur ein Programm, das darauf wartet, Anweisungen von dir zu bekommen. + +> **Hinweis:** Bitte beachte, dass wir in dem gesamten Buch die Begriffe "Verzeichnis" und "Ordner" abwechselnd gebrauchen, aber sie stehen für ein und dasselbe. + +## Was ist die Konsole? + +Das Fenster, welches gewöhnlich die **Kommandokonsole** (command line) oder **Kommandozeilen-Interface** (command-line interface) genannt wird, ist eine textbasierte Applikation zum Betrachten, Bearbeiten und Manipulieren von Dateien auf deinem Computer. Es ist dem Windows Explorer oder Finder auf dem Mac ähnlich, aber ohne die grafische Benutzeroberfläche. Andere Bezeichnungen dafür sind: *CMD*, *CLI*, *Prompt (Eingabeaufforderung)*, *Konsole* oder *Terminal*. + +## Öffnen der Konsole + +Um mit unserem Tutorial zu starten, musst du als Erstes das Kommandozeilenprogramm starten. + +{% include "/intro_to_command_line/open_instructions.md" %} + +## Eingabeaufforderung (Prompt) + +Du solltest nun ein weißes oder schwarzes Fenster sehen, das auf deine Anweisungen wartet. + + + +Auf einem Mac- oder Linux-Rechner siehst du wahrscheinlich ein `$`, also so: + +{% filename %}command-line{% endfilename %} + + $ + + + + + + +Auf einem Windows-Rechner siehst du wahrscheinlich ein `>`, so hier: + +{% filename %}command-line{% endfilename %} + + > + + +Schau 'mal in den Linux-Abschnitt hier obendrüber -- so etwas wirst du wieder im Abschnitt PythonAnywhere später im Tutorial antreffen. + + + +Vor jedem Kommando wird das Zeichen `$` oder `>` und ein Leerzeichen vorangestellt, aber du musst das nicht hinschreiben. Dein Computer macht das für dich. :) + +> Ein kleiner Hinweis: Falls du etwas in der Art wie `C:\Users\ola>` oder `Olas-MacBook-Air:~ ola$` sehen solltest, ist das auch 100%ig korrekt. + +Der Teil bis und einschließlich `$` oder `>` heißt *Kommandozeilen-Eingabeaufforderung* oder kurz *Eingabeaufforderung*. Sie fordert dich auf, hier etwas einzugeben. + +Wenn wir im Tutorial wollen, dass du einen Befehl eingibst, schreiben wir `$` oder `>` mit hin, gelegentlich auch noch die anderen Angaben links davon. Ignoriere den linken Teil und gib nur das Kommando ein, welches rechts der Eingabeaufforderung steht. + +## Dein erstes Kommando (YAY!) + +Lass uns mit diesem Kommando beginnen: + + + +{% filename %}command-line{% endfilename %} + + $ whoami + + + + + + +{% filename %}command-line{% endfilename %} + + > whoami + + + + +Und dann bestätige mit `Enter`. Das ist unser Ergebnis: + +{% filename %}command-line{% endfilename %} + + $ whoami + olasitarska + + +Wie du sehen kannst, hat der Computer gerade deinen Benutzernamen ausgegeben. Toll, was? :) + +> Versuch, jeden Befehl abzuschreiben und nicht zu kopieren und einzufügen. Auf diese Weise wirst du dir mehr merken! + +## Grundlagen + +Jedes Betriebssystem hat einen geringfügig anderen Bestand an Befehlen für die Kommandozeile, beachte daher die Anweisungen für dein Betriebssystem. Lass uns das ausprobieren. + +### Aktuelles Verzeichnis + +Es wäre schön zu sehen, wo wir uns befinden, oder? Lass uns nachsehen. Gib diesen Befehl in die Konsole ein und bestätige ihn mit `Enter`: + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska + + +> Hinweis: 'pwd' steht für 'print working directory' (zeige derzeitiges Arbeitsverzeichnis). + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska + + +> Hinweis: "cd" steht für "change directory". Mit PowerShell kannst du auch 'pwd' verwenden, wie auf Linux oder macOS. + + + +Du wirst wahrscheinlich etwas Ähnliches auf deinem Gerät sehen. Wenn du die Konsole öffnest, befindest du dich normalerweise im Heimverzeichnis deines Benutzers. + +* * * + +### Mehr über ein Kommando lernen + +Viele Befehle, die du in der Kommandozeile nutzen kannst, haben eine eingebaute Hilfe, die du anzeigen und lesen kannst! Zum Beispiel kannst du etwas über den eben verwendeten Befehl lernen: + + + +macOS und Linux haben einen `man`-Befehl, mit dem du die Hilfe über die Kommandos aufrufen kannst. Gib `man pwd` ein und schau, was angezeigt wird oder setzte `man` vor andere Kommandos und sieh dir deren Hilfe an. Das Ergebnis von `man` wird in der Regel seitenweise ausgegeben. Du kannst die Leertaste benutzen, um auf die nächste Seite zu gelangen und `q` (für engl. "quit", was "verlassen"/"rausgehen" heisst), um die Hilfeseiten zu schließen. + + + + + +Wenn du Windows benutzt, dann wird dir der Suffix `/?` für die meisten Kommandos die Hilfeseite ausgeben. Gegebenenfalls musst du nach oben scrollen, um alles zu sehen. Versuch es mal mit `cd /?`. + + + +### Anzeigen von Dateien und Unterordnern + +Nun, was befindet sich in deinem Verzeichnis? Es wäre toll, das herauszufinden. Lass uns mal schauen: + + + +{% filename %}command-line{% endfilename %} + + $ ls + Anwendungen + Desktop + Downloads + Musik + ... + + + + + + +{% filename %}command-line{% endfilename %} + + > dir + Directory of C:\Users\olasitarska + 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 + ... + + +> Hinweis: PowerShell kannst du auch 'ls' verwenden, wie auf Linux oder macOS. + +* * * + +### Wechseln des Verzeichnisses + +Lass uns jetzt zu unserem Desktop-Verzeichnis wechseln: + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + +Wenn dein Linux-Benutzerkonto auf Deutsch eingestellt ist, kann es sein, dass auch der Name des Desktop-Verzeichnisses übersetzt ist. Wenn dem so ist, musst du im obigen Befehl `Desktop` durch den übersetzten Verzeichnisnamen `Schreibtisch` ersetzen. + + + + + +{% filename %}command-line{% endfilename %} + + > cd Desktop + + + + +Schau, ob das Wechseln des Verzeichnisses funktioniert hat: + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + + +Passt! + +> Profi-Tipp: Wenn du `cd D` tippst und dann `tab` auf deiner Tastatur drückst, wird die Kommandozeile automatisch den Rest des Namens vervollständigen, wodurch du schneller navigieren kannst. Wenn es mehr als einen Ordner gibt, dessen Name mit "D" beginnt, drücke die `tab`-Taste zweimal, um eine Liste der Möglichkeiten anzuzeigen. + +* * * + +### Erstellen eines Verzeichnisses + +Wie wär's damit, ein Übungsverzeichnis auf deinem Desktop zu erstellen? So kannst du das tun: + + + +{% filename %}command-line{% endfilename %} + + $ mkdir practice + + + + + + +{% filename %}command-line{% endfilename %} + + > mkdir practice + + + + +Dieser kleine Befehl erstellt einen Ordner mit dem Namen `practice` auf deinem Desktop. Du kannst nun überprüfen, ob er wirklich dort ist, indem du auf deinem Desktop nachschaust oder indem du den Befehl `ls` oder `dir` ausführst! Versuch es. :) + +> Profi-Tipp: Wenn du die selben Befehle nicht immer wieder und wieder schreiben willst, verwende die `Pfeil aufwärts`- und `Pfeil abwärts`-Tasten deiner Tastatur, um durch die zuletzt verwendeten Befehle zu blättern. + +* * * + +### Übung! + +Eine kleine Herausforderung für dich: Erstelle in deinem neu erstellten `practice`-Ordner ein Verzeichnis namens `test`. (Verwende dazu die Kommandos `cd` und `mkdir`.) + +#### Lösung: + + + +{% filename %}command-line{% endfilename %} + + $ cd practice + $ mkdir test + $ ls + test + + + + + + +{% filename %}command-line{% endfilename %} + + > cd practice + > mkdir test + > dir + 05/08/2020 07:28 PM test + + + + +Glückwunsch! :) + +* * * + +### Aufräumen + +Wir wollen kein Chaos hinterlassen, also lass uns das bislang Geschaffene wieder löschen. + +Zuerst müssen wir zurück zum Desktop wechseln: + + + +{% filename %}command-line{% endfilename %} + + $ cd .. + + + + + + +{% filename %}command-line{% endfilename %} + + > cd .. + + + + +Durch Verwendung von `..` mit dem `cd`-Kommando wechselst du von deinem aktuellen Verzeichnis zum übergeordneten Verzeichnis (dies ist das Verzeichnis, das das aktuelle Verzeichnis enthält). + +Schau nach, wo du gerade bist: + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + + +Jetzt ist es an der Zeit, dein `practice`-Verzeichnis zu löschen: + +> **Achtung**: Wenn du Daten mit `del`, `rmdir` oder `rm` löschst, kannst du das nicht mehr rückgängig machen, das bedeutet, *die gelöschten Dateien sind für immer weg*! Sei also sehr vorsichtig mit diesem Befehl. + + + +{% filename %}command-line{% endfilename %} + + $ rm -r practice + + + + + + +{% filename %}command-line{% endfilename %} + + > rmdir /S practice + practice, Are you sure ? Y + + + + +Geschafft! Lass uns schauen, ob es wirklich gelöscht ist: + + + +{% filename %}command-line{% endfilename %} + + $ ls + + + + + + +{% filename %}command-line{% endfilename %} + + > dir + + + + +### Beenden + +Das wärs fürs Erste. Du kannst nun beruhigt deine Konsole schließen. Lass es uns wie die Hacker machen, okay? :) + + + +{% filename %}command-line{% endfilename %} + + $ exit + + + + + + +{% filename %}command-line{% endfilename %} + + > exit + + + + +Cool, was? :) + +## Zusammenfassung + +Hier ist eine Zusammenfassung einiger nützlicher Kommandos: + +| Befehl (Windows) | Befehl (Mac OS / Linux) | Beschreibung | Beispiel | +| ---------------- | ----------------------- | ------------------------------- | ---------------------------------------------------- | +| exit | exit | Fenster schließen | **exit** | +| cd | cd | Verzeichnis wechseln | **cd test** | +| cd | pwd | aktuelles Verzeichnis anzeigen | **cd** (Windows) oder **pwd** (Mac OS / Linux) | +| dir | ls | Unterordner/Dateien zeigen | **dir** | +| copy | cp | Datei kopieren | **copy c:\test\test.txt c:\windows\test.txt** | +| move | mv | Datei verschieben | **move c:\test\test.txt c:\windows\test.txt** | +| mkdir | mkdir | neues Verzeichnis erstellen | **mkdir testdirectory** | +| rmdir (oder del) | rm | Datei löschen | **del c:\test\test.txt** | +| rmdir /S | rm -r | Verzeichnis löschen | **rm -r testdirectory** | +| [CMD] /? | man [CMD] | Hilfe für ein Kommando aufrufen | **cd /?** (Windows) oder **man cd** (Mac OS / Linux) | + +Das sind nur sehr wenige der Befehle, welche du in deiner Konsole verwenden kannst, aber du wirst heute nicht mehr brauchen. + +Falls du neugierig bist, findest du auf [ss64.com](http://ss64.com) eine vollständige Übersicht über alle Kommandozeilen-Befehle für alle Betriebssysteme. + +## Fertig? + +Lass uns mit Python anfangen! \ No newline at end of file diff --git a/de/intro_to_command_line/open_instructions.md b/de/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..45b84b93895 --- /dev/null +++ b/de/intro_to_command_line/open_instructions.md @@ -0,0 +1,29 @@ + + + +Abhängig von deiner Windows-Version und deiner Tastatur sollte eine der folgenden Methoden ein Kommandozeilen-Fenster öffnen (du musst vielleicht etwas herumexperimentieren, aber du musst nicht jeden dieser Vorschläge ausprobieren): + +- Gehe zum Start-Menü oder Start-Bildschirm und gib "Eingabeaufforderung" in das Suchfeld ein. +- Klicke Start-Menü → Windows System → Eingabeaufforderung. +- Geh ins Start Menü → Alle Programme → Zubehör → Eingabeaufforderung. +- Gehe zum Startbildschirm, bewege deinen Mauszeiger zur unteren linken Bildschirmecke und klicke auf den nach unten zeigenden Pfeil, der erschienen ist (auf einem Touch-Screen streichst du mit dem Finger vom unteren Bildschirmrand nach oben). Die Apps-Seite sollte sich öffnen. Klicke auf Eingabeaufforderung im Abschnitt Windows System. +- Drücke die Windows-Taste und gleichzeitig "x" auf deiner Tastatur. Wähle "Eingabeaufforderung" aus dem Menü aus. +- Drücke die Windows-Taste und gleichzeitig "r", um das "Ausführen"-Fenster zu erhalten. Tippe "cmd" in das Feld und klicke OK. + +![Tippe "cmd" in das "Ausführen"-Fenster](../python_installation/images/windows-plus-r.png) + +Später im Tutorial wirst du zwei offene Kommandozeilen-Fenster gleichzeitig brauchen. Wenn du aber schon ein Kommandozeilen-Fenster offen hast, wirst du bei manchen Windows-Versionen einfach zu diesem geschickt, wenn du mit derselben Methode versuchst, ein zweites Fenster zu öffnen. Probiere das nun aus und achte darauf, was passiert! Wenn du nur ein Kommandozeilen-Fenster bekommst, versuche eine der anderen Methoden aus der Liste oben. Mindestens eine der Methoden sollte dazu führen, dass ein neues (zweites) Kommandozeilen-Fenster geöffnet wird. + + + + + +Öffne das Launchpad → Andere → Terminal. + + + + + +Wahrscheinlich ist es unter Programme → Zubehör → Terminal, aber das ist von deinem System abhängig. Wenn es nicht da ist, kannst du versuchen, danach zu googlen. :) + + diff --git a/de/python_installation/README.md b/de/python_installation/README.md new file mode 100644 index 00000000000..6ed46093a8a --- /dev/null +++ b/de/python_installation/README.md @@ -0,0 +1,15 @@ +# Lass uns mit Python anfangen + +Wir sind endlich da! + +Aber lass uns zuerst erklären, was Python ist. Python ist eine sehr beliebte Programmiersprache, die du zur Erstellung von Webseiten, Spielen, wissenschaftlichen Programmen, Computergrafiken und vielem, vielem mehr verwenden kannst. + +Python entstand in den späten 1980ern mit dem Hauptziel, von Menschen lesbar zu sein (nicht nur von Computern). Darum sieht es einfacher aus als andere Programmiersprachen. Aber keine Sorge - Python ist auch sehr mächtig! + +# Python-Installation + +> **Hinweis** Wenn du ein Chromebook verwendest, überspringe bitte dieses Kapitel und folge den Anweisungen im Kapitel [Chromebook Installation](../chromebook_setup/README.md). +> +> **Hinweis:** Falls du dich bereits durch die [Installationsschritte](../installation/README.md) gearbeitet hast, gibt es keinen Grund dies erneut zu tun – du kannst direkt zum nächsten Kapitel springen! + +{% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/de/python_installation/images/add_python_to_windows_path.png b/de/python_installation/images/add_python_to_windows_path.png new file mode 100644 index 00000000000..3266efb6177 Binary files /dev/null and b/de/python_installation/images/add_python_to_windows_path.png differ diff --git a/de/python_installation/images/python-installation-options.png b/de/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..a0a6c65d81d Binary files /dev/null and b/de/python_installation/images/python-installation-options.png differ diff --git a/de/python_installation/images/windows-plus-r.png b/de/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/de/python_installation/images/windows-plus-r.png differ diff --git a/de/python_installation/instructions.md b/de/python_installation/instructions.md new file mode 100644 index 00000000000..f579473b278 --- /dev/null +++ b/de/python_installation/instructions.md @@ -0,0 +1,117 @@ +> Für Leserinnen zuhause: Dieses Kapitel wird auch im Video [Installing Python & Code Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA) behandelt. +> +> Dieses Kapital basiert auf einem Tutorial der Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). + +Django ist in Python geschrieben. Wir brauchen Python für alles in Django. Fangen wir mit der Installation an! Wir möchten, dass du Python 3 installierst. Solltest du also bereits eine ältere Version installiert haben, musst du diese aktualisieren. Wenn du schon Version {{ book.py_min_version }} oder höher hast, ist das in Ordnung. + +Bitte installiere ein gewöhnliches Python wie folgt, selbst falls auf deinem Computer bereits Anaconda installiert ist. + + + +Bitte schau zuerst auf der "Systemtyp"-Zeile der Systeminformationsseite nach, ob auf deinem Computer eine 32-Bit-Version oder eine 64-Bit-Version von Windows läuft. Um diese Seite zu finden, versuche eine der folgenden Methoden: + +* Drücke die Windows-Taste und die Pause/Break-Taste zur selben Zeit +* Öffne dein Control Panel über das Windows Menü und navigiere dann zu System & Sicherheit, dann System +* Drücke die Windows-Taste und navigiere dann zu Einstellungen > System > Über +* Suche im Windows-Startmenü nach "Systeminformationen". Klicke dazu auf Start oder drücke die Windows-Taste, dann beginne `Systeminformationen` zu tippen. Sobald du etwas eingegeben hast, bekommst du passende Vorschläge. Wähle den Eintrag "Systeminformationen" an, sobald er erscheint. + +Du kannst Python für Windows von der Webseite https://www.python.org/downloads/windows/ herunterladen. Klicke auf den "Latest Python 3 Release - Python x.x.x" Link. Wenn du eine **64-bit**-Version von Windows benutzt, lade die Datei **Windows x86-64 executable installer** herunter. Andernfalls lade den **Windows x86 executable installer** herunter. Führe den Installer nach dem Download (per Doppelklick) aus und folge den Anweisungen des Installationsprogramms. + +Auf eine Sache solltest du achten: Während der Installation wird ein Setup-Fenster auftauchen. Stell sicher, dass du die Checkbox mit "Add Python {{ book.py_version }} to PATH" oder "Add Python to your environment variables" aktiviert hast und klicke dann auf "Install Now" wie hier gezeigt (es kann bei dir etwas anders aussehen, wenn du eine andere Version installierst): + +![Vergiss nicht, Python zum Pfad hinzuzufügen](../python_installation/images/python-installation-options.png) + +Wenn die Installation abgeschlossen ist, siehst du vielleicht ein Dialogfeld mit einem Link, wo du mehr über Python oder über die Version lernen kannst. Schließe es oder brich den Dialog ab -- du wirst darüber mehr in diesem Tutorial lernen! + +Hinweis: Falls du eine ältere Version von Windows verwendest (7, Vista oder älter) und die Installation von Python {{ book.py_version }} mit einer Fehlermeldung fehlschlägt, dann installiere alle Windows-Updates und versuche erneut, Python zu installieren. Falls der Fehler dann immer noch auftritt, installiere Python-Version {{ book.py_min_release }} von [Python.org](https://www.python.org/downloads/windows/). + +> Django {{ book.django_version }} benötigt Python {{ book.py_min_version }} oder höher, das weder Windows XP noch frühere Windows-Versionen unterstützt. + + + + + +> **Hinweis** Bevor du Python auf macOS installierst, musst du sicherstellen, dass deine Mac-Einstellungen es erlauben, Pakete zu installieren, die nicht aus dem App Store stammen. Geh auf Systemeinstellungen (im Ordner "Programme"), klicke auf "Sicherheit", und dann auf die Registerkarte "Allgemein". Wenn "Apps-Download erlauben von:" auf "Mac App Store" gestellt ist, ändere die Einstellung auf "Mac App Store und verifizierte Entwickler". + +Auf der Website https://www.python.org/downloads/mac-osx/ findest du aktuellen Python-Installer: + +* Lade die Datei *macOS 64-bit/32-bit installer* herunter, +* Doppelklicke auf *python-{{ book.py_release }}-macosx10.9.pkg*, um die Installation zu starten. + + + + + +Es ist ziemlich wahrscheinlich, dass du Python schon automatisch installiert hast. Um herauszufinden, ob das so ist (und wenn ja, welche Version du hast), öffne eine Konsole und gib das folgende Kommando ein: + +{% filename %}command-line{% endfilename %} +``` +$ python3 --version +Python {{ book.py_release }} +``` + +Wenn du eine andere Version von Python installiert hast, die {{ book.py_min_version }} oder höher ist, z.B. {{ book.py_min_release }}, dann musst du die Version nicht aktualisieren. Wenn du Python noch nicht installiert hast oder wenn du eine andere Python-Version willst, prüfe zuerst mit folgendem Befehl, welche Linux-Distribution du benutzt: + +{% filename %}command-line{% endfilename %} + + $ grep '^NAME=' /etc/os-release + + +Folge danach je nach Ergebnis einer der unterhalb dieses Abschnitts folgenden Installationsanweisungen. + + + + + +Gib diesen Befehl in die Konsole ein: + +{% filename %}command-line{% endfilename %} + + $ sudo apt install python3 + + + + + + +Gib diesen Befehl in die Konsole ein: + +{% filename %}command-line{% endfilename %} + + $ sudo dnf install python3 + + +Auf älteren Fedora-Versionen kann es sein, dass du eine Fehlermeldung bekommst, dass das Kommando `dnf` nicht gefunden wird. Falls das passiert, musst du stattdessen `yum` verwenden. + + + + + +Gib diesen Befehl in die Konsole ein: + +{% filename %}command-line{% endfilename %} + + $ sudo zypper install python3 + + + + +Prüfe, ob die Installation erfolgreich war, indem du ein Kommandozeilenfenster öffnest und den `python3`-Befehl ausführst: + +{% filename %}command-line{% endfilename %} +``` +$ python3 --version +Python {{ book.py_release }} +``` + +Die angezeigte Version kann bei dir eine andere sein als {{ book.py_release }} -- sie sollte aber der entsprechen, die du installiert hast. + +**Hinweis:** Wenn du unter Windows eine Fehlermeldung bekommst, dass `python3` nicht gefunden wurde, versuche es mit `python` (ohne die `3`) und prüfe, ob es dennoch eine Version von Python {{ book.py_min_version }} oder höher ist. Wenn auch das nicht funktioniert, kannst du ein neues Kommandozeilenfenster öffnen und es dort erneut versuchen; dies geschieht, wenn du ein Kommandozeilenfenster verwendet, das schon vor der Python-Installation geöffnet war. + +* * * + +Wenn es Unklarheiten gibt oder wenn etwas schief ging und du nicht weiter weißt, frage bitte deinen Coach! Manchmal laufen die Dinge einfach nicht so glatt und dann ist es besser, jemanden mit mehr Erfahrung um Hilfe zu bitten. diff --git a/de/python_introduction/README.md b/de/python_introduction/README.md new file mode 100644 index 00000000000..bd5bc5802a2 --- /dev/null +++ b/de/python_introduction/README.md @@ -0,0 +1,1071 @@ +{% set warning_icon = '' %} + +# Einführung in Python + +> Ein Teil dieses Kapitels basiert auf dem Tutorial der Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). + +Fangen wir an, schreiben wir Code! + +## Der Python-Prompt + +> Für Leserinnen, die sich bereits mit Python auskennen: Dieser Teil befindet sich im [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U) Video. + +Um Python zu starten, musst du an die *Kommandozeile* deines Computers. Wie das geht, weißt du bereits - denn du hast es im Kapitel [Einführung in die Kommandozeile](../intro_to_command_line/README.md) gelernt. + +Also öffne die Konsole, dann fangen wir an. + +Wir wollen eine Python Konsole öffnen, also tippe unter Windows `python` oder im Mac OS/Linux Terminal `python3` und drücke `Enter`. + +{% filename %}command-line{% endfilename %} + + $ python3 + Python {{ book.py_release }} (...) + Type "help", "copyright", "credits" or "license" for more information. + >>> + + +## Dein erster Python-Befehl! + +Nach Eingabe von python3 in der Konsole ändert sich das Prompt-Zeichen zu `>>>`. Für uns bedeutet das, dass wir ab nun nur noch Python-Code eingeben können. Den Python-Prompt `>>>` musst du nicht jedesmal eingeben - dies macht Python für dich. + +Wenn du die Python-Konsole wieder verlassen möchtest, gib `exit()` ein oder nutze das Tastatur-Kürzel `Strg + Z` unter Windows bzw. `Strg + D`, wenn du einen Mac hast oder Linux verwendest. Dann bist du wieder in der normalen Konsole und der Python-Prompt `>>>` ist weg. + +Fürs Erste bleiben wir in der Python Konsole, wir wollen mehr darüber lernen. Lass uns mit ein wenig Mathematik anfangen, gib `2 + 3` ein und drück `enter`. + +{% filename %}command-line{% endfilename %} + +```python +>>> 2 + 3 +5 +``` + +Cool! Schon ist das Ergebnis da. Python kann rechnen! Probier einfach einige andere Befehle aus, wie z.B.: + +- `4 * 5` +- `5 - 1` +- `40 / 2` + +Um Potenzen zu berechnen, sagen wir 2 hoch 3, müssen wir Folgendes eingeben: {% filename %}command-line{% endfilename %} + +```python +>>> 2 ** 3 +8 +``` + +Spiel ein wenig herum, dann machen wir weiter. :) + +Wie du siehst, kann Python richtig toll rechnen. Aber Python kann noch viel mehr ... + +## Strings + +Strings sind Zeichenketten. Das ist eine Folge von Buchstaben, die von Anführungszeichen umgeben sind. Gib einfach mal deinen Namen ein (bei mir "Ola"): + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" +'Ola' +``` + +Nun hast du deinen ersten String erzeugt! Dies ist eine Folge von Zeichen (also nicht nur Buchstaben, wie ich oben schrieb, sondern Zeichen aller Art), die von einem Computer verarbeitet werden können. Ein String muss stets mit dem gleichen Zeichen beginnen und enden. Dies kann entweder ein einzelnes Gänsefüßchen sein (`'`) oder ein doppeltes (`"`), da gibt es keinen Unterschied! Die Anführungszeichen zeigen Python nur an, dass alles dazwischen ein String ist. + +Strings können zusammengesetzt werden. Versuch es einmal: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Hi there " + "Ola" +'Hi there Ola' +``` + +Du kannst Strings auch vervielfältigen: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` + +Brauchst du einen Apostroph in einem String, so hast du zwei Möglichkeiten. + +Du kannst für den String doppelte Anführungszeichen verwenden: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Runnin' down the hill" +"Runnin' down the hill" +``` + +oder du kannst den Apostroph mit einem Backslash (`\`) markieren: + +{% filename %}command-line{% endfilename %} + +```python +>>> 'Runnin\' down the hill' +"Runnin' down the hill" +``` + +Toll, was? Um deinen Namen in Großbuchstaben anzuzeigen, gib Folgendes ein: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola".upper() +'OLA' +``` + +Hier hast du die `upper`-**Methode** auf den String angewendet! Eine Methode (wie `upper()`) ist eine Abfolge von Anweisungen, die Python für ein gegebenes Objekt (hier `"Ola"`) ausführt, wenn sie aufgerufen wird. + +Nehmen wir an, du möchtest die Zahl der Buchstaben in deinem Namen wissen. Auch dafür gibt es eine **Funktion**! + +{% filename %}command-line{% endfilename %} + +```python +>>> len("Ola") +3 +``` + +Nun fragst du dich sicher, warum du manchmal eine Methode mit einem `.` am Ende des Strings (wie bei `"Ola".upper()`) schreibst und manchmal eine Funktion direkt aufrufst und den String dahinter in Klammern setzt? Im ersten Fall gehören solche Methoden, wie `upper()`, zu Objekten (hier: ein String) und funktionieren auch nur bei diesen. In solchen Fällen bezeichnen wir eine Funktion als **Methode**. Andere Funktionen sind dagegen allgemeiner und können auf unterschiedliche Datentypen angewendet werden, wie beispielsweise `len()`. Daher übergeben wir `"Ola"` als Parameter an die `len` Funktion. + +### Zusammenfassung + +Ok, genug über Strings. Bisher haben wir Folgendes kennengelernt: + +- **Der Prompt** - Wenn wir beim Python-Prompt Anweisungen (oder Programm-Code) in Python eingeben, dann erhalten wir auch Ergebnisse in Python. Man sagt zu dieser Python-Umgebung auch "Python-Shell". +- **Zahlen und Strings** - In Python nutzen wir Zahlen für Berechnungen und Strings für Text-Objekte. +- **Operatoren**, wie + und *, verarbeiten mehrere Werte und erzeugen als Ergebnis einen neuen Wert. +- **Funktionen** - wie upper() und len(), tun etwas mit Objekten (in unserem Beispiel ändern sie diese, wie bei upper(), oder sie geben eine Eigenschaft zurück, wie bei len()). + +Das sind Grundlagen jeder Programmiersprache, die Du lernen wirst. Bist Du bereit für mehr? Bestimmt! + +## Fehler + +Probieren wir etwas Neues: Errors. Können wir die Länge einer Zahl auf die gleiche Weise ermitteln, wie die Länge eines Namens? Gib dazu `len(304023)` ein und drücke auf Enter: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` + +Wir haben unsere erste Fehlermeldung (Error) erhalten! Mit dem Icon {{ warning_icon }} teilen wir dir in diesem Tutorial jeweils mit, dass der einzugebende Code nicht wie erwartet funktionieren wird. Fehler zu machen (selbst absichtlich) ist ein wesentlicher Teil beim Lernen! + +Unser erster Fehler sagt, dass Objekte vom Typ "int" (Integers, das sind ganze Zahlen) keine Länge haben. Was also nun? Vielleicht sollten wir unsere Zahl als String schreiben? Denn bei Strings funktioniert es ja, wie wir wissen. + +{% filename %}command-line{% endfilename %} + +```python +>>> len(str(304023)) +6 +``` + +Ja, das funktioniert! Hier haben wir die `str`-Funktion innerhalb der Funktion `len` aufgerufen. `str()` konvertiert alles zu einem String. + +- Die `str`-Funktion wandelt den übergebenen Wert in einen **String** um. +- Die `int`-Funktion wandelt den übergebenen Wert in einen **Integer** um. + +> Wichtig: Zwar können wir Zahlen in Text umwandeln, aber nicht immer auch Text in Zahlen - was beispielsweise sollte `int('hello')` ergeben? + +## Variablen + +Ein wichtiger Bestandteil beim Programmieren sind Variablen. Eine Variable ist einfach ein Name für etwas, das wir später unter genau diesem Namen wieder verwenden können. Programmiererinnen nutzen Variablen, um Daten zu speichern, den Code lesbar zu halten und um sich nicht immer alles merken zu müssen. + +Lass uns eine Variable mit der Bezeichnung `name` anlegen: + +{% filename %}command-line{% endfilename %} + +```python +>>> name = "Ola" +``` + +Wir geben ein: name ist gleich "Ola". + +Du hast sicher schon bemerkt, dass Python diesmal kein Ergebnis zurückgegeben hat. Woher sollen wir nun wissen, dass es die Variable jetzt auch tatsächlich gibt? Gib `name` ein und drücke wieder auf `Enter`: + +{% filename %}command-line{% endfilename %} + +```python +>>> name +'Ola' +``` + +Hurra! Deine erste Variable :)! Nun kannst du auch stets ändern, was sie enthalten soll: + +{% filename %}command-line{% endfilename %} + +```python +>>> name = "Sonja" +>>> name +'Sonja' +``` + +Du kannst die Variable auch in Funktionen verwenden: + +{% filename %}command-line{% endfilename %} + +```python +>>> len(name) +5 +``` + +Das ist toll, oder? Variablen können alles enthalten, also auch Zahlen. Versuche Folgendes: + +{% filename %}command-line{% endfilename %} + +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` + +Was aber, wenn wir für eine Variable den falschen Namen verwenden? Uns einfach vertippen. Hast du schon eine leise Ahnung, was dann passiert? Probieren wir es aus! + +{% 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 +``` + +Ein Fehler! Wie du siehst, kennt Python verschiedene Arten von Fehlern. In unserem Fall hier ist es ein **NameError**. Python liefert diesen Fehler immer dann, wenn du versuchst, eine Variable zu verwenden, die es noch gar nicht gibt. Wenn du einen solchen Fehler erhältst, prüfe einfach in deinem Code, ob du dich irgendwo vertippt hast. + +Spiel einfach ein wenig rum und schaue, was alles so passiert. + +## Die print-Funktion + +Gib einmal Folgendes ein: + +{% filename %}command-line{% endfilename %} + +```python +>>> name = 'Maria' +>>> name +'Maria' +>>> print(name) +Maria +``` + +Wenn du in der zweiten Zeile `name` eintippst, dann gibt der Python-Interpreter die String-*Darstellung* (engl. 'representation') der Variable 'name' aus. In unserem Beispiel die Buchstaben M-a-r-i-a, umschlossen von einfachen Anführungszeichen ('). Wenn du hingegen `print(name)` schreibst, dann gibt Python den Inhalt der Variablen ohne die Anführungszeichen zurück, was etwas schöner aussieht. + +Wie wir später sehen werden, ist `print()` auch recht nützlich, wenn wir etwas aus Funktionen heraus ausgeben möchten oder auch eine Ausgabe über mehrere Zeilen darstellen wollen. + +## Listen + +Außer Strings (Zeichenketten) und Integern (ganze Zahlen) hat Python noch viele andere Arten von Datentypen. Von denen wollen wir uns nun **Listen** anschauen. Listen sind genau das, was du wahrscheinlich schon vermutest: Es sind Objekte, die Listen von anderen Objekten enthalten. :) + +Legen wir los und erzeugen eine Liste: + +{% filename %}command-line{% endfilename %} + +```python +>>> [] +[] +``` + +Ja, dies ist eine leere Liste. Für uns noch nicht sehr nützlich. Legen wir nun eine Liste von Lottozahlen an. Da wir uns nicht dauernd wiederholen wollen, ordnen wir diese Liste auch direkt einer Variablen zu: + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery = [3, 42, 12, 19, 30, 59] +``` + +So, nun haben wir eine Liste mit Lottozahlen! Was aber können wir damit tun? Zuerst einmal wollen wir feststellen, wie viele Zahlen in ihr enthalten sind. Hast du schon eine Idee, wie dies geht? Klar, das weißt du ja bereits! + +{% filename %}command-line{% endfilename %} + +```python +>>> len(lottery) +6 +``` + +Genau! `len()` liefert die Anzahl von Objekten in einer Liste zurück. Praktisch, nicht wahr? Nun wollen wir die Liste sortieren: + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.sort() +``` + +Diese Anweisung gibt nichts zurück, sie hat aber die Reihenfolge der Objekte in der Liste geändert. Um zu sehen, was passiert ist, müssen wir die Liste ausgeben: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery) +[3, 12, 19, 30, 42, 59] +``` + +Wie du siehst, sind die Zahlen in der Liste nun aufsteigend sortiert. Super! + +Aber vielleicht wollten wir es genau andersherum haben? Nichts leichter als das! + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.reverse() +>>> print(lottery) +[59, 42, 30, 19, 12, 3] +``` + +Einfach, oder? Du kannst auch etwas zu deiner Liste hinzufügen: + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.append(199) +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +``` + +Falls du nicht immer die gesamte Liste, sondern beispielsweise nur den ersten Eintrag sehen möchtest, kannst du dafür **Indizes** benützen. Ein Index gibt die Stelle innerhalb einer Liste an, die uns interessiert. Programmierer bevorzugen es, bei 0 mit dem Zählen anzufangen. Also hat das erste Objekt in deiner Liste den Index 0, das nächste die 1 und so weiter. Gib einmal Folgendes ein: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery[0]) +59 +>>> print(lottery[1]) +42 +``` + +Wie du siehst, kannst du auf die einzelnen Objekte in deiner Liste zugreifen, indem du den Namen der Liste verwendest und anschließend den Index in eckigen Klammern anfügst. + +Um etwas aus deiner Liste zu löschen, musst du die **Indizes** wie gerade gelernt benutzen und die `pop()`-Methode. Lass uns ein Beispiel versuchen und das festigen, was wir zuvor gelernt haben; wir werden die erste Nummer aus unserer Liste löschen. + +{% filename %}command-line{% 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] +``` + +Das hat doch super geklappt! + +Probier einmal andere Indizes aus: 6, 7, 1000, -1, -6 oder -1000 und versuch dir das Ergebnis vorzustellen, bevor du den jeweiligen Index verwendest. Sind die Ergebnisse sinnvoll? + +Eine Liste aller Methoden, die du auf Listen anwenden kannst, findest du in der Python-Dokumentation: https://docs.python.org/3/tutorial/datastructures.html + +## Dictionaries + +> Für die Leser zu Hause: Dieses Kapitel wird im Video [Installing Python Code Editor](https://www.youtube.com/watch?v=ZX1CVvZLE6c) behandelt. + +Ein Wörterbuch (von nun an mit dem englischen Begriff 'Dictionary' bezeichnet) verhält sich ähnlich wie eine Liste, jedoch greifen wir auf die enthaltenen Objekte nicht mit einem Index, sondern mit einem Schlüssel zu (auf englisch 'key', und auch hier verwenden wir im weiteren den englischen Begriff). Ein 'key' kann ein String oder eine Zahl sein. Ein leeres Dictionary legen wir wie folgt an: + +{% filename %}command-line{% endfilename %} + +```python +>>> {} +{} +``` + +Und schon hast du ein leeres Dictionary erstellt. Super! + +Nun gib einmal Folgendes ein (verwende statt 'Ola' usw. deine eigenen Informationen): + +{% filename %}command-line{% endfilename %} + +```python +>>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} +``` + +Du hast nun soeben die Variable mit dem Namen `participant` angelegt, die ein Dictionary mit drei key-value Paaren enthält (values, also Werte, sind die Objekte in einem Dictionary, - aber auch hier bleiben wir beim englischen Begriff): + +- Der key `name` verweist auf den value `'Ola'` (welches ein `string` Objekt ist), +- `country` verweist auf `'Poland'` (ebenfalls ein `string` Objekt), +- und `favorite_numbers` schließlich verweist auf `[7, 42, 92]` (eine `Liste` mit drei Zahlen). + +Auf die einzelnen Objekte in einem Dictionary kannst du wie folgt zugreifen: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(participant['name']) +Ola +``` + +Also ganz ähnlich wie bei einer Liste. Aber statt dir einen Index merken zu müssen, benutzt du bei einem Dictionary einfach einen key (hier: den String 'name'). + +Was aber geschieht, wenn wir Python nach dem Wert eines keys fragen, den es gar nicht gibt? Errätst du es schon? Probieren wir es einfach aus und schauen was passiert! + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> participant['age'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'age' +``` + +Ah, wieder ein Fehler! Diesmal ein **KeyError**. Python hilft uns auch hier und sagt uns, dass es den key `'age'` in diesem Dictionary gar nicht gibt. + +Wenn du zwischen Dictionaries und Listen wählen kannst, wann sollte welche Datenstruktur verwendet werden? Das ist eine gute Frage, über die es sich nachzudenken lohnt; und vielleicht möchtest du dies kurz tun, bevor du weiterliest. + +- Du brauchst nur eine geordnete Folge von Elementen? Dann wähle eine Liste. +- Du brauchst eine Sammlung von Elementen, auf die du später einzeln, gezielt und effizient mit Hilfe eines Namens (d.h. keys) zugreifen kannst? Dann wähle ein Dictionary. + +Dictionaries sind, so wie auch Listen, *mutable*, d. h. nachträglich veränderbar. So kannst du bei Dictionaries später noch weitere key-value Paare hinzufügen: + +{% filename %}command-line{% endfilename %} + +```python +>>> participant['favorite_language'] = 'Python' +``` + +Wie bei Listen können wir auch bei Dictionaries die `len()`-Funktion verwenden, um die Zahl der enthaltenen Einträge (das sind die key-value Paare) zu ermitteln. Probier es gleich aus und tippe dieses Kommando ein: + +{% filename %}command-line{% endfilename %} + +```python +>>> len(participant) +4 +``` + +Wir hoffen, dass das Alles für dich bisher Sinn ergibt. :) Bist du bereit für mehr Spaß mit Dictionaries? Machen wir weiter. + +Zum Löschen von Elementen kannst du den `pop()`-Befehl verwenden. Nehmen wir an, du möchtest den Eintrag mit dem key `'favorite_numbers'` entfernen, dann tippe: + +{% filename %}command-line{% endfilename %} + +```python +>>> participant.pop('favorite_numbers') +[7, 42, 92] +>>> participant +{'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +Wie du an der Ausgabe erkennst, ist nun das key-value Paar von 'favorite_numbers' gelöscht. + +Ebenso kannst du auch den Wert eines bestehenden Eintrages ändern: + +{% filename %}command-line{% endfilename %} + +```python +>>> participant['country'] = 'Germany' +>>> participant +{'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +Wie du siehst, hast du nun im key-value Paar mit dem key `'country'` den Wert von `'Poland'` nach `'Germany'` geändert. :) Hurra! Schon wieder was gelernt. + +### Zusammenfassung + +Großartig! Inzwischen hast du schon einiges über Programmierung gelernt und die folgenden Dinge sind dir vertraut: + +- **Errors** - Du weißt, wie sie zu lesen sind und dass Python sie dann ausgibt, wenn es eine Anweisung von dir nicht ausführen kann. +- **Variablen** - sind Namen für Objekte, die dir dabei helfen, deinen Code leichter zu schreiben und ihn dabei auch gut lesbar zu halten. +- **Listen** - können Objekte in einer geordneten Reihenfolge speichern. +- **Dictionaries** - speichern Objekte als key-value Paare. + +Schon gespannt auf den nächsten Teil? :) + +## Vergleichen + +> Für die Leser zu Hause: Dieses Kapitel wird im Video [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4) behandelt. + +Ein großer Teil beim Programmieren besteht darin, Dinge zu vergleichen. Was lässt sich am besten vergleichen? Zahlen! Schauen wir uns mal an, wie das funktioniert: + +{% 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 +``` + +Hier haben wir Python einige Zahlen zum Vergleichen gegeben. Wie du siehst, kann Python nicht nur die Zahlen vergleichen, sondern auch die Ergebnisse von mathematischen Ausdrücken wie `2 * 2` und Funktionswerte wie die `2`, die von `len([4, 5])` zurückgegeben wird. Cool, nicht wahr? + +Womöglich wunderst du dich aber über die beiden `==` Gleichheitszeichen zum Vergleich, ob zwei Zahlen den selben Wert haben? Ein einfaches Gleichheitszeichen `=` verwenden wir bereits, um Variablen bestimmte Werte zuzuweisen. Da beim Programmieren alle Anweisungen eindeutig sein müssen, benötigst du in Python daher **stets** zwei `==` Zeichen, um Dinge auf Gleichheit zu testen. Wir können auch feststellen, ob Werte unterschiedlich sind. Dafür verwenden wir das Symbol `!=`, wie im obigen Beispiel. + +Nun noch zwei weitere Vergleiche: + +{% filename %}command-line{% endfilename %} + +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` + +`>` und `<` sind klar, was aber sollen `>=` und `<=` bedeuten? Vergleiche liest du folgendermaßen: + +- x `>` y bedeutet: x ist größer als y +- x `<` y bedeutet: x ist kleiner als y +- x `<=` y bedeutet: x ist kleiner oder gleich y +- x `>=` y bedeutet: x ist größer oder gleich y + +Sensationell! Lust auf mehr? Dann probier das: + +{% filename %}command-line{% endfilename %} + +```python +>>> 6 > 2 and 2 < 3 +True +>>> 3 > 2 and 2 < 1 +False +>>> 3 > 2 or 2 < 1 +True +``` + +Du kannst Python beliebig viele Vergleiche vornehmen lassen und wirst ein Ergebnis erhalten. Das ist wirklich cool, oder? + +- **and** - wenn Du den `and`-Operator verwendest, müssen beide Vergleiche True (d.h. wahr) ergeben, damit das Gesamtergebnis auch True ist +- **or** - wenn Du den `or`-Operator verwendest, genügt es, wenn einer der beiden Vergleiche True ergibt, damit das Gesamtergebnis True ergibt + +Die Redewendung "Äpfel mit Birnen zu vergleichen" hast du bestimmt schon einmal gehört. Machen wir dies doch einmal in Python: + +{% 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' +``` + +Unterschiedliche Dinge, hier die Datentypen Zahlen (`int`) und Strings (`str`), lassen sich auch in Python nicht miteinander vergleichen. In solch einem Fall liefert uns Python einen **TypeError** und sagt uns, dass diese zwei Datentypen nicht miteinander verglichen werden können. + +## Boolean + +Du hast gerade einen neuen Typ von Python-Objekten kennen gelernt. Er heisst **Boolean**. + +Es gibt zwei Boolean-Objekte: + +- True (wahr) +- False (falsch) + +Damit Python diese beiden Werte versteht, musst du sie auch genau so schreiben (den ersten Buchstaben groß, alle weiteren klein). **true, TRUE und tRUE funktionieren nicht – nur True ist korrekt.** (Dasselbe gilt auch für False.) + +Auch Booleans können Variablen zugewiesen werden: + +{% filename %}command-line{% endfilename %} + +```python +>>> a = True +>>> a +True +``` + +Auch Folgendes geht: + +{% filename %}command-line{% endfilename %} + +```python +>>> a = 2 > 5 +>>> a +False +``` + +Übe ein wenig, indem du mit Booleans rumspielst, zum Beispiel mit diesen Anweisungen: + +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` + +Glückwunsch! Booleans sind echt eine der coolsten Features beim Programmieren und du hast gerade gelernt, damit umzugehen! + +# Speicher es! + +> Für die Leser zu Hause: Dieses Kapitel wird im Video [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk) behandelt. + +Bisher haben wir den Python-Code nur im Interpreter eingegeben, wodurch wir immer nur eine Zeile Code auf einmal ausführen konnten. Richtige Programme dagegen werden in Dateien gespeichert und, je nach Programmiersprache, durch einen **Interpreter** ausgeführt oder durch einen **Compiler** übersetzt. Unseren bisherigen Code haben wir dagegen im Python-**Interpreter** Zeile für Zeile eingegeben und einzeln ausgeführt. Für die nächsten Beispiele brauchen wir mehr als eine Zeile, daher werden wir nun: + +- Den Python-Interpreter beenden +- Einen Code-Editor unserer Wahl öffnen +- Code eingeben und diesen in einer Python-Datei sichern +- Und diesen dann laufen lassen! + +Um den Python-Interpreter zu beenden, nutze die `exit()`-Funktion + +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +``` + +Nun siehst du wieder den normalen Kommandozeilen-Prompt. + +Im Kapitel [Code-Editor](../code_editor/README.md) haben wir uns bereits einen Code-Editor ausgesucht. Nun öffnen wir den Code-Editor und schreiben folgenden Code in eine neue Datei (wenn du ein Chromebook benutzt, dann erstelle eine neue Datei in der Cloud-IDE, öffne sie und du befindest dich automatisch im integrierten Code-Editor): + +{% filename %}editor{% endfilename %} + +```python +print('Hello, Django girls!') +``` + +Da du nun schon einige Python-Erfahrung hast, schreibe ein wenig Code mit dem, was du bislang gelernt hast. + +Als nächstes wollen wir diesen Code in einer Datei mit einem aussagekräftigen Namen speichern. Lass uns die Datei **python_intro.py** nennen und auf dem Desktop speichern. Wir können der Datei jeden Namen geben, den wir wollen, aber es ist wichtig sicherzustellen, dass der Dateiname auf **.py** endet. Die Erweiterung **.py** gibt unserem Betriebssystem an, dass dies ein **Python executable file** ist und Python diese ausführen kann. + +> **Hinweis:** Du wirst eines der coolsten Eigenschaften von Code-Editoren bemerken: Farben! In der Python-Konsole hatte alles die gleiche Farbe. Der Code-Editor dagegen sollte dir nun die `print`-Funktion in einer anderen Farbe anzeigen als der von ihr auszugebende Text. Dies wird "Syntax Hervorhebung" ("syntax highlighting") genannt und ist ein wirklich sehr nützliches Werkzeug beim Programmieren. Die Farbe von Dingen gibt dir Hinweise auf z.B. nicht geschlossene Zeichenfolgen oder Tippfehler in einem Schlüsselwort (wie das `def` in einer Funktion, das wir weiter unten sehen werden). Dies ist einer der Gründe, warum wir Code-Editoren verwenden. :) + +Nun, da die Datei gesichert ist, wollen wir sie ausführen! Nutze, was du bisher über die Kommandozeile (das mit dem Prompt) gelernt hast, um in der Konsole in das Desktop-Verzeichnis zu wechseln. + + + +Auf einem Mac sieht das etwa so aus: + +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop + + + + + + +Unter Linux ist es ähnlich: + +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop + + +(Denk daran, dass das "Desktop"-Verzeichnis bei dir "Schreibtisch" heißen kann.) + + + + + +In der Eingabeaufforderung von Windows wird's so sein: + +{% filename %}command-line{% endfilename %} + + > cd %HomePath%\Desktop + + + + + + +Und in der Powershell von Windows so: + +{% filename %}command-line{% endfilename %} + + > cd $Home\Desktop + + + + +Wenn du nicht weiterkommst, frag' um Hilfe. Denn genau dafür sind die Coaches da! + +Benutze jetzt Python, um den Code in der Datei auszuführen: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hello, Django girls! + + +Hinweis: Unter Windows gibt es den 'python3'-Befehl nicht. Verwende stattdessen 'python', um die Datei auszuführen: + +{% filename %}command-line{% endfilename %} + +```python +> python python_intro.py +``` + +Prima! Du hast soeben dein erstes Python-Programm aus einer Datei heraus ausgeführt. Großartig, oder? + +Nun wollen wir uns einem wichtigen Teil der Programmierung zuwenden: + +## Wenn ... sonst-wenn ... sonst (If … elif … else) + +Oft sollen manche Programmteile nur ausgeführt werden, wenn bestimmte Vorbedingungen erfüllt sind. Dafür gibt es in Python sogenannte **if-Anweisungen**. + +Nun ändere den Code in deiner **python_intro.py** Datei: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 3 > 2: +``` + +Würden wir das nun speichern und anschließend ausführen, würden wir einen Fehler erhalten: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + + $ python3 python_intro.py + File "python_intro.py", line 2 + ^ + SyntaxError: unexpected EOF while parsing + + +Python erwartet hier noch weiteren Programmcode, der ausgeführt werden soll, wenn die Bedingung `3 > 2` wahr ist (also `True` ergibt). Versuchen wir, Python “It works!” ausgeben zu lassen. Ändere den Code in **python_intro.py** zu: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 3 > 2: + print('It works!') +``` + +Du fragst dich nun, warum wir die angefügte Zeile mit 4 Leerzeichen eingerückt haben? Damit teilen wir Python mit, dass dieser Code ausgeführt werden soll, wenn die vorhergehende Bedingung True ergeben hat. Du könntest auch eine andere Anzahl von Leerzeichen wählen, aber fast alle Python-Programmier nutzen 4 Leerzeichen, damit's gut aussieht. Ein einfaches Tab zählt auch wie 4 Leerzeichen, sofern dies in deinem Editor so eingestellt ist. Wenn du dich einmal entschieden hast, bleib dabei! Wenn du mit 4 Leerzeichen angefangen hast, solltest du alle weiteren Einrückungen auch mit 4 Leerzeichen machen, anderweitig könnte das Probleme verursachen. + +Nun sichere die Datei und führe sie noch einmal aus: + +{% filename %}command-line{% endfilename %} + +```python +$ python3 python_intro.py +It works! +``` + +Hinweis: Denk daran, dass Windows den 'python3'-Befehl nicht kennt. Falls du auf Windows arbeitest, verwende ab jetzt immer 'python', wenn in dieser Anleitung 'python3' steht. + +### Was passiert, wenn eine Bedingung nicht wahr (not True) ist? + +In den vorigen Beispielen wurde Code ausgeführt, wenn eine vorhergehende Bedingung True (wahr) ergab. Aber Python kennt auch `elif`- und `else`-Anweisungen: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 5 > 2: + print('5 ist wirklich größer als 2') +else: + print('5 ist nicht größer als 2') +``` + +Wenn dies ausgeführt wird, wird es anzeigen: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + 5 ist wirklich größer als 2 + + +Wenn 2 größer als 5 wäre, würde die zweite Anweisung (die nach dem else) ausgeführt. Schauen wir uns nun an, wie `elif` funktioniert: + +{% filename %}python_intro.py{% endfilename %} + +```python +name = 'Sonja' +if name == 'Ola': + print('Hey Ola!') +elif name == 'Sonja': + print('Hey Sonja!') +else: + print('Hey anonymous!') +``` + +und ausgeführt erhalten wir: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hey Sonja! + + +Hast du bemerkt, was passiert ist? `elif` lässt dich zusätzliche Bedingungen hinzufügen, die geprüft werden, falls die vorherige fehlschlägt. + +Du kannst so viele `elif`-Bedingungen nach der anfänglichen `if`-Anweisung hinzufügen, wie du magst. Zum Beispiel: + +{% filename %}python_intro.py{% endfilename %} + +```python +volume = 57 # "volume" ist Englisch für "Lautstärke" +if volume < 20: + print("Das ist etwas leise.") +elif 20 <= volume < 40: + print("Das ist gut für Hintergrund-Musik.") +elif 40 <= volume < 60: + print("Perfekt, ich kann alle Details hören.") +elif 60 <= volume < 80: + print("Gut für Partys.") +elif 80 <= volume < 100: + print("Etwas laut!") +else: + print("Mir tun die Ohren weh! :(") +``` + +Python läuft durch jeden Test der Reihe nach und gibt dann aus: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Perfekt, ich kann alle Details hören. + + +## Kommentare + +Kommentare sind Zeilen, die mit `#` beginnen. Du kannst nach dem `#` schreiben, was auch immer du willst, und Python wird es ignorieren. Kommentare können deinen Code für andere Leute einfacher zu verstehen machen. + +Schauen wir, wie das aussieht: + +{% filename %}python_intro.py{% endfilename %} + +```python +# Ändert die Lautstärke, wenn sie zu leise oder zu laut ist +if volume < 20 or volume > 80: + volume = 50 + print("So ist's besser!") +``` + +Du musst nicht für jede Codezeile einen Kommentar schreiben, aber Kommentare sind nützlich um zu erklären, wieso dein Code etwas macht, oder um zusammenzufassen, wenn er etwas Komplexes tut. + +### Zusammenfassung + +In den letzten paar Übungen hast du gelernt: + +- **Vergleiche vorzunehmen** – in Python kannst du Vergleiche mit den folgenden Operatoren `>`, `>=`, `==`, `<=`, `<` sowie `and` und `or` vornehmen +- **Boolsche Datentypen** zu verwenden – dies sind Objekte, die nur zwei Werte annehmen können: `True` bzw. `False` +- **Dateien zu speichern** – also Programmcode in Dateien abzulegen, so dass du auch umfangreichere Programme schreiben kannst. +- **if … elif … else** – Anweisungen, die dir erlauben, bestimmte Programmteile nur auszuführen, wenn bestimmte Bedingungen erfüllt sind. +- **Kommentare** – Zeilen, die Python nicht ausführt und die dir ermöglichen deinen Code zu dokumentieren + +Zeit für den letzten Teil dieses Kapitels! + +## Deine eigenen Funktionen! + +> Für die Leser zu Hause: Dieses Kapitel wird im Video [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0) behandelt. + +Erinnerst du dich an Funktionen wie `len()`, die du in Python aufrufen kannst? Prima! Du wirst nun lernen, eigene Funktionen zu schreiben! + +Eine Funktion ist eine Folge von Anweisungen, die Python ausführen soll. Jede Funktions-Definition beginnt mit dem Schlüsselwort (engl. "Keyword") `def`, bekommt einen Namen und kann Argumente (manchmal auch "Parameter" genannt) haben. Probieren wir's aus! Ersetze den Code in der Datei **python_intro.py** mit dem folgenden: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hallo(): + print("Halli-hallo!") + print("Wie geht's?") + +hallo() +``` + +Und schon hast du deine erste Funktion erstellt! + +Nun fragst du dich vielleicht, warum wir am Ende der Datei den Namen der Funktion nochmal hingeschrieben haben. Wenn wir `def hallo():` und die darauf folgenden, eingerückten Zeilen schreiben, dann schreiben wir Anweisungen, was die `hallo()` Funktion tun soll. Python wird diese Anweisungen lesen und speichern, die Funktion jedoch noch nicht ausführen. Um Python zu sagen, dass wir die Funktion ausführen wollen, müssen wir die Funktion mit `hallo()` aufrufen. Python liest und führt die Datei von oben nach unten aus, daher müssen wir die Funktion in der Datei erst definieren bevor wir sie aufrufen. + +Schauen wir, was passiert, wenn wir die Datei ausführen: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Halli-hallo! + Wie geht's? + + +Falls das nicht funktionert hat, keine Panik! Die Ausgabe wird dir dabei helfen, herauszufinden wieso: + +- Wenn du einen `NameError` erhältst, hast du dich vermutlich irgendwo im Code vertippt. Prüfe also, ob du bei der Funktionsdefinition `def hallo():` und beim Funktionsaufruf `hallo()` den Funktionsnamen gleich geschrieben hast. +- Wenn du einen `IndentationError` bekommst, prüfe, ob beide `print`-Zeilen die gleichen Whitespaces am Zeilenanfang haben: Python will den ganzen Code in einer Funktion hübsch ausgerichtet haben. +- Wenn du gar keine Ausgabe erhältst, stelle sicher, dass `hallo()` am Datei-Ende *nicht* eingerückt ist. Wenn es eingerückt ist, ist dieser Aufruf selbst Teil der Funktion und sie wird gar nicht ausgeführt. + +Als Nächstes bauen wir Funktionen mit sogenannten Argumenten. Wir werden das gerade gebaute Beispiel benutzen – eine Funktion, die die ausführende Person begrüßt – aber diesmal mit Namen: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hallo(name): +``` + +Wie du siehst, geben wir der Funktion jetzt einen Parameter, den wir `name` nennen: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hallo(name): + if name == 'Ola': + print('Hallo Ola!') + elif name == 'Sonja': + print('Hallo Sonja!') + else: + print('Hallo Unbekannte(r)!') + +hallo() +``` + +Denk daran: Die `print`-Funktion ist 4 Leerzeichen innerhalb der `if`-Anweisung eingerückt. Das ist sinnvoll, da die Funktion ausgeführt wird, wenn die Bedingung eintritt. Mal sehen, wie das jetzt funktioniert: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + + $ python3 python_intro.py + Traceback (most recent call last): + File "python_intro.py", line 10, in + hallo() + TypeError: hallo() missing 1 required positional argument: 'name' + + +Hoppla, ein Fehler. Zum Glück gibt uns Python eine recht nützliche Fehlermeldung. Diese besagt, dass die Funktion `hallo()` (welche wir definiert haben) ein erforderliches Argument (namens `name`) hat und dass wir vergessen haben, dieses beim Funktionsaufruf mitzugeben. Lass uns das am unteren Ende der Datei schnell beheben: + +{% filename %}python_intro.py{% endfilename %} + +```python +hallo("Ola") +``` + +Und wir führen sie erneut aus: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hallo Ola! + + +Und wenn wir den Namen ändern? + +{% filename %}python_intro.py{% endfilename %} + +```python +hallo("Sonja") +``` + +Und ausgeführt: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hallo Sonja! + + +Nun, was denkst du, wird passieren, wenn du einen anderen Namen dort hinein schreibst? (Weder Ola noch Sonja.) Probier es aus und schau, ob du richtig liegst. Es sollte das Folgende herauskommen: + +{% filename %}command-line{% endfilename %} + + Hallo Unbekannte(r)! + + +Das ist genial, oder? Auf diese Weise musst du dich nicht jedesmal wiederholen, wenn du den Namen der Person änderst, die die Funktion grüßen soll. Und das ist genau der Grund, warum wir Funktionen brauchen – du willst auf keinem Fall deinen Code wiederholen! + +Lass uns noch etwas Schlaueres probieren – es gibt schließlich mehr als zwei Namen und für jeden eine eigene Bedingung aufzuschreiben, wäre ziemlich aufwendig, oder? Ersetze also deinen Code in der Datei durch den folgenden: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hallo(name): + print('Hallo ' + name + '!') + +hallo("Rachel") +``` + +Lass uns den Code aufrufen: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hallo Rachel! + + +Herzlichen Glückwunsch! Du hast gerade gelernt, wie du Funktionen schreibst! :) + +## Schleifen + +> Für die Leser zu Hause: Dieses Kapitel wird im Video [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0) behandelt. + +Dies ist bereits der letzte Teil. Das ging doch schnell, oder? :) + +Programmierer wiederholen sich nicht gerne. Beim Programmieren geht es darum, Dinge zu automatisieren. Wir wollen also nicht jede Person mit ihrem Namen manuell grüßen müssen, oder? Für so etwas kommen Schleifen gelegen. + +Erinnerst du dich noch an Listen? Lass uns eine Liste mit Mädchennamen erstellen: + +{% filename %}python_intro.py{% endfilename %} + +```python +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +``` + +Wir wollen alle mit ihrem Namen grüßen. Wir besitzen bereits die `hallo`-Funktion, um dies zu tun, also lass sie uns in einer Schleife verwenden: + +{% filename %}python_intro.py{% endfilename %} + +```python +for name in girls: +``` + +Die `for`-Anweisung verhält sich ähnlich wie die `if`-Anweisung; Code unter beiden muss 4 Leerzeichen eingerückt werden. + +Hier ist der vollständige Code für die Datei: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hallo(name): + print('Hallo ' + name + '!') + +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'du'] +for name in girls: + hallo(name) + print('Nächstes Mädchen') +``` + +Und wenn wir es ausführen: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hallo Rachel! + Nächstes Mädchen + Hallo Monica! + Nächstes Mädchen + Hallo Phoebe! + Nächstes Mädchen + Hallo Ola! + Nächstes Mädchen + Hallo du! + Nächstes Mädchen + + +Wie du sehen kannst, wird alles, was du innerhalb einer `for`-Anweisung eingerückt hast, für jedes Element der Liste `girls` wiederholt. + +Du kannst auch `for` auf Ganzzahlen beziehen, wenn du die `range`-Funktion benutzt: + +{% filename %}python_intro.py{% endfilename %} + +```python +for i in range(1, 6): + print(i) +``` + +Das würde ausgeben: + +{% filename %}command-line{% endfilename %} + + 1 + 2 + 3 + 4 + 5 + + +`range` ist eine Funktion, die eine Liste von aufeinander folgenden Zahlen erschafft (die Randwerte werden von dir als Argumente bereitgestellt). + +Beachte, dass der zweite der Werte, die du als Argumente übergibst, nicht in der Liste enthalten ist, die von Python ausgegeben wird. (Das bedeutet, dass `range(1, 6)` von 1 bis 5 zählt, aber nicht die Zahl 6 enthält). Das liegt daran, dass "range" halboffen ist, was wiederum bedeutet, dass es den ersten Wert enthält, aber nicht den letzten. + +## Zusammenfassung + +Das ist alles. **Du rockst total!** Das war ein kniffliges Kapitel, du darfst also ruhig stolz auf dich sein. Wir sind definitiv stolz auf dich und darauf, dass du es so weit geschafft hast! + +Wenn du zum offiziellen und vollständigen Python-Tutorial willst, besuche https://docs.python.org/3/tutorial/. Dort gibt's (bislang jedoch noch nicht auf Deutsch) eine gründlichere und umfassendere Einführung in diese Programmiersprache. Viel Erfolg! :) + +Bevor du zum nächsten Kapitel übergehst, mach kurz 'was anderes – streck dich, lauf etwas 'rum, ruh' deine Augen aus. :) + +![Cupcake](images/cupcake.png) \ No newline at end of file diff --git a/de/python_introduction/images/cupcake.png b/de/python_introduction/images/cupcake.png new file mode 100644 index 00000000000..8c1820adee8 Binary files /dev/null and b/de/python_introduction/images/cupcake.png differ diff --git a/de/template_extending/README.md b/de/template_extending/README.md new file mode 100644 index 00000000000..5362ae574b6 --- /dev/null +++ b/de/template_extending/README.md @@ -0,0 +1,151 @@ +# Erweiterung der Templates + +Eine weitere praktische Sache von Django ist das **template extending**, Erweiterungen des Templates. Was bedeutet das? Damit kannst du Teile deines HTML-Codes für andere Seiten deiner Website nutzen. + +Templates helfen, wenn du die selben Informationen oder das selbe Layout an mehreren Stellen verwenden willst. Du musst dich so nicht in jeder Datei wiederholen. Und wenn du etwas ändern willst, dann musst du es nicht in jedem einzelnen Template tun, sondern nur in einem! + +## Ein Basis-Template erstellen + +Ein Basis-Template ist das grundlegende Template, welches dann auf jeder einzelnen Seite deiner Website erweitert wird. + +Wir erstellen jetzt eine `base.html`-Datei in `blog/templates/blog/`: + + blog + └───templates +     └───blog +             base.html +             post_list.html + + +Öffne sie im Code-Editor, kopiere alles von `post_list.html` und füge es wie folgt in die `base.html`-Datei ein: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% load static %} + + + + Django Girls blog + + + + + + + +
+
+
+ {% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
+ + +``` + +Dann ersetze in `base.html` den gesamten `` (alles zwischen `` und ``) hiermit: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ +``` + +{% raw %}Vielleicht hast du bemerkt, dass das alles von `{% for post in posts %}` bis `{% endfor %}` mit dem Folgenden ersetzt: {% endraw %} + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% block content %} +{% endblock %} +``` + +Aber warum? Du hast gerade einen `block` erstellt! Du hast den Template-Tag `{% block %}` benutzt, um einen Bereich zu schaffen, der HTML aufnehmen kann. Dieses HTML kommt aus einem anderen Template, welches das Template hier (`base.html`) erweitert. Wir zeigen dir gleich, wie das geht. + +Speichere nun die Datei `base.html` und öffne wieder `blog/templates/blog/post_list.html` im Code-Editor. {% raw %}Du löschst alles oberhalb von `{% for post in posts %}` und unterhalb von `{% endfor %}`. Wenn du das gemacht hast, sieht die Datei so aus:{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` + +Dieser Teil unseres Templates soll nun das Basis-Template erweitern. Wir müssen daher Block-Tags ergänzen! + +{% raw %}Deine Block-Tags müssen mit den Tags in der `base.html`-Datei übereinstimmen. Stelle sicher, dass die Block-Tags den ganzen Code deines content-Blocks umschließen. Um das zu erreichen, umschließt du ihn mit `{% block content %}` und `{% endblock %}`. So hier:{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% block content %} + {% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +Nur eine Sache noch. Wir müssen die beiden Templates miteinander verknüpfen. Darum geht es ja bei der Template-Erweiterung! Dafür ergänzen wir einen Tag für Erweiterung (extends tag) ganz oben in der Datei. Und zwar so: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +Das war's! Speichere die Datei und probier aus, ob deine Website noch richtig funktioniert. :) + +> Wenn du den Fehler `TemplateDoesNotExist` erhältst, dann heißt das, dass es die Datei `blog/base.html` nicht gibt und dass `runserver` in der Konsole läuft. Halte ihn an (durch Drücken von Ctrl+C bzw. Strg+C – Control- und die C-Taste gleichzeitig) und starte ihn neu, indem du den Befehl `python manage.py runserver` ausführst. \ No newline at end of file diff --git a/de/whats_next/README.md b/de/whats_next/README.md new file mode 100644 index 00000000000..caa79e6cb03 --- /dev/null +++ b/de/whats_next/README.md @@ -0,0 +1,43 @@ +# Wie geht es weiter? + +Herzlichen Glückwunsch! **Du bist der Hammer!** Wir sind echt stolz! <3 + +### Was jetzt? + +Mach eine Pause und entspanne! Du hast gerade etwas wirklich Großes geleistet. + +Und dann folge Django Girls doch auf [Facebook](http://facebook.com/djangogirls) oder [Twitter](https://twitter.com/djangogirls), um auf dem Laufenden zu bleiben. + +### Könnt ihr weiteres Lernmaterial empfehlen? + +Ja! Es gibt *sehr* viele Online-Ressourcen zum Erlernen aller möglichen Programmierfähigkeiten – es kann ziemlich entmutigend sein, herauszufinden, was man als Nächstes machen sollte, aber wir helfen dir dabei. Was auch immer du für Interessen hattest, bevor du zu Django Girls gekommen bist und was auch immer du für Interessen während des Tutorials entwickelt hast, hier sind einige kostenfreie Ressourcen (oder solche mit größeren kostenlosen Teilen), die du nutzen kannst, um auf deinem Weg voranzukommen. + +#### Django + +- Unser anderes Buch, [Django Girls Tutorial: Erweiterungen](https://tutorial-extensions.djangogirls.org/) +- [Das offizielle Django-Tutorial](https://docs.djangoproject.com/en/2.2/intro/tutorial01/) +- [Video-Lektionen "Getting Started With Django"](http://www.gettingstartedwithdjango.com/) +- Spezialisierung [Django for Everybody](https://www.coursera.org/specializations/django) – einige Video-Lektionen können kostenlos getestet werden und du kannst ein Coursera-Zertifikat erlangen, wenn du diesen Kurs belegst + +#### HTML, CSS und JavaScript + +- [Web-Development-Kurs auf Codeacademy](https://www.codecademy.com/learn/paths/web-development) +- [freeCodeCamp](https://www.freecodecamp.org/) + +#### Python + +- [Python-Kurs auf Codecademy](https://www.codecademy.com/learn/learn-python) +- [Googles Python-Kurs](https://developers.google.com/edu/python/) +- [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) – die ersten Übungen sind kostenlos +- [New Coder Tutorials](http://newcoder.io/tutorials/) – eine Vielzahl von praktischen Beispielen, wie Python verwendet werden kann +- [edX](https://www.edx.org/course?search_query=python) – die meisten Kurse kannst du kostenfrei testen, aber wenn du ein Zertifikat oder Credits für eine Weiterbildung erhalten willst, dann kostet das etwas +- [Courseras Python-Spezialisierung](https://www.coursera.org/specializations/python) – einige Video-Lektionen können kostenlos getestet werden und du kannst ein Coursera-Zertifikat erlangen, wenn du diesen Kurs belegst +- [Python for Everybody](https://www.py4e.com/) - eine kostenlose und offene Version der Coursera-Python-Spezialisierung + +#### Mit Daten arbeiten + +- [Der Data-Science-Kurs von Codecademy](https://www.codecademy.com/learn/paths/data-science) +- [edX](https://www.edx.org/course/?search_query=python&subject=Data%20Analysis%20%26%20Statistics) – die meisten Kurse kannst du kostenfrei testen, aber wenn du ein Zertifikat oder Credits für eine Weiterbildung erhalten willst, dann kostet das etwas +- [Dataquest](https://www.dataquest.io/) – die ersten 30 "Missionen" sind frei + +Wir sind gespannt darauf, was du als Nächstes baust! \ No newline at end of file diff --git a/el/GLOSSARY.md b/el/GLOSSARY.md new file mode 100644 index 00000000000..b1bce01c323 --- /dev/null +++ b/el/GLOSSARY.md @@ -0,0 +1,3 @@ +# Επεξεργαστής Κώδικα + +Ο επεξεργαστής κώδικα είναι μια εφαρμογή που σου επιτρέπει να επεξεργάζεσαι και να αποθηκεύεις τον κώδικα σου, ώστε να είσαι σε θέση να επιστρέψεις σε αυτό αργότερα. Επίσης σου προσφέρει διάφορα εργαλεία όπως εύκολη αναζήτηση, αυτόματη συμπλήρωση κώδικα, απ' ευθείας μετάβαση σε κάποιο σημείο κλπ. Μπορείς να μάθεις πού μπορείς να βρείς ένα από το [κεφάλαιο επεξεργαστής κώδικα](./code_editor/README.md) \ No newline at end of file diff --git a/el/README.md b/el/README.md new file mode 100644 index 00000000000..447cc87d29b --- /dev/null +++ b/el/README.md @@ -0,0 +1,51 @@ +# Φροντιστήριο Django Girls + +[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial) + +> Αυτό το φροντιστήριο χορηγείται υπό την άδεια χρήσης με το όνομα: Creative Commons Attribution-ShareAlike 4.0 International License. Για να δείτε ένα αντίγραφο αυτής της άδειας χρήσης, επισκεφθείτε τον ακόλουθο σύνδεσμο https://creativecommons.org/licenses/by-sa/4.0/ + +## Καλώς ήρθατε + +Καλώς ήρθατε στο φροντιστήριο Django Girls! Χαιρόμαστε που σε βλέπουμε εδώ :) Σε αυτόν τον οδηγό θα σε πάμε ένα ταξίδι γύρω από τις τεχνολογίες ιστοσελίδων, προσφέροντας σου μία γεύση από όλα τα κομμάτια που πρέπει να συγκεντρωθούν ώστε να κάνουν τον ιστό (με άλλα λόγια το internet) να δουλέψει όπως το γνωρίζουμε. + +Όπως με όλα τα άγνωστα πράγματα, αυτό πρόκειται να είναι άλλη μία εμπειρία για σένα, αλλά μην ανησυχείς, αφού ήδη πήρες την απόφαση να είσαι εδώ, θα είσαι μια χαρά :) + +## Εισαγωγή + +Έχεις νιώσει ποτέ ότι ο κόσμος γίνεται όλο και περισσότερο σχετικός με την τεχνολογία και δεν μπορείς (ακόμα) να συσχετιθείς; Έχεις ποτέ αναρωτηθεί πώς να δημιουργήσεις μια ιστοσελίδα, αλλά ποτέ δεν είχες αρκετό κίνητρο για να ξεκινήσεις; Έχεις ποτέ σκεφτεί οτι ο κόσμος του software είναι πολύ περίπλοκος για σένα για να προσπαθήσεις να κάνεις κάτι από μόνη σου; + +Λοιπόν, έχουμε καλά νέα για σένα! Ο προγραμματισμός δεν είναι τόσο δύσκολος όσο φαίνεται και θέλουμε να σου δείξουμε πόσο διασκεδαστικός μπορεί να είναι. + +Αυτός ο οδηγός δεν θα σε μετατρέψει σε προγραμματιστή ως δια μαγείας. Αν θέλεις να γίνεις καλή προγραμματίστρια, χρειάζεται μήνες ή ακόμη και χρόνια εκμάθησης και πρακτικής εξάσκησης. Όμως θέλουμε να σου δείξουμε οτι ο προγραμματισμός ή η δημιουργία ιστιοσελίδων δεν είναι τόσο περίπλοκο όσο φαίνεται. Θα προσπαθήσουμε να σου εξηγήσουμε τα διάφορα κομμάτια όσο καλύτερα μπορούμε, ούτως ώστε να μην σε φοβίζει η τεχνολογία. + +Ελπίζουμε να μπορέσουμε να σε κάνουμε να αγαπήσεις την τεχνολογία, όπως εμείς! + +## Τι θα μάθεις κατα τη διάρκεια του οδηγού; + +Μόλις ολοκληρώσεις τον οδηγό, θα έχεις μία μικρή λειτουργική εφαρμογή ιστού (web application): το δικό σου blog. Θα σου δείξουμε πως να το ανεβάσεις ηλεκτρονικά, ώστε άλλοι να δουν την δουλειά σου! + +Θα φαίνεται έτσι (πάνω κάτω): + +![Σχήμα 0.1](images/application.png) + +> Αν είσαι μόνος σου χωρίς κάποιον να σε βοηθάει, τότε σε περίπτωση προβλήματος, έχουμε ένα σύστημα συνομιλίας για εσένα: [![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial). Ζητήσαμε από τους προπονητές μας και τους προηγούμενους συμμετάσχοντες να είναι εκεί που και που και να βοηθάνε άλλους με το σεμινάριο! Μην φοβάστε να κάνετε ερωτήσεις εκεί! + +Οκ, [ ας ξεκινήσουμε από την αρχή...](./how_the_internet_works/README.md) + +## Ακολουθώντας τον οδηγό στο σπίτι + +Είναι εκπληκτικό να λάβετε μέρος στο εργαστήριο Django Girls, αλλά γνωρίζουμε ότι δεν είναι πάντα εφικτό να παρακολουθήσετε ένα. Για αυτό σας ενθαρρύνουμε να προσπαθήσετε να ακολουθήσετε αυτό το σεμινάριο στο σπίτι. Για τους αναγνώστες στο σπίτι, προς το παρόν ετοιμάζουμε βίντεο που θα το κάνουν ευκολότερο να παρακολουθήσετε τον οδηγό από μόνοι σας. Είναι ακόμα ένα έργο σε εξέλιξη, αλλά όλο και περισσότερα πράγματα θα καλυφθούν σύντομα στο κανάλι του YouTube [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed). + +Σε κάθε κεφάλαιο που έχει ήδη καλυφθεί, υπάρχει ένας σύνδεσμος που οδηγεί στο αντίστοιχο βίντεο. + +## Σχετικά με μας και πως να συνεισφέρετε + +Αυτό το σεμινάριο συντηρείται από την κοινότητα [DjangoGirls](https://djangogirls.org/). Εάν βρείτε τυχόν λάθη ή θέλετε να ενημερώσετε το φροντιστήριο παρακαλούμε [ακολουθήστε τις οδηγίες για συνεισφορά](https://github.com/DjangoGirls/tutorial/blob/master/README.md). + +## Θα θέλατε να μας βοηθήσετε να μεταφράσετε τον οδηγό σε άλλες γλώσσες; + +Προς το παρόν, οι μεταφράσεις διατηρούνται στην πλατφόρμα του crowdin.com στο: + +https://crowdin.com/project/django-girls-tutorial + +Εάν η γλώσσα σας δεν είναι καταχωρημένη στο [crowdin](https://crowdin.com/), παρακαλούμε [ανοίξτε ένα νέο θέμα](https://github.com/DjangoGirls/tutorial/issues/new) ενημερώνοντας μας για την γλώσσα ώστε να την προσθέσουμε. \ No newline at end of file diff --git a/el/SUMMARY.md b/el/SUMMARY.md new file mode 100644 index 00000000000..fd3f634310a --- /dev/null +++ b/el/SUMMARY.md @@ -0,0 +1,27 @@ +# Περίληψη + +* [Εισαγωγή](README.md) +* [Εγκατάσταση](installation/README.md) +* [Εγκατάσταση (chromebook)](chromebook_setup/README.md) +* [Πως λειτουργεί το διαδίκτυο](how_the_internet_works/README.md) +* [Εισαγωγή στην γραμμή εντολών](intro_to_command_line/README.md) +* [Εγκατάσταση Python](python_installation/README.md) +* [Επεξεργαστής Κώδικα](code_editor/README.md) +* [Εισαγωγή στην Python](python_introduction/README.md) +* [Τι είναι το Django;](django/README.md) +* [Εγκατάσταση του Django](django_installation/README.md) +* [Το πρώτο σου Django project!](django_start_project/README.md) +* [Μοντέλα (models) του Django](django_models/README.md) +* [Διαχείριση μέσω Django admin](django_admin/README.md) +* [Ανεβάστε!](deploy/README.md) +* [Django urls](django_urls/README.md) +* [Django views - ώρα να δημιουργήσετε!](django_views/README.md) +* [Εισαγωγή στην HTML](html/README.md) +* [Django ORM (Querysets)](django_orm/README.md) +* [Δυναμικά δεδομένα στα templates](dynamic_data_in_templates/README.md) +* [Django templates](django_templates/README.md) +* [CSS - κάντε το όμορφο](css/README.md) +* [Επεκτείνοντας τα templates](template_extending/README.md) +* [Επεκτείνοντας την εφαρμογή σας](extend_your_application/README.md) +* [Φόρμες Django](django_forms/README.md) +* [Τι υπάρχει μετά;](whats_next/README.md) \ No newline at end of file diff --git a/el/chromebook_setup/README.md b/el/chromebook_setup/README.md new file mode 100644 index 00000000000..6cb47273d1a --- /dev/null +++ b/el/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# Ρυθμίσεις για χρήστες Chromebook + +> **Σημείωση** Εάν έχετε ήδη τελειώσει με τα βήματα της εγκατάστασης, δεν χρειάζεται να επαναλάβετε αυτή την ενότητα - μπορείτε να πάτε απευθείας στην ενότητα [ Εισαγωγή στην Python](../python_introduction/README.md). + +{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/el/chromebook_setup/instructions.md b/el/chromebook_setup/instructions.md new file mode 100644 index 00000000000..85ac6811b0a --- /dev/null +++ b/el/chromebook_setup/instructions.md @@ -0,0 +1,75 @@ +Μπορείτε [ να παραλείψετε αυτή την ενότητα](http://tutorial.djangogirls.org/en/installation/#install-python) εάν δεν χρησιμοποιείτε το Chromebook. Εάν το χρησιμοποιείτε, η διαδικασία εγκατάστασης θα είναι λίγο διαφορετική. Σε αυτή την περίπτωση μπορείτε να αγνοήσετε τις υπόλοιπες οδηγίες εγκατάστασης. + +### Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9) + +Το CloudIDE είναι ένα εργαλείο το οποίο σου παρέχει έναν επεξεργαστή κώδικα καθώς και πρόσβαση σε έναν υπολογιστή στο internet στον οποίο μπορείς να εγκαταστήσεις, να γράψεις και να τρέξεις το λογισμικό. Κατά τη διάρκεια του οδηγού, το CloudIDE θα παίζει το ρόλο του *local machine* (δηλαδή του τοπικού υπολογιστή σας). Παραταύτα, θα χρειαστεί να γράφετε εντολές στο τερματικό όπως ακριβώς οι συμμαθητές σας που χρησιμοποιούν macOS, Ubuntu ή Windows, με την μόνη διαφορά ότι το τερματικό δεν θα τρέχει στον υπολογιστή που κάθεστε αλλά στο cloud (σύννεφο), εκεί που το όρισε το CloudIDE (σε κάποιον εικονικό υπολογιστή, δηλαδή, στο internet). Εδώ είναι οι οδηγίες για τα cloud IDEs (PaizaCloud Cloud IDE, AWS Cloud9). Μπορείτε να επιλέξετε ένα από τα cloud IDEs και να ακολουθήσετε τις αντίστοιχες οδηγίες του. + +#### PaizaCloud Cloud IDE + +1. Πηγαίνετε στο [PaizaCloud Cloud IDE](https://paiza.cloud/) +2. Δημιούργησε λογαριασμό +3. Κάντε κλικ στο κουμπί *New Server* +4. Κάντε κλικ στο κουμπί Terminal (στην αριστερή πλευρά του παραθύρου) + +Τώρα θα πρέπει να δείτε μια σελίδα με πλαϊνή μπάρα εργασίων και κουμπιά στα αριστερά. Κάντε κλικ στο κουμπί «Terminal» για να ανοίξετε το παράθυρο του τερματικού (ή αλλιώς "κοσνόλα" ή "γραμμή εντολών") όπως παρακάτω: + +{% filename %}Terminal{% endfilename %} + + $ + + +Το τερματικό στο PaizaCloud Cloud IDE είναι έτοιμο να δεχτεί τις εντολές σας. Μπορείτε να αλλάξετε το μέγεθος του παραθύρου ή να το μεγιστοποιήσετε, αν θέλετε. + +#### AWS Cloud9 + +1. Μεταβείτε στο [AWS Cloud9](https://aws.amazon.com/cloud9/) +2. Δημιούργησε λογαριασμό +3. Κάντε κλικ στο κουμπί *Create Environment* + +Τώρα θα πρέπει να δείτε μια σελίδα με πλαϊνή μπάρα εργασίων, ένα μεγάλο κύριο παράθυρο με κείμενο και ένα μικρό παράθυρο στο κάτω μέρος της που μοιάζει κάπως έτσι: + +{% filename %}bash{% endfilename %} + + yourusername:~/workspace $ + + +Αυτή η περιοχή κάτω είναι το *τερματικό*, όπου θα μπορείτε να δίνετε εντολές στον υπολογιστή που έφτιαξε για εσάς το Cloud 9. Μπορείτε να αλλάξετε τις διαστάσεις του παραθύρου ανάλογα τις ανάγκες σας. + +### Εικονικό Περιβάλλον + +Το εικονικό περιβάλλον (επίσης και ως virtualenv - virtual environment) είναι σαν ένα κουτί όπου μπορούμε να βάλουμε μέσα κώδικα για ένα project χωρίς αυτό να αλληλεπιδρά με κώδικα του συστήματος. Τα χρησιμοποιούμε ούτως ώστε κάθε project να έχει τα δικά του κομμάτια κώδικα και έτσι επιτυγχάνουμε απομόνωση των projects. Φανταστείτε να είχατε ένα project που εξαρτάται από την έκδοση Django 2.0 και ένα άλλο που εξαρτάται από το Django 2.1. Πως θα ικανοποιούσατε τις απαιτήσεις κάθε project; Η απάντηση είναι τα virtualenvs! + +Στο τερματικό σας στο κάτω μέρος, γράψτε τα εξής: + +{% filename %}Cloud 9{% endfilename %} + + sudo apt update + sudo apt install python3.6-venv + + +Αν αυτό εξακολουθεί να μην λειτουργεί, θα πρέπει να ζητήσετε βοήθεια από κάπου. + +Στη συνέχεια, τρέξτε τις ακόλουθες εντολές: + +{% filename %}Cloud 9{% endfilename %} + + mkdir djangogirls + cd djangogirls + python3.6 -mvenv myvenv + source myvenv/bin/activate + pip install django~={{ book.django_version }} + + +(παρατήρησε ότι στην τελευταία γραμμή χρησιμοποιούμε μία περισπωμένη, την οποία ακολουθεί ένα ίσον: ~=). + +### GitHub + +Φτιάξε έναν λογαριασμό στο [GitHub](https://github.com). + +### PythonAnywhere + +Ο οδηγός της κοινότητας Django Girls περιλαμβάνει μια ενότητα αυτού που ονομάζεται Deployment (δυστυχώς δεν υπάρχει κάποιος ακριβής ελληνικός όρος, οπότε θα αναφερόμαστε σε αυτόν με την αγγλική λέξη) που είναι η δυνατότητα του να "ανεβάσεις" τον κώδικα σου - αυτόν που είναι γραμμένη η εφαρμογή σου - σε κάποιον διακομιστή (server) ο οποίος είναι προσβάσιμος από όλους, ούτως ώστε οι άλλοι να δουν τη δουλειά σας. + +Αυτό το κομμάτι είναι λίγο περίεργο όταν ακολουθείτε αυτόν τον οδηγό σε ένα Chromebook, δεδομένου ότι χρησιμοποιείτε ήδη έναν υπολογιστή που βρίσκεται στο διαδίκτυο (σε αντίθεση με την περίπτωση του φορητού ή επιτραπέζιου υπολογιστή). Ωστόσο, θεωρείται ακόμα χρήσιμος ο όρος αυτός (deployment), καθώς μπορούμε να αναλογιστούμε το χώρο εργασίας του Cloud 9 ως το «προς εξέλιξη έργο» και την εταιρεία PythonAnywhere ως ένα μέρος για να "ανεβάσουμε" την εργασία μας καθώς αυτή θα ολοκληρώνεται. + +Δημιουργήστε λοιπόν έναν νέο λογαριασμό στο PythonAnywhere ακολουθώντας αυτόν τον σύνδεσμο [www.pythonanywhere.com](https://www.pythonanywhere.com). \ No newline at end of file diff --git a/el/code_editor/README.md b/el/code_editor/README.md new file mode 100644 index 00000000000..816de29e135 --- /dev/null +++ b/el/code_editor/README.md @@ -0,0 +1,11 @@ +# Επεξεργαστής Κώδικα + +> Για τους αναγνώστες στο σπίτι: αυτό το κεφάλαιο καλύπτεται στο [ Εγκαθιστώντας την Python& Πρόγραμμα επεξεργασίας κώδικα](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s)βίντεο. + +Είστε έτοιμοι να γράψετε την πρώτη σας γραμμή κώδικα, οπότε ήρθε η ώρα για να κατεβάσετε ένα πρόγραμμα επεξεργασίας κώδικα (code editor)! + +> **Σημείωση** εάν χρησιμοποιείτε Chromebook, παρακάμψτε αυτό το κεφάλαιο και σιγουρευτείτε ότι ακολουθείτε τις οδηγίες [Εγκατάστασης Chromebook](../chromebook_setup/README.md). Η επιλογή σας ως προς το cloud IDE (PaizaCloud cloud IDE ή AWS Cloud9) περιλαμβάνει ήδη ένα πρόγραμμα επεξεργασίας κώδικα και όταν ανοίγετε ένα αρχείο στο IDE σας από το μενού "Αρχείο", θα χρησιμοποιείτε αυτόματα εκείνον τον επεξεργαστή. +> +> **Σημείωση** Μπορεί να το έχετε ήδη κάνει αυτό νωρίτερα στο κεφάλαιο εγκατάστασης. Αν ναι, μπορείτε να μεταβείτε κατευθείαν στο επόμενο κεφάλαιο! + +{% include "/code_editor/instructions.md" %} \ No newline at end of file diff --git a/el/code_editor/instructions.md b/el/code_editor/instructions.md new file mode 100644 index 00000000000..5c1738d2f37 --- /dev/null +++ b/el/code_editor/instructions.md @@ -0,0 +1,31 @@ +Υπάρχουν πολλά code editors (επεξεργαστές κώδικα) διαθέσιμοι και για αυτό είστε ελεύθεροι να διαλέξετε αυτόν που σας αρέσει περισσότερο (ή ανάλογα την τσέπη σας αν θέλετε να αγοράσετε κάποιον). Οι περισσότεροι προγραμματιστές της Python χρησιμοποιούν περίπλοκα, αλλά εξαιρετικά ισχυρά IDEs (Integrated Development Environments - Ολοκληρωμένα Περιβάλλοντα Ανάπτυξης), όπως το PyCharm. Για αρχάριους, ωστόσο, αυτή η επιλογή είναι ίσως η λιγότερο κατάλληλη· οι συστάσεις μας είναι προγράμματα εξίσου ισχυρά, αλλά πολύ απλούστερα. + +Οι προτάσεις μας φαίνονται παρακάτω αλλά μην διστάσετε να ρωτήσετε τον προπονητή σας ποιες είναι οι προτιμήσεις του. Θα είναι ευκολότερο να σας βοηθήσουν. + +## Gedit + +Το Gedit είναι ένα ανοικτού κώδικα (open source) δωρεάν πρόγραμμα επεξεργασίας (free editor), διαθέσιμο για όλα τα λειτουργικά συστήματα. + +[Κατεβάστε το εδώ](https://wiki.gnome.org/Apps/Gedit#Download) + +## Sublime Text + +Το Sublime Text είναι ένας δημοφιλής επεξεργαστής με μια περίοδο δωρεάν χρήσης (στο πέρας αυτής μπορείτε να εξακολουθείτε να το χρησιμοποιείτε) και είναι διαθέσιμο για όλα τα λειτουργικά συστήματα. + +[Κατεβάστε το εδώ](https://www.sublimetext.com/) + +## Atom + +Το Atom είναι άλλος ένας δημοφιλής επεξεργαστής. Είναι δωρεάν, ανοιχτού κώδικα και διαθέσιμος για Windows, macOS και Linux. Το Atom αναπτύχθηκε από το [GitHub](https://github.com/). + +[Κατεβάστε το εδώ](https://atom.io/) + +## Γιατί χρειαζόμαστε τον Επεξεργαστή Κώδικα; + +Μπορεί να αναρωτιέσαι γιατί εγκαθιστούμε αυτό το ειδικό πρόγραμμα επεξεργασίας κώδικα λογισμικού, αντί να χρησιμοποιήσουμε κάτι σαν το Word ή το Notepad. + +Ο πρώτος λόγος είναι ότι ο κώδικας πρέπει να είναι **απλό κείμενο** (δίχως bold, italic, πίνακες, εικόνες κλπ, όπως θα χρησιμοποιούσε κανείς ένας επεξεργαστή κειμένου). Το πρόβλημα με τα προγράμματα όπως το Word και το Textedit είναι ότι δεν παράγουν στην ουσία απλό κείμενο αλλά "πλούσιο" (με γραμματοσειρές, φορμάρισμα κειμένου και αυτά που αναφέραμε παραπάνω), χρησιμοποιώντας δικές του μορφές όπως [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format). + +Δεύτερον, τα προγράμματα επεξεργασίας κώδικα είναι εξειδικευμένα στην σύνταξη κώδικα ούτως ώστε να μπορούν να παρέχουν χρήσιμα χαρακτηριστικά όπως η επισήμανση κώδικα με χρώμα σύμφωνα με την σημασία του, η αυτόματο κλείσιμο εισαγωγικών κλπ. + +Θα τα δούμε όλα αυτά αργότερα. Σύντομα, θα αρχίσετε να βλέπετε τον παλιό σας, έμπιστο επεξεργαστή κώδικα ως ένα από τα αγαπημένα σας εργαλεία. :) diff --git a/el/css/README.md b/el/css/README.md new file mode 100644 index 00000000000..b1afe88b2d3 --- /dev/null +++ b/el/css/README.md @@ -0,0 +1,305 @@ +# CSS - κάντε το όμορφο! + +Το blog μας φαίνεται αρκετά άσχημο, έτσι δεν είναι; Ωρα να το κάνουμε όμορφο! Γι'αυτή τη δουλειά θα χρειαστούμε το CSS. + +## Τι είναι το CSS; + +Το CSS (Cascading Style Sheets - Διαδοχικά Φύλλα Στυλ) είναι μια γλώσσα που χρησιμοποιείται για να περιγράψει την εμφάνιση και την μορφοποίηση μιας ιστοσελίδας που έχει γραφτεί σε γλώσσα σήμανσης (όπως η HTML). Δείτε το σαν το μακιγιάζ για την ιστοσελίδα μας ;) + +Άλλα δεν θέλουμε να ξεκινήσουμε από την αρχή ξανά, έτσι; Για ακόμα μια φορά θα χρησιμοποιήσουμε κάτι που οι προγραμματιστές χρησιμοποιούν ήδη και είναι δωρεάν στο διαδίκτυο. Το να ανακαλύπτουμε τον τροχό δεν έχει πλάκα, ξέρετε. + +## Ας χρησιμοποιήσουμε το Bootstrap! + +Το Bootstrap είναι μια από τις πιο δημοφιλή HTML / CSS εργαλειοθήκες (framework) που αποσκοπούν στην εύκολη και γρήγορη ανάπτυξη όμορφων ιστοσελίδων: https://getbootstrap.com/ + +Γράφτηκε από προγραμματιστές που εργάστηκαν στο Twitter. Τώρα αναπτύσσεται από εθελοντές από ολόκληρο το κόσμο! + +## Εγκατάσταση του Bootstrap + +Για την εγκατάσταση του Bootstrap, ανοίξτε το αρχείο `.html` στον επεξεργαστή κώδικα και προσθέστε αυτό στην ενότητα ``: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + +``` + +Αυτό δεν προσθέτει κάποια αρχεία στο project σας. Απλώς, δείχνει σε αρχεία που υπάρχουν στο διαδίκτυο. Πηγαίνετε, λοιπόν, επισκεφτείτε την ιστοσελίδα σας και ανανεώστε τη σελίδα. Νάτο! + +![Σχήμα 14.1](images/bootstrap1.png) + +Δείχνει ήδη πολύ καλύτερο! + +## Στατικά αρχεία στο Django + +Τέλος, ας ρίξουμε μια πιο προσεκτική ματιά στα λεγόμενα **στατικά αρχεία**. Τα στατικά αρχεία (static files) είναι όλα τα αρχεία CSS και όλα τα αρχεία εικόνας (φωτογραφίες). Το περιεχόμενο τους δεν εξαρτάται από το εκάστοτε request και έτσι μένει ίδιο για κάθε χρήστη. + +### Πού να τοποθετήσετε τα στατικά αρχεία στο Django + +Το Django ήδη ξέρει πού να βρει τα στατικά αρχεία για την ενσωματωμένη εφαρμογή «admin». Τώρα πρέπει να προσθέσουμε κάποια στατικά αρχεία για την δική μας εφαρμογή, `blog`. + +Για να το κάνουμε αυτό πρέπει να δημιουργήσουμε ένα φάκελο με το όνομα `static` μέσα στο φάκελο blog της εφαρμογής μας: + + djangogirls + ├── blog + │ ├── migrations + │ ├── static + │   └── templates + └── mysite + + +Το Django θα βρίσκει αυτόματα οποιοδήποτε φάκελο ονομάζεται "static" μέσα στους φακέλους οποιασδήποτε εφαρμογή σας. Έπειτα θα μπορεί να χρησιμοποιεί το περιεχόμενο τους ως στατικά αρχεία. + +## Το πρώτο CSS αρχείο σας! + +Ας δημιουργήσουμε ένα CSS αρχείο τώρα, για να προσθέσετε το δικό σας στυλ στην ιστοσελίδα σας. Δημιουργήστε έναν νέο φάκελο που ονομάζεται `css` μέσα στο `static` φάκελο. Στη συνέχεια, δημιουργήστε ένα νέο αρχείο που ονομάζεται `blog.css` μέσα σε αυτόν τον φάκελο `css`. Είστε έτοιμοι; + + djangogirls + └─── blog + └─── static + └─── css + └─── blog.css + + +Ώρα να γράψουμε λίγο CSS! Άνοιξτε το αρχείο `blog/static/css/blog.css` στον επεξεργαστή. + +Δεν θα εμβαθύνουμε πολύ σχετικά με την γλώσσα CSS. Υπάρχει μια πρόταση σχετικά με μάθημα CSS στο τέλος αυτής της σελίδας αν θέλετε να μάθετε περισσότερα. + +Αλλά ας δοκιμάσουμε μερικά πράγματα. Ίσως θα μπορούσαμε να αλλάξουμε το χρώμα των τίτλων της σελίδας μας; Για να καταλάβετε τη λογική των χρωμάτων, οι υπολογιστές χρησιμοποιούν ειδικούς κώδικες. Αυτοί οι κώδικες ξεκινάνε με `#` και ακολουθούνται από 6 γράμματα (A-F) και αριθμούς (0-9). Για παράδειγμα, ο κωδικός για το μπλε είναι `#0000FF`. Μπορείτε να βρείτε τους κωδικούς των χρωμάτων για πολλά χρώματα εδώ: http://www.colorpicker.com/. Μπορείτε επίσης να χρησιμοποιήσετε [προκαθορισμένα χρώματα](http://www.w3schools.com/colors/colors_names.asp) με το αγγλικό όνομά τους, όπως το `red` (κόκκινο) και το `green` (πράσινο). + +Στο αρχείο `blog/static/css/blog.css` πρέπει να προσθέσετε τον παρακάτω κώδικα: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +h1 a, h2 a { + color: #C25100; +} + +``` + +Το `h1 a` είναι ένας επιλογέας CSS (CSS selector). Αυτό σημαίνει ότι θέλουμε να εφαρμόσουμε τα στυλ (στη συγκεκριμένη περίπτωση έχουμε ένα στυλ, το χρώμα) σε κάθε `a` στοιχείο μέσα σε κάθε `h1` στοιχείο. Ο επιλογέας `h2 a` κάνει το ίδιο πράγμα αλλά για τα `h2` στοιχεία. Έτσι όταν έχουμε κάτι σαν `

σύνδεσμο

`, το `h1 a ` στυλ θα εφαρμοστεί. Σε αυτή τη περίπτωση, του λέμε να αλλάξει το χρώμα του σε `#C25100`, που είναι το σκούρο πορτοκαλί. Ή μπορείτε να βάλετε το δικό σας χρώμα εδώ, αλλά σιγουρευτείτε ότι έχει καλή αντίθεση σε λευκό φόντο! + +Μέσα σε ενα αρχείο CSS καθορίζουμε τα στύλ για τα στοιχεία μέσα στο HTML αρχείο. Ο πρώτος τρόπος που αναγνωρίζουμε στοιχεία είναι με το όνομα στοιχείου. Μπορεί να τα θυμάστε αυτά ως ετικέτες από την HTML. Πράγματα όπως `a`, `h1` και το `body` είναι όλα τα παραδείγματα των ονομάτων στοιχείων (HTML elements). Μπορούμε επίσης να προσδιορίσουμε στοιχεία από το χαρακτηριστικό `class` ή το χαρακτηριστικό `id`. Η τάξη (class) και η ταυτότητα (id) είναι ονόματα που δίνεις εσύ στο κάθε στοιχείο. Οι τάξεις αναφέρονται σε ομάδες στοιχείων και οι ταυτότητες σε συγκεκριμένα στοιχεία. Για παράδειγμα, το ακόλουθο tag μπορεί να προσδιοριστεί απο την CSS χρησιμοποιώντας το όνομα του tag `a`, την class `external_link`, ή το id `link_to_wiki_page`: + +```html + +``` + +Διαβάστε περισσότερα για τους επιλογείς CSS στο [w3schools](http://www.w3schools.com/cssref/css_selectors.asp). + +Στη συνέχεια, πρέπει να πούμε στο HTML αρχείο οτι θέλουμε να συμπεριλάβουμε αρχείο/α CSS. Ανοίξτε το αρχείο `blog/templates/blog/post_list.html` και προσθέστε αυτή τη γραμμή στην αρχή: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% load static %} +``` + +Απλά "φορτώνουμε" στατικά αρχεία σε αυτό το σημείο :) Μεταξύ του `` και `` ετικετών (tags), μετά τα links με τα Bootstrap αρχεία CSS, προσθέστε αυτή τη γραμμή: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +Ο browser διαβάζει τα αρχεία με την σειρά που δίνονται, οπότε πρέπει να σιγουρευτούμε ότι αυτή είναι η σωστή θέση. Διαφορετικά ο κώδικας στο αρχείο μας μπορεί να παρακαμφθεί από τον κώδικα στα αρχεία Bootstrap. Μόλις είπαμε στο template μας που βρίσκεται το CSS αρχείο μας. + +Το αρχείο σας πρέπει τώρα να μοιάζει κάπως έτσι: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% load static %} + + + Django Girls blog + + + + + + + + {% for post in posts %} +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} + + +``` + +Εντάξει, αποθηκεύστε το αρχείο και ανανεώστε τη σελίδα! + +![Σχήμα 14.2](images/color2.png) + +Πολύ καλά! Θα θέλατε να δώσουμε λίγο αέρα στην ιστοσελίδα μας και να αυξήσουμε το περιθώριο στα αριστερά; Ας το δοκιμάσουμε! + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +body { + padding-left: 15px; +} +``` + +Προσθέστε αυτό στο CSS σας, αποθηκεύστε τον αρχείο και δείτε πως λειτουργεί! + +![Σχήμα 14.3](images/margin2.png) + +'Ισως μπορούμε να αλλάξουμε την γραμματοσειρά της επικεφαλίδας μας. Μεσα στο `` που βρίσκεται μεσα στο αρχείο `blog/templates/blog/post_list.html` βάλτε αυτό: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +Όπως πριν, ελέγξτε τη σειρά και τοποθετήστε το πριν τον σύνδεσμο `blog/static/css/blog.css`. Αυτή η γραμμή θα εισάγει μια γραμματοσειρά που λέγεται *Lobster* από τα Google Fonts (https://www.google.com/fonts). + +Βρείτε το `h1 a` μπλοκ (τον κώδικα μεταξύ `{` και `}`) μέσα στο αρχείο CSS `blog/static/css/blog.css`. Τώρα προσθέστε την γραμμή `font-family: 'Lobster';` μεταξύ των αγκύλων και ανανεώστε τη σελίδα: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +h1 a, h2 a { + color: #C25100; + font-family: 'Lobster'; +} +``` + +![Σχήμα 14.3](images/font.png) + +Τέλεια! + +Όπως αναφέρθηκε παραπάνω, το CSS έχει την έννοια των κλάσεων (classes). Αυτές σας επιτρέπουν να ονομάσετε ένα μέρος του κώδικα HTML και να εφαρμόσετε στυλ μόνο σε αυτό το μέρος, χωρίς να επηρεάσετε άλλα μέρη. Αυτό μπορεί να είναι εξαιρετικά χρήσιμο! Ίσως να έχετε δύο divs τα οποία περιγράφουν κάτι διαφορετικό το καθένα (όπως πχ μια επικεφαλίδα και ένα post). Μια class μπορεί να σας βοηθήσει να τα κάνετε να μοιάζουν διαφορετικά. + +Πηγαίνετε λοιπόν και ονομάστε μερικά μέρη του HTML. Πρόσθεσε μια κλάση μεε το όνομα `page-header` στο `div` που περιέχει την επικεφαλίδα σας. Κάπως έτσι: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +Και τώρα προσθέστε μια κλάση `post` στο `div` που περιέχει ένα blog post. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+``` + +Τώρα θα προσθέσουμε κώδικα στους επιλογείς (selectors) που μόλις δημιουργήσαμε. Οι επιλογείς που ξεκινούν με `.` αναφέρονται σε κλάσεις. Υπάρχουν πολλοί σπουδαίοι οδηγοί (tutorials) και εξηγήσεις σχετικά με το CSS στο διαδίκτυο τα οποία θα σας βοηθήσουν να καταλάβετε τον παρακάτω κώδικα. Για αρχή, αντιγράψτε το στο αρχείο `blog/static/css/blog.css`: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +.page-header { + background-color: #C25100; + margin-top: 0; + padding: 20px 20px 20px 40px; +} + +.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 { + font-family: 'Lobster', cursive; +} + +.date { + color: #828282; +} + +.save { + float: right; +} + +.post-form textarea, .post-form input { + width: 100%; +} + +.top-menu, .top-menu:hover, .top-menu:visited { + color: #ffffff; + float: right; + font-size: 26pt; + margin-right: 20px; +} + +.post { + margin-bottom: 70px; +} + +.post h1 a, .post h1 a:visited { + color: #000000; +} +``` + +Μετά, περιβάλλετε τον κώδικα HTML που προβάλει τα posts με κλάσεις. Αντικατάστησε αυτό: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} +
+

published: {{ post.published_date }}

+

{{ 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.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
+``` + +Αποθήκευσε τα αρχεία και ανανέωστε την ιστοσελίδα σας. + +![Σχήμα 14.4](images/final.png) + +Ουάου! Φαίνεται τέλειο, έτσι δεν είναι; Κοιτάξτε τον κώδικα που μόλις κάναμε επικόλληση για να βρείτε τα σημεία που προσθέσαμε κλάσεις στην HTML και τις χρησιμοποιήσαμε στο CSS. Που θα κάνατε την αλλαγή αν θέλατε την ημερομηνία να είναι τιρκουάζ; + +Μην φοβάστε να πειραματιστείτε με το CSS λίγο και να προσπαθήσετε να αλλάξετε μερικά πράγματα. Παίζοντας με το CSS μπορεί να σε κάνει να καταλάβεις τι κάνουν τα διάφορα πράγματα. Εάν κάτι πάει στραβά μην ανησυχείτε - μπορείτε πάντα να το αναιρέσετε! + +Συστήνουμε να πάρετε αυτή την δωρεάν online σειρά μαθημάτων [Codeacademy HTML &](https://www.codecademy.com/tracks/web). Μπορεί να σας βοηθήσει να μάθετε τα πάντα σχετικά με το να κάνεις τις ιστοσελίδες σας ομορφότερες με το CSS. + +Είστε έτοιμοι για το επόμενο κεφάλαιο; :) \ No newline at end of file diff --git a/el/css/images/bootstrap1.png b/el/css/images/bootstrap1.png new file mode 100644 index 00000000000..bd81cd14373 Binary files /dev/null and b/el/css/images/bootstrap1.png differ diff --git a/el/css/images/color2.png b/el/css/images/color2.png new file mode 100644 index 00000000000..3f82e7d3922 Binary files /dev/null and b/el/css/images/color2.png differ diff --git a/el/css/images/final.png b/el/css/images/final.png new file mode 100644 index 00000000000..067c83d36cc Binary files /dev/null and b/el/css/images/final.png differ diff --git a/el/css/images/font.png b/el/css/images/font.png new file mode 100644 index 00000000000..310f9e85f18 Binary files /dev/null and b/el/css/images/font.png differ diff --git a/el/css/images/margin2.png b/el/css/images/margin2.png new file mode 100644 index 00000000000..895828b688d Binary files /dev/null and b/el/css/images/margin2.png differ diff --git a/el/deploy/README.md b/el/deploy/README.md new file mode 100644 index 00000000000..80c17ae0d61 --- /dev/null +++ b/el/deploy/README.md @@ -0,0 +1,220 @@ +# Ανεβάστε! + +> **Σημείωση** Το ακόλουθο κεφάλαιο μπορεί να είναι μερικές φορές λίγο δύσκολο να ολοκληρωθεί. Επιμένετε και τελειώστε το, το ανέβασμα είναι ένα σημαντικό μέρος της διαδικασίας ανάπτυξης της ιστοσελίδας. Άλλωστε όταν αναπτύσετε ένα website θα θέλατε στο τέλος να το δει όλος ο κόσμος, όχι μόνο εσείς στον υπολογιστή σας. Το κεφάλαιο αυτό τοποθετείται στη μέση του οδηγού, έτσι ώστε ο μέντορας σας να μπορεί να σας βοηθήσει με την περίπλοκη διαδικασία του "ανεβάσματος" της ιστοσελίδας στο διαδίκτυο. Αυτό σημαίνει ότι μπορείτε ακόμη να ολοκληρώσετε τον οδηγό μόνοι σας ακόμα και αν σας τελειώσει ο χρόνος. + +Μέχρι τώρα, η ιστοσελίδα σου ήταν μόνο διαθέσιμη στον υπολογιστή σου. Τώρα θα μάθεις πως να την ανεβάσεις σε κάποιον server! "Ανεβάζω στο server" (ή άλλιώς deploy) είναι η διαδικασία της δημοσίευσης την εφαρμογής σας στο διαδίκτυο, έτσι ώστε οι άνθρωποι τελικά να πάνε και να δουν την εφαρμογή σας (μέσα από κάποιο url, πχ https://www.mypage. gr). :) + +Όπως μάθατε, μια ιστοσελίδα πρέπει να βρίσκεται σε ένα διακομιστή (server). Υπάρχουν εκατοντάδες υπηρεσίες διακομιστών (server providers) εκεί έξω. Εμείς θα χρησιμοποιήσουμε το [PythonAnywhere](https://www.pythonanywhere.com/). Το PythonAnywhere είναι δωρεάν για μικρές εφαρμογές που δεν έχουν πολλούς επισκέπτες, καθιστώντας το ιδανικό για την περίπτωση μας. + +Η άλλη υπηρεσία που θα χρησιμοποιήσουμε είναι το [GitHub](https://www.github.com), το οποίο είναι μια υπηρεσία φιλοξενίας κώδικα. Υπάρχουν και άλλες υπηρεσίες φιλοξενίας κώδικα εκεί έξω (όπως το BitBucket και άλλες), αλλά σχεδόν όλοι οι προγραμματιστές έχουν λογαριασμό GitHub αυτές τις μέρες όπως και εσείς τώρα! + +Αυτά τα τρία μέρη θα είναι σημαντικά για εσάς. Ο τοπικός σας υπολογιστής θα είναι το μέρος όπου θα κάνετε ανάπτυξη και δοκιμή. Όταν είστε ικανοποιημένοι με τις αλλαγές, θα τοποθετήσετε ένα αντίγραφο του προγράμματος σας στο GitHub. Η ιστοσελίδα σας θα είναι στο PythonAnywhere και θα την ενημερώσετε με το να πάρετε ένα καινούριο αντίγραφο του κωδικού σας από το GitHub. + +# Git + +> **Σημείωση** Αν κάνατε ήδη τα βήματα εγκατάστασης, δεν χρειάζεται να τα ξανακάνετε. Μπορείτε να μεταβείτε στην επόμενη ενότητα και να ξεκινήσετε να δημιουργήσετε GitHub repository σας (ή με μια λέξη, repo). + +{% include "/deploy/install_git.md" %} + +## Ξεκινώντας με το Git repo + +Το Git παρακολουθεί τις αλλαγές σε ένα συγκεκριμένο σύνολο αρχείων που αποκαλείται αρχείο αποθήκευσης κώδικα (ή «repo» εν συντομία, όπως είπαμε παραπάνω). Ας δημιουργήσουμε ένα για την εφαρμογή μας. Ανοίξτε την κονσόλα σας, μεταβείτε στον φάκελο`djangogirls` και εκτελέστε αυτές τις εντολές: + +> **Σημείωση** Ελέγξτε που βρίσκεστε στην κονσόλα (δηλαδή σε ποιον φάκελο) με την εντολή `pwd` (macOS/Linux) ή `cd` (Windows) πριν αρχικοποιήσετε το repo σας. Θα πρέπει να βρίσκεστε στο φάκελο `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 + + +Η αρχικοποίηση του repo είναι κάτι που πρέπει να γίνεται μόνο μια φορά ανά project (δίχως να χρειάζεται να εισάγετε το όνομα χρήστη και το email σας, ποτέ ξανά). + +Το Git θα παρακολουθήσει τις αλλαγές σε όλα τα αρχεία και τους φακέλους σε αυτόν τον φάκελο (σε αυτό το project). Ωστόσο υπάρχουν ορισμένα αρχεία που θέλουμε να τα αγνοήσει και να μην συμπεριληφθούν στο repo. Το κάνουμε αυτό δημιουργώντας ένα αρχείο που ονομάζεται `.gitignore` στον αρχικό φάκελο. Ανοίξτε το πρόγραμμα επεξεργασίας κειμένου και δημιουργήστε ένα νέο αρχείο με το ακόλουθο περιεχόμενο: + +{% filename %}.gitignore{% endfilename %} + + *.pyc + *~ + __pycache__ + myvenv + db.sqlite3 + /static + .DS_Store + + +Αποθηκεύστε το ως `.gitignore` μέσα στον φάκελο "djangogirls". + +> **Σημείωση** Η τελεία στην αρχή του ονόματος του αρχείου είναι σημαντική! Αν έχετε κάποιο πρόβλημα στη δημιουργία του (στο Finder, για παράδειγμα, των Mac υπολογιστών, δεν αρέσει να δημιουργούνται αρχεία με την τελεία ως πρώτο χαρακτήρα), τότε χρησιμοποιήστε το "Αποθήκευση ως...". Σιγουρευτείτε, πάντως, να μην προσθέσετε `.txt`, `.py`, ή οποιοδήποτε άλλη κατάληξη στο όνομα του αρχείου. Θα αναγνωριστεί από το Git μόνο αν το όνομα του είναι ακριβώς `.gitignore`. +> +> **Σημείωση** Ένα από τα ονόματα αρχείων που συμπεριλάβατε στο αρχείο `.gitignore` είναι το αρχείο `db.sqlite3`. Αυτό το αρχείο είναι μια τοπική βάση δεδομένων (database), όπου όλοι οι χρήστες και τα posts σας είναι αποθηκευμένα. Ακολουθούμε μια κοινή πρακτική όσον αφορά τον προγραμματισμό ιστού (web programming) η οποία απαιτεί την χρήση ξεχωριστής βάσης δεδομένων τοπικά στον υπολογιστή μας και στον server όπου θα ανεβάσουμε την εφαρμογή μας (PythonAnywhere). Η βάση δεδομένων του PythonAnywhere θα μπορούσε να είναι και αυτή SQLite, όπως στον υπολογιστή σας αλλά συχνά θα χρησιμοποιείτε μια πιο ευρέως διαδεδομένη και εμπλουτισμένη με πιο πολλά χαρακτηριστικά και δυνατότητες όπως η PostgresQL ή η MySQL. Όπως και να 'χει, μη συμπεριλαμβάνοντας την SQLite βάση στο repo, σημαίνει ότι όλα τα posts και οι χρήστες που δημιουργήσατε μέχρι τώρα θα είναι διαθέσιμα τοπικά στον υπολογιστή σας και θα χρειαστεί να τα ξαναδημιουργήσετε όταν ανεβάσετε το project σας. Να σκέφτεστε την τοπική βάση δεδομένων σας ως ένα παιδότοπο όπου μπορείτε να δοκιμάσετε διαφορετικά πράγματα και να μην φοβάστε ότι πρόκειται να διαγράψετε τις αληθινές σας δημοσιεύσεις από το blog σας. + +Είναι καλή ιδέα να χρησιμοποιήσετε την εντολή `git status` πριν από την εντολή`git add` ή όποτε δεν είστε βέβαιοι για το τι έχει αλλάξει. Αυτό θα βοηθήσει να αποτραπούν οποιεσδήποτε εκπλήξεις, όπως το να προστεθούν ή να αποθηκευτούν λανθασμένα αρχεία. Η εντολή `git status` επιστρέφει πληροφορίες σχετικά με το ποια αρχεία είναι untracked/modified/staged files, το status του branch και πολλές ακόμη πληροφορίες. Η έξοδος πρέπει να είναι παρόμοια με τα ακόλουθα: + +{% filename %}command-line{% endfilename %} + + $ git status + On branch master + + Initial commit + + 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) + + +Και τέλος αποθηκεύουμε τις αλλαγές μας. Πηγαίνετε στην κονσόλα σας και εκτελέστε αυτές τις εντολές: + +{% filename %}command-line{% endfilename %} + + $ git add --all . + $ git commit -m "My Django Girls app, first commit" + [...] + 13 files changed, 200 insertions(+) + create mode 100644 .gitignore + [...] + create mode 100644 mysite/wsgi.py + + +## Ανεβάζοντας τον κώδικα σας στο GitHub + +Πηγαίνετε στο [https://github.com](https://www.github.com) και δημιουργήστε έναν δωρεάν λογαριασμό. (Αν το έχετε ήδη κάνει αυτό, τέλεια!). Σιγουρευτείτε ότι θυμάστε τον κωδικό πρόσβασης σας (προσθέστε τον σε κάποιον διαχειριστή κωδικών πρόσβασης, αν έχετε κάποιον). + +Έπειτα, δημιουργήστε ένα νέο repo, δίνοντας του το όνομα "my-first-blog". Αφήστε το κουτάκι "initialize with a README" κενό. Αφήστε, επίσης την επιλογή .gitignore κενή (το έχουμε ήδη αυτό το αρχείο) και τέλος αφήστε το License ως None. + +![](images/new_github_repo.png) + +> **Σημείωση** Το όνομα `my-first-blog` είναι σημαντικό. Θα μπορούσατε να διαλέξετε ένα άλλο, αλλά επειδή θα το χρησιμοποιείτε αρκετά στις ακόλουθες εντολές, καλό να είναι χρησιμοποιήσετε το ίδιο εκτός και αν είστε λάτρης του πληκτρολογίου και σας αρέσει να γράφετε! Είναι πιο εύκολο να μείνετε με το όνομα `my-first-blog`. + +Στην επόμενη οθόνη θα δείτε το url (την διεύθυνση) του repo σας την οποία θα χρησιμοποιήσουμε παρακάτω: + +![](images/github_get_repo_url_screenshot.png) + +Τώρα το μόνο που μένει είναι να συνδέσουμε το τοπικό repo μας με το remote (απομακρυσμένο). + +Πληκτρολογήστε τα ακόλουθα στην κονσόλα σας (αντικαταστήστε το `` με το όνομα χρήστη σας στο GitHub αλλά χωρίς τα "<>". Το url θα πρέπει να είναι το ίδιο με το url που είδατε πριν: + +{% filename %}command-line{% endfilename %} + + $ git remote add origin https://github.com//my-first-blog.git + $ git push -u origin master + + +Όταν ανεβάζετε στο GitHub, θα ερωτηθείτε για το όνομα χρήστη και τον κωδικό πρόσβασης σας (είτε μέσω κονσόλας είτε μέσω ενός χωριστού παράθυρου). Αφού τα εισάγετε, θα δείτε κάτι σαν το παρακάτω: + +{% filename %}command-line{% endfilename %} + + 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/ola/my-first-blog.git + + * [new branch] master -> master + Branch master set up to track remote branch master from origin. + + + + +Ο κώδικας σας είναι πλέον στο GitHub. Πηγαίνετε να τον δείτε! Θα διαπιστώσετε ότι και άλλο δημοφιλή ανοιχτού λογισμικού projects φιλοξενούνται στο GitHub, όπως το ίδιο το [Django](https://github.com/django/django), το [Django Girls Tutorial](https://github.com/DjangoGirls/tutorial) και άλλα πολλά. :) + +# Ανεβάζοντας το blog μας στο PythonAnywhere + +## Δημιουργήστε έναν δωρεάν λογαριασμό στο PythonAnywhere + +> **Σημείωση** Αν έχετε δημιουργήσει ήδη έναν τότε παραλείψτε αυτό το βήμα. + +{% include "/deploy/signup_pythonanywhere.md" %} + +## Παραμετροποιώντας το site μας στο PythonAnywhere + +Μεταβείτε πίσω στο [PythonAnywhere Dashboard](https://www.pythonanywhere.com/) κλικάροντας στο logo και επιλέξτε να εκκινήσετε μια κονσόλα "Bash". Αυτή είναι η έκδοση της κονσόλας του PythonAnywhere σαν και αυτή που έχετε στον υπολογιστή σας. + +![Η ενότητα 'New Console' στο PythonAnywhere με ένα κουμπί για το 'bash'](images/pythonanywhere_bash_console.png) + +> **Σημείωση** Το PythonAnywhere είναι βασισμένο στο Linux, οπότε αν τρέχετε Windows, η κονσόλα ίσως να σας φανεί διαφορετική από αυτή που έχετε συνηθίσει. + +Η διαδικασία του ανεβάσματος της εφαρμογή σας (το blog) στο PythonAnywhere περιλαμβάνει τα εξής βήματα: το PythonAnywhere να μπορεί να "διαβάσει" τον κώδικα σας στο GitHub, να τον "κατεβάσει" και να τον αποθηκεύσει σε κάποιον από τους σκληρούς του δίσκους (pull) και στο τέλος να κάνει serve την εφαρμογή αυτή. Υπάρχουν οι χειροκίνητοι τρόποι για να επιτευχθούν αυτά τα βήματα αλλά το PythonAnywhere προσφέρει εργαλεία για αυτόν ακριβώς το λόγο. Ας το εγκαταστήσουμε πρώτα: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ pip3.6 install --user pythonanywhere + + +Αυτό θα εμφανίσει κάτι σαν `Collecting pythonanywhere` και στο τέλος θα τελειώσει με μια γραμμή η οποία θα λέει `Successfully installed (...) pythonanywhere- (...)`. + +Τώρα θα τρέξουμε το βοηθητικό εργαλείο ούτως ώστε να παραμετροποιήσει την εφαρμογή μας από το GitHub. Πληκτρολογήστε τα ακόλουθα στην κονσόλα του PythonAnywhere (μην ξεχάσετε να χρησιμοποιήσετε αντί του `` το όνομα χρήστη σας του GitHub ούτως ώστε τα urls να είναι τα ίδια): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ pa_autoconfigure_django.py https://github.com//my-first-blog.git + + +Μπορείτε να βλέπετε τι γίνεται καθώς το πρόγραμμα τρέχει: + +- Κατεβάζει τον κώδικα σας από το GitHub +- Δημιουργεί ένα virtualenv στο PythonAnywhere όπως ακριβώς αυτό στον υπολογιστή σας +- Εμπλουτίζει το αρχείο settings.py με κάποιες ρυθμίσεις για το deployment +- Ρυθμίζει τη βάση δεδομένων στο PythonAnywhere χρησιμοποιώντας την εντολή `manage.py migrate` +- Ρυθμίζει τα στατικά αρχεία (θα μάθουμε γι'αυτά αργότερα) +- Τέλος ρυθμίζει το PythonAnywhere για να εξυπηρετήσει την εφαρμογή σας + +Παρόλο που στο PythonAnywhere όλα αυτά τα βήματα είναι αυτοματοποιημένα, όλα αυτά δεν αλλάζουν αν επιλέξετε κάποιον άλλον server provider. + +Αυτό που πρέπει να τονίσουμε είναι ότι η βάση δεδομένων στο PythonAnywhere είναι διαφορετική από αυτήν στον υπολογιστή σας. Ως αποτέλεσμα αυτού, θα χρειαστεί να αρχικοποιήσουμε τον λογαριασμό διαχειριστή με την εντολή `createsuperuser`. Το PythonAnywhere έχει ενεργοποιήσει το virtualenv για σας, οπότε το μόνο που μένει είναι να τρέξουμε: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + (ola.pythonanywhere.com) $ python manage.py createsuperuser + + +Εισάγετε τα στοιχεία του χρήστη admin. Καλό είναι να χρησιμοποιήσετε τα ίδια με αυτά στον τοπικό υπολογιστή σας για να μην μπερδεύεστε εκτός και αν θέλετε να κάνετε να φτιάξετε ένα πιο ρεαλιστικό σενάριο όπου ο κωδικός αυτός θα πρέπει να είναι πιο δύσκολος ως προς την μαντεψιά. + +Τώρα, αν θέλετε, μπορείτε να δείτε τον κώδικα σας στο PythonAnywhere δίνοντας την εντολή `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 forms.py migrations models.py static + templates tests.py urls.py views.py + + +Μπορείτε, επίσης, να μεταβείτε στη σελίδα "Files" και απο κει να περιηγηθείτε χρησιμοποιώντας τον browser του PythonAnywhere. (Από την σελίδα Console, μπορείτε να μεταβείτε στις άλλες σελίδες του PythonAnywhere από το κουμπί menu στην πάνω δεξιά γωνία. Μόλις είστε σε μία από τις σελίδες, υπάρχουν συνδέσεις με τις άλλες πάνω στην κορυφή.) + +## Τώρα είστε ζωντανά! + +Το site σας είναι πλεόν deployed! Κλικάρετε στη σελίδα "Web" του PythonAnywhere για να αποκτήσετε το url σας. Μπορείτε να το μοιραστείτε με όποιον θέλετε :) + +> **Σημείωση** Αυτός είναι ένας οδηγός για αρχάριους και κατά τη διάρκεια του deploying παρακάμψαμε κάποια βήματα τα οποία είναι πολύ σημαντικά από άποψη ασφάλειας. Αν και όταν θελήσετε να εμπλουτίσετε ή να φτιάξετε ένα νέο project αλλά πιο σοβαρό αυτή τη φορά, καλό θα ήταν να συμβουλευτείτε το [Django deployment checklist](https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/) για μερικές συμβουλές ασφάλειας. + +## Συμβουλές debugging + +Αν λάβετε κάποιο σφάλμα καθώς τρέχετε το script `pa_autoconfigure_django.py`, δείτε τα ακόλουθα: + +- Έχετε ξεχάσει να δημιουργήσετε ένα PythonAnywhere API token. +- Έχετε κάνει λάθος στο GitHub URL +- Αν δείτε ένα σφάλμα που λέει *«Could not find your settings.py»*, είναι πιθανώς επειδή δεν συμπεριλάβατε όλα τα αρχεία σας στο repo ή/και δεν έχετε κάνει push τις αλλαγές σας στο GitHub επιτυχώς. Δείτε ξανά την ενότητα Git παραπάνω + +Αν δείτε ένα σφάλμα όταν προσπαθείτε να επισκεφθείτε την ιστοσελίδα σας, το πρώτο μέρος για debbuging είναι το αρχείο **error log**. Θα βρείτε ένα σύνδεσμο για το error log στο ["Web" page](https://www.pythonanywhere.com/web_app_setup/) του PythonAnywhere. Δείτε εάν υπάρχουν μηνύματα σφάλματος εκεί. Τα πιο πρόσφατα είναι στο κάτω μέρος. + +Υπάρχουν επίσης ορισμένες [γενικές συμβουλές εντοπισμού σφαλμάτων στο PythonAnywhere](http://help.pythonanywhere.com/pages/DebuggingImportError). + +Και θυμηθείτε, ο εκπαιδευτής σας είναι είδω να σας βοηθήσει! + +# Δείτε το site σας! + +Η αρχική σελίδα του site σας θα λέει "Δούλεψε", όπως ακριβώς εμφανίστηκε στον υπολογιστή σας. Μεταβείτε στη διαχειριστική σελίδα προσθέτοντας το `/admin/` στο τέλος του URL. Κάντε login χρησιμοποιώντας το όνομα χρήστη και τον κωδικό σας και θα δείτε την γνώριμη σελίδα που σας επιτρέπει να προσθέστε χρήστες, posts και άλλα. Θημηθείτε, ο λόγος που δεν βλέπετε τα posts σας είναι διότι η βάση δεδομένων στο PythonAnywhere είναι "κενή" από αυτή του τοπικού υπολογιστή σας. + +Μόλις δημιουργήσετε μερικά posts, πηγαίνετε πάλι στην αρχική σελίδα του site σας. Από αυτό εδώ το σημείο και ύστερα θα πρέπει να εργάζεστε πρώτα τοπικά στον υπολογιστή σας για τυχόν αλλαγές και μετά να τις ανεβάζετε στον server. Αυτό είναι μια κοινή καλή πρακτική. Όταν λέμε αλλαγές, δεν εννοούμε προσθήκη posts, users κλπ αλλά αλλαγές στον κώδικα. Αυτό επιτρέπει να εργάζεστε και να πειραματίζεστε τοπικά δίχως να χαλάσετε κάτι στο site σας που είναι στον αέρα. Πολύ καλό, εε; + +Πείτε στον εαυτό σας ένα *ΜΕΓΑΛΟ* "ΣΥΓΧΑΡΗΤΗΡΙΑ"! Το ανέβασμα σε κάποιον server αποτελεί ένα από τα δυσκολότερα βήματα του web development και συνήθως παίρνει αρκετές μέρες για να επιτευχθεί. Όμως εσείς έχετε το site σας live, στο internet! \ No newline at end of file diff --git a/el/deploy/images/github_get_repo_url_screenshot.png b/el/deploy/images/github_get_repo_url_screenshot.png new file mode 100644 index 00000000000..ee1560b1e85 Binary files /dev/null and b/el/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/el/deploy/images/new_github_repo.png b/el/deploy/images/new_github_repo.png new file mode 100644 index 00000000000..d1f82e5d863 Binary files /dev/null and b/el/deploy/images/new_github_repo.png differ diff --git a/el/deploy/images/pythonanywhere_account.png b/el/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/el/deploy/images/pythonanywhere_account.png differ diff --git a/el/deploy/images/pythonanywhere_bash_console.png b/el/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..458b43f5d0d Binary files /dev/null and b/el/deploy/images/pythonanywhere_bash_console.png differ diff --git a/el/deploy/images/pythonanywhere_beginner_account_button.png b/el/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/el/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/el/deploy/images/pythonanywhere_create_api_token.png b/el/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..6e617d0a53e Binary files /dev/null and b/el/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/el/deploy/install_git.md b/el/deploy/install_git.md new file mode 100644 index 00000000000..93ff5b1c4ee --- /dev/null +++ b/el/deploy/install_git.md @@ -0,0 +1,52 @@ +Το Git είναι ένα «σύστημα ελέγχου έκδοσης» και χρησιμοποιείται από πολλούς προγραμματιστές. Αυτό το εργαλείο μπορεί να παρακολουθήσει τις αλλαγές στα αρχεία με την πάροδο του χρόνου έτσι ώστε να μπορείτε να ανακαλέσετε συγκεκριμένες εκδόσεις σε μεταγενέστερο στάδιο. Είναι κάπως σαν την δυνατότητα "παρακολούθηση αλλαγών" σε προγράμματα επεξεργασίας κειμένου (όπως το Microsoft Word ή το LibreOffice Writer) αλλά πολύ πιο δυνατό. + +## Εγκαθιστώντας το Git + + + +Μπορείτε να κατεβάσετε το Git από το [git-scm.com](https://git-scm.com/). Μπορείτε να πατάτε "επόμενο" σε όλα τα στάδια εκτός από δύο: στο στάδιο που ρωτάει για τον προτιμώμενο επεξεργαστή κειμένου θα πρέπει να επιλέξετε το Nano και στο στάδιο με το όνομα "Adjusting your PATH environment", θα πρέπει να επιλέξετε το "Use Git and optional Unix tools from the Windows Command Prompt" (την τελευταία επιλογή). Εκτός από αυτό, οι προκαθορισμένες ρυθμίσεις είναι μια χαρά. Επίσης, οι επιλογές Checkout Windows-style και Commit Unix-style είναι μια χαρά. + +Μη ξεχάσετε να επανεκκινήσετε τη γραμμή εντολών ή το PowerShell μετά την επιτυχής εγκατάσταση. + + + +Κατεβάστε το Git από το [git-scm.com](https://git-scm.com/) και ακολουθήστε τις οδηγίες. + +> **Σημείωση** Αν έχετε OS X 10.6, 10.7, ή 10.8, θα χρειαστεί να εγκαταστήσετε την έκδοση του git από εδώ: [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) + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo apt install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo dnf install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo zypper install git +``` + + \ No newline at end of file diff --git a/el/deploy/signup_pythonanywhere.md b/el/deploy/signup_pythonanywhere.md new file mode 100644 index 00000000000..e0631825139 --- /dev/null +++ b/el/deploy/signup_pythonanywhere.md @@ -0,0 +1,19 @@ +Το PythonAnywhere είναι μια υπηρεσία για την εκτέλεση Python κώδικα σε διακομιστές «στο σύννεφο» (cloud). Θα το χρησιμοποιήσουμε για τη φιλοξενία του site μας στο internet. + +Θα φιλοξενήσουμε το blog που χτίσαμε στο PythonAnywhere. Δημιουργήστε έναν "Beginner" λογαριασμό (δεν χρειάζεστε πιστωτική κάρτα). + +* [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +![H σελίδα εγγραφής του PythonAnywhere δείχνει ένα κουμπί για να δημιουργήσετε έναν δωρεάν «Beginner» λογαριασμό](../deploy/images/pythonanywhere_beginner_account_button.png) + +> **Σημείωση** Όταν επιλέξετε όνομα χρήστη θυμηθείτε ότι τα urls του blog σας θα έχουν τη μορφή `yourusername.pythonanywhere.com`. Οπότε επιλέξτε είτε το συνηθισμένο σας όνομα χρήστη (πχ αυτό που βάλατε στο GitHub) είτε κάποιο που να ταιριάζει με τη θεματολογία του blog σας. Επίσης, σιγουρευτείτε ότι θα θυμάστε τον κωδικό πρόσβασης σας. + +## Δημιουργώντας ένα PythonAnywhere API token + +Αυτό είναι κάτι που πρέπει να κάνετε μόνο μια φορά. Μετά την εγραφή σας στο  PythonAnywhere θα μεταφερθείτε στο ταμπλό σας. Βρείτε το σύνδεσμο "Λογαριασμός" πάνω δεξιά στη σελίδα σας: + +![Σύνδεσμος λογαριασμού πάνω δεξιά στη σελίδα](../deploy/images/pythonanywhere_account.png) + +στη συνέχεια επιλέξτε την καρτέλα που ονομάζεται "API Token" και πατήστε το κουμπί που λεει "Δημιουργία νέου  API Token". + +![Η καρτέλα "API Token" στη σελίδα λογαριασμού](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/el/django/README.md b/el/django/README.md new file mode 100644 index 00000000000..c615f899a96 --- /dev/null +++ b/el/django/README.md @@ -0,0 +1,27 @@ +# Τι είναι το Django; + +Το Django (*goh/ˈdʒæŋɡoʊ/jang-goh*) είναι ένα δωρεάν και ανοικτού κώδικα web framework γραμμένο σε Python. Ένα web framework είναι ένα σύνολο από στοιχεία που σας βοηθά να αναπτύξετε ιστοσελίδες πιο γρήγορα και εύκολα. + +Όταν κατασκευάζετε μία ιστοσελίδα, χρειάζεστε πάντα ένα παρόμοιο σύνολο στοιχείων: έναν τρόπο για να χειρίζεστε τον έλεγχο ταυτότητας χρήστη (εγγραφή, σύνδεση, αποσύνδεση), ένα πάνελ διαχείρισης για την ιστοσελίδα σας, φόρμες, έναν τρόπο για να ανεβάσετε αρχεία κλπ. + +Ευτυχώς για εσάς, άλλα άτομα πριν από αρκετό καιρό παρατήρησαν ότι οι προγραμματιστές ιστού αντιμετωπίζουν παρόμοια προβλήματα κατά τη δημιουργία ενός νέου ιστοτόπου και έτσι συνεργάστηκαν και δημιούργησαν τα frameworks (το Django είναι ένα από αυτά) που σας δίνουν έτοιμα συστατικά που μπορείτε να χρησιμοποιήσετε. + +Τα πλαίσια υπάρχουν για να μην χρειάζεται να "επανεφεύρετε τον τροχό" και να σας ελαφρύνουν από αρκετές εργασίες κατά την διάρκεια της κατασκευής μίας νέας ιστοσελίδας. + +## Γιατί χρειάζεστε ένα framework; + +Για να καταλάβουμε τι είναι πραγματικά το Django, πρέπει να ρίξουμε μία πιο προσεκτική ματιά στους διακομιστές (servers). Το πρώτο πράγμα είναι ότι ο διακομιστής θα πρέπει να ξέρει τι θέλετε να εξυπηρετήσει σε μια ιστοσελίδα. + +Φανταστείτε ένα γραμματοκιβώτιο (θύρα), το οποίο παρακολουθείται για εισερχόμενα γράμματα (αιτήματα). Αυτό γίνεται από έναν διακομιστή διαδικτύου (web server). Ο διακομιστής διαδικτύου διαβάζει το γράμμα και αποκρίνεται με μια ιστοσελίδα. Αλλά όταν θέλετε να στείλετε κάτι, πρέπει να έχει και κάποιο περιεχόμενο. Και το Django είναι κάτι που σας βοηθάει να δημιουργήσετε αυτό το περιεχόμενο. + +## Τι συμβαίνει όταν κάποιος ζητά μια ιστοσελίδα από το διακομιστή σας; + +Όταν ένα αίτημα φτάσει σε ένα διακομιστή δικτύου, περνάει στο Django το οποίο προσπαθεί να καταλάβει τι ζητάει αυτό το αίτημα στην ουσία. Λαμβάνει πρώτα μια διεύθυνση σελίδας δικτύου και προσπαθεί να καταλάβει τι να κάνει. Αυτό το κομμάτι γίνεται από τον **urlresolver** του Django (σημειώστε ότι η διεύθυνση ενός ιστότοπου ονομάζεται URL - Uniform Resource Locator - και έτσι το όνομα *urlresolver* βγάζει νόημα). Παρόλαυτα δεν είναι πολύ έξυπνο. Παίρνει μια λίστα από μοτίβα και προσπαθεί να ταιριάξει την διεύθυνση URL. Το Django ελέγχει τα μοτίβα από πάνω προς τα κάτω και αν κάτι ταιριάζει, μεταβιβάζει το αίτημα στην σχετική λειτουργία (η οποία ονομάζεται *view*). + +Φανταστείτε έναν ταχυδρόμο με ένα γράμμα. Περπατάει στην οδό και ελέγχει κάθε αριθμό σπιτιού αν είναι ίδιος με τον αντίστοιχο αριθμό στο γράμμα. Αν ταιριάζει, βάζει το γράμμα εκεί. Αυτός είναι ο τρόπος που λειτουργεί ο urlresolver! + +Στο *view*, γίνονται όλα τα ενδιαφέροντα πράγματα: μπορούμε να δούμε μια βάση δεδομένων για να ψάξουμε για μερικές πληροφορίες. Μήπως ο χρήστης ζήτησε να αλλάξει κάτι στα δεδομένα; Όπως ένα γράμμα που λέει "Παρακαλώ, αλλάξτε την περιγραφή της δουλειάς μου.» Το *view* μπορεί να ελέγξει αν επιτρέπεται να το κάνετε αυτό και στη συνέχεια ενημερώνει την περιγραφή της δουλειάς σας και στείλνει πίσω ένα μήνυμα: "Έγινε!". Έπειτα το *view* παράγει ένα response και το Django το στέλνει πίσω στον web browser του χρήστη και προβάλεται στην οθόνη. + +Φυσικά, η παραπάνω περιγραφή είναι λίγο απλοποιημένη, αλλά δεν χρειάζεται να γνωρίζετε όλα τα τεχνικά ζητήματα ακόμη. Μια γενική ιδέα είναι αρκετή. + +Έτσι αντί να αφιερώνουμε πάρα πολύ χρόνο σε λεπτομέρειες, θα ξεκινήσουμε απλά δημιουργώντας κάτι με το Django και θα μάθουμε όλα τα σημαντικά κομμάτια καθοδόν! \ No newline at end of file diff --git a/el/django_admin/README.md b/el/django_admin/README.md new file mode 100644 index 00000000000..023d7f6179c --- /dev/null +++ b/el/django_admin/README.md @@ -0,0 +1,57 @@ +# Διαχείριση μέσω Django admin + +Για να προσθέσουμε, επεξεργαστούμε και να διαγράψουμε τις δημοσιεύσεις που έχουμε αναρτήσει, θα χρησιμοποιήσουμε την εφαρμογή Django admin. + +Ας ανοίξουμε το αρχείο `blog/admin.py` μέσα σε έναν code editor και ας αντικαταστήσουμε τα περιεχόμενα του με τα ακόλουθα: + +{% filename %}blog/admin.py{% endfilename %} + +```python +from django.contrib import admin +from .models import Post + +admin.site.register(Post) +``` + +Με τον παραπάνω κώδικα, εισάγουμε το μοντέλο Post (δηλαδή τον πίνακα της βάσης δεδομένων με το όνομα Post) όπως ορίστηκε από το προηγούμενο κεφάλαιο. Για να κάνουμε το μοντέλο μας ορατό στην σελίδα διαχείρισης θα πρέπει να το "εγγράψουμε" (να το κάνουμε register) με την συνάρτηση `admin.site.register(Post)`. + +Εντάξει λοιπόν, ας ρίξουμε μια ματιά στο Post μοντέλο μας. Θυμηθείτε ότι πρέπει πρώτα να πληκτρολογήσουμε `python manage.py runserver` στην κονσόλα μας ώστε να ξεκινήσει ο development server. Πηγαίνετε στον browser και πληκτρολογήστε http://127.0.0.1:8000/admin/. Θα δείτε μία σελίδα σύνδεσης όπως αυτή: + +![Login page](images/login_page2.png) + +Για να συνδεθείτε, χρειάζεται να δημιουργήσετε έναν *superuser*, δηλαδή έναν χρήστη ο οποίος θα έχει δικαιώματα σε οτιδήποτε σε αυτή την σελίδα. Πηγαίνετε πίσω στην γραμμή εντολών, πατήστε Ctrl + c για να σταματήσετε τον development server Που ήδη τρέχει, πληκτρολογήστε `python manage.py createsuperuser` και πατήστε enter. + +> Θυμηθείτε, για να γράψετε νέες εντολές ενώ ο server εκτελείται, ανοίξτε μια νέα κονσόλα και ενεργοποιήστε το virtualenv. Είδαμε πως να γράφετε νέες εντολές μέσα στο κεφάλαιο **Το πρώτο σας Django project!**, στην ενότητα **Ξεκινώντας τον web server**. + +{% filename %}macOS or Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py createsuperuser + + +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py createsuperuser + + +Όταν σας ζητηθεί, πληκτρολογήστε το όνομα χρήστη σας (πεζά, δίχως κενά), το email σας και ένα password. **Μην ανησυχείτε όταν πληκτρολογείτε τον κωδικό σας και δεν βλέπετε κάτι στην οθόνη. Έτσι πρέπει να είναι.** Πληκτρολογήστε τον και μετά πατήστε `enter` για να συνεχίσετε. Η απόκριση από το τερματικό θα μοιάζει κάπως έτσι (όπου "όνομα χρήστη" και "email" θα είναι τα δικά σας): + + Username: ola + Email address: ola@example.com + Password: + Password (again): + Superuser created successfully. + + +Αν ο server δεν τρέχει κάντε το τώρα: <0>python manage.py runserver. Μετά, επιστρέψτε στον browser σας. Κάντε login και εισάγετε το όνομα χρήστη και τον κωδικό σας. Θα πρέπει να δείτε, επιτέλους, την κεντρική σελίδα διαχείρισης του Django. + +![Django admin](images/django_admin3.png) + +Πηγαίνετε στα Posts και πειραματιστείτε με αυτά. Προσθέστε πέντε ή έξι posts. Μην ανησυχείτε για το περιεχόμενο των posts. Είναι μονάχα ορατό σε εσάς, στον υπολογιστή σας. Μπορείτε να κάνετε αντιγραφή-επικόλληση κείμενο από αυτόν εδώ τον οδηγό για να γλυτώσετε χρόνο. :) + +Σιγουρευτείτε ότι δύο ή τρία posts (αλλά όχι όλα) έχουν συμπληρώσει το πεδίο "publish date". Θα μας βοηθήσει αυτό αργότερα. + +![Django admin](images/edit_post3.png) + +Αν θέλετε να μάθετε περισσότερα για το Django admin, θα πρέπει να επισκεφτείτε την επίσημη σελίδα του στο: https://docs.djangoproject.com/en/2.0/ref/contrib/admin/ + +Αυτή είναι μάλλον μια καλή στιγμή να πιείτε μια γουλιά καφέ (ή τσάι) ή κάτι να φάτε για να γεμίσετε ενέργεια. Μόλις δημιουργήσατε το πρώτο σας Django model. Αξίζετε ένα μικρό διάλλειμα! \ No newline at end of file diff --git a/el/django_admin/images/django_admin3.png b/el/django_admin/images/django_admin3.png new file mode 100644 index 00000000000..fb221bd18e1 Binary files /dev/null and b/el/django_admin/images/django_admin3.png differ diff --git a/el/django_admin/images/edit_post3.png b/el/django_admin/images/edit_post3.png new file mode 100644 index 00000000000..57299b6f5af Binary files /dev/null and b/el/django_admin/images/edit_post3.png differ diff --git a/el/django_admin/images/login_page2.png b/el/django_admin/images/login_page2.png new file mode 100644 index 00000000000..c16d1aa4289 Binary files /dev/null and b/el/django_admin/images/login_page2.png differ diff --git a/el/django_forms/README.md b/el/django_forms/README.md new file mode 100644 index 00000000000..ea789f40649 --- /dev/null +++ b/el/django_forms/README.md @@ -0,0 +1,449 @@ +# Φόρμες Django + +Το τελευταίο που έμεινε για την ιστοσελίδα μας είναι να δημιουργήσουμε μια όμορφη φόρμα για την εισαγαγωγή και τροποποίηση των post μας. Θα μπορούσαμε να χρησιμοποιήσουμε το Django `admin` αλλά είναι αρκετά πολύπλοκο να τροποποιήσουμε και να κάνουμε όμορφη τη φόρμα εισαγωγής εκεί. Με τις `φόρμες` έχουμε τον πλήρη έλεγχο στο περιβάλλον του χρήστη. Μπορούμε να κάνουμε ότι μπορούμε να φανταστούμε! + +Μία από τις ευκολίες των Django φορμών είναι ότι μπορούμε να ξεκινήσουμε από το μήδεν ή να χρησιμοποιήσουμε το `ModelForm` που ουσιαστικά αποθηκεύει τα δεδομένα της φόρμας στο μοντέλο (ή διαφορετικά στο σωστό πίνακα της βάσης μας). + +Αυτό είναι ακριβώς που θέλουμε να κάνουμε: δηλαδή να δημιουργήσουμε εύκολα μια φόρμα εισαγωγής δεδομένων για το ήδη υπάρχων `Post` μοντέλο. + +Οπώς κάθε άλλο σημαντικό τμήμα του Django, οι φόρμες εισαγωγής "ζούν" στο δικό τους αρχείο: `forms.py`. + +Πρέπει να δημιουργήσουμε το αρχείο forms.py μέσα στο φάκελο `blog`. + + blog + └── forms.py + + +Ωραία. Ας ανοίξουμε τον επεξεργαστή κώδικα και ας γράψουμε τον ακόλουθο κώδικα: + +{% filename %}blog/forms.py{% endfilename %} + +```python +from django import forms + +from .models import Post + +class PostForm(forms.ModelForm): + + class Meta: + model = Post + fields = ('title', 'text',) +``` + +Θα χρειαστεί να κάνουμε import τις Django forms πρώτα (`from django import forms`) καθώς και το μοντέλο μας `Post` (`from .models import Post`). + +Οπώς πιθανόν να υποψιάζεστε το `PostForm`, είναι το όνομα της φόρμας εισαγωγής. Θα χρειαστεί να πούμε στο Django ότι αυτή η φόρμα είναι μια `ModelForm` (ούτως ώστε το Django να κάνει τα "μαγικά" του για εμάς). Η κλάση `forms.ModelForm` είναι υπεύθυνη γι'αυτό. + +Στην συνέχεια, έχουμε `class Meta`, όπου "λέμε" στο Django για ποιο μοντέλο πρέπει να δημιουργήσει την φόρμα εισαγωγής δεδομένων (`model = Post`). + +Τέλος, πρέπει να ορίσουμε ποιο/α πεδίο/α πρέπει να διαθέσουμε στην φόρμα μας. Σε αυτό το σενάριο θέλουμε μόνο το `title` και το `text` να εμφανίζονται. Το `author` θα πρέπει να είναι το πρόσωπο που είναι συνδεδεμένο εκείνη τη στιγμή (εσείς!) και το `created_date` θα παράγεται αυτόματα όταν δημιουργούμε ένα post (πχ μέσω κώδικα), σωστά; + +Αυτό ήταν! Αυτό που μας απομένει είναι να χρησιμοποιήσουμε την φόρμα μας μέσα σε ένα *view* ώστε να είναι διαθεσίμη μέσω ενός template. + +Οπότε, για ακόμα μια φορά, θα χρειαστεί να συνδέσουμε τη σελίδα με ένα url, ένα view και ένα template. + +## Πως συνδέουμε μια σελίδα με την φόρμα μας + +Ανοίξτε το template `blog/templates/blog/base.html`. Θα προσθέσουμε έναν σύνδεσμο στο `div` με το όνομα `page-header`: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + +``` + +Σημειώστε ότι θέλουμε να ονομάσουμε το view ως `post_new`. Η κλάση `"glyphicon glyphicon-plus"` παρέχεται από το bootstrap και θα εμφανίσει το σύμβολο της πρόσθεσης. + +Αφού προσθέσουμε τη γραμμή, το HTML αρχείο θα δείχνει κάπως έτσι: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% load static %} + + + Django Girls blog + + + + + + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ + +``` + +Αφού αποθηκεύσετε και ανανέωσετε τη σελίδα http://127.0.0.1:8000 θα δείτε τη γνωστή σελίδα σφάλματος `NoReverseMatch`. Αν ναι, τότε ωραία! + +## URL + +Ανοίξτε το αρχείο `blog/urls.py` και προσθέστε τη γραμμή: + +{% filename %}blog/urls.py{% endfilename %} + +```python +path('post/new', views.post_new, name='post_new'), +``` + +Ο ολοκληρωμένος κώδικας θα δείχνει κάπως έτσι: + +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views + +urlpatterns = [ + 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`, αφού δεν έχουμε φτιάξει ακόμα το view `post_new`. Ας το φτιάξουμε τώρα. + +## post_new view + +Ανοίξτε το αρχείο`blog/views.py` και προσθέστε τις ακόλουθες γραμμές μαζί με τις γραμμές `from`: + +{% filename %}blog/views.py{% endfilename %} + +```python +from .forms import PostForm +``` + +Στη συνέχεια το *view*: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Για να δημιουργήσετε μια νέα `Post` φόρμα, θα χρειαστεί να αρχικοποιήσουμε την κλάση `PostForm()` όπως επίσης και να δηλώσουμε ένα template. Θα επιστρέψουμε σε αυτό το *view* αλλά για τώρα, ας δημιουργήσουμε γρήγορα ένα template για την φόρμα. + +## Template + +Θα χρειαστεί να δημιουργήσουμε ένα αρχείο `post_edit.html` μέσα στο φάκελο `blog/templates/blog` και να το ανοίξουμε. Για να κάνουμε τη φόρμα να δουλέψει θα χρειαστεί να κάνουμε διάφορα πράγματα: + +* Πρέπει να εμφανίσουμε τη φόρμα. Μπορούμε να το κάνουμε αυτό (για παράδειγμα) {% raw %}`{{ form.as_p }}`{% endraw %}. +* Η παραπάνω γραμμή πρέπει συμπεριληφθεί γύρω από ένα HTML form tag: `...`. +* Χρειαζόμαστε ένα κουμπί `Αποθήκευση`. Το κάνουμε αυτό με ένα κουμπί HTML: ``. +* Και στο τέλος, ακριβώς μετά το tag `
` πρέπει να προσθέσουμε {% raw %}`{% csrf_token %}`{% endraw %}. Αυτό είναι πολύ σημαντικό, αφού καθιστά τις φόρμες σας ασφαλείς! Εάν ξεχάσετε αυτό το κομμάτι, το Django θα παραπονεθεί όταν προσπαθήσετε να αποθηκεύσετε τη φόρμα: + +![Σελίδα CSFR Forbidden](images/csrf2.png) + +Εντάξει, ας δούμε πως η HTML στο template `post_edit.html` πρέπει να δείχνει: + +{% filename %}blog/templates/blog/post_edit.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} +

New post

+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} +``` + +Ώρα να ανανεώσετε! Ναι! Η φόρμα σας εμφανίζεται! + +![Νέα φόρμα](images/new_form2.png) + +Αλλά, περιμένετε ένα λεπτό! Όταν πληκτρολογείτε κάτι στα πεδία `title` και `text` και προσπαθήσετε να το αποθηκεύσετε, τι θα συμβεί; + +Τίποτα! Είμαστε άλλη μια φορά στην ίδια σελίδα και το κείμενο μας έχει εξαφανιστεί... και δεν έχει προστεθεί καμία νέα δημοσίευση. Οπότε τι πήγε λάθος; + +Η απάντηση είναι: τίποτα. Πρέπει να κάνουμε λίγη περισσότερη δουλειά στο αρχείο *view*. + +## Αποθηκεύοντας τη φόρμα + +Ανοίξτε το αρχείο `blog/views.py` ξανά. Προς το παρόν αυτό που έχουμε στο `post_new` είναι τα ακόλουθα: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Όταν υποβάλουμε την φόρμα, επανερχόμαστε στο ίδιο view αλλά αυτή τη φορά έχουμε περισσότερα δεδομένα στο `request`. Πιο συγκεκριμένα στο `request.POST` (το όνομα δεν έχει να κάνει με μία "δημοσίευση" blog, έχει να κάνει με το γεγονός ότι "δημοσιεύουμε" δεδομένα). Θυμηθείτε πως στο αρχείο HTML ο `
` ορισμός μας είχε την μεταβλητή `method="POST"`; Όλα τα πεδία από τη φόρμα είναι στο `request.POST`. Δεν πρέπει να μετονομάσετε το `POST` σε οτιδήποτε άλλο (η μόνο άλλη έγκυρη τιμή για το `method` είναι `GET`, αλλά δεν έχουμε χρόνο για να εξηγήσουμε ποια είναι η διαφορά). + +Έτσι στο *view* έχουμε δύο ξεχωριστές καταστάσεις να διαχειριστούμε: 1ον, όταν αποκτούμε πρόσβαση στην σελίδα για πρώτη φορά και θέλουμε μία άδεια φόρμα και 2ον, όταν πάμε πίσω στο *view* με όλα τα δεδομένα της φόρμας που μόλις πληκτρολογήσαμε. Επομένως, πρέπει να προσθέσουμε μια συνθήκη (θα χρησιμοποιήσουμε `if` για αυτό): + +{% filename %}blog/views.py{% endfilename %} + +```python +if request.method == "POST": + [...] +else: + form = PostForm() +``` + +Είναι καιρός να συμπληρώσουμε τις τελείες `[...]`. Αν το `method` είναι `POST` τότε θέλουμε να δημιουργήσουμε μια `PostForm` με τα δεδομένα από τη φόρμα, σωστά; Θα το κάνουμε αυτό όπως παρακάτω: + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(request.POST) +``` + +Το επόμενο πράγμα είναι να ελέγξουμε αν η φόρμα είναι σωστή (όλα τα απαιτούμενα πεδία έχουν οριστεί και δεν έχουν υποβληθεί εσφαλμένες τιμές). Το κάνουμε αυτό με τη μέθοδο `form.is_valid()`. + +Ελέγχουμε αν η αίτηση είναι έγκυρη και αν ναι, μπορούμε να την αποθηκεύσουμε! + +{% filename %}blog/views.py{% endfilename %} + +```python +if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() +``` + +Βασικά, έχουμε δύο πράγματα εδώ: αποθηκεύουμε τη φόρμα με τη μέθοδο `form.save()` και προσθέτουμε έναν συγγραφέα (μιας και δεν υπήρχε πεδίο `author` στην κλάση `PostForm` και αυτό το πεδίο είναι απαραίτητο). `commit=False` σημαίνει ότι δεν θέλουμε να αποθηκεύσουμε το μοντέλο `Post` ακόμα. Θέλουμε να προσθέσουμε τον author πρώτα. Τις περισσότερες φορές θα χρησιμοποιήσετε το `form.save()` χωρίς το `commit=False`, αλλά σε αυτή την περίπτωση, πρέπει να το κάνουμε. Η μέθοδος `post.save()` θα διατηρήσει τις αλλαγές (προσθέτοντας τον author) και έτσι δημιουργείται ένα νέο blog post! + +Τέλος, θα ήταν ωραίο εάν μπορούσαμε να πάμε αμέσως στην σελίδα `post_detail` για το νεοσυσταθέν blog post μας, σωστά; Για να το κάνουμε αυτό χρειαζόμαστε ένα ακόμα import: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import redirect +``` + +Προσθέστε το στην αρχή του αρχείου σας. Και τώρα μπορούμε να πούμε, "πηγαίνε στη σελίδα `post_detail` για το νεοσυσταθέν post": + +{% filename %}blog/views.py{% endfilename %} + +```python +return redirect('post_detail', pk=post.pk) +``` + +Το `post_detail` είναι το όνομα του view στο οποίο θέλουμε να πάμε. Θυμηθείτε ότι αυτό το *view* απαιτεί μία μεταβλητή `pk`; Για να το περάσουμε στα views, χρησιμοποιούμε το `pk=post.pk`, όπου `post` είναι το νεοσύστατο blog post! + +Εντάξει. Έχουμε μιλήσει πολύ. Αλλά μάλλον θέλουμε να δούμε πως μοιάζει το *view*, σωστά; + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + if request.method == "POST": + form = PostForm(request.POST) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Ας δούμε αν λειτουργεί. Πηγαίνετε στην σελίδα http://127.0.0.1:8000/post/new/ και προσθέστε ένα `title` και ένα `text`, αποθηκεύστε το… και voilà! Το νέο σας post προστέθηκε και αυτόματως ανακατευθυνόμαστε στη σελίδα του `post_detail`! + +Ίσως να προσέξατε ότι ορίζουμε την ημ/νια έκδοσης (publish date) πριν την αποθήκευση του post. Αργότερα θα παρουσιάσουμε ένα *publish button* στην ενότητα **Οδηγός Django Girls: Επεκτάσεις**. + +Αυτό είναι απίθανο! + +> Επειδή έχουμε χρησιμοποιήσει το Django Admin πρόσφατα, το σύστημα υποθέτει ότι είμαστε ακόμα συνδεδεμένοι. Υπάρχουν μερικοί τρόποι που μπορεί να μας οδηγήσουν εκτός σύνδεσης (κλείνοντας τον browser, επανεκκινώντας την βάση δεδομένων κλπ). Αν, κατά τη διάρκεια δημιουργίας ενός post, λαμβάνετε σφάλματα ότι είστε εκτός σύνδεσης, πηγαίνετε στη σελίδα admin http://127.0.0.1:8000/admin και συνδεθείτε ξανά. Αυτό θα διορθώσει το πρόβλημα, προσωρινά. Υπάρχει, ωστόσο, η μόνιμη λύση του προβλήματος η οποία σας περιμένει στο κεφάλαιο **Εργασία: ασφάλεια για το site σας!** μετά από αυτόν τον οδηγό. + +![Σφάλμα σύνδεσης](images/post_create_error.png) + +## Form validation + +Τώρα θα σας δείξουμε πόσο ωραίες είναι οι Django φόρμες. Ένα post χρειάζεται να έχει τουλάχιστον τα εξής πεδία: `title` και `text`. Στο μοντέλο μας `Post` δεν δηλώσαμε ότι θέλουμε αυτά τα πεδία να είναι προαιρετικά (εν εντιθέση με το πεδίο `published_date`). Έτσι το Django, από προεπιλογή, αναμένει αυτά τα πεδία να υπάρχουν. + +Προσπαθήστε να αποθηκεύσετε τη φόρμα δίχως τιμές για τα πεδία `title` και `text`. Τι θα συμβεί; + +![Form validation](images/form_validation2.png) + +Το Django χειρίζεται την εγκυρότητα της φόρμας. Με άλλα λόγια κάνει το λεγόμενο form validation. Δεν είναι φοβερό αυτό; + +## Επεξεργασία φόρμας + +Τώρα ξέρουμε πως να προσθέσουμε μια νέα φόρμα. Αλλά πως επεξεργαζόμαστε μια ήδη υπάρχουσα; Αυτό είναι παρόμοιο με αυτό που κάναμε. Ας δημιουργήσουμε, γρήγορα, μερικά σημαντικά πράγματα. (Αν δεν καταλαβαίνετε κάτι, θα πρέπει να ζητήσετε τη βοήθεια του επιτηρητή σας ή να κοιτάξετε στα προηγούμενα κεφάλαια, δεδομένου ότι καλύψαμε ήδη όλα αυτά τα βήματα.) + +Ανοίξτε το αρχείο `blog/templates/blog/post_detail.html` και προσθέστε τη γραμμή + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + +``` + +ούτως ώστε το template να δείχνει κάπως έτσι: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} + +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endblock %} +``` + +Ανοίξτε το αρχείο `blog/urls.py` και προσθέστε τη γραμμή: + +{% filename %}blog/urls.py{% endfilename %} + +```python + path('post//edit/', views.post_edit, name='post_edit'), +``` + +Θα ξαναχρησιμοποιήσουμε το template `blog/templates/blog/post_edit.html`, οπότε λείπει μόνο το *view*. + +Ανοίξτε το αρχείο `blog/views.py` και προσθέστε αυτό στο τέλος του αρχείου: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_edit(request, pk): + post = get_object_or_404(Post, pk=pk) + if request.method == "POST": + form = PostForm(request.POST, instance=post) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm(instance=post) + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Αυτό μοιάζει σχεδόν το ίδιο με το view `post_new`, σωστά; Αλλά όχι εντελώς. Για το πρώτο, περνάμε μια έξτρα παράμετρο `pk` από τα urls. Στη συνέχεια, παίρνουμε το μοντέλο `Post` που θέλουμε να επεξεργαστούμε με την συνάρτηση `get_object_or_404 (Post, pk=pk)` και στη συνέχεια όταν δημιουργούμε μια φόρμα, περνάμε το post αυτό ως ένα `instance`, τόσο όταν αποθηκεύουμε τη φόρμα... + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(request.POST, instance=post) +``` + +… όσο και όταν έχουμε μόλις ανοίξει μία φόρμα προς επεξεργασία με αυτό το post: + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(instance=post) +``` + +Εντάξει, ας δοκιμάσουμε αν λειτουργεί! Πάμε στην σελίδα `post_detail`. Θα πρέπει να υπάρχει ένα κουμπί επεξεργασίας στην πάνω δεξιά γωνία: + +![Κουμπί επεξεργασίας](images/edit_button2.png) + +Όταν κάνετε κλικ θα δείτε την φόρμα με την δημοσίευση στο blog μας: + +![Επεξεργασία φόρμας](images/edit_form2.png) + +Νιώστε ελεύθεροι να αλλάξετε τον τίτλο ή το κείμενο και να αποθηκεύσετε τις αλλαγές! + +Συγχαρητήρια! Η εφαρμογή σας γίνεται όλο και πιο πλήρης! + +Εάν χρειάζεστε περισσότερες πληροφορίες για τις φόρμες Django, θα πρέπει να διαβάσετε το: https://docs.djangoproject.com/en/2.0/topics/forms/ + +## Ασφάλεια + +Το να μπορείς να δημιουργήσεις νέες δημοσιεύσεις κάνοντας απλώς ένα κλικ σε ένα σύνδεσμο είναι φοβερό! Αλλά τώρα, οποιοσδήποτε επισκεφθεί την σελίδα σας θα μπορεί να φτιάξει μία καινούρια δημοσίευση blog, και αυτό είναι κάτι που πιθανώς δεν θέλετε. Ας το κάνουμε έτσι ώστε το κουμπί να εμφανίζεται μόνο για εσάς και για κανέναν άλλο. + +Ανοίξτε το αρχείο `Blog/templates/blog/base.html` και βρείτε το `page-header` `div` καθώς και το tag a του link. Θα μοιάζει κάπως έτσι: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + +``` + +Πρόκειται να προσθέσουμε άλλη μία ετικέτα `{% if %}` σε αυτό, το οποίο θα κάνει τον σύνδεσμο να εμφανίζεται μόνο για χρήστες που είναι συνδεδεμένοι στο Django Admin. Προς το παρόν, είστε μόνο εσείς! Αλλάξτε το tag `` να μοιάζει σαν αυτό: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% if user.is_authenticated %} + +{% endif %} +``` + +Αυτό το `{% if %}` θα προκαλέσει τον σύνδεσμο να σταλθεί στο πρόγραμμα περιήγησης μόνο αν ο χρήστης που ζητά την σελίδα είναι συνδεδεμένος. Αυτό δεν προστατεύει την δημιουργία νέων δημοσιεύσεων εντελώς, αλλά είναι ένα καλό πρώτο βήμα. Θα καλύψουμε περισσότερα σχετικά με την ασφάλεια στα μαθήματα επέκτασης. + +Θυμάστε το εικονίδιο επεξεργασίας που μόλις προσθέσαμε στην σελίδα λεπτομερειών; Θέλουμε επίσης να προσθέσουμε την ίδια αλλαγή εκεί, ώστε άλλα άτομα δεν θα μπορούν να επεξεργαστούν τις υπάρχουσες δημοσιεύσεις. + +Ανοίξτε το αρχείο `blog/templates/blog/post_detail.html` και προσθέστε τη γραμμή: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + +``` + +Αλλάξτε το σε αυτό: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% if user.is_authenticated %} + +{% endif %} +``` + +Μιας και είστε πιθανότατα συνδεδεμένοι, εάν ανανεώσετε την σελίδα, δεν θα δείτε τίποτα διαφορετικό. Φορτώστε την σελίδα σε ένα διαφορετικό πρόγραμμα περιήγησης ή ένα παράθυρο ανώνυμης περιήγησης (που ονομάζεται "InPrivate" στο Windows Edge), όμως, και θα δείτε ότι ο σύνδεσμος δεν εμφανίζεται, ούτε και το εικονίδιο! + +## Ένα πράγμα ακόμα: ώρα να το ανεβάσετε! + +Για να δούμε αν όλα αυτά λειτουργούν στο PythonAnywhere. Ώρα για άλλο ένα deploy! + +* Πρώτα κάντε commit τον νέο σας κώδικα και έπειτα push στο GitHub: + +{% filename %}command-line{% endfilename %} + + $ git status + $ git add --all . + $ git status + $ git commit -m "Added views to create/edit blog post inside the site." + $ git push + + +* Έπειτα, στην [κονσόλα Bash του PythonAnywhere](https://www.pythonanywhere.com/consoles/): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Θυμηθείτε να αντικαταστήσετε με το ``πραγματικό όνομα χρήστη σας του PythonAnywhere χωρίς τα <>). + +* Τέλος, επισκεφτείτε τη σελίδα σας ["Web" page](https://www.pythonanywhere.com/web_app_setup/) (χρησιμοποιήστε το κουμπί του menu στην πάνω δεξιά γωνία της κονσόλας) και κλικάρετε **Reload**. Ανανεώστε τη σελίδα https://yourname.pythonanywhere.com και δείτε τις αλλαγές. + +Αυτό ήταν! Συγχαρητήρια :) \ No newline at end of file diff --git a/el/django_forms/images/csrf2.png b/el/django_forms/images/csrf2.png new file mode 100644 index 00000000000..ee946324f92 Binary files /dev/null and b/el/django_forms/images/csrf2.png differ diff --git a/el/django_forms/images/drafts.png b/el/django_forms/images/drafts.png new file mode 100644 index 00000000000..1d62f8866f4 Binary files /dev/null and b/el/django_forms/images/drafts.png differ diff --git a/el/django_forms/images/edit_button2.png b/el/django_forms/images/edit_button2.png new file mode 100644 index 00000000000..804674f0965 Binary files /dev/null and b/el/django_forms/images/edit_button2.png differ diff --git a/el/django_forms/images/edit_form2.png b/el/django_forms/images/edit_form2.png new file mode 100644 index 00000000000..3d4e525d5d0 Binary files /dev/null and b/el/django_forms/images/edit_form2.png differ diff --git a/el/django_forms/images/form_validation2.png b/el/django_forms/images/form_validation2.png new file mode 100644 index 00000000000..6e333af3077 Binary files /dev/null and b/el/django_forms/images/form_validation2.png differ diff --git a/el/django_forms/images/new_form2.png b/el/django_forms/images/new_form2.png new file mode 100644 index 00000000000..8f2a1088070 Binary files /dev/null and b/el/django_forms/images/new_form2.png differ diff --git a/el/django_forms/images/post_create_error.png b/el/django_forms/images/post_create_error.png new file mode 100644 index 00000000000..d140e8e2419 Binary files /dev/null and b/el/django_forms/images/post_create_error.png differ diff --git a/el/django_installation/README.md b/el/django_installation/README.md new file mode 100644 index 00000000000..9abda63495d --- /dev/null +++ b/el/django_installation/README.md @@ -0,0 +1,7 @@ +# Εγκατάσταση του Django + +> **Σημείωση** Αν χρησιμοποιείτε ένα Chromebook, παραλείψτε αυτό το κεφάλαιο και σιγουρευτείτε ότι ακουλουθείτε τις [Chromebook Setup](../chromebook_setup/README.md) οδηγίες. +> +> **Σημείωση** Αν έχετε ήδη περάσει τα βήματα εγκατάστασης τότε το έχετε ήδη κάνει αυτό - μπορείτε να μεταβείτε απευθείας στο επόμενο κεφάλαιο! + +{% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/el/django_installation/instructions.md b/el/django_installation/instructions.md new file mode 100644 index 00000000000..daa2509df12 --- /dev/null +++ b/el/django_installation/instructions.md @@ -0,0 +1,218 @@ +> Μέρος αυτής της ενότητας βασίζεται στους οδηγούς των Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> +> Μέρος αυτής της ενότητας βασίζεται στον οδηγό [django-marcador](http://django-marcador.keimlink.de/) υπό την άδεια χρήσης Creative Commons Attribution-ShareAlike 4.0 International License. Τα πνευματικά δικαιώματα του οδηγού django-marcador ανήκουν στον Markus Zapke-Gründemann. + +## Εικονικό περιβάλλον + +Πριν την εγκατάσταση του Django, θα εγκαταστήσουμε ενα εξαιρετικά χρήσιμο εργαλείο για να κρατήσουμε το περιβάλλον του υπολογιστή σας τακτοποιημένο και καθαρό. Μπορείτε να παραβλέψετε αυτό το βήμα, αλλά προτείνουμε να το ακολουθήσετε καθώς αν δεν το ακολουθήσετε υπάρχει σοβαρή πιθανότητα να προκύψουν σφάλματα αργότερα. Ξεκινώντας με την καλύτερη δυνατή εγκατάσταση, θα αποφύγετε πολλά προβλήματα στο μέλλον! + +Ας δημιουργήσουμε λοιπόν ενα **εικονικό περιβάλλον** (το αποκαλούμενο *virtualenv*). Το virtualenv θα απομονώσει την κάθε εγκατάσταση Python/Django ανά έργο (project). Αυτό σημαίνει ότι οι αλλαγές που κάνετε σε μια ιστοσελίδα (έργο - project) δεν θα επηρεάζουν οποιεσδήποτε άλλες ιστοσελίδες που αναπτύσσετε παράλληλα. Κάθε ιστοσελίδα θα έχει τα δικά της πακέτα και κάθε πακέτο την δική του έκδοση (version). Καλό, ε; + +Το μόνο που χρειάζεται να κάνετε είναι να βρείτε έναν φάκελο στον οποίο θέλετε να δημιουργήσετε το `virtualenv`. Για παράδειγμα, το home directory σας. Στα Windows, θα μοιάζει κάπως έτσι `C:\Users\Name` ( όπου `Name` είναι το όνομα της σύνδεσης σας). + +> **ΣΗΜΕΙΩΣΗ:** Στα Windows, σιγουρευτείτε ότι αυτός ο κατάλογος δεν περιέχει χαρακτήρες που τονίζονται ή ειδικούς χαρακτήρες. Αν το όνομα χρήστη σας περιέχει χαρακτήρες που τονίζονται, χρησιμοποιείστε ένα διαφορετικό φάκελο, για παράδειγμα `C:\djangogirls`. + +Για αυτό το tutorial θα χρησιμοποιήσουμε ένα νεο φάκελο `djangogirls` από το home directory σας: + +{% filename %}command-line{% endfilename %} + + $ mkdir djangogirls + $ cd djangogirls + + +Θα δημιουργήσουμε ένα virtualenv με το όνομα `myvenv`. Η γενική εντολή είναι: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + + + +Για την δημιουργία ενός νέου `virtualenv`, θα χρειαστεί να ανοίξετε την γραμμή εντολών στον υπολογιστή σας (κονσόλα) και να τρέξετε την εντολή `python -m venv myvenv`. Θα μοιάζει κάπως έτσι: + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls> python -m venv myvenv + + +Όπου `myvenv` είναι το όνομα του `virtualenv` σας. Μπορείτε να χρησιμοποιήσετε οποιοδήποτε άλλο όνομα, αλλά πρέπει να είναι αγγλικοί χαρακτήρες, πεζά, χωρίς κενά, εμφάσεις ή άλλους ειδικούς χαρακτήρες. Είναι επίσης καλή ιδέα να κρατήσετε το όνομα μικρό - θα το αναφέρετε συχνά! + + + + + +Μπορούμε να δημιουργήσουμε ένα `virtualenv` σε Linux και σε macOS τρέχοντας την εντολή `python3 -m venv myvenv`. Θα μοιάζει κάπως έτσι: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + +Το `myvenv` είναι το όνομα του `virtualenv` σας. Μπορείτε να χρησιμοποιήσετε οποιοδήποτε άλλο όνομα, αλλα πρέπει να είναι αγγλικοί χαρακτήρες, πεζά, χωρίς κενά και χωρίς άλλους ειδικούς χαρακτήρες. Είναι επίσης καλή ιδέα να κρατήσετε το όνομα μικρό - θα το αναφέρετε συχνά! + +> **ΣΗΜΕΙΩΣΗ:** Σε μερικές εκδόσεις των Debian/Ubuntu ίσως εμφανιστεί το ακόλουθο σφάλμα: +> +> {% filename %}command-line{% endfilename %} +> +> The virtual environment was not created successfully because ensurepip is not available. Στα λειτουργικά συστήματα Debian/Ubuntu, θα χρειαστεί να εγκαταστήσετε το πακέτο python3-venv χρησιμοποιώντας την ακόλουθη εντολή. +> apt install python3-venv +> Ίσως χρειαστεί να χρηιμοποιήσετε sudo με αυτή την εντολή. Αφού εγκατασταθεί επιτυχώς το πακέτο python3-venv, επαναδημιουργήστε το εικονικό σας περιβάλλον. +> +> +> Σε αυτή την περίπτωση, ακολουθήστε τις οδηγίες παραπάνω και εγκαταστήστε το πακέτο `python3-venv`: {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python3-venv +> +> +> **ΣΗΜΕΙΩΣΗ:** Σε μερικές εκδόσεις των Debian/Ubuntu η ενεργοποίηση του virtual environment με αυτόν τον τρόπο, παράγει το ακόλουθο σφάλμα: +> +> {% 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=python3.6 myvenv +> +> +> **ΣΗΜΕΙΩΣΗ:** Αν λάβετε κάποιο σφάλμα όπως +> +> {% filename %}command-line{% endfilename %} +> +> E: Unable to locate package python3-venv +> +> +> τότε τρέξτε: +> +> {% filename %}command-line{% endfilename %} +> +> sudo apt install python3.6-venv +> + + + +## Δουλεύοντας με το virtualenv + +Η παραπάνω εντολή θα δημιουργήσει έναν φάκελο που ονομάζεται `myvenv` (ή όποιο άλλο όνομα διαλέξετε) που περιέχει το εικονικό μας περιβάλλον (βασικά ένα μάτσο φακέλων και αρχείων). + + + +Ξεκινήστε το εικονικό σας περιβάλλον εκτελώντας: + +{% 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 +> + + + + + +Ξεκινήστε το εικονικό σας περιβάλλον εκτελώντας: + +{% filename %}command-line{% endfilename %} + + $ source myvenv/bin/activate + + +Θυμηθείτε να αντικαταστήσετε το `myvenv` με το επιλεγμένο `virtualenv` όνομα που επιλέξατε! + +> **ΣΗΜΕΙΩΣΗ:** μερικές φορές `πηγή` μπορεί να μην είναι διαθέσιμη. Σε αυτές τις περιπτώσεις προσπαθήστε να κάνετε αυτό: +> +> {% filename %}command-line{% endfilename %} +> +> $ . myvenv/bin/activate +> + + + +Θα ξέρετε ότι είστε μέσα σε ένα `virtualenv` όταν δείτε την γραμμή εντολών στην κονσόλα σας να είναι συμπληρωμένη με το όνομα του μέσα σε παρένθεση, πχ `(myvenv)`. + +Όταν δουλεύετε μέσα σε ένα εικονικό περιβάλλον, η εντολή `python` θα αναφέρετε αυτόματα στην σωστή έκδοση ώστε να μπορείτε να χρησιμοποιήσετε την εντολή `python` αντί για `python3`. + +Εντάξει, μέχρι τώρα έχουμε τακτοποιήσει το περιβάλλον εργασίας μας. Μπορούμε επιτέλους να εγκαταστήσουμε το Django! + +## Εγκατάσταση Django + +Τώρα που είστε μέσα στο `virtualenv`, μπορείτε να εγκαταστήσετε το Django. + +Πριν κάνουμε αυτό, πρέπει να σιγουρευτούμε ότι έχουμε την τελευταία έκδοση του `pip`, το εργαλείο που χρησιμοποιούμε για να εγκαταστήσουμε το Django (και οποιοδήποτε άλλο Python πακέτο όπως θα δούμε αργότερα): + +{% filename %}command-line{% endfilename %} + + (myvenv) ~$ python3 -m pip install --upgrade pip + + +### Εγκατάσταση πακέτων με τα requirements + +Το αρχείο requirements είναι μια λίστα από dependencies (δυστυχώς, πάλι, δεν υπάρχει αντίστοιχος ελληνικός όρος αλλά φανταστείτε το ως τις "απαιτήσεις" της εφαρμογής σας - απαιτήσεις όχι σε μνήμη, σκληρό δίσκο κλπ αλλά σε άλλα προγράμματα) προς εγκατάσταση χρησιμοποιώντας την εντολή `pip install`: + +Δημιουργήστε πρώτα ένα αρχείο `requirements.txt` μέσα στο φάκελο `djangogirls /` χρησιμοποιώντας το πρόγραμμα επεξεργασίας κώδικα που εγκαταστήσατε νωρίτερα. Μπορείτε να το κάνετε αυτό, ανοίγοντας ένα νέο αρχείο στο πρόγραμμα επεξεργασίας κώδικα και στη συνέχεια αποθηκεύοντάς το ως `requirements.txt` στο φάκελο `djangogirls /`. Ο φάκελός σας θα μοιάζει κάπως έτσι: + + djangogirls + └───requirements.txt + + +Στο αρχείο `djangogirls/requirements.txt` θα πρέπει να προσθέσετε τα ακόλουθα: + +{% filename %}djangogirls/requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +Τώρα τρέξτε `pip install -r requirements.txt` για να ξεκινήσει η εγκατάσταση του Django. + +{% filename %}command-line{% endfilename %} + + (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.1MB) + Installing collected packages: Django + Successfully installed Django-{{ book.django_version }} + + + + +> Εάν λάβετε κάποιο σφάλμα όταν τρέχετε το pip σε Windows, παρακαλούμε ελέγξτε εάν η διαδρομή (pathname) του project σας περιέχει κενά, εμφάσεις ή ειδικούς χαρακτήρες (για παράδειγμα,`C:\Users\User Name\djangogirls`). Εάν ναι, παρακαλούμε σκεφτείτε να χρησιμοποιήσετε μία άλλη τοποθεσία χωρίς κενά, εμφάσεις ή ειδικούς χαρακτήρες (για παράδειγμα: `C:\djangogirls`). Δημιουργήστε ένα νέο virtualenv στον νέο αυτό φάκελο, σβήστε τον παλιό και δοκιμάστε την παραπάνω εντολή ξανά. (Το να μετακινήσετε τον virtualenv φάκελο δεν θα δουλέψει μιας και το virtualenv χρησιμοποιεί απόλυτες διαδρομές.) + + + + + +> Η γραμμή εντολών μπορεί να παγώσει όταν εγκατασταθεί το Django. Εάν γίνει αυτό, αντί για την παραπάνω εντολή χρησιμοποιήστε: +> +> {% filename %}command-line{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> + + + + + +> Αν λάβετε κάποιο σφάλμα καθώς τρέχετε την εντολή pip σε Ubuntu 12.04, παρακαλούμε τρέξτε `python -m pip install -U --force-reinstall pip` για να διορθωθεί η εγκατάσταση του pip μέσα στο virtualenv. + + + +Αυτό ήταν! Είστε (επιτέλους) έτοιμοι να δημιουργήσετε μια Django εφαρμογή! \ No newline at end of file diff --git a/el/django_models/README.md b/el/django_models/README.md new file mode 100644 index 00000000000..48875c34b30 --- /dev/null +++ b/el/django_models/README.md @@ -0,0 +1,198 @@ +# Django μοντέλα (models) + +Αυτό που θέλουμε να δημιουργήσουμε τώρα είναι κάτι που θα αποθηκεύει όλες τις αναρτήσεις του blog μας. Αλλά για να είμαστε σε θέση να το κάνουμε, πρέπει να μιλήσουμε λίγο για το τι ονομάζουμε `"αντικείμενα" (objects)`. + +## Objects + +Υπάρχει μια έννοια στον προγραμματισμό που ονομάζεται `"Αντικειμενοστραφής προγραμματισμός`. Η ιδέα είναι ότι αντί να γράφετε τα πάντα ως μια βαρετή ακολουθία από προγραμματιστικές εντολές, μπορούμε να μοντελοποιήσουμε τα πράγματα και να καθορίσουμε πως αλληλεπιδρούν μεταξύ τους. + +Άρα, τι είναι ένα αντικείμενο; Είναι μια συλλογή από ιδιότητες και συμπεριφορές. Ακούγεται παράξενο, αλλά θα σας δώσουμε ένα παράδειγμα. + +Εάν θέλουμε να μοντελοποιήσουμε μια γάτα, θα δημιουργήσουμε ένα αντικείμενο `Γάτα` το οποίο έχει κάποιες ιδιότητες όπως `χρώμα`, `ηλικία`, `διάθεση` (όπως καλή, κακή, νυσταγμένη :)), και `ιδιοκτήτης`(που θα μπορεί να ανατεθεί σε ένα αντικείμενο `άτομο` ή ίσως, στην περίπτωση μιας αδέσποτης γάτας, αυτή η ιδιότητα θα μπορούσε να είναι άδεια). + +Έπειτα η `γάτα` έχει κάποιες δράσεις `γουργούρισμα`, `ξύσιμο` ή `τάισμα`( σε αυτή την περίπτωση, θα δώσουμε στην γάτα λίγη `γατοτροφή`, που θα μπορούσε να είναι ένα ξεχωριστό αντικείμενο με ιδιότητες, όπως `γεύση`). + + Cat + -------- + color + age + mood + owner + purr() + scratch() + feed(cat_food) + + + CatFood + -------- + taste + + +Βασικά η ιδέα είναι να περιγράψουμε τα αληθινά πράγματα στον κώδικα με ιδιότητες (που ονομάζονται `object properties`) και συμπεριφορές (που ονομάζονται `methods`). + +Πώς θα μοντελοποιήσουμε τότε τις αναρτήσεις του blog; Θέλουμε να κατασκευάσουμε ένα blog, σωστά; + +Πρέπει να δώσουμε απάντηση στο ερώτημα: τι είναι μία ανάρτηση στο blog; Τι ιδιότητες πρέπει να έχει; + +Λοιπόν, σίγουρα μία ανάρτηση στο blog μας χρειάζεται κάποιο κείμενο με το περιεχόμενό του και έναν τίτλο, σωστά; Θα ήταν επίσης ωραίο να ξέρουμε ποιος το έγραψε αυτό. Έτσι χρειαζόμαστε έναν συγγραφέα. Τέλος, θέλουμε να γνωρίζουμε πότε δημιουργήθηκε και δημοσιεύτηκε η συγκεκριμένη ανάρτηση. + + Post + -------- + title + text + author + created_date + published_date + + +Τι είδους πράγματα θα μπορούσαν να γίνουν με μια ανάρτηση στο blog; Θα ήταν ωραίο να έχουμε κάποια `method` που δημοσιεύει την ανάρτηση, σωστά; + +Έτσι, θα χρειαστούμε μια μέθοδο `publish`. + +Δεδομένου ότι γνωρίζουμε ήδη τι θέλουμε να επιτύχουμε, ας ξεκινήσουμε τη μοντελοποίηση στο Django! + +## Django model + +Γνωρίζοντας τι είναι ένα αντικείμενο, μπορούμε να δημιουργήσουμε ένα μοντέλο Django για την ανάρτηση στο blog μας. + +Ένα μοντέλο στο Django είναι ένα ιδιαίτερο είδος αντικειμένου το οποίο αποθηκεύεται στη βάση δεδομένων `database`. Η βάση δεδομένων είναι μια συλλογή δεδομένων. Είναι εκεί όπου θα αποθηκευτούν όλες οι πληροφορίες για τους χρήστες, τις αναρτήσεις στο blog, κλπ. Θα χρησιμοποιήσουμε την βάση δεδομένων SQLite για την αποθήκευση των δεδομένων μας. Αυτός είναι η προεπιλεγμένη βάση δεδομένων του Django. Είναι αρκετό για εμάς για την ώρα. + +Μπορείτε να σκεφτείτε ένα μοντέλο της βάσης δεδομένων ως ένα υπολογιστικό φύλλο με στήλες (πεδία) και γραμμές (δεδομένα). + +### Δημιουργία μιας εφαρμογής + +Για να κρατήσουμε τα πάντα τακτοποιημένα, θα δημιουργήσουμε μια ξεχωριστή εφαρμογή μέσα στο project μας. Είναι πολύ ωραίο να έχουμε τα πάντα οργανωμένα από την αρχή. Για την δημιουργία μιας εφαρμογής θα χρειαστεί να τρέξουμε την ακόλουθη εντολή στην κονσόλα (από τον φάκελο `djangogirls` όπου βρίσκεται το αρχείο `manage.py`): + +{% filename %}macOS and Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py startapp blog + + +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + + +Θα παρατηρήσετε ότι ένας νέος φάκελος με το όνομα `blog` δημιουργήθηκε και περιέχει έναν αριθμό αρχείων. Οι φάκελοι και τα αρχεία στο project μας πρέπει να μοιάζουν κάπως έτσι: + + djangogirls + ├── blog + │   ├── __init__.py + │   ├── admin.py + │   ├── apps.py + │   ├── migrations + │   │   └── __init__.py + │   ├── models.py + │   ├── tests.py + │   └── views.py + ├── db.sqlite3 + ├── manage.py + ├── mysite + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + └── requirements.txt + + +Μετά την δημιουργία μίας εφαρμογής, πρέπει επίσης να πούμε στο Django ότι πρέπει να τη χρησιμοποιήσει. Το κάνουμε αυτό μέσα στο αρχείο `mysite/settings.py`. Ανοίξτε το. Πρέπει να βρούμε την λίστα `INSTALLED_APPS` και να προσθέσουμε εκεί το εξής: `'blog',` πάνω από το `]`. Έτσι το τελικό προϊόν πρέπει να μοιάζει κάπως έτσι: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog', +] +``` + +### Δημιουργία ενός post model + +Μέσα στο αρχείο `blog/models.py` ορίζουμε όλα τα objects με το όνομα `Models`. Αυτό είναι ένα μέρος όπου θα ορίσουμε το post μοντέλο μας. + +Ας ανοίξουμε το αρχείο `blog/models.py`, διαγράψτε τα περιεχόμενα του και γράψτε τα εξής: + +{% filename %}blog/models.py{% endfilename %} + +```python +from django.conf import settings +from django.db import models +from django.utils import timezone + + +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) + + def publish(self): + self.published_date = timezone.now() + self.save() + + def __str__(self): + return self.title +``` + +> Σιγουρευτείτε ότι χρησιμοποιείτε δύο φορές την κάτω παύλα (`_`) σε κάθε πλευρά του `str`. Αυτό είναι απαραίτητο και συχνά θα το συναντάτε στην Python. Συνηθίζεται να ονομάζεται "dunder" (σύντμηση για "double-underscore"). + +Μη φοβάστε. Θα εξηγήσουμε τι συμβαίνει! + +Όλες οι γραμμές που ξεκινούν με τις λέξεις `from` ή `import` είναι γραμμές που εισάγουν λειτουργίες από άλλα Python αρχεία (αυτά με την κατάληξη .py). Έτσι αντί να κάνουμε αντιγραφή-επικόλληση κώδικα, πολύ απλά συμπεριλαμβάνουμε κώδικα από άλλα αρχεία με τη χρήση του `from ... import ...`. + +`class Post(models.Model):` – αυτή η γραμμή ορίζει το μοντέλο μας (είναι μια κλάση που με τη σειρά της είναι και αυτή ένα `object`). + +- Η λέξη `class` είναι μια ιδιαίτερη λέξη-κλειδί που καθορίζει τον ορισμό μιας κλάσης. +- Η λέξη `Post` είναι το όνομα του μοντέλου μας. Μπορούμε να του δώσουμε όποιο όνομα θέλουμε (αλλά πρέπει να αποφεύγουμε ιδιαίτερους χαρακτήρες και κενά). Πάντα το όνομα μιας κλάσης να ξεκινάει με ένα κεφαλαίο γράμμα. +- Η γραμμή `models.Model` σημαίνει ότι το Post είναι ένα Django Model. Με αυτό τον τρόπο το Django θα ξέρει ότι θα πρέπει να αποθηκεύεται σε μια βάση δεδομένων. + +Τώρα ορίζουμε τα properties που λέγαμε: `title`, `text`, `created_date`, `published_date` και `author`. Για να το κάνουμε αυτό θα πρέπει να ορίσουμε τον τύπο τιμών που θα δέχεται το κάθε πεδίο (είναι κείμενο; αριθμός; ημερομηνία; κάποια συσχέτιση με ένα άλλο object, όπως ένας χρήστης;) + +- `models.CharField` – έτσι δηλώνετε ότι θέλετε να ορίσετε ένα κείμενο με συγκεκριμένο αριθμό χαρακτήρων. +- `models.TextField`- αυτό είναι για μεγάλα κείμενα χωρίς όριο. Ακούγεται ιδανικό για περιεχόμενο δημοσιεύσεων blog, έτσι δεν είναι; +- `models.DateTimeField`- αυτό είναι για ημερομηνία και ώρα. +- `models.ForeignKey`- αυτό είναι ένας σύνδεσμος για ένα άλλο μοντέλο. + +Δεν θα εξηγήσουμε κάθε κομμάτι του κώδικα διότι θα πάρει αρκετό χρόνο. Θα πρέπει να ρίξετε μια ματιά στo documentation του Django αν θέλετε να μάθετε περισσότερα σχετικά με τα πεδία των μοντέλων και πως να ορίζετε πράγματα εκτός από αυτά που αναφέρθηκαν παραπάνω (https://docs.djangoproject.com/en/2.0/ref/models/fields/#field-types). + +Τι γίνεται με την μέθοδο `def publish(self):`; Αυτή είναι ακριβώς η μέθοδος `publish` για την οποία μιλούσαμε πριν. `def` σημαίνει ορίζουμε μια συνάρτηση/μέθοδο (ανάλογα αν είναι μέρος τηε κλάσης ή όχι) και `publish` είναι το όνομα της. Μπορείτε να αλλάξετε το όνομα της μεθόδου αν θέλετε. Ο κανόνας ονομασίας είναι ότι χρησιμοποιούμε πεζά γράμματα και κάτω παύλες αντί για κενά. Αν χρησιμοποιήσετε κενά τότε λάβετε σφάλμα. Για παράδειγμα, μια μέθοδος που υπολογίζει την μέση τιμή θα λεγόταν `calculate_average_price`. + +Οι μέθοδοι συχνά κάνουν `return` κάτι, δηλαδή επιστρέφουν μια τιμή ή οτιδήποτε άλλο. Μπορεί όμως και όχι. Υπάρχει ένα παράδειγμα αυτού στη μέθοδο `__str__`. Σε αυτό το σενάριο, όταν καλούμε την `__str__()` θα λάβουμε ένα κείμενο (**string**) με τον τίτλο του post. + +Επίσης προσέξτε ότι και το `def publish(self):` και το `def __str__(self):` είναι δηλωμένα μέσα στην κλάση μας (με κενά ή με tab). Επειδή η Python είναι ευαίσθητη στα κενά (στους κενούς χαρακτήρες), θα πρέπει να "βάλουμε" τις μεθόδους μας μέσα στην κλάση. Αλλιώς, οι μέθοδοι δεν θα ανήκουν στην κλάση και μπορεί να συναντήσετε απρόοπτη συμπεριφορά. + +Εάν κάτι ακόμα δεν είναι ξεκάθαρο σχετικά με τα μοντέλα, μη διστάσετε να ρωτήσετε τον επιτηρητή σας! Ξέρουμε ότι είναι περίπλοκο, ειδικά όταν μαθαίνετε τι είναι τα αντικείμενα και συναρτήσεις ταυτόχρονα. Αλλά ελπίζουμε να μοιάζει λιγότερο μαγικό για εσάς τώρα! + +### Δημιουργία πινάκων για μοντέλα στην βάση δεδομένων σας + +Το τελευταίο βήμα εδώ είναι να προσθέσουμε το νέο μοντέλο μας στην βάση δεδομένων μας. Πρώτα πρέπει να ενημερώσουμε το Django ότι έχουμε κάποιες αλλαγές στο μοντέλο μας. (Μόλις το δημιουργήσαμε!) Πηγαίνετε στο παράθυρο της κονσόλας σας και πληκτρολογήστε `python manage.py makemigrations blog`. Θα μοιάζει κάπως έτσι: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py makemigrations blog + Migrations for 'blog': + blog/migrations/0001_initial.py: + + - Create model Post + + +**Σημείωση:** Θυμηθείτε να αποθηκεύετε τα αρχεία που επεξεργάζεστε. Αλλιώς, ο υπολογιστής σας θα εκτελέσει τις προηγούμενες εκδόσεις που μπορεί να σας δώσει μηνύματα απρόοπτων σφαλμάτων. + +Το Django προετοίμασε ένα αρχείο migration για εμάς που πρέπει τώρα να εφαρμόσουμε στην βάση δεδομένων μας. Πληκτρολογήστε `python manage.py migrate blog` και τo αποτελέσματα πρέπει να είναι όπως παρακάτω: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py migrate blog + Operations to perform: + Apply all migrations: blog + Running migrations: + Applying blog.0001_initial... OK + + +Ζήτω! Το Post μοντέλο μας είναι στην βάση δεδομένων! Θα ήταν ωραίο να το δούμε, σωστά; Πηγαίνετε στο επόμενο κεφάλαιο για να δείτε πως μοιάζει η ανάρτηση σας! \ No newline at end of file diff --git a/el/django_orm/README.md b/el/django_orm/README.md new file mode 100644 index 00000000000..524c8fd9e3c --- /dev/null +++ b/el/django_orm/README.md @@ -0,0 +1,221 @@ +# Django ORM και QuerySets + +Σε αυτό το κεφάλαιο θα μάθετε πως το Django συνδέεται στην βάση δεδομένων και αποθηκεύει δεδομένα μέσα της. Ας ξεκινήσουμε! + +## Τι είναι ένα QuerySet; + +Ένα QuerySet είναι, στην ουσία, μία λίστα αντικειμένων ενός Μοντέλου. Τα QuerySets σας επιτρέπουν να διαβάσετε τα δεδομένα από την βάση δεδομένων, να τα φιλτράρετε και να τα ταξινομήσετε. + +Είναι πιο εύκολο να μάθεις κάνοντας το. Πάμε να δοκιμάσουμε; + +## Παράθυρο εντολών Django (django shell) + +Άνοιξτε την κονσόλα (όχι στο PythonAnywhere) και πληκτρολογήστε αυτήν την εντολή: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py shell + + +Το αποτέλεσμα πρέπει να είναι σαν αυτό: + +{% filename %}command-line{% endfilename %} + +```python +(InteractiveConsole) +>>> +``` + +Είστε τώρα στην διαδραστική κονσόλα του Django. Είναι ακριβώς όπως το παράθυρο εντολών της Python, αλλά με μια μικρή επιπρόσθετη μαγεία του Django. :) Φυσικά, μπορείτε να χρησιμοποιήσετε όλες τις εντολές Python εδώ. + +### Όλα τα αντικείμενα + +Ας προσπαθήσουμε να εμφανίσουμε όλες τις δημοσιεύσεις του blog μας πρώτα. Μπορείτε να το κάνετε με την ακόλουθη εντολή: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +Traceback (most recent call last): + File "", line 1, in +NameError: name 'Post' is not defined +``` + +Ωχ! Εμφανίστηκε ένα λάθος, μας λέει ότι δεν υπάρχει καμία δημοσίευση. Είναι σωστό. Ξεχάσαμε να το εισάγουμε πρώτα (να το κάνουμε, δηλαδή, import)! + +{% filename %}command-line{% endfilename %} + +```python +>>> from blog.models import Post +``` + +Εισάγουμε το μοντέλο `Post` από το module `blog.models`. Ας προσπαθήσουμε να εμφανίσουμε όλες τις αναρτήσεις ξανά: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, ]> +``` + +Αυτή είναι μια λίστα των αναρτήσεων που δημιουργήσαμε νωρίτερα! Δημιουργήσαμε αυτές τις αναρτήσεις χρησιμοποιώντας το περιβάλλον διαχειριστή Django. Αλλά τώρα θέλουμε να δημιουργήσουμε νέες αναρτήσεις χρησιμοποιώντας την Python, οπότε πως το κάνουμε αυτό; + +### Δημιουργία αντικειμένου + +Έτσι δημιουργείται ένα νέο αντικείμενο Post στην βάση δεδομένων: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') +``` + +Αλλά μας λείπει ένα συστατικό εδώ: `εγώ`. Χρειαζόμαστε να περάσουμε μία παρουσία του μοντέλου `User` ως τον author. Πως το κάνουμε αυτό; + +Ας εισάγουμε το μοντέλο User πρώτα: + +{% filename %}command-line{% endfilename %} + +```python +>>> from django.contrib.auth.models import User +``` + +Τι χρήστες έχουμε στην βάση δεδομένων μας; Δοκιμάστε αυτό: + +{% filename %}command-line{% endfilename %} + +```python +>>> User.objects.all() +]> +``` + +Αυτός είναι ο χρήστης superuser που δημιουργήσαμε νωρίτερα! Ας πάρουμε ένα instance από την κλάση User τώρα (αντικαταστείστε το όνομα με το όνομα χρήστη που βάλατε νωρίτερα ως superuser): + +{% filename %}command-line{% endfilename %} + +```python +>>> me = User.objects.get(username='ola') +``` + +Όπως βλέπετε, κάνουμε ένa `get` για έναν `User` με ένα `username` το οποίο ισούται με 'ola'. Καλό! + +Τώρα μπορούμε, επιτέλους να δημιουργήσουμε το post: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') + +``` + +Ζήτω! Θέλετε να ελέγξετε αν λειτούργησε; + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, , ]> +``` + +Αυτό είναι, άλλη ένα post στη λίστα! + +### Προσθέστε περισσότερα posts + +Τώρα μπορείτε να διασκεδάσετε λίγο και να προσθέσετε περισσότερες δημοσιεύσεις για να δείτε πως δουλεύει. Προσθέστε δυο-τρεις ακόμα και μετά προχωρήστε στο επόμενο μέρος. + +### Φιλτράρισμα αντικειμένων + +Ένα μεγάλο μέρος των χαρακτηριστικών των QuerySets είναι η δυνατότητα να τα φιλτράρουμε. Ας υποθέσουμε ότι θέλουμε να βρούμε όλα τα posts όπου ο χρήστης ola έγραψε. Θα χρησιμοποιήσουμε την μέθοδο `filter` αντί της `all` στην εντολή `Post.objects.all()`. Μέσα στις παρενθέσεις της μεθόδου filter δηλώνουμε τα κριτήρια αναζήτησης για αυτό που ψάχνουμε. Στην περίπτβση μας, το κριτήριο είναι ένα `author` και θέλουμε να είναι ίσο με `me`. Ο τρόπος που το γράφουμε στο Django είναι `author=me`. Τώρα ο κώδικας μοιάζει κάπως έτσι: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(author=me) +, , , ]> +``` + +Ή ίσως θα θέλαμε να δούμε όλα τα posts τα οποία περιέχουν τη λέξη 'title' μέσα στο πεδίο `title`; + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(title__contains='title') +, ]> +``` + +> **Σημείωση** Υπάρχουν δύο κάτω παύλες (`_`) μεταξύ του `title` και του `contains`. Το Django ORM χρησιμοποιεί αυτόν τον κανόνα για να διαχωρίσει τα ονόματα των πεδίων των μοντέλων ("title") με τους διαχωριστές ή τα φίλτρα ("contains"). Αν χρησιμποιούσατε μόνο μια κάτω παύλα θα λαμβάνατε το σφάλμα "FieldError: Cannot resolve keyword title_contains". + +Μπορείτε επίσης να πάρετε μια λίστα από δημοσιευμένα posts. Το κάνουμε αυτό φιλτράροντας όλα τα posts που έχουν παρελθοντική ημ/νια `published_date`: + +{% filename %}command-line{% endfilename %} + +```python +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) + +``` + +Δυστυχώς, το post που αναρτήσαμε από την Python κονσόλα δεν είναι δημοσιευμένο ακόμα. Αλλά μπορούμε να το αλλάξουμε αυτό. Πρώτα, πάρτε ένα instance από το post που θέλετε να δημοσιεύσετε: + +{% filename %}command-line{% endfilename %} + +```python +>>> post = Post.objects.get(title="Sample title") +``` + +Και έπειτα δημοσιεύστε το με την μέθοδο `publish`: + +{% filename %}command-line{% endfilename %} + +```python +>>> post.publish() +``` + +Τώρα προσπαθήστε να πάρετε μια λίστα από δημοσιευμένα posts ξανά (πιέστε το πάνω βελάκι στο πληκτρολόγιο 3 φορές και έπειτα `enter`): + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +]> +``` + +### Ταξινόμηση objects + +Τα QuerySets επίσης σου επιτρέπουν να ταξινομήσεις την λίστα των αντικειμένων. Ας προσπαθήσουμε να τα ταξινομήσουμε ως προς πεδίο `created_date`: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.order_by('created_date') +, , , ]> +``` + +Μπορούμε επίσης να αντιστρέψουμε την ταξινόμηση προσθέτοντας `-` στην αρχή: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.order_by('-created_date') +, , , ]> +``` + +### Αλυσιδωτά QuerySets + +Μπορείτε επίσης να συνδυάσετε QuerySets με το να τα **αλυσοδέσετε** μαζί: + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> +``` + +Αυτό είναι πολύ ισχυρό και σας επιτρέπει να γράψετε αρκετά σύνθετα ερωτήματα. + +Ωραία! Τώρα είστε έτοιμοι για το επόμενο μέρος! Για να κλείσετε το κέλυφος, πληκτρολογήστε αυτό: + +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` \ No newline at end of file diff --git a/el/django_start_project/README.md b/el/django_start_project/README.md new file mode 100644 index 00000000000..59b6da15d12 --- /dev/null +++ b/el/django_start_project/README.md @@ -0,0 +1,205 @@ +# Το πρώτο σας Django project! + +> Μέρος αυτού του κεφαλαίου είναι βασισμένο στους οδηγούς από την κοινότητα 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 ανήκουν στον Markus Zapke-Gründemann. + +Πρόκειται να δημιουργήσουμε ένα μικρό blog! + +Το πρώτο βήμα είναι να ξεκινήσουμε ένα νέο Django project. Βασικά αυτό σημαίνει ότι θα εκτελέσουμε μερικά scripts (εντολές) που παρέχονται από το Django τα οποία θα δημιουργήσουν τον σκελετό ενός Django project για εμάς. Αυτά είναι ένα σύμπλεγμα φακέλων και αρχείων που θα χρησιμοποιήσουμε αργότερα. + +Τα ονόματα μερικών αρχείων και φακέλων είναι πολύ σημαντικά για το Django. Δεν πρέπει να μετονομάσετε τα αρχεία που πρόκειται να δημιουργήσουμε. Μετακινώντας τα σε ένα διαφορετικό μέρος δεν είναι επίσης καλή ιδέα. Το Django χρειάζεται να διατηρήσει μία συγκεκριμένη δομή για να μπορεί να βρει σημαντικά πράγματα. + +> Θυμηθείτε να εκτελείτε τα πάντα μέσα σε κάποιο εικονικό περιβάλλον. Εάν δεν δείτε ένα πρόθεμα `(myenv)` στην κονσόλα σας, θα πρέπει να ενεργοποιήσετε το εικονικό περιβάλλον σας. Εξηγήσαμε πως να το κάνετε αυτό στο κεφάλαιο **Εγκατάσταση Django** στην ενότητα **Δουλεύοντας με το εικονικό περιβάλλον**. Σε Windows δοκιμάστε να γράψετε `myvenv\Scripts\activate` ή αν έχετε Lixux/macOS γράψτε `source myvenv/bin/activate`. + + + +Στην κονσόλα σας macOS ή Linux, πρέπει να εκτελέσετε την ακόλουθη εντολή. ** Μην ξεχάσετε να προσθέσετε την τελεία `. ` στο τέλος!** + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ django-admin startproject mysite . + + +> Η τελεία `.` είναι ζωτικής σημασίας επειδή λέει στην εντολή να εγκαταστήσει το Django στο τρέχον φάκελο σας ( για το οποίο η τελεία `.` είναι μία συντόμευση). +> +> **Σημείωση** Όταν πληκτρολογείτε την παραπάνω εντολή, θυμηθείτε ότι πληκτρολογείτε το κομμάτι που ξεκινά με `django-admin`. Το κομμάτι κονσόλας που εμφανίζεται εδώ `(myvenv) ~/djangogirls$` είναι απλώς ένα παράδειγμα. + + + + + +Στα Windows πρέπει να εκτελέσετε την ακόλουθη εντολή. **(Μην ξεχάσετε να προσθέσετε την τελεία `.` στο τέλος)**: + +{% filename %}command-line{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . + + +> Η τελεία `.` είναι ζωτικής σημασίας επειδή λέει στην εντολή να εγκαταστήσει το Django στο τρέχον φάκελο σας ( για το οποίο η τελεία `.` είναι μία συντόμευση). +> +> **Σημείωση** Όταν πληκτρολογείτε την παραπάνω εντολή, θυμηθείτε ότι πληκτρολογείτε το κομμάτι που ξεκινά με `django-admin.exe`. Το κομμάτι κονσόλας που εμφανίζεται εδώ `(myvenv) ~/djangogirls$` είναι απλώς ένα παράδειγμα. + + + +Η εντολή `django-admin.py` μπορεί να δημιουργήσει τους φακέλους και τα αρχεία για εσάς. Θα πρέπει τώρα να έχετε μια δομή φακέλων που μοιάζει κάπως έτσι: + + djangogirls + ├───manage.py + ├───mysite + │ settings.py + │ urls.py + │ wsgi.py + │ __init__.py + └───requirements.txt + + +> **Σημείωση**: Στην δομή φακέλων σας, θα δείτε επίσης τον `myvenv` φάκελο σας που δημιουργήσαμε προηγουμένως. + +Το `manage.py` είναι ένα script που βοηθά με την διαχείριση του project σας. Με αυτό θα μπορούμε να (μεταξύ άλλων πραγμάτων) ξεκινήσουμε έναν server στον υπολογιστή μας χωρίς να εγκαταστήσουμε οτιδήποτε άλλο. + +Το αρχείο `settings.py` περιέχει τις διάφορες παραμέτρους του project σας. + +Θυμάστε όταν μιλήσαμε σχετικά με ένα μεταφορέα αλληλογραφίας που ελέγχει που να παραδώσει ένα γράμμα; Το αρχείο `urls.py` περιέχει μία λίστα από σχέδια που χρησιμοποιούνται από τον `urlresolver`. + +Ας αφνοήσουμε τα υπόλοιπα αρχεία προς το παρόν καθώς δεν θα τα αλλάξουμε καθόλου. Το μόνο πράγμα που πρέπει να θυμάστε είναι να μην τα διαγράψετε κατά λάθος! + +## Αλλάζοντας τις ρυθμίσεις + +Ας κάνουμε μερικές αλλαγές στο αρχείο `mysite/settings.py`. Ανοίξτε το. + +**Σημείωση**: Κρατήστε στο μυαλό σας ότι το αρχείο `settings.py` είναι ένα κοινό Python αρχείο όπως όλα τα άλλα Python αρχεία (έχουν, δηλαδή, την κατάληξη .py). Μπορείτε να το ανοίξετε μέσα από τον επεξεργαστή κώδικα που χρησιμοποιείτε, κλικάροντας στο "File -> Open". Αυτό θα εμφανίσει ένα παράθυρο εξερεύνησης αρχείων μέσα από το οποίο επιλέγετε το αρχείο `settings.py` και το ανοίγετε. Εναλλακτικά, μπορείτε να μεταβείτε μέσα από τον φάκελο djangogirls και με δεξί κλικ να το ανοίξετε. Έπειτα, επιλέξτε τον επεξεργαστή κώδικα από την προτινώμενη λίστα προγραμμάτων. Η επιλογή του επεξεργαστή κώδικα είναι σημαντική καθώς μπορεί να έχετε άλλα προγράμματα εγκατεστημένα. + +Θα ήτνα καλό να έχουμε τη σωστή ώρα στην ιστοσελίδα μας. Πηγαίνετε στο [Wikipedia's list of time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) και αντιγράψτε την ζώνη ώρας σας (TZ) (πχ `Europe/Athens`). + +Στο αρχείο `settings.py`, βρείτε τη γραμμή που λέει `TIME_ZONE` και αλλάξτε την τιμή της σε αυτή που αντιγράψατε. Για παράδειγμα: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +TIME_ZONE = 'Europe/Berlin' +``` + +Ο κωδικό γλώσσας (language code) αποτελείται από την γλώσσα, πχ `en` για Αγγλικά ή `el` για Ελληνικά και τον κωδικό χώρας πχ `gr` για Ελλάδα ή `ch` για την Ελβετία. Αν τα Ελληνικά είναι η μητρική σας γλώσσα, μπορείτε να προσθέσετε το παρακάτω για να αλλάξετε την γλώσσα σε Ελληνικά: Μπορείτε, δηλαδή, να έχετε ένα κουμπί "Άκυρο" μεταφρασμένο στην γλώσσα σας. [Το Django έρχεται με προεγκατεστημένες κάποιες μεταφράσεις](https://docs.djangoproject.com/en/2.0/ref/settings/#language-code). + +Αν θέλετε κάποια διαφορετική γλώσσα, αλλάξτε το string LANGUAGE_CODE όπως παρακάτω με την τική που εσείς επιθυμείτε: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +LANGUAGE_CODE = 'el-GR' +``` + +Χρειάζεται επίσης να ρυθμίσουμε τα στατικά αρχεία μας. (Θα βρείτε τα πάντα για τα στατικά αρχεία και το CSS αργότερα στον οδηγό.) Πηγαίνετε προς τα κάτω μέχρι το *τέλος* του αρχείου και ακριβώς κάτω από την καταχώρηση `STATIC_URL`, προσθέστε μια νέα που ονομάζεται `STATIC_ROOT`: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +STATIC_URL = '/static/' +STATIC_ROOT = BASE_DIR / 'static' +``` + +Όταν το flag `DEBUG` είναι `True` και η λίστα `ALLOWED_HOSTS` είναι κενή, ο host επικυρώνεται μέσα από την ακόλουθη λίστα `[«localhost', '127.0.0.1', ' [:: 1]']`. Αυτό δεν θα ταιριάξει το hostname μας στο PythonAnywhere μόλις κάνουμε deploy την εφαρμογή μας. Οπότε θα χρειαστεί να κάνουμε την ακόλουθη αλλαγή: + +{% 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 + +## Δημιουργία μιας βάσης δεδομένων + +Υπάρχουν πολλές διαφορετικές βάσεις δεδομένων που μπορούν να αποθηκεύσουν δεδομένα για την σελίδα σας. Θα χρησιμοποιήσουμε την προεπιλεγμένη, `sqlite3`. + +Αυτό έχει ήδη δηλωθεί στο αρχείο `mysite/settings.py`: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} +``` + +Για να δημιουργήσετε μία βάση δεδομένων για το blog σας, ας εκτελέσουμε το ακόλουθο στην κονσόλα: `python manage.py migrate` ( χρειάζεται να είμαστε στον φάκελο `djangogirls` που περιέχει το αρχείο `manage.py`). Αν αυτό πάει καλά, θα πρέπει να δείτε κάτι σαν αυτό: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py migrate + Operations to perform: + Apply all migrations: auth, admin, 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 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 sessions.0001_initial... ΟΚ + + +Και τελειώσαμε! Ώρα να ξεκινήσουμε τον server και να δούμε εάν η ιστοσελίδα μας λειτουργεί! + +## Εκκίνηση του development server + +Θα πρέπει να είστε στον φάκελο που περιέχει το αρχείο `manage.py` (στον φάκελο `djangogirls`). Στην κονσόλα, μπορούμε να ξεκινήσουμε τον server εκτελώντας `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 + + +Αν είστε σε Windows και αυτή η ενέργεια αποτύχει με σφάλμα `UnicodeDecodeError`, χρησιμοποιείστε αντί για αυτό, αυτή την εντολή: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + + +Τώρα θα χρειαστεί να ελέγξετε αν το site σας δουλεύει. Ανοίξτε έναν browser (Firefox, Chrome, Safari ή Internet Explorer ή οτιδήποτε άλλο χρησιμοποιείτε) και πληκτρολογήστε την παρακάτω διεύθυνση: + +{% filename %}browser{% endfilename %} + + http://127.0.0.1:8000/ + + +Αν χρησιμοποιείτε Chromebook και Cloud9, αντί κλικάρετε στο παράθυρο που εμφανίστηκε στην πάνω δεξιά γωνία όπου ο server τρέχει. Το url θα δείχνει κάπως έτσι: + +{% filename %}browser{% endfilename %} + + https://.vfs.cloud9.us-west-2.amazonaws.com + + +Συγχαρητήρια! Μόλις δημιουργήσατε το πρώτο σας website το οποίο τρέχει χρησιμοποιώντας έναν web server! Δεν είναι φοβερό; + +![Η εγκατάσταση πέτυχε!](images/install_worked.png) + +Σημειώστε ότι ένα παράθυρό εντολών μπορεί να εκτελεί μόνο μια εντολή κάθε φορά και η εντολή που τρέχει αυτή τη στιγμή είναι ένας web server. Όσο ο server τρέχει και αναμένει εισερχόμενα requests το τερματικό θα εμφανίζει κάποια μηνύματα αλλά δεν θα εκτελεί νέες εντολές. + +> Είδαμε πως λειτουργούν οι web servers στο κεφάλαιο **Πως λειτουργεί το internet**. + +Για να γράψετε άλλες εντολές όσο ο server τρέχει, ανοίξτε ένα νέο παράθυρο και ενεργοποιήστε το virtualenv σας. Για να σταματήσετε τον server, μεταβείτε στο παράθυρο που τρέχει και πιέστε Ctrl + C (σε Windows θα πρέπει να πιέσετε Ctrl + Break). + +Έτοιμοι για το επόμενο βήμα; Ώρα να δημιουργήσουμε περιεχόμενο για το blog μας! \ No newline at end of file diff --git a/el/django_start_project/images/install_worked.png b/el/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..4354c634ddb Binary files /dev/null and b/el/django_start_project/images/install_worked.png differ diff --git a/el/django_templates/README.md b/el/django_templates/README.md new file mode 100644 index 00000000000..445ed333831 --- /dev/null +++ b/el/django_templates/README.md @@ -0,0 +1,106 @@ +# Django templates + +Ήρθε η ώρα να παρουσιάσουμε ορισμένα δεδομένα! Το Django μας δίνει κάποια προεγκατεστημένα **template tags**. + +## Τι είναι τα template tags; + +Βλέπετε, στην HTML δεν μπορείτε να γράψετε κώδικα σε Python επειδή οι browsers δεν καταλαβαίνουν αυτή τη γλώσσα. Εκείνοι ξέρουν μόνο HTML, CSS και Javascript. Ξέρουμε ότι η HTML είναι στατική γλώσσα ενώ η Python περισσότερο δυναμική. + +Τα **Django template tags** μας επιτρέπουν να μεταφέρουμε πράγματα της Python μέσα στην HTML, ούτως ώστε να χτίσετε δυναμικές ιστοσελίδες γρηγορότερα. Τέλεια! + +## Template προβολή λίστας των post + +Σε προηγούμενο κεφάλαιο δώσαμε στο template μας μια λίστα από posts μέσα σε μια μεταβλητή με το όνομα `posts`. Τώρα θα την προβάλουμε στην HTML. Άλλωστε αυτό θέλαμε να κάνουμε από την αρχή. + +Για να εκτυπώσουμε μια μεταβλητή μέσα στα Django templates, χρησιμοποιούμε διπλές αγκύλες ({% raw %}{{ }}{% endraw %}) με το όνομα της μεταβλητής ανάμεσα: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{{ posts }} +``` + +Δοκιμάστε αυτό μέσα στο template `blog/templates/blog/post_list.html`. Ανοίξτε το και αντικαταστήστε τα πάντα από το δεύτερο `
` to the third `
` με το `{{ posts }}`. Αποθηκεύστε το αρχείο και ανανεώστε τη σελίδα για να δείτε τα αποτελέσματα: + +![Σχήμα 13.1](images/step1.png) + +Όπως βλέπετε, το μόνο που έχουμε είναι το εξής: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +, ]> +``` + +Αυτό σημαίνει ότι το Django το εκλαμβάνει ως μια λίστα από objects. Θυμηθείτε στο κεφάλαιο **Εισαγωγή στην Python** πως προβάλαμε λίστες; Ναι, με επαναλήψεις! Στα Django template το κάνετε ως εξής: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} + {{ post }} +{% endfor %} +``` + +Δοκιμάστε αυτό στο template. + +![Σχήμα 13.2](images/step2.png) + +Δούλεψε! Αλλά θέλουμε τα posts μα εμφανίζονται όπως τα στατικά posts που φτιάξαμε νωρίτερα στο κεφάλαιο **Εισαγωγή στην HTML**. Μπορείτε να μιξάρετε HTML και template tags μαζί. Έτσι, το `body` θα μοιάζει κάπως έτσι: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+ +{% for post in posts %} +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` + +{% raw %}Οτιδήποτε βάζετε ανάμεσα στο `{% for %}` και το `{% endfor %}` θα επαναληφθεί για κάθε object στη λίστα. Ανανεώστε τη σελίδα:{% endraw %} + +![Σχήμα 13.3](images/step3.png) + +Παρατηρήσατε ότι χρησιμοποιούμε έναν διαφορετικό τρόπο πρόσβασης αυτή τη φορά (`{{ post.title }}` ή `{{ post.text }}`); Αποκτούμε πρόσβαση στα δεδομένα κάθε πεδίου που είναι ορισμένα στο μοντέλο `Post`. Επίσης, η κάθετη γραμμή `|linebreaksbr` φιλτράρει το κείμενο του posts όπου μετατρέπει τις αλλαγές γραμμής σε παράγράφους. + +## Ένα ακόμα πράγμα + +Θα ήταν καλό να βλέπαμε αν το site σας εξακολουθεί να λειτουργεί ακόμα στο internet, σωστά; Ας το κάνουμε deploy στο PythonAnywhere για ακόμη μια φορά. Παρακάτω φαίνεται μια περίληψη των βημάτων… + +* Πρώτα κάντε push τον κώδικα σας στο GitHub + +{% filename %}command-line{% endfilename %} + + $ git status + [...] + $ git add --all . + $ git status + [...] + $ git commit -m "Modified templates to display posts from database." + [...] + $ git push + + +* Έπειτα συνδεθείτε στο [PythonAnywhere](https://www.pythonanywhere.com/consoles/), μεταβείτε στο **Bash console** (ή ανοίξτε ένα νέο) και τρέξτε: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd $USER.pythonanywhere.com + $ git pull + [...] + + +* Τέλος, πηγαίνετε στο ["Web" page](https://www.pythonanywhere.com/web_app_setup/) και κλικάρετε **Reload** στην εφαρμογή σας. (Για να δείτε άλλες σελίδες του PythonAnywhere από την κονσόλα χρησιμοποιήστε το κουμπί του μενού στην πάνω δεξιά γωνία.) Η αλλαγή σας θα πρέπει να φαίνεται στο https://yourname.pythonanywhere.com. Δείτε το στο browser! Δεν πειράζει αν τα posts στο PythonAnywhere δεν είναι τα ίδια με τα posts που εμφανίζονται τοπικά στον υπολογιστή σας. Οι βάσεις δεδομένων στον τοπικό υπολογιστή σας και στο PythonAnywhere δεν είναι συγχρονισμένες μεταξύ τους. + +Συγχαρητήρια! Τώρα, πηγαίντε και προσθέστε μερικά posts μέσω του Django admin (θυμηθείτε να προσθέσετε το published_date!) Σιγουρευτείτε ότι βρίσκεστε στο Django admin του pythonanywhere site, https://yourname.pythonanywhere.com/admin (και όχι του τοπικού υπολογιστή σας). Έπειτα, ανανεώστε τη σελίδα και δείτε αν αυτά τα posts εμφανίστηκαν. + +Δουλεύει μια χαρά, έτσι; Είμαστε περήφανοι! Απομακρυνθείτε από τον υπολογιστή σας για λίγο. Αξίζετε ένα διάλλειμα. :) + +![Σχήμα 13.4](images/donut.png) \ No newline at end of file diff --git a/el/django_templates/images/donut.png b/el/django_templates/images/donut.png new file mode 100644 index 00000000000..f31cebdc8a3 Binary files /dev/null and b/el/django_templates/images/donut.png differ diff --git a/el/django_templates/images/step1.png b/el/django_templates/images/step1.png new file mode 100644 index 00000000000..cbf6420360a Binary files /dev/null and b/el/django_templates/images/step1.png differ diff --git a/el/django_templates/images/step2.png b/el/django_templates/images/step2.png new file mode 100644 index 00000000000..fd6269c837c Binary files /dev/null and b/el/django_templates/images/step2.png differ diff --git a/el/django_templates/images/step3.png b/el/django_templates/images/step3.png new file mode 100644 index 00000000000..b471fdd4d7b Binary files /dev/null and b/el/django_templates/images/step3.png differ diff --git a/el/django_urls/README.md b/el/django_urls/README.md new file mode 100644 index 00000000000..d6ead3275eb --- /dev/null +++ b/el/django_urls/README.md @@ -0,0 +1,103 @@ +# Django URLs + +Είμαστε έτοιμοι να χτίσουμε την πρώτη μας σελίδα: μια αρχική σελίδα (homepage) για το blog μας! Αλλά πρώτα πρέπει να μάθουμε λίγα πράγματα για τα Django URLs. + +## Τι είναι ένα URL; + +Ένα URL είναι μια διεύθυνση ιστού. Μπορείτε να δείτε ένα URL κάθε φορά που επισκέπτεστε μια σελίδα. Είναι ορατό στην γραμμή διεύθυνσης. (Ναι! `127.0.0.1:8000` είναι ένα URL! Και το `https://djangogirls.org` είναι, επίσης, ένα URL.) + +![Url](images/url.png) + +Κάθε σελίδα στο ιντερνετ χρειάζεται το δικό της URL. Με αυτό τον τρόπο η εφαρμογή σας θα ξέρει τι να δείξει στον χρήστη που ανοίγει αυτό το URL. Στο Django, χρησιμοποιούμε κάτι που το ονομάζουμε `URLconf` (URL configuration). Το URLconf είναι ένα σετ από μοτίβα που το Django θα προσπαθήσει να ταιριάξει με το ζητούμενο URL ούτως ώστε να βρει το κατάλληλο view. + +## Πως δουλεύουν τα URLs στο Django; + +Ας ανοίξουμε το αρχείο `mysite/urls.py` και να δούμε τι έχει μέσα: + +{% filename %}mysite/urls.py{% endfilename %} + +```python +"""mysite URL Configuration + +[...] +""" +from django.contrib import admin +from django.urls import path + +urlpatterns = [ + path('admin/', admin.site.urls), +] +``` + +Όπως βλέπετε, το Django έχει γράψει μέσα κάποια πράγματα για εμάς. + +Οι γραμμές μεταξύ των τριπλών εισαγωγικών (`'''` ή `"""`) ονομάζονται docstrings. Μπορείτε να τα γράψετε στην αρχή κάθε Python αρχείου, κλάσης, μεθόδου ή συνάρτησης για να περιγράψετε το τι κάνει. Δεν θα εκτελεστούν από την Python. + +Το admin URL, το οποίο επισκεφτήκατε σε προηγούμενο κεφάλαιο, είναι ήδη εκεί: + +{% filename %}mysite/urls.py{% endfilename %} + +```python + path('admin/', admin.site.urls), +``` + +Η γραμμή αυτή σημαίνει ότι για κάθε URL που ξεκινά με τη λέξη `admin/`, το Django θα ψάξει να βρει το αντίστοιχο *view*. Σε αυτή την περίπτωση συμπεριλαμβάνουμε αρκετά admin URLs ούτως ώστε να μην εμφανίζονται όλα σε αυτό το αρχείο. Είναι περισσότερο ευανάγνωστο κατ' αυτό τον τρόπο. + +## Το πρώτο σας Django URL! + +Ώρα να δημιουργήσουμε το πρώτο σας URL! Θέλουμε η διεύθυνση 'http://127.0.0.1:8000/' να είναι η αρχική μας σελίδα για το blog, η οποία θα εμφανίζει όλα τα posts. + +Θέλουμε, επίσης, να κρατήσουμε το αρχείο `mysite/urls.py` καθαρό. Οπότε, θα κάνουμε import τα URLs από το `blog` application στο αρχείο `mysite/urls.py`. + +Πηγαίνετε λοιπόν, και προσθέστε αυτή τη γραμμή στο αρχείο `blog.urls`. Θα χρειαστεί, επίσης, να αλλάξετε την γραμμή `from django.urls…` επειδή χρησιμοποιούμε την συνάρτηση `include`. Επομένως, θα χρειαστεί να προσθέσετε αυτή τη γραμμή. + +Το αρχείο σας `mysite/urls.py` θα μοιάζει κάπως έτσι: + +{% filename %}mysite/urls.py{% endfilename %} + +```python +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('blog.urls')), +] +``` + +Το Django, τώρα, θα ανακατευθύνει οτιδήποτε έρχεται στο 'http://127.0.0.1:8000/' προς το αρχείο `blog.urls` και από κει και πέρα θα πράττει αναλόγως. + +## blog.urls + +Δημιουργήστε ένα κενό αρχείο `urls.py` μέσα στο φάκελο `blog` και ανοίξτε το. Τέλεια! Προσθέστε αυτές τις δύο γραμμές: + +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views +``` + +Εδώ κάνουμε import τη συνάρτηση `path` του Django και όλα τα `views` από το `blog` application. (Δεν κάποια views ακόμα αλλά θα φτάσουμε εκεί σε λίγο!) + +Μετά από αυτό, μπορούμε να προσθέσουμε το πρώτο μας URL μοτίβο (URL pattern): + +{% filename %}blog/urls.py{% endfilename %} + +```python +urlpatterns = [ + path('', views.post_list, name='post_list'), +] +``` + +Όπως μπορείτε να δείτε, αναθέτουμε ένα `view` με το όνομα `post_list` στο πηγαίο URL. Αυτό το μοτίβο θα ταιριάξει το κενό string και ο Django URL resolver θα αγνοήσει το domain name (πχ http://127.0.0.1:8000/) που το πρόθεμα του ενιαίου URL μονοπατιού. Αυτό το μοτίβο θα πει στο Django ότι το view `views.post_list` είναι το σωστό μέρος να πας αν κάποιος επισκεφτεί τη διεύθυνση 'http://127.0.0.1:8000/'. + +Το τελευταίο μέρος, `name='post_list'`, είναι το όνομα του URL το οποίο θα χρησιμοποιηθεί για να αναγνωρίσουμε αυτό το URL. Αυτό μπορεί να είναι το ίσιο όπως το όνομα του view αλλά μπορεί να είναι κάτι τελείως το διαφορετικό αν θέλετε. Θα χρησιμοποιούμε τα URLs με όνομα (named URLs) αργότερα στο project, οπότε είναι σημαντικό να ονομάσετε κάθε URL στην εφαρμογή σας. Θα προσπαθήσουμε, επίσης, να κρατήσουμε τα ονόματα μοναδικά μεταξύ τους και εύκολα να τα θυμόμαστε. + +Αν προσπαθήσετε να επισκεφτείτε τη διεύθυνση http://127.0.0.1:8000/, τότε θα δείτε ένα σφάλμα τύπου 'web page not available'. Αυτό προκύπτει επειδή ο server (θυμάστε όταν γράψατε `runserver`?) δεν τρέχει. Δείτε στην κονσόλα που έτρεχε ο server σας και δείτε το γιατί. + +![Σφάλμα](images/error1.png) + +Η κονσόλα, σας εμφάνισε σφάλμα αλλά μην ανησυχείτε. Είναι στην ουσία πολύ χρήσιμο: σας λέει **no attribute 'post_list'**. Αυτό είναι το όνομα του *view* το οποίο προσπαθεί να βρει και να χρησιμοποιήσει το Django αλλά δεν το έχουμε δημιουργήσει ακόμα. Σε αυτό το σημείο, ούτε η σελίδα `/admin/` δεν θα λειτουργεί. Μην ανησυχείτε. Θα φτάσουμε και εκεί. Αν δείτε κάποιο διαφορετικό σφάλμα προσπαθείστε να επανεκκινήσετε τον τοπικό server σας. Για να το κάνετε αυτό, στην κονσόλα που τρέχει ο server, σταματήστε τον πιέζοντας Ctrl+C και επανεκκινήστε τον γράφοντας `python manage.py runserver` και μετά πιέστε enter. + +> Αν θέλετε να περισσότερα σχετικά με τα Django URLconfs, δείτε στο επίσημο documentation: https://docs.djangoproject.com/en/2.0/topics/http/urls/ \ No newline at end of file diff --git a/el/django_urls/images/error1.png b/el/django_urls/images/error1.png new file mode 100644 index 00000000000..50618fca3fe Binary files /dev/null and b/el/django_urls/images/error1.png differ diff --git a/el/django_urls/images/url.png b/el/django_urls/images/url.png new file mode 100644 index 00000000000..c22441e930e Binary files /dev/null and b/el/django_urls/images/url.png differ diff --git a/el/django_views/README.md b/el/django_views/README.md new file mode 100644 index 00000000000..50b7c40aeb8 --- /dev/null +++ b/el/django_views/README.md @@ -0,0 +1,44 @@ +# Django views – ώρα να δημιουργήσουμε! + +Ώρα να ξεφορτωθούμε το σφάλμα που δημιουργήσαμε στο προηγούμενο κεφάλαιο! :) + +Ένα *view* είναι το μέρος όπου βάζουμε την "λογική" της εφαρμογής μας. Θα ζητήσει πληροφορίες από το μοντέλο μας (`model`) που δημιουργήσαμε νωρίτερα και θα το περάσει στο `template`. Θα δημιουργήσουμε ένα template στο επόμενο κεφάλαιο. Τα views είναι απλώς Python συναρτήσεις οι οποίες είναι ελαφρώς πιο περίπλοκες από αυτές που γράψαμε στο κεφάλαιο **Εισαγωγή στην Python**. + +Τα views τοποθετούνται σε ένα αρχείο (ανα εφαρμογή) με το όνομα `views.py`. Θα προσθέσουμε τα δικά μας *views* στο αρχείο `blog/views.py`. + +## blog/views.py + +Ωραία. Ας ανοίξουμε το αρχείο να δούμε τι έχει μέσα: + +{% filename %}blog/views.py{% endfilename %} + +```python +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` η οποία παίρνει την παράμετρο `request` και επιστρέφει `return` την τιμή που παίρνει από άλλη συνάρτηση, την `render`, η οποία κάνει render ("χτίζει") το template `blog/post_list.html`. + +Αποθηκεύστε το αρχείο και επισκεφτείτε τη σελίδα http://127.0.0.1:8000/ να δούμε τι εμφανίζεται. + +Κι άλλο σφάλμα! Διαβάστε το γιατί: + +![Σφάλμα](images/error.png) + +Αυτή τη φορά δείχνει ότι ο server, τουλάχιστον, τρέχει αλλά κάτι δεν πάει καλά, σωστά; Μην ανησυχείτε. Είναι απλώς μια σελίδα σφάλματος! Όπως ακριβώς τα μηνύματα σφάλματος στην κονσόλα, αυτά τα σφάλματα στον browser είναι στην πραγματικότητα πολύ χρήσιμα. Διαβάζετε ότι *TemplateDoesNotExist*. Ας το φτιάξουμε δημιουργώντας ένα template στο επόμενο κεφάλαιο! + +> Διαβάστε περισσότερα για τα Django views στο επίσημο documentation: https://docs.djangoproject.com/en/2.0/topics/http/views/ \ No newline at end of file diff --git a/el/django_views/images/error.png b/el/django_views/images/error.png new file mode 100644 index 00000000000..2ef613c8a5d Binary files /dev/null and b/el/django_views/images/error.png differ diff --git a/el/dynamic_data_in_templates/README.md b/el/dynamic_data_in_templates/README.md new file mode 100644 index 00000000000..d8afea253a9 --- /dev/null +++ b/el/dynamic_data_in_templates/README.md @@ -0,0 +1,81 @@ +# Δυναμικά δεδομένα στα templates + +Μέχρι τώρα έχουμε διαφορετικά κομμάτια έτοιμα να συναρμολογηθούν: το μοντέλο `Post` είναι δηλωμένο στο αρχείο `models.py`, την συνάρτηση `post_list` στο αρχείο `views.py` το template. Αλλά πως θα κάνουμε τα posts να εμφανιστούν στο HTML template; Επειδή αυτό θέλουμε να κάνουμε. Να αντλήσουμε δεδομένα (αποθηκευμένα μοντέλα στη βάση δεδομένων) και να τα παρουσιάσουμε όμορφα μέσα από ένα template, σωστά; + +Αυτό ακριβώς κάνουν τα *views*: συνδέουν τα μοντέλα με τα templates. Μέσα στη συνάρτηση `post_list` *view* πρέπει να προσπελάσουμε τα μοντέλα που θέλουμε και να τα δώσουμε στο template. Μέσα στο *view* αποφασίσαμε τι (μοντέλο) θα εμφανιστεί στο template. + +Ωραία, πως το κάνουμε αυτό; + +Πρέπει να ανοίξουμε το αρχείο `blog/views.py`. Μέχρι τώρα η συνάρτηση `post_list` *view* δείχνει κάπως έτσι: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render + +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` + +Θυμάστε όταν είπαμε να συμπεριλαμβάνουμε κώδικα γραμμένο σε διαφορετικά αρχεία; Τώρα είναι η στιγμή να συπεριλάβουμε το μοντέλο που είχαμε γράψει στο αρχείο `models.py`. Θα προσθέσουμε τη γραμμή `from .models import Post`, όπως κάτωθι: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from .models import Post +``` + +Η τελεία πριν τη λέξη `models` σημαίνει ο *παρόν φάκελος* ή το *παρόν application*. Και τα δύο αρχεία `views.py` και `models.py` βρίσκονται στον ίδιο φάκελο. Αυτό σημαίνει ότι μπορούμε να χρησιμοποιήσουμε την τελεία `.` και μετά το όνομα του αρχείου (δίχως την κατάληξη `.py`). Έπειτα κάνουμε import το όνομα του μοντέλου, δηλαδή της κλάσης (`Post`). + +Και μετά; Για να εξάγουμε τα posts από το μοντέλο `Post` χρειαζόμαστε κάτι που ονομάζεται `QuerySet`. + +## QuerySet + +Θα πρέπει να είστε ήδη εξοικειωμένοι με τον όρο QuerySet και πως αυτό λειτουργεί. Μιλήσαμε γι'αυτά στο κεφάλαιο [Django ORM (QuerySets)](../django_orm/README.md). + +Οπότε τώρα θέλουμε δημοσιευμένα posts ταξινομημένα κατά `published_date`, σωστά; Αυτό το κάναμε ήδη στο κεφάλαιο με τα QuerySets! + +{% filename %}blog/views.py{% endfilename %} + +```python +Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +``` + +Επομένως, ας ανοίξουμε το αρχείο `blog/views.py` και ας προσθέσουμε αυτό το κομμάτι κώδικα στη συνάρτηση `def post_list(request)`. Αλλά μην παραλείψετε να προσθέσετε `from django.utils import timezone`: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from django.utils import timezone +from .models import Post + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {}) +``` + +Το τελευταίο κομμάτι του παζλ είναι να περάσουμε το `posts` QuerySet στο template. Μην ανησυχείτε. Θα δούμε πως να το παρουσιάσουμε σε επόμενο κεφάλαιο. + +Παρακαλούμε σημειώστε ότι δημιουργούμε μια *μεταβλητή* για το QuerySet: `posts`. Μεταχειριστείτε τη ως το όνομα του QuerySet. Απο δω και στο εξής μπορούμε να αναφερόμαστε σε αυτό με το όνομα αυτό. + +Στη συνάρτηση `render` έχουμε μια παράμετρο `request` (οτιδήποτε λαμβάνουμε από το χρήστη μέσω του Internet) και άλλη μια ακόμα, εκείνη του αρχείου template (`'blog/post_list.html'`). Η τελευταία παράμετρος `{}`, είναι το σημείο που μπορούμε να προσθέσουμε πράγματα για να τα αξιοποιήσει το template. Χρειαζόμαστε να τους δώσουμε ονόματα (θα μείνουμε με το όνομα `'posts'`). :) Θα δείχνει κάπως έτσι: `{'posts': posts}`. Παρακαλούμε σημειώστε ότι το κομμάτι πριν το `:` είναι ένα string; πρέπει να το περικυκλώσετε με "αυτάκια": `''`. + +Εν τέλει, το αρχείο `blog/views.py` θα δείχνει κάπως έτσι: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from django.utils import timezone +from .models import Post + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {'posts': posts}) +``` + +Αυτό ήταν! Ήρθε η ώρα να πάμε πίσω στο template και να εμφανίσουμε αυτό το QuerySet! + +Θέλετε να διαβάσετε περισσότερα για τα QuerySets στο Django; Θα πρέπει να διαβάσετε εδώ: https://docs.djangoproject.com/en/2.0/ref/models/querysets/ \ No newline at end of file diff --git a/el/extend_your_application/README.md b/el/extend_your_application/README.md new file mode 100644 index 00000000000..848c3ed2ad3 --- /dev/null +++ b/el/extend_your_application/README.md @@ -0,0 +1,214 @@ +{% set warning_icon = '' %} + +# Επεκτείνετε την εφαρμογή σας + +Έχουμε ήδη ολοκληρώσει όλα τα βήματα που είναι απαραίτητα για τη δημιουργία της ιστοσελίδας μας: γνωρίζουμε πώς να γράψουμε ένα μοντέλο, ένα url, ένα view και ένα template. Γνωρίζουμε επίσης πώς να κάνουμε το website μας όμορφο. + +Ώρα για εξάσκηση! + +Το πρώτο πράγμα που χρειαζόμαστε στο blog μας είναι, προφανώς, μια σελίδα για το εκάστοτε post (της οποίας η εμφάνιση θα είναι η ίδια για όλα post και το μόνο που θα αλλάζει θα είναι το περιεχόμενο), σωστά; + +Έχουμε ήδη ένα μοντέλο `Post`, έτσι δεν χρειάζεται να προσθέσετε τίποτα στο αρχείο `models.py`. + +## Δημιουργία ενός συνδέσμου template με τις λεπτομέρειες του post + +Θα ξεκινήσουμε με την προσθήκη ενός συνδέσμου στο αρχείο `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.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +{% raw %}Θέλουμε να έχουμε έναν σύνδεσμο (link) για κάθε τίτλο του post μέσα στη λίστα ο οποίος όταν κλικάρετε να μεταβαίνει στη σελίδα λεπτομερειών του post. Ας αλλάξουμε το `

{{ post.title }}

` έτσι ώστε να συνδέεται με τη σελίδα λεπτομερειών του post:{% endraw %} + +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} + +```html +

{{ post.title }}

+``` + +{% raw %}Ώρα να εξηγήσουμε το μυστηριώδης `{% url 'post_detail' pk=post.pk %}`. Όπως υποψιάζεστε, το `{% %}` σημαίνει ότι χρησιμοποιούμε τα Django template tags. Αυτή τη φορά θα χρησιμοποιήσουμε ένα που δημιουργεί μια διεύθυνση URL για εμάς!{% endraw %} + +Το μέρος `post_detail` σημαίνει ότι θα πρέπει το Django θα περιμένει μια διεύθυνση URL με το όνομα αυτό στο αρχείο `blog/urls.py` με το όνομα=post_detail + +Τι γίνεται όμως με το `pk=post.pk`; Το `pk` είναι σύντμηση για τη λέξη primary key, το οποίο είναι ένα μοναδικό όνομα για κάθε εγγραφή σε μια βάση δεδομένων. Επειδή δεν ορίσαμε κάποιο primary key στο μοντέλο μας `Post`, το Django δημιουργεί ένα για μας (από προεπιλογή, ένας αριθμός που αυξάνεται κατά ένα για κάθε εγγραφή, δηλαδή 1, 2, 3) και το προσθέτει ως ένα πεδίο που ονομάζεται `pk` σε κάθε μία από τα post μας. Μπορούμε να έχουμε πρόσβαση σε κάθε primary key γράφοντας `post.pk`, με τον ίδιο τρόπο που έχουμε πρόσβαση σε άλλα πεδία (`title`, `author`, κ.λπ.) του `Post` object μας! + +Τώρα, όταν πάμε στη διεύθυνση http://127.0.0.1:8000 / θα εμφανιστεί σφάλμα (όπως ήταν αναμενόμενο, καθώς δεν έχουμε ακόμη διεύθυνση URL ή κάποιο *view* για το `post_detail`). Αυτό θα μοιάζει κάπως έτσι: + +![Σφάλμα NoReverseMatch](images/no_reverse_match2.png) + +## Δημιουργία ενός URL για τις λεπτομέρειες του post + +Ας δημιουργήσουμε μια διεύθυνση URL στο αρχείο `urls.py` για το `post_detail` *view* μας! + +Θέλουμε οι λεπτομέρειες του πρώτου μας post να εμφανίζονται σε αυτό το **URL**: http://127.0.0.1:8000/θέση/1 / + +Ας δημιουργήσουμε ένα URL μέσα στο αρχείο `blog/urls.py` που θα κατευθύνει το Django στο *view* με το όνομα `post_detail`, που με τη σειρά του θα δείξει ένα ολόκληρο blog post. Ανοίξτε το αρχείο `blog/urls.py` και προσθέστε τη γραμμή `path('post//', views.post_detail, name='post_detail'),` έτσι ώστε το αρχείο να μοιάζει κάπως έτσι: + +{% filename %}{{ warning_icon }} blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), +] +``` + +Το μέρος `post//` καθορίζει ένα URL μοτίβο. Θα σας το εξηγήσουμε: + +- Το μέρος `post/` σημαίνει ότι το URL θα πρέπει να ξεκινά με τη λέξη **post** ακολουθούμενο από μια κάθετο **/**. Μέχρι τώρα όλα καλά. +- `` – Αυτό το μέρος είναι πιο δύσκολο. Σημαίνει ότι το Django περιμένει έναν ακέραιο όπου με την σειρά του θα το μεταφέρει ως παράμετρο με το όνομα `pk` στο αντίστοιχο view. +- `/` – έπειτα χρειαζόματε άλλη μια κάθετο **/** πριν να κλείσει το URL. + +Αυτό σημαίνει ότι αν μεταβείτε στο `http://127.0.0.1:8000/post/5/` στον browser σας, το Django θα καταλάβει ότι ψάχνετε το *view* με το όνομα `post_detail` και θα μεταφέρει την πληροφορία του `pk` που ισούται με το `5` σε αυτό το *view*. + +Ωραία. Προσθέσαμε ένα νέο URL μοτίβο στο αρχείο `blog/urls.py`! Ας ανανεώσουμε τη σελίδα: http://127.0.0.1:8000/ Μπαμ! Ο server σταμάτησε να τρέχει ξανά. Ρίξτε μια ματιά στην κονσόλα. Όπως ήταν αναμενόμενο, υπάρχει ακόμα ένα σφάλμα! + +![AttributeError](images/attribute_error2.png) + +Θυμάστε το επόμενο βήμα; Προσθήκη ενός view! + +## Προσθήκη ενός view για τις λεπτομέρειες του post + +Αυτή τη φορά το *view* δέχεται μια έξτρα παράμετρο, το `pk`. Το *view* μας χρειάζεται με κάποιο τρόπο να αιχμαλωτίσει αυτή την παράμετρο, σωστά; Έτσι, λοιπόν, θα ορίσουμε την συνάρτηση μας ως `def post_detail(request, pk):`. Σημειώστε ότι χρειάζεται να ορίσουμε την παράμετρο με το ίδιο ακριβώς όνομα που δώσαμε στο URL μέσα στο αρχείο urls (`pk`). Η απουσία της παραμέτρου είναι λάθος και θα παρουσιάσει σφάλμα! + +Τώρα, θέλουμε να πάρουμε ένα και μόνο ένα post. Για να το κάνουμε αυτό, μπορούμε να χρησιμοποιήσουμε τα querysets, όπως παρακάτω: + +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} + +```python +Post.objects.get(pk=pk) +``` + +Αλλά αυτός ο κώδικας έχει πρόβλημα. Αν δεν υπάρχει κάποιο `Post` με το δεδομένο `primary key` (`pk`) θα έχουμε ένα άσχημο σφάλμα! + +![Σφάλμα DoesNotExist](images/does_not_exist2.png) + +Δεν το θέλουμε αυτό! Αλλά ευτυχώς το Django περιλαμβάνει με κάτι που θα μας φανεί χρήσιμο: `get_object_or_404`. Σε αυτή την περίπτωση δεν υπάρχει κάποιο `Post` με αυτό το `pk`, θα εμφανίσει μια πολύ πιο όμορφη σελίδα, την σελίδα `Page Not Found 404`. + +![Page not found](images/404_2.png) + +Τα καλά νέα είναι ότι μπορείτε να δημιουργήσετε τη δική σας σελίδα `Page not found` και να την κάνετε όσο όμορφη θέλετε. Αλλά δεν είναι εξαιρετικά σημαντικό αυτή τη στιγμή, οπότε θα το παραλείψουμε τώρα. + +Ωραία, ώρα να προσθέσουμε ένα *view* στο αρχείο `views.py`! + +Στο αρχείο `blog/urls.py` δημιουργήσαμε ένα URL με το όνομα `post_detail`, που αναφέρεται σε ένα view με το όνομα `views.post_detail`. Αυτό σημαίνει ότι το Django θα περιμένει να υπάρχει μια συνάρτηση με το όνομα `post_detail` μέσα στο αρχείο `blog/views.py`. + +Ανοίξτε το αρχείο`blog/views.py` και προσθέστε τις ακόλουθες γραμμές μαζί με τις γραμμές `from`: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render, get_object_or_404 +``` + +Και στο τέλος του αρχείου θα προσθέσουμε το *view*: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) +``` + +Ναι. Ήρθε η ώρα να ανανεώσουμε τη σελίδα: http://127.0.0.1:8000/ + +![view για την λίστα των post](images/post_list2.png) + +Δούλεψε! Αλλά τι συμβαίνει όταν κλικάρετε στον σύνδεσμο σε κάποιον τίτλο ενός post; + +![Σφάλμα TemplateDoesNotExist](images/template_does_not_exist2.png) + +Ω όχι! Άλλο ένα άλλο σφάλμα! Αλλά ήδη γνωρίζουμε πώς να το αντιμετωπίσουμε, έτσι; Πρέπει να προσθέσουμε ένα template! + +## Δημιουργία template για τις λεπτομέρειες του post + +Θα δημιουργήσoυμε ένα αρχείο μέσα στο φάκελο `blog/πρότυπα/blog` με το όνομα `post_detail.html`. Ανοίξτε το. + +Θα μοιάζει κάπως έτσι: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endblock %} +``` + +Για μια ακόμη φορά θα επεκτείνουμε το template `base.html`. Στο block`content` θέλουμε να εμφανίσουμε την ημ/νια έκδοσης του post (αν υπάρχει) τον τίτλο και το κυρίως κείμενο. Αλλά θα πρέπει να συζητήσουμε ορισμένα σημαντικά πράγματα, έτσι; + +{% raw %}`{% if ... %} ... {% endif %}` είναι ένα template tag που μας επιτρέπει να ελέγξουμε κάτι - με άλλα λόγια είναι μια συνθήκη. (Θυμάστε το `if ... else ..` από το κεφάλαιο **Εισαγωγή στην Python**?) Σε αυτό το σενάριο θέλουμε να δούμε αν το πεδίο `published_date` του post έχει κάποια τιμή.{% endraw %} + +Ωραία, μπορούμε να ανανεώσουμε τη σελίδα και να δούμε, για αρχή, αν το σφάλμα `TemplateDoesNotExist` έχει φύγει. + +![Σελίδα λεπτομέρειας του post](images/post_detail2.png) + +Ναι! Έφυγε! + +# Ώρα για deploy! + +Θα ήταν καλό να δούμε εάν η σελίδα σας εξακολουθεί να λειτουργεί στο PythonAnywhere, σωστά; Ας δοκιμάσουμε να το κάνουμε deploy ξανά. + +{% filename %}command-line{% endfilename %} + + $ 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 + + +Έπειτα, στην [κονσόλα Bash του PythonAnywhere](https://www.pythonanywhere.com/consoles/): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Θυμηθείτε να αντικαταστήσετε με το ``πραγματικό όνομα χρήστη σας του PythonAnywhere χωρίς τα <>). + +## Ενημέρωση των στατικών αρχείων στο διακομιστή + +Οι διακομιστές όπως το PythonAnywhere τους αρέσει να διαχειρίζονται τα «στατικά αρχεία» (όπως τα αρχεία CSS) διαφορετικά από τα αρχεία της Python επειδή μπορεί να βελτιστοποιηθούν ούτως ώστε να φορτώνονται πιο γρήγορα. Ως αποτέλεσμα, κάθε φορά που μπορούμε να κάνουμε αλλαγές στα αρχεία CSS, θα πρέπει να εκτελούμε μια πρόσθετη εντολή στο διακομιστή η οποία του λέει να τα ενημερώσει. Η εντολή ονομάζεται `collectstatic`. + +Ξεκινήστε με το να ενεργοποιήσετε το virtualenv σας, αν δεν είναι ήδη ενεργό (το PythonAnywhere χρησιμοποιεί μια εντολή που ονομάζεται `workon` για να γίνει αυτό, είναι ακριβώς σαν την εντολή `source myenv/bin/activate` που χρησιμοποιείτε στον υπολογιστή σας): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ workon .pythonanywhere.com + (ola.pythonanywhere.com)$ python manage.py collectstatic + [...] + + +Η εντολή `manage.py collectstatic` είναι λίγο σαν την `manage.py migrate`. Κάνουμε κάποιες αλλαγές στον κώδικα και στη συνέχεια λέμε στο Django να *εφαρμόσει* αυτές τις αλλαγές είτε στον αντίστοιχο φάκελο στατικών αρχείων του server είτε στη βάση δεδομένων. + +Σε κάθε περίπτωση, είμαστε τώρα έτοιμοι να κλικάρουμε ["Web" page](https://www.pythonanywhere.com/web_app_setup/) (από το κουμπί του μενού στην επάνω δεξιά μεριά της κονσόλας) και κλικάρουμε στο **Reload**. Δείτε τη σελίδα https://yourname.pythonanywhere.com με το αποτέλεσμα. + +Αυτό ήταν! Συγχαρητήρια :) \ No newline at end of file diff --git a/el/extend_your_application/images/404_2.png b/el/extend_your_application/images/404_2.png new file mode 100644 index 00000000000..0a6fdf3234e Binary files /dev/null and b/el/extend_your_application/images/404_2.png differ diff --git a/el/extend_your_application/images/attribute_error2.png b/el/extend_your_application/images/attribute_error2.png new file mode 100644 index 00000000000..4b8262476d9 Binary files /dev/null and b/el/extend_your_application/images/attribute_error2.png differ diff --git a/el/extend_your_application/images/does_not_exist2.png b/el/extend_your_application/images/does_not_exist2.png new file mode 100644 index 00000000000..e7015f2c80d Binary files /dev/null and b/el/extend_your_application/images/does_not_exist2.png differ diff --git a/el/extend_your_application/images/no_reverse_match2.png b/el/extend_your_application/images/no_reverse_match2.png new file mode 100644 index 00000000000..aba1c9c8980 Binary files /dev/null and b/el/extend_your_application/images/no_reverse_match2.png differ diff --git a/el/extend_your_application/images/post_detail2.png b/el/extend_your_application/images/post_detail2.png new file mode 100644 index 00000000000..b40c92efb8c Binary files /dev/null and b/el/extend_your_application/images/post_detail2.png differ diff --git a/el/extend_your_application/images/post_list2.png b/el/extend_your_application/images/post_list2.png new file mode 100644 index 00000000000..dd0a0d67a6f Binary files /dev/null and b/el/extend_your_application/images/post_list2.png differ diff --git a/el/extend_your_application/images/template_does_not_exist2.png b/el/extend_your_application/images/template_does_not_exist2.png new file mode 100644 index 00000000000..c856abeda31 Binary files /dev/null and b/el/extend_your_application/images/template_does_not_exist2.png differ diff --git a/el/how_the_internet_works/README.md b/el/how_the_internet_works/README.md new file mode 100644 index 00000000000..7a6fdb69806 --- /dev/null +++ b/el/how_the_internet_works/README.md @@ -0,0 +1,47 @@ +# Πως λειτουργεί το internet + +> Για τους αναγνώστες στο σπίτι: αυτή η ενότητα καλύπτεται στο βίντεο [How the Internet Works](https://www.youtube.com/watch?v=oM9yAA09wdc). +> +> Αυτό το κεφάλαιο είναι εμπνευσμένο από την ομιλία της Jessica McKellar με τίτλο "How the Internet works" (http://web.mit.edu/jesstess/www/). + +Στοιχηματίζουμε ότι δουλεύετε το Internet κάθε μέρα. Αλλά ξέρετε τι συμβαίνει όταν πληκτρολογείτε μια διεύθυνση όπως https://djangogirls.org στο browser σας και μετά πατήσετε `enter`; + +Το πρώτο πράγμα που πρέπει να καταλάβετε είναι ότι ένα website αποτελείτε από ένα σωρό από φακέλους αποθηκευμένους σε έναν σκληρό δίσκο. Όπως ακριβώς οι ταινίες, η μουσική και οι φωτογραφίες σας. Ωστόσο, υπάρχει ένα κομμάτι που είναι μοναδικό για τα websites: περιλαμβάνουν κώδικα υπολογιστή με το όνομα HTML. + +Αν δεν είστε εξοικειωμένοι με προγραμματισμό θα σας φανεί λίγο δύσκολη η HTML στην αρχή. Αλλά οι web browsers (όπως Chrome, Safari, Firefox, κλπ) την αγαπούν. Οι web browsers σχεδιάστηκαν για να κατανοούν αυτό τον κώδικα, να ακολουθούν τις εντολές του και να παρουσιάζουν αυτά τα αρχεία από τα οποία είναι φτιαγμένα το website σας με τον τρόπο που εσείς θέλετε. + +Όπως με κάθε αρχείο, χρειαζόμαστε να αποθηκεύουμε τα HTML αρχεία κάπου στον σκληρό δίσκο. Για το Internet, χρησιμοποιούμε ειδικούς υπολογιστές γι'αυτό, με το όνομα *servers*. Δεν έχουν οθόνη, ποντίκι ή πληκτρολόγιο επειδή ο μοναδικός σκοπός τους είναι να αποθηκεύουν δεδομένα και να τα εξυπηρετούν. Γι' αυτό το λόγο ονομάζονται *εξυπηρετητές*. Επειδή *εξυπηρετούν την μεταφορά* δεδομένων. + +ΟΚ, αλλά θέλετε να μάθετε πως φαίνεται το Internet, σωστά; + +Ζωγραφίσαμε μια εικόνα! Φαίνεται κάπως έτσι: + +![Σχήμα 1.1](images/internet_1.png) + +Λίγο χαοτική, έτσι; Στην πραγματικότητα είναι ένα δίκτυο συνδεδεμένων συσκευών (των προαναφερομένων *servers*). Εκατοντάδες χιλιάδες συσκευές! Πολλά πολλά χιλιόμετρα καλωδίων γύρω από ολόκληρο τον κόσμο! Μπορείτε να επισκεφτείτε την ιστοσελίδα του Submarine Cable Map (http://submarinecablemap.com) και να δείτε πόσο περίπλοκο είναι το δίκτυο. Παρακάτω φαίνεται ένα στιγμιότυπο από το website: + +![Σχήμα 1.2](images/internet_3.png) + +Φανταστικό, έτσι; Αλλά δεν είναι δυνατόν να έχουμε καλώδια ανάμεσα σε κάθε ζευγάρι συσκευών που είναι συνδεδμένο στο Internet. Οπότε, για να συνδεθούμε με μία συσκευή (για παράδειγμα, αυτή που είναι αποθηκευμένο το site https://djangogirls.org) θα χρειαστεί να περάσουμε ένα αίτημα (request) μέσα από πολλές πολλές διαφορετικές συσκευές. + +Δείχνει κάπως έτσι: + +![Σχήμα 1.3](images/internet_2.png) + +Φανταστείτε ότι όταν πληκτρολογείτε https://djangogirls.org, στέλνετε ένα γράμμα που λέει: "Αγαπητά Django Girls, θα ήθελα να δω την σελίδα djangogirls.org. Στείλτε τη μου, παρακαλώ!" + +Το γράμμα σας πηγαίνει στο πλησιέστερο ταχυδρομικό γραφείο. Μετά το γράμμα σας πηγαίνει σε άλλο γραφείο που είναι πιο κοντά στον παραλήπτη, μετά σε άλλον κοκ μέχρις ότου φτάσει στον προορισμό του. Το μόνο μοναδικό πράγμα είναι ότι αν στέλνετε πολλά γράμματα (*data packets*) στο ίδιο σημείο, τότε ίσως φτάσουν στον προορισμό τους μέσα από διαφορετικές διαδρομές και ταχυδρομικά γραφεία (*routers*). Αυτό εξαρτάται από το πως είναι ταξινομημένα σε κάθε γραφείο. + +![Σχήμα 1.4](images/internet_4.png) + +Έτσι λειτουργεί. Μπορείτε να στείλετε μηνύματα και να περιμένετε κάποια απάντηση. Αντί για χαρτί και στυλό χρησιμοποιείτε byte δεδομένων αλλά η ιδέα είναι η ίδια! + +Αντί για διευθύνσεις με όνομα οδού, πόλη, ταχυδρομικό κώδικα και χώρα, χρησιμοποιούμε διευθύνσεις IP. Ο υπολογιστής σας ρωτά πρώτα το DNS (Domain Name System) για να μεταφραστεί η λέξη djangogirls.org σε μια διεύθυνση IP. Λειτουργεί λίγο σαν τους παλιούς τηλεφωνικούς καταλόγους όπου μπορείτε να αναζητήσετε το όνομα του ατόμου που θέλετε να επικοινωνήσετε και να βρείτε τον αριθμό τηλεφώνου και τη διεύθυνση τους. + +Όταν στέλνετε ένα γράμμα, πρέπει να έχει ορισμένα χαρακτηριστικά πρέπει για να παραδοθεί σωστά: μια διεύθυνση, μια σφραγίδα, κλπ. Χρησιμοποιείτε επίσης μια γλώσσα που κατανοεί ο παραλήπτης, σωστά; Το ίδιο ισχύει για τα *data packets* που μπορείτε να στείλετε για να δείτε μια ιστοσελίδα. Χρησιμοποιούμε ένα πρωτόκολλο που ονομάζεται HTTP (Hypertext Transfer Protocol). + +Έτσι, βασικά, όταν έχετε μια ιστοσελίδα, θα πρέπει να έχετε έναν *server* (συσκευή). Όταν ο *server* λαμβάνει μια εισερχόμενη *αίτηση* (σε ένα γράμμα), στέλνει πίσω την ιστοσελίδα σας (σε άλλη επιστολή). + +Δεδομένου ότι αυτό είναι ένας Django οδηγός, μπορείτε να ρωτήσετε τι κάνει Django. Όταν στέλνετε μια απάντηση, δεν θέλετε να στέλνετε την ίδια σε όλους. Είναι πολύ καλύτερα αν τα γράμματα είναι εξατομικευμένα, ειδικά για το πρόσωπο που έχει γράψει αποκλειστικά για εσάς, σωστά; Το Django, σας βοηθά με τη δημιουργία αυτών των εξατομικευμένων, ενδιαφέροντων γραμμάτων. :) + +Αρκετά μιλήσαμε. Πάμε να δημιουργήσουμε! \ No newline at end of file diff --git a/el/how_the_internet_works/images/internet_1.png b/el/how_the_internet_works/images/internet_1.png new file mode 100644 index 00000000000..e289eac2b23 Binary files /dev/null and b/el/how_the_internet_works/images/internet_1.png differ diff --git a/el/how_the_internet_works/images/internet_2.png b/el/how_the_internet_works/images/internet_2.png new file mode 100644 index 00000000000..e8cf8b77999 Binary files /dev/null and b/el/how_the_internet_works/images/internet_2.png differ diff --git a/el/how_the_internet_works/images/internet_3.png b/el/how_the_internet_works/images/internet_3.png new file mode 100644 index 00000000000..6f5d95dec80 Binary files /dev/null and b/el/how_the_internet_works/images/internet_3.png differ diff --git a/el/how_the_internet_works/images/internet_4.png b/el/how_the_internet_works/images/internet_4.png new file mode 100644 index 00000000000..d4748ac48ef Binary files /dev/null and b/el/how_the_internet_works/images/internet_4.png differ diff --git a/el/html/README.md b/el/html/README.md new file mode 100644 index 00000000000..f5ccc02ba49 --- /dev/null +++ b/el/html/README.md @@ -0,0 +1,217 @@ +# Εισαγωγή στην HTML + +Ίσως αναρρωτιέστε, τι είναι ένα template; + +Ένα template είναι ένα αρχείο που μπορούμε να επαναχρησιμοποιούμε για να παρουσιάζουμε διαφορετικές πληροφορίες μέσα από μια συνεπή μορφή. Για παράδειγμα, θα μπορούσατε να χρησιμοποιήσετε ένα πρότυπο (template) για να σας βοηθήσει να γράψετε μια επιστολή, γιατί αν και κάθε επιστολή μπορεί να περιέχει διαφορετικό μήνυμα και να απευθύνεται σε ένα διαφορετικό πρόσωπο, μερικά σημεία θα μοιραστούν την ίδια μορφή. + +Η μορφή ενός Django template περιγράφεται με μια γλώσσα που ονομάζεται HTML (που είναι η HTML που αναφέραμε στο πρώτο κεφάλαιο, **Πώς λειτουργεί το Internet**). + +## Τι είναι η HTML; + +Η HTML είναι ένας κώδικας που ερμηνεύεται από τον web browser σας – όπως ο Chrome, Firefox ή Safari - για να εμφανιστεί μια ιστοσελίδα στον χρήστη. + +HTML σημαίνει "HyperText Markup Language". Η λέξη **HyperText** σημαίνει ότι είναι ένας τύπος κειμένου που υποστηρίζει υπερ-συνδέσεις μεταξύ των σελιδών. **Markup** σημαίνει ότι έχουμε λάβει ένα έγγραφο και το έχουμε επισημάνει με κώδικα ούτως ώστε να πει κάτι (στην προκειμένη περίπτωση, ένας browser) πώς να ερμηνεύσει τη σελίδα. Ο HTML κώδικας είναι χτισμένος με **tags**, όπου καθένα αρχίζει με `<` και τελειώνει με `>`. Αυτά τα tags αντιπροσωπεύουν τα markup **elements**. + +## Το πρώτο σας template! + +H δημιουργία ενός template σημαίνει τη δημιουργία ενός αρχείου template. Τα πάντα είναι ένα αρχείο, σωστά; Πιθανώς να το έχετε παρατηρήσει αυτό. + +Τα templates αποθηκεύονται στο φάκελο `blog/templates/blog`. Άρα, πρώτα δημιουργήστε έναν φάκελο με το όνομα `templates` μέσα στον φάκελο blog. Στη συνέχεια, δημιουργήστε έναν άλλο φάκελο που ονομάζεται `blog` μέσα στον φάκελο templates: + + blog + └───templates + └───blog + + +(Ίσως να αναρωτηθείτε γιατί χρειαζόμαστε δύο φακέλους που και οι δύο ονομάζονται `blog`. Όπως θα ανακαλύψετε αργότερα, αυτό είναι μια τεχνική ονομασίας που κάνει τη ζωή ευκολότερη όταν τα πράγματα αρχίζουν να περιπλέκονται.) + +Και τώρα δημιουργήστε ένα αρχείο `post_list.html` (απλά αφήστε το κενό για τώρα) μέσα στον φάκελο `blog/templates/blog`. + +Δείτε πώς εμφανίζεται η ιστοσελίδα σας στο: http://127.0.0.1:8000 / + +> Αν παρουσιάζεται ακόμα το σφάλμα `TemplateDoesNotExist`, δοκιμάστε να επανεκκινήσετε τον server σας. Προσπαθήστε να τον σταματήσετε (πιέζοντας Ctrl + C) και επανεκκινήστε τον τρέχοντας την εντολή `python manage.py runserver`. + +![Σχήμα 11.1](images/step1.png) + +Δεν υπάρχει σφάλμα πια! Συγχαρητήρια :) Ωστόσο, ιστοσελίδα σας δεν δείχνει κάτι παρά μια κενή σελίδα επειδή το template σας είναι κενό. Πρέπει να το διορθώσουμε αυτό. + +Ανοίξτε το νέο αρχείο και προσθέστε τα εξής: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + +

Hi there!

+

It works!

+ + +``` + +Οπότε πως φαίνεται τώρα η ιστοσελίδα μας; Επισκεφθείτε το για να μάθετε: http://127.0.0.1:8000/ + +![Σχήμα 11.2](images/step3.png) + +Λειτουργεί! Καλή δουλειά :) + +* Το πιο βασικό tag, ``, είναι πάντα η αρχή οποιασδήποτε ιστοσελίδας και `` είναι πάντα στο τέλος. Όπως μπορείτε να δείτε, όλο το περιεχόμενο της σελίδας ενσωματώνεται μεταξύ της αρχής του tag `` και του tag κλεισίματος `` +* `

`είναι ένα tag για στοιχεία κειμένου παραγράφου. Το tag `

` κλείνει κάθε παράγραφο + +## Head και body + +Κάθε σελίδα HTML χωρίζεται σε δύο στοιχεία: το **head** και το **body**. + +* To **head** είναι ένα στοιχείο (element) που περιέχει πληροφορίες σχετικά με το έγγραφο αλλά αυτές οι πληροφορίες δεν εμφανίζονται στην οθόνη. + +* Το **body** είναι ένα στοιχείο που περιέχει όλα τα υπόλοιπα που εμφανίζονται ως μέρος της ιστοσελίδας. + +Χρησιμοποιούμε το tag ``για να πούμε στον browser σχετικά με τη διαμόρφωση της σελίδας και το tag `` για να πούμε για το περιεχόμενο της. + +Για παράδειγμα, μπορείτε να προσθέσετε τίτλο στην ιστοσελίδα σας μέσα από το tag ``, όπως παρακάτω: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + Ola's blog + + +

Hi there!

+

It works!

+ + +``` + +Αποθηκεύστε το αρχείο και ανανέωστε την σελίδα σας. + +![Σχήμα 11.3](images/step4.png) + +Παρατηρήσατε πως ο browser κατάλαβε το "Ola's blog" ως τίτλο για την σελίδα σας; Ερμήνευσε το κείμενο `Ola's blog` και το τοποθέτησε στην μπάρα τίτλων του browser σας (το ίδιο κείμενο θα λειτουργήσει και ως όνομα σελιδοδείκτη κλπ). + +Πιθανώς να έχετε παρατηρήσει ότι κάθε tag αντιστοιχίζεται με ένα *tag κλεισίματος*, με μια κάθετο `/` και ότι τα στοιχεία είναι *ένθετα* (δηλαδή δεν μπορείτε να κλείσετε μια συγκεκριμένη ετικέτα μέχρι να έχουν κλείσει όλα αυτά που ήταν μέσα σε αυτό). + +Είναι σαν να βάζουμε πράγματα μέσα σε κουτιά. Έχετε ένα μεγάλο κουτί, ``. Στο εσωτερικό του υπάρχει το `` το οποίο με τη σειρά του περιέχει ακόμα μικρότερα κουτιά: `

`. + +Θα πρέπει να ακολουθείτε αυτούς τους κανόνες *κλεισίματος ετικέτας* και *"φωλιάσματος"* των elements. Αν δεν το κάνετε, ο browser ενδέχεται να μην μπορεί να τα ερμηνεύσει ορθά και η σελίδα να μην εμφανίζεται σωστά. + +## Παραμετροποιώντας το template + +Μπορείτε, τώρα, να διασκεδάσετε λιγάκι και να τροποιήσετε το template σας! Παρακάτω παρουσιάζονται μερικά χρήσιμα tags γι'αυτό: + +* `

A heading

` για επικεφαλίδες +* `

A sub-heading

` για επικεφαλίδες χαμηλότερου επιπέδου +* `

A sub-sub-heading

` …κοκ μέχρι την `
` +* `

Μια παράγραφος κειμένου

` +* `text` δίνει έμφαση στο κείμενο σας +* `text` κάνει τα γράμματα πιο έντονα +* `
` αλλάζει γραμμή (δεν μπορείτε να βάλετε τίποτα ανάμεσα και δεν υπάρχει αντίστοιχο tag που να το κλείνει) +* `link` δημιουργεί έναν σύνδεσμο +* `
  • first item
  • second item
` δημιουργεί μια λίστα, όπως αυτή εδώ που διαβάζετε τώρα! +* `
` ορίζει ένα τμήμα στη σελίδα + +Παρακάτω φαίνεται ένα πλήρες παράδειγμα ενός template. Αντιγράψτε-επικολλήστε το μέσα στο αρχείο `blog/templates/blog/post_list.html`: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + 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` περιέχει τον τίτλο του blog μας – είναι μια επικεφαλίδα και ένας σύνδεσμος +* Τα υπόλοιπα δύο `div` περιέχουν τα posts μας με ημ/νια δημοσίευσης, το `h2` με τον τίτλο του post ο οποίος μπορεί να κλικαριστεί και επίσης δύο `p`s (παραγράφους) κείμενα, ένα για την ημ/νια και το άλλο για το κυρίως κείμενο. + +Δίνει αυτή την αίσθηση: + +![Σχήμα 11.4](images/step6.png) + +Ναιιι! Αλλά μέχρι στιγμής, το template μας εμφανίζει **τις ίδιες πληροφορίες** – ενώ προηγουμένως μιλούσαμε για templates που μας επέτρεπαν να εμφανίσουμε **διαφορετικές/δυναμικές** πληροφορίες με την **ίδια μορφή**. + +Αυτό που θέλουμε να κάνουμε είναι να εμφανίσουμε πραγματικά posts τα οποία θα τα προσθέτουμε μέσω του Django admin. Και αυτό ακριβώς θα κάνουμε μετά. + +## Ένα πράγμα ακόμα: ώρα να το ανεβάσετε! + +Θα ήταν καλό να το δούμε όλο αυτό στο internet, σωστά; Ας κάνουμε άλλο ένα deploy στο PythonAnywhere: + +### Κάντε commit και έπειτα push τον κώδικα σας στο GitHub + +Πρώτ'απ'όλα ας δούμε ποια αρχεία έχουν αλλάξει από την τελευταία φορά που κάναμε deploy (τρέξτε αυτές τις εντολές τοπικά, όχι στο PythonAnywhere): + +{% filename %}command-line{% endfilename %} + + $ git status + + +Σιγουρευτείτε ότι βρίσκεστε μέσα στο φάκελο `djangogirls` και ας πούμε στο `git` να συμπεριλάβει όλες τις αλλαγές μέσα σε αυτό το φάκελο: + +{% filename %}command-line{% endfilename %} + + $ git add --all . + + +> **Σημείωση** `--all` σημαίνει ότι το `git` θα αναγνωρίσει, επίσης, και τυχόν διεγραμμένα αρχεία/φακέλους (από προεπιλογή, αναγνωρίζει μόνο νέα/τροποποιημένα αρχεία). Επίσης, θυμηθείτε (από το κεφάλαιο 3) ότι η τελεία `.` σημαίνει ο τρέχων φάκελος. + +Πριν ανεβάσουμε όλα τα αρχεία, ας δούμε τι επρόκειτο να ανεβάσει το `git` (όλα τα αρχεία που επρόκειτο να ανεβούν από το `git` θα εμφανίζονται με πράσινο χρώμα): + +{% filename %}command-line{% endfilename %} + + $ git status + + +Σχεδόν φτάσαμε. Τώρα είναι η ώρα να του πούμε να αποθηκεύσει αυτή την αλλαγή στο ιστορικό του. Θα του δώσουμε ένα "commit message" όπου θα περιγράψουμε τι άλλαξε. Μπορείτε να γράψετε ότι θέλετε σε αυτό το σημείο αλλά είναι χρήσιμο να γράψετε κάτι περιγραφικό ούτως ώστε να το θυμάστε στο μέλλον. + +{% filename %}command-line{% endfilename %} + + $ git commit -m "Changed the HTML for the site." + + +> **Σημείωση** Σιγουρευτείτε ότι χρησιμοποιείτε διπλά "αυτάκια" γύρω από το commit message. + +Μόλις τελειώσουμε με αυτό, θα ανεβάσουμε (push) τις αλλαγές μας στο GitHub: + +{% filename %}command-line{% endfilename %} + + $ git push + + +### Κάντε pull τον νέο σας κώδικα στο PythonAnywhere και ανανεώστε την εφαρμογή + +* Έπειτα συνδεθείτε στο [PythonAnywhere](https://www.pythonanywhere.com/consoles/), μεταβείτε στο **Bash console** (ή ανοίξτε ένα νέο) και τρέξτε: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Θυμηθείτε να αντικαταστήσετε με το ``πραγματικό όνομα χρήστη σας του PythonAnywhere χωρίς τα <>). + +Και δείτε τον κώδικα σας να κατεβαίνει. Αν θέλετε να δείτε ότι ολοκληρώθηκε, μεταβείτε στη σελίδα **"Files" page** και δείτε τον κώδικα σας στο PythonAnywhere (μπορείτε να ανοίξετε και άλλες σελίδες του PythonAnywhere από το κουμπί του μενού στην σελίδα της κονσόλας). + +* Τέλος, πηγαίνετε στο ["Web" page](https://www.pythonanywhere.com/web_app_setup/) και κλικάρετε **Reload** στην εφαρμογή σας. + +Οι αλλαγές θα πρέπει να είναι ορατές τώρα! Πηγαίνετε και ανανεώστε τη σελίδα στον browser σας. :) \ No newline at end of file diff --git a/el/html/images/step1.png b/el/html/images/step1.png new file mode 100644 index 00000000000..eb474aaeddd Binary files /dev/null and b/el/html/images/step1.png differ diff --git a/el/html/images/step3.png b/el/html/images/step3.png new file mode 100644 index 00000000000..47ede3f9993 Binary files /dev/null and b/el/html/images/step3.png differ diff --git a/el/html/images/step4.png b/el/html/images/step4.png new file mode 100644 index 00000000000..0e6b48ec4a5 Binary files /dev/null and b/el/html/images/step4.png differ diff --git a/el/html/images/step6.png b/el/html/images/step6.png new file mode 100644 index 00000000000..f044389de53 Binary files /dev/null and b/el/html/images/step6.png differ diff --git a/el/images/application.png b/el/images/application.png new file mode 100644 index 00000000000..79071fe8d1b Binary files /dev/null and b/el/images/application.png differ diff --git a/el/installation/README.md b/el/installation/README.md new file mode 100644 index 00000000000..17799c07b44 --- /dev/null +++ b/el/installation/README.md @@ -0,0 +1,64 @@ +# Για σένα που κάνεις το tutorial από το σπίτι + +Αν κάνεις το tutorial στο σπίτι και όχι στο πλαίσιο ενός από τα [Django Girls events](https://djangogirls.org/events/), μπορείς να αγνοήσεις εντελώς αυτό το κεφάλαιο και να πας κατευθείαν στο κεφάλαιο [Πώς δουλεύει το internet](../how_the_internet_works/README.md). + +Αυτό οφείλεται στο γεγονός ότι καλύπτουμε γνωστικά ένα αντικείμενο καθώς το συναντάμε και όχι όλα μαζεμένα. Αυτή είναι μια σελίδα που συγκεντρώνει όλες τις οδηγίες εγκατάστασης σε ένα μέρος (το οποίο είναι χρήσιμο για ορισμένες μορφές των εργαστηρίων). Μπορείτε να διαλέξετε να τα εγκαταστήσετε όλα όσα είναι σε αυτή τη σελίδα αν θέλετε. Αλλά αν θέλετε να μαθαίνετε πράγματα καθώς εγκαθιστάτε πράγματα στον υπολογιστή σας, αγνοήστε αυτό το κεφάλαιο και θα εξηγήσουμε τη διαδικασία εγκατάστασης διαφόρων εργαλείων καθώς τα συναντάμε μπροστά μας. + +Καλή τύχη! + +# Αν παρακαλουθείτε ένα εργαστήριο + +Εάν παρακολουθείτε ένα από τα [Django Girls events](https://djangogirls.org/events/): + +* Το εργαστήριο μπορεί να έχει μια "ομάδα εγκατάστασης" πριν το κυρίως εργαστήριο. Αν ανήκετε στην ομάδα εγκατάστασης, τότε αυτή η σελίδα είναι για εσάς! Ακολουθήστε τις οδηγίες εδώ, για να έχετε όλα όσα χρειάζεστε για το εργαστήριο εγκατεστημένα, με τη βοήθεια των βοηθών αν χρειαστεί. Στη συνέχεια, στο κυρίως εργαστήριο, θα είστε σε θέση να παρακάμψετε τις οδηγίες εγκατάστασης που θα συναντήσετε στον οδηγό. +* Μπορεί να σας έχουν ζητήσει οι διοργανωτές του εργαστηρίου να δοκιμάσετε στο σπίτι να εγκαταστήσετε τα πάντα στον υπολογιστή σας, πριν ξεκινήσει το εργαστήρι. Εάν σας έχει ζητηθεί να το κάνετε αυτό, η σελίδα αυτή είναι για εσάς! Ακολουθήστε τις οδηγίες εδώ, όσο καλύτερα μπορείτε. Στη συνέχεια, στο κυρίως εργαστήριο, όταν φτάνετε σε ένα βήμα εγκατάσταση στον οδηγό, αν δεν έχει συμπεριληφθεί από εμάς μπορείτε να λάβετε βοήθεια από το λεωφορείο. +* Αν το εργαστήριο σας δεν έχει ομάδα εγκατάστασης (ή δεν μπορούσατε να παρευρεθείτε) και οι διοργανωτές δεν σας ζήτησαν να εγκαταστήσετε όσα χρειάζεται πριν φτάσετε, αγνοήστε αυτή τη σελίδα και πηγαίνετε στον κεφάλαιο [Πως δουλεύει το internet](../how_the_internet_works/README.md). Θα εγκαθιστάτε οτιδήποτε χρειάζεται καθώς το συναντάτε στον οδηγό. + +# Εγκατάσταση + +Σε αυτό τον οδηγό θα φτιάξουμε ένα blog. Για να το κάνουμε αυτό, καθώς προχωράμε θα σας ζητηθεί να εγκαταστήσετε διάφορα προγράμματα στον υπολογιστή σας και να δημιουργήσετε μερικούς λογαριασμούς. Αυτή η σελίδα συγκεντρώνει όλες τις εγκαταστάσεις και τις δημιουργίες λογαριασμών σε ένα μέρος (το οποίο είναι χρήσιμο για μερικούς τύπους εργαστηρίων). + + {% include "/chromebook_setup/instructions.md" %} + + + +# Εγκατάσταση Python + +{% include "/python_installation/instructions.md" %} + +# Εγκατάσταση επεξεργαστή κώδικα + +{% include "/code_editor/instructions.md" %} + +# Εγκατάσταση virtualenv και Django + +{% include "/django_installation/instructions.md" %} + +# Εγκατάσταση Git + +{% include "/deploy/install_git.md" %} + +# Δημιουργία GitHub λογαριασμού + +Πηγαίνετε στο [GitHub.com](https://www.github.com) και φτιάξτε έναν δωρεάν λογαριασμό. Σιγουρευτείτε ότι θα θυμάστε τον κωδικό πρόσβασης (προσθέστε τον σε κάποιον password manager, αν χρησιμοποιείτε κάποιον). + +# Δημιουργία λογαριασμού στο PythonAnywhere + +{% include "/deploy/signup_pythonanywhere.md" %} + +# Αρχίστε να διαβάζετε + +Συγχαρητήρια, όλα έχουν ρυθμιστεί σωστά και είστε πανέτοιμοι! Αν έχετε ακόμα χρόνο πριν το workshop, ίσως να σας βοηθούσε να ξεκινήσετε να διαβάζετε μερικά από τα εισαγωγικά κεφάλαια: + +* [Πως λειτουργεί το internet](../how_the_internet_works/README.md) + +* [Εισαγωγή στην γραμμή εντολών](../intro_to_command_line/README.md) + +* [Εισαγωγή στην Python](../python_introduction/README.md) + +* [Τι είναι το Django;](../django/README.md) + +# Καλά να περάσετε στο workshop! + +Όταν ξεκινήσει το workshop, μπορείτε να πατε αμέσως στο [Το πρώτο σας Django project!](../django_start_project/README.md), αφού έχετε ήδη καλύψει το υλικό των ενδιάμεσων ενοτήτων στα προηγούμενα κεφάλαια. \ No newline at end of file diff --git a/el/intro_to_command_line/README.md b/el/intro_to_command_line/README.md new file mode 100644 index 00000000000..543b5ecbd7d --- /dev/null +++ b/el/intro_to_command_line/README.md @@ -0,0 +1,448 @@ +# Εισαγωγή στην γραμμή εντολών + +> Για τους αναγνώστες στο σπίτι: αυτή η ενότητα καλύπτεται στο βίντεο [Your new friend: Command Line](https://www.youtube.com/watch?v=jvZLWhkzX-8). + +Είναι φοβερό έτσι; Θα γράψετε την πρώτη γραμμή κώδικα σε μερικά λεπτά! :) + +**Αφήστε μας να σας παρουσιάσουμε το νέο σας φίλο πρώτα: τη γραμμή εντολών!** + +Τα επόμενα βήματα θα σας δείξουν πώς να χρησιμοποιήσετε το μαύρο παράθυρο που όλοι οι χάκερ χρησιμοποιούν. Αυτό μπορεί να μοιάζει λίγο τρομακτικό στην αρχή αλλά πραγματικά αυτό είναι απλά ένα prompt σε αναμονή για εντολές από εσάς. + +> **Σημείωση** Παρακαλούμε να σημειώσετε ότι σε όλο το βιβλίο αυτό χρησιμοποιούμε το τους όρους «φάκελος» και «κατάλογος» αλλά στην ουσία είναι το ίδιο πράγμα. + +## Τι είναι η γραμμή εντολών; + +Το παράθυρο, το οποίο συνήθως ονομάζεται **γραμμή εντολών** ή **περιβάλλον γραμμής εντολών**, είναι μια εφαρμογή που βασίζεται σε κείμενο για προβολή, διαχείριση και χειρισμό αρχείων στον υπολογιστή σας. Είναι κάπως σαν το Windows Explorer ή το Finder στα Mac αλλά χωρίς το γραφικό κομμάτι (κουμπιά, βελάκια, σχήματα κλπ). Άλλα ονόματα για την γραμμή εντολών είναι: *cmd*, *CLI*, *prompt*, *console* ή *terminal*. + +## Άνοιγμα της γραμμής εντολών + +Για να πειραματιστείτε πρέπει πρώτα να ανοίξετε μια γραμμή εντολών (ή κονσόλα, πιο σύντομα). + + + +Πηγαίνετε στο Start menu → Windows System → Command Prompt. + +> Σε παλαιότερες εκδόσεις των Windows, κοιτάχτε στο Start menu → All Programs → Accessories → Command Prompt. + + + + + +Πηγαίνετε στο Launchpad → Other → Terminal. + + + + + +Συνήθως είναι κάτω από το Applications → Accessories → Terminal, αλλά αυτό εξαρτάται από το σύστημα σας. Αν δεν είναι εκεί ψάξτε το στο Google. :) + + + +## Prompt + +Θα πρέπει, τώρα, να βλέπετε ένα άσπρο ή μαύρο παράθυρο που αναμένει εντολές από εσάς. + + + +Αν είστε σε Mac ή Linux, θα βλέπετε το `$`, όπως αυτό: + +{% filename %}command-line{% endfilename %} + + $ + + + + + + +Στα Windows, θα βλέπετε το `>`, όπως: + +{% filename %}command-line{% endfilename %} + + > + + +Ρίξτε μια ματιά τώρα στο τμήμα του Linux από πάνω. Θα δείτε κάτι παρόμοιο με αυτό του PythonAnywhere αργότερα στον οδηγό. + + + +Πριν από κάθε εντολή θα προηγείται ο χαρακτήρας `$` ή `>` και ένα κενό αλλά εσείς δεν πρέπει να τα γράφετε. Ο υπολογιστής σας θα το κάνει για εσάς. :) + +> Μια μικρή σημείωση: στην περίπτωση σας μπορεί να δείτε κάτι σαν `C:\Users\ola>` ή `Olas-MacBook-Air:~ ola$` πριν το σύμβολο του prompt. Αυτό είναι 100% OK. + +Το σημείο μέχρι το (και συμπεριλαμβανομένου) `$` ή το `>` ονομάζεται *command line prompt*, ή σκέτο *prompt* εν συντομία. Σας προτρέπει να εισάγεται κάτι εκεί. + +Στον οδηγό, όταν θέλουμε εσείς να γράψετε μια εντολή, θα συμπεριλαμβάνουμε και το `$` ή `>` και, κατά περίπτωση, περισσότερα πιο αριστερά. Αγνοήστε, λοιπόν, το αριστερό κομμάτι και πληκτρολογείτε μόνο την εντολή ως έχει η οποία θα ξεκινά μετά το prompt. + +## Η πρώτη σας εντολή (ΝΑΙ!) + +Ας ξεκινήσουμε με αυτή την εντολή: + + + +{% filename %}command-line{% endfilename %} + + $ whoami + + + + + + +{% filename %}command-line{% endfilename %} + + > whoami + + + + +Και μετά πατήστε `enter`. Αυτό είναι το αποτέλεσμα: + +{% filename %}command-line{% endfilename %} + + $ whoami + olasitarska + + +Όπως μπορείτε να δείτε, ο υπολογιστής μόλις εκτύπωσε το όνομα χρήστη σας. Ωραίο, εε; :) + +> Προσπαθείτε να γράφετε ξάθε εντολή. Μην κάνετε αντιγραγή-επικόλληση. Θα θυμάστε περισσότερα με αυτό τον τρόπο! + +## Βασικά + +Κάθε υπολογιστικό σύστημα ένα διαφορετικό ρεπερτόριο εντολών στη γραμμή εντολών. Οπότε, φροντίστε να ακολουθάτε τις οδηγίες του δικού σας λειτουργικού συστήματος. Ας το δοκιμάσουμε, έτσι; + +### Παρόν φάκελος + +Θα ήταν ωραίο να γνωρίζουμε πού βρισκόμαστε τώρα, έτσι; Ας δούμε. Πληκτρολογήσετε αυτή την εντολή πατήστε `enter`: + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska + + +> Σημείωση: 'pwd' σημαίνει 'print working directory'. + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska + + +> Σημείωση: 'cd' σημαίνει 'change directory'. Με το PowerShell μπορείτε να χρησιμοποιήσετε την εντολή pwd όπως στο Linux ή το macOS. + + + +Κατά πάσα πιθανότητα θα δείτε κάτι παρόμοιο στο μηχάνημά σας. Μόλις ανοίγετε τη γραμμή εντολών, θα ξεκινάτε στον φάκελο του χρήστη (home folder). + +* * * + +### Μάθετε περισσότερα σχετικά με μια εντολή + +Πολλές εντολές που πληκτρολογείτε στη γραμμή εντολών έχουν ενσωματωμένη βοήθεια που μπορείτε να εμφανίσετε και να διαβάσετε! Για παράδειγμα, για να μάθετε περισσότερα σχετικά με τον τρέχων φάκελο: + + + +Τα λειτουργικά συστήματα macOS και Linux έχουν μια εντολή `man`, η οποία δίνει βοήθεια στις εντολές. Δοκιμάστε `man pwd` και δείτε τι λέει ή βάλτε την εντολή `man` πριν από άλλες εντολές για να δείτε τη βοήθειά τους. Η έξοδος της εντολής `man` παρουσιάζεται, συνήθως, ως σελιδοποιημένη (paged). Χρησιμοποιήστε το κουμπί του διαστήματος για να κινηθείτε προς την επόμενη σελίδα και το πλήκτρο `q` για να βγείτε από την "σελιδοποιημένη" βοήθεια, πίσω στην γραμμή εντολών. + + + + + +Προσθέτοντας το πρόθεμα `/?` στις περισσότερες εντολές θα εκτυπώσετε τη σελίδα βοήθειας. Ίσως να χρειαστεί να κάνετε scroll στο παράθυρο σας για να δείτε όλα. Δοκιμάστε `cd /;`. + + + +### Προβολή αρχείων και φακέλων + +Τι είναι, λοιπόν, μέσα; Θα ήταν ωραίο να μάθουμε. Ας δούμε: + + + +{% filename %}command-line{% endfilename %} + + $ ls + Applications + Desktop + Downloads + Music + ... + + + + + + +{% 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 + ... + + +> Σημείωση: Σε PowerShell μπορείτε επίσης να χρησιμοποιήσετε το 'ls' όπως στο Linux και στο macOS. + +* * * + +### Αλλαγή του τρέχοντος φακέλου + +Τώρα, ας μεταβούμε στον φάκελο επιφάνεια εργασίας: + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd Desktop + + + + +Δείτε αν όντως άλλαξε: + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + + +Εδώ είναι! + +> PRO tip: Εάν πληκτρολογήσετε `cd D` και στη συνέχεια πατήσετε το πλήκτρο `tab`, τότε η γραμμή εντολών θα συμπληρώσει αυτόματα το υπόλοιπο όνομα του. Έτσι μπορείτε να πλοηγηθείτε ταχύτερα. Εάν υπάρχουν περισσότεροι από ένας φάκελος που ξεκινάει με το «D», πατήστε το πλήκτρο `tab` δύο φορές για να εμφανιστεί μια λίστα επιλογών. + +* * * + +### Δημιουργία φακέλου + +Τι θα λέγατε να δημιουργούσαμε έναν φάκελο για σκοπούς εξάσκησης στην επιφάνεια εργασίας; Μπορείτε να το κάνετε κατ' αυτό τον τρόπο: + + + +{% filename %}command-line{% endfilename %} + + $ mkdir practice + + + + + + +{% filename %}command-line{% endfilename %} + + > mkdir practice + + + + +Αυτή η μικρή εντολή θα δημιουργήσει ένα φάκελο με το όνομα `practice` στην επιφάνεια εργασίας. Μπορείτε να ελέγξετε αν είναι εκεί εξετάζοντας την επιφάνεια εργασίας σας ή εκτελώντας την εντολή `ls` ή `dir`! Δοκιμάστε το. :) + +> PRO tip: Αν δεν θέλετε να γράφετε την ίδια εντολή ξανά και ξανά, πιέστε το `πάνω βελάκι` ή/και το `κάτω βελάκι` στο πληκτρολόγιο σας για να περιηγηθείτε στο ιστορικό των εντολών σας. + +* * * + +### Εξασκηθείτε! + +Μια μικρή πρόκληση για εσάς: στον καινούργιο σας φάκελο με το όνομα `practice`, δημιουργήστε έναν φάκελο με το όνομα `test`. (Χρησιμοποιήστε τις εντολές `cd` και `mkdir`.) + +#### Λύση: + + + +{% filename %}command-line{% endfilename %} + + $ cd practice + $ mkdir test + $ ls + test + + + + + + +{% filename %}command-line{% endfilename %} + + > cd practice + > mkdir test + > dir + 05/08/2014 07:28 PM test + + + + +Συγχαρητήρια! :) + +* * * + +### Διαγραφή + +Δεν θέλουμε να αφήσουμε πίσω μας άχρηστα αρχεία/φακέλους. Ας διαγράψουμε ότι έχουμε δημιουργήσει μέχρι τώρα. + +Πρώτα, πρέπει να πάμε πίσω στην Επιφάνεια Εργασίας: + + + +{% filename %}command-line{% endfilename %} + + $ cd .. + + + + + + +{% filename %}command-line{% endfilename %} + + > cd .. + + + + +Χρησιμοποιώντας τις δύο τελίτσες `..` παρέα με την εντολή `cd` αλλάζετε την θέση σας από τον παρόν φάκελο σε 1 επίπεδο πιο ψηλά (δηλαδή στον φάκελο που περιέχει τον τρέχων φάκελο). + +Δείτε που είστε: + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + + +Ώρα να διαγράψουμε τον φάκελο `practice`: + +> **Προσοχή**: Η διαγραφή των αρχείων χρησιμοποιώντας τις εντολές `del`, `rmdir` ή `rm` είναι μη αναστρέψιμες, δηλαδή *τα διεγραμμένα αρχεία δεν μπορούν να επανακτηθούν*! Οπότε να είστε προσεκτικοί με αυτή την εντολή. + + + +{% filename %}command-line{% endfilename %} + + $ rm -r practice + + + + + + +{% filename %}command-line{% endfilename %} + + > rmdir /S practice + practice, Are you sure ? Y + + + + +Έγινε! Για να βεβαιωθείτε ότι όντως διαγράφηκε, ας το δούμε: + + + +{% filename %}command-line{% endfilename %} + + $ ls + + + + + + +{% filename %}command-line{% endfilename %} + + > dir + + + + +### Έξοδος + +Αυτά για τώρα! Μπορείτε να κλείσετε τη γραμμή εντολών με ασφάλεια τώρα. Ας το κάνουμε με τον τρόπο του χάκερ, εντάξει;:) + + + +{% filename %}command-line{% endfilename %} + + $ exit + + + + + + +{% filename %}command-line{% endfilename %} + + > exit + + + + +Ωραίο, ε; :) + +## Περίληψη + +Παρακάτω φαίνεται μια περίληψη μερικών χρήσιμων εντολών: + +| Εντολή (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** | +| rmdir (ή 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) που περιέχει μια πλήρη αναφορά σε όλες τις εντολές όλων των λειτουργικών συστημάτων. + +## Είστε έτοιμοι; + +Ας μάθουμε λίγο Python! \ No newline at end of file diff --git a/el/python_installation/README.md b/el/python_installation/README.md new file mode 100644 index 00000000000..cacadba685a --- /dev/null +++ b/el/python_installation/README.md @@ -0,0 +1,15 @@ +# Ας ξεκινήσουμε με την Python + +Είμαστε επιτέλους εδώ! + +Αλλά πρώτα θα θέλαμε να σας εξηγήσουμε τι είναι η Python. Η Python είναι μια πολύ δημοφιλής γλώσσα προγραμματισμού η οποία μπορεί να χρησιμοποιηθεί σε πολλούς τομείς όπως δημιουργία ιστοσελίδων, παιχνίδια, επιστημονικό λογισμικό, γραφικά και πολλά πολλά άλλα. + +Η Python δημιουργήθηκε στα τέλη της δεκαετίας του 1980 και ο κύριος σκοπός της είναι να είναι ευανάγνωστη από ανθρώπους (και όχι από μηχανές!). Γι'αυτό το λόγο φαίνεται απλούστερη από άλλες γλώσσες προγραμματισμού, αλλά μην ανησυχείτε. Η Python είναι πραγματικά δυνατή! + +# Εγκατάσταση Python + +> **Σημείωση** Αν χρησιμοποιείτε Chromebook, μεταβείτε στο κεφάλαιο [Εγκατάσταση Chromebook](../chromebook_setup/README.md). +> +> **Σημείωση** Αν έχετε ήδη ολοκληρώσει τα βήματα εγκατάστασης, δεν υπάρχει λόγος να τα ξανακάνετε. Μπορείτε να διαβάσετε το ακόλουθο κεφάλαιο! + +{% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/el/python_installation/images/add_python_to_windows_path.png b/el/python_installation/images/add_python_to_windows_path.png new file mode 100644 index 00000000000..3266efb6177 Binary files /dev/null and b/el/python_installation/images/add_python_to_windows_path.png differ diff --git a/el/python_installation/images/python-installation-options.png b/el/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..a0a6c65d81d Binary files /dev/null and b/el/python_installation/images/python-installation-options.png differ diff --git a/el/python_installation/images/windows-plus-r.png b/el/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/el/python_installation/images/windows-plus-r.png differ diff --git a/el/python_installation/instructions.md b/el/python_installation/instructions.md new file mode 100644 index 00000000000..ce03da6cd23 --- /dev/null +++ b/el/python_installation/instructions.md @@ -0,0 +1,116 @@ +> Για τους αναγνώστες στο σπίτι: αυτό το κεφάλαιο καλύπτεται στο βίντεο [Installing Python & Code Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA). +> +> Αυτή η ενότητα βασίζεται σε tutorials από tην κοινότητα Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) + +Το Django είναι γραμμένο σε Python. Χρειαζόμαστε την Python για να κάνουμε το οτιδήποτε στο Django. Ακόμη και να το εγκαταστήσουμε. Ας ξεκινήσουμε εγκαθιστώντας την Python! Θέλουμε να εγκαταστήσετε την τελευταία έκδοση της Python 3. Αν έχετε κάποια παλαιότερη έκδοση θα θέλαμε να την αναβαθμίσετε. Αν έχετε ήδη την έκδοση 3.4 ή υψηλότερη τότε θα είστε μια χαρά. + + + +Πρώτα ελέγξτε αν ο υπολογιστής σας τρέχει το λειτουργικό σύστημα 32-bit ή 64-bit των Windows. Επιλέξτε "System type" από τη σελίδα System Info. Για να φτάσετε σε αυτή τη σελίδα με μια από τις ακόλουθες μεθόδους: + +* Πιέστε το κουμπί των Windows (δίπλα από το αριστερό Alt) και το Pause/Break ταυτόχρονα. +* Ανοίξτε τον πίνακα ελέγχου (Control Panel) από το Windows μενού και περιηγηθείτε στο System & Security, έπειτα επιλέξτε System +* Πιέστε το πλήκτρο των Windows και έπειτα περιηγηθείτε στο Settings > System > About + +Μπορείτε να κατεβάσετε την Python για Windows από τη σελίδα https://www.python.org/downloads/windows/. Κλικάρετε στο σύνδεσμο "Latest Python 3 Release - Python x.x.x". Αν ο υπολογιστής σας τρέχει **64-bit** Windows, τότε κατεβάστε το αρχείο **Windows x86-64 executable installer**. Ειδάλλως, κατεβάστε το αρχείο **Windows x86 executable installer**. Αφού κατεβάσετε το αρχείο εγκατάστασης, κάντε διπλό κλικ πάνω του και ακολουθήστε τις οδηγίες. + +Ένα πράγμα να προσέξετε: Κατά τη διάρκεια της εγκατάστασης, θα παρατηρήσετε ένα παράθυρο με το όνομα "Setup". Σιγουρευτείτε ότι είναι επιλεγμένο το κουτάκι "Add Python 3.6 to PATH" ή 'Add Python to your environment variables" και έπειτα κλικάρετε στην επιλογή "Install Now", όπως φαίνεται εδώ (ίσως να φαίνεται διαφορετικά σε εσάς αν εγκαθιστάτε διαφορετική έκδοση): + +![Don't forget to add Python to the Path](../python_installation/images/python-installation-options.png) + +Όταν ολοκληρωθεί η εγκατάσταση, ενδέχεται να δείτε ένα παράθυρο διαλόγου με μια σύνδεση που μπορείτε να ακολουθήσετε για να μάθετε περισσότερα σχετικά με την Python ή σχετικά με την έκδοση που έχετε εγκαταστήσει. Κλείστε ή πατήστε "Άκυρο" σε αυτό το παράθυρο διαλόγου. Θα μάθετε περισσότερα σε αυτό τον οδηγό! + +Στα επερχόμενα βήματα, θα χρησιμοποιείτε τη γραμμή εντολών των Windows (το οποίο, επίσης, θα σας πούμε). Για τώρα, εάν χρειάζεται να πληκτρολογήσετε μερικές εντολές, πηγαίνετε στο μενού Έναρξη και πληκτρολογήστε στο πεδίο Αναζήτηση «Command Prompt» (Γραμμή Εντολών). (Σε παλαιότερες εκδόσεις των Windows, μπορείτε να ξεκινήσετε τη γραμμή εντολών με το Start menu → Windows System → Command Prompt.) Μπορείτε να επίσης κρατήστε πατημένο το πλήκτρο των Windows και το πλήκτρο «R» μέχρι να εμφανιστεί το παράθυρο «Εκτέλεση» (Run). Για να ανοίξετε τη γραμμή εντολών, πληκτρολογήστε "cmd" και πατήστε enter στο παράθυρο «Εκτέλεση» (Run). + +![Πληκτρολογήστε "cmd" στο παράθυρο "Run"](../python_installation/images/windows-plus-r.png) + +Σημείωση: Εάν χρησιμοποιείτε μια παλαιότερη έκδοση των Windows (7, Vista ή οποιαδήποτε παλαιότερη έκδοση) και το πρόγραμμα εγκατάστασης της Python 3.6.x αποτύχει με σφάλμα, τότε μπορείτε να δοκιμάσετε τα εξής: + +1. Εγκαταστήστε όλες τις ενημερώσεις των Windows και προσπαθήστε ξανά να εγκαταστήσετε Python ή +2. εγκαταστήστε μια [παλαιότερη έκδοση της Python](https://www.python.org/downloads/windows/), π.χ. [3.4.6](https://www.python.org/downloads/release/python-346/). + +Εάν εγκαταστήσετε μια παλαιότερη έκδοση της Python, η οθόνη εγκατάστασης μπορεί να φαίνεται λίγο διαφορετική από ότι φαίνεται παραπάνω. Βεβαιωθείτε ότι μπορείτε να μετακινηθείτε προς τα κάτω για να δείτε το «Add python.exe to Path». Όταν το δείτε τότε κάντε κλικ στο κουμπί στην αριστερή πλευρά και διαλέξτε το "Will be installed on local hard drive": + +![Παλαιότερες εκδόσεις Add Python to the Path](../python_installation/images/add_python_to_windows_path.png) + + + + + +> **Σημείωση** Πριν εγκαταστήσετε την Python σε λειτουργικό macOS, θα πρέπει να σιγουρευτείτε ότι οι ρυθμίσεις του Mac σας, επιτρέπουν την εγκατάσταση πακέτων που δεν είναι από το App Store. Πηγαίνετε στο System Preferences (βρίσκεται στο φάκελο Applications) και κλικάρετε στο "Security & Privacy" και έπειτα στη καρτέλα "General". Αν η επιλογή "Allow apps downloaded from:" είναι ρυθμισμένη στο "Mac App Store," αλλάξτε το σε "Mac App Store and identified developers." + +Θα χρειαστεί να μεταβείτε στη σελίδα https://www.python.org/downloads/release/python-361/ και να κατεβάσετε το αρχείο εγκατάστασης: + +* Κατεβάστε το αρχείο *macOS 64-bit/32-bit installer*, +* Διπλό κλικ στο *python-3.6.1-macosx10.6.pkg* για να ξεκινήσει η διαδικασία εγκατάστασης. + + + + + +Είναι πολύ πιθανόν ότι η Python είναι προεγκατεστημένη στο σύστημα σας. Για να δείτε αν ναι (και ποια έκδοση επίσης), ανοίξτε μια κονσόλα και γράψτε: + +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python 3.6.1 + + +Αν έχετε διαφορετική έκδοση, τουλάχιστον την 3.4.0 (πχ 3.6.0), τότε δεν χρειάζεται να αναβαθμίσετε. Αν δεν την έχετε εγκατεστημένη ή αν θέλετε μια νέα έκδοση, τότε εγκαταστήστε τη ως εξής: + + + + + +Γράψτε τα ακόλουθα στην κονσόλα: + +{% filename %}command-line{% endfilename %} + + $ sudo apt install python3 + + + + + + +Χρησιμοποιήστε αυτή την εντολή στην κονσόλα: + +{% filename %}command-line{% endfilename %} + + $ sudo dnf install python3 + + +Αν χρησιμοποιείτε κάποια παλιά έκδοση της Fedora ίσως να λάβετε ένα σφάλμα ότι η εντολή `dnf` δεν υπάρχει. Σε αυτή την περίπτωση, θα χρειαστεί να χρησιμοποιήσετε την εντολή `yum`. + + + + + +Χρησιμοποιήστε αυτή την εντολή στην κονσόλα: + +{% filename %}command-line{% endfilename %} + + $ sudo zypper install python3 + + + + +Επιβεβαιώστε ότι η εκγκατάσταση πέτυχε ανοίγοντας μια κονσόλα και τρέχοντας `python3`: + +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python 3.6.1 + + +Η έκδοση σας μπορεί να είναι διαφορετική από την 3.6.1. Θα πρέπει να είναι η ίδια με αυτή που εγκαταστήσατε. + +**ΣΗΜΕΙΩΣΗ:** Αν είστε σε Windows και λάβετε ένα σφάλμα ότι η εντολή `python3` δεν βρέθηκε, προσπαθήστε την εντολή `python` (χωρίς το `3`) και σιγουρευτείτε ότι η έκδοση εξακολουθεί να είναι ίση ή μεγαλύτερη της 3.4.0. + +* * * + +Αν έχετε τυχόν απορίες ή κάτι πήγε στραβά και δεν έχετε ιδέα τι να κάνετε, παρακαλούμε ρωτήστε τον βοηθό σας! Μερικές φορές τα πράγματα δεν πηγαίνουν καλά και είναι καλύτερο να ρωτάμε κάποιον με εμπειρία. \ No newline at end of file diff --git a/el/python_introduction/README.md b/el/python_introduction/README.md new file mode 100644 index 00000000000..5618a295b7c --- /dev/null +++ b/el/python_introduction/README.md @@ -0,0 +1,1068 @@ +{% set warning_icon = '' %} + +# Εισαγωγή στην Python + +> Μέρος αυτού του κεφαλαίου είναι βασισμένο στους οδηγούς από την κοινότητα Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). + +Ας γράψουμε λίγο κώδικα! + +## Παράθυρο εντολών Python + +> Για τους αναγνώστες στο σπίτι: αυτό το μέρος που καλύπτεται από το βίντεο [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U). + +Για να αρχίσετε να παίζετε με την Python, πρέπει να ανοίξετε μια *γραμμή εντολών* στον υπολογιστή σας. Πρέπει ήδη να ξέρετε πως το κάνουμε αυτό. Το μάθαμε στο κεφάλαιο [Εισαγωγή στη γραμμή εντολών](../intro_to_command_line/README.md). + +Μόλις είστε έτοιμοι, ακολουθήστε τις παρακάτω οδηγίες. + +Θέλουμε να ανοίξουμε μια κονσόλα Python. Πληκτρολογήστε `python` αν είστε σε Windows ή `python3` αν είστε σε Mac OS/Linux και πατήστε `enter`. + +{% filename %}command-line{% endfilename %} + + $ python3 + Python 3.6.1 (...) + Type "help", "copyright", "credits" or "license" for more information. + >>> + + +## Η πρώτη σας Python εντολή! + +Αφού εκτελέσετε την εντολή Python, το prompt θα αλλάξει σε `>>>`. Για εμάς αυτό σημαίνει ότι τώρα μπορεί να χρησιμοποιούμε μόνο εντολές για τη γλώσσα Python. Δεν χρειάζεται να πληκτρολογήσετε `>>>`. Θα το κάνει η Python για σας. + +Εάν θέλετε να τερματίσετε την κονσόλα Python σε οποιοδήποτε σημείο, απλά πληκτρολόγηστε `exit()` ή `Ctrl + Z` για Windows και `Ctrl + D` για Mac/Linux. Τότε δεν θα μπορείτε να δείτε το `>>>` πια. + +Για τώρα δεν θέλουμε να φύγουμε από αυτό το περιβάλλον. Θέλουμε να μάθουμε περισσότερα γι'αυτό. Ας ξεκινήσουμε να γράφουμε μερικές μαθηματικές πράξεις, όπως `2 + 3` και μετά πατάμε `enter`. + +{% filename %}command-line{% endfilename %} + +```python +>>> 2 + 3 +5 +``` + +Ωραία! Είδατε την απάντηση από κάτω; Η Python ξέρει μαθηματικά! Μπορείτε να δοκιμάσετε και άλλες εντολές, όπως: + +- `4 * 5` +- `5 - 1` +- `40 / 2` + +Για να εκτελέσετε εκθετικούς υπολογισμούς, πχ 2 στη δύναμη του 3, γράφουμε: {% filename %}command-line{% endfilename %} + +```python +>>> 2 ** 3 +8 +``` + +Διασκέδασε με αυτό για λίγο και στη συνέχεια συνεχίστε πίσω εδώ. :) + +Όπως μπορείτε να δείτε, η Python είναι μια πολύ καλή αριθμομηχανή. Αν αναρωτιέστε τι άλλο μπορείτε να κάνετε… + +## Strings + +Τι θα λέγατε για το όνομα σας; Πληκτρολογήστε το μικρό σας όνομα μέσα σε "αυτάκια", όπως παρακάτω: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" +"Ola" +``` + +Μόλις δημιουργήσατε το πρώτο σας string! Είναι μια ακολουθία χαρακτήρων η οποία επεξεργάζεται από τον υπολογιστή. Ένα string πρέπει πάντα να ξεκινά και να τελειώνει με τον ίδιο χαρακτήρα. Αυτό μπορεί να είναι είτε μονά "αυτάκια" (`'`) ή διπλά (`"`) (καμία διαφορά!). Τα "αυτάκια" λένε στην Python το εξής: ότι υπάρχει ανάμεσα θεώρησε το ως ένα string. + +Τα strings μπορούν να ενωθούν. Δοκιμάστε το ακόλουθο: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Hi there " + "Ola" +"Hi there Ola" +``` + +Μπορείτε επίσης να πολλαπλασιάσετε strings με αριθμό: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` + +Αν χρειαστεί να βάλετε κάποια απόστροφο μέσα στο string, υπάρχουν δύο τρόποι να το κάνετε. + +Χρησιμοποιώντας διπλά "αυτάκια": + +{% filename %}command-line{% endfilename %} + +```python +>>> "Runnin' down the hill" +"Runnin' down the hill" +``` + +ή κάνοντας escape την απόστροφο με ένα backslash (``): + +{% filename %}command-line{% endfilename %} + +```python +>>> 'Runnin\' down the hill' +"Runnin' down the hill" +``` + +Ωραίο εε; Για να δείτε το όνομα σας σε κεφαλαία, γράψτε: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola".upper() +'OLA' +``` + +Μόλις χρησιμοποιήσατε την `upper` **method** πάνω στο string σας! Η μέθοδος (όπως η `upper()`) είναι μια ακολουθία από οδηγίες/εντολές που η Python πρέπει να εκτελέσει πάνω σε ένα συγκεκριμένο object (`"Ola"`) μόλις την καλέσετε. + +Αν θέλετε να μάθετε τον αριθμό των γραμμάτων που περιέχονται στο όνομα σας, υπάρχει συνάρτηση **function** και γι'αυτό! + +{% filename %}command-line{% endfilename %} + +```python +>>> len("Ola") +3 +``` + +Αναρρωτιέστε γιατί μερικές φορές καλείτε συναρτήσεις με την τελεία `.` στο τέλος ενός string (όπως `"Ola".upper()`) και άλλες καλείτε μια συνάρτηση και τοποθετείτε μέσα στις παρενθέσεις το string; Λοιπόν, σε κάποια σημεία οι συναρτήσεις ανήκουν σε objects, όπως η `upper()` η οποία επιδρά μόνο πάνω σε strings. Σε αυτή την περίπτωση, ονομάζουμε τις συναρτήσεις αυτές μεθόδους (**method**). Άλλες, πάλι, φορές οι συναρτήσεις δεν ανήκουν σε κάτι συγκεκριμένο και μπορούν να χρησιμοποιηθούν σε οποιουδήποτε τύπου object, όπως η `len()`. Γι'αυτό δίνουμε το string `"Ola"` ως παράμετρο στη συνάρτηση `len`. + +### Περίληψη + +Αρκετά με τα strings. Μέχρι τώρα μάθατε: + +- **το prompt** – γράφοντας εντολές (κώδικα) μέσα σε περειβάλλον της Python έχει ως αποτέλεσμα να παίρνετε απαντήσεις από την Python +- **αριθμούς και strings** – στην Python οι αριθμοί χρησιμοποιούνται για μαθηματικά και τα strings για χαρακτήρες +- **operators** – όπως `+` και `*`, συνδυάζουν τιμές και παράγουν μια νέα τιμή +- **functions** – όπως η `upper()` και η `len()`, εκτελούν κάποιες ενέργειες στα objects. + +Αυτά είναι τα βασικά για κάθε γλώσσα προγραμματισμού. Είστε έτοιμοι για κάτι πιο δύσκολο; Είμαστε σίγουροι ότι είστε! + +## Σφάλματα + +Ας δοκιμάσουμε κάτι καινούργιο. Μπορούμε να βρούμε το μήκος ενός αριθμού ακριβώς όπως κάναμε με το όνομα σας νωρίτερα; Πληκτρολογήστε `len(304023)` και πατήστε `enter`: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` + +Μόλις λάβατε το πρώτο σας σφάλμα! Το εικονίδιο {{ warning_icon }} είναι ο δικός μας τρόπος να σας πούμε ότι ο κώδικάς που πρόκειται να τρέξετε δεν θα έχει τα αναμενόμενα αποτελέσματα. Κάνοντας λάθη (ακόμα και εσκεμμένα) είναι σημαντικό κομμάτι κατά τη διάρκεια της εκμάθησης! + +Το συγκεκριμένο σφάλμα λέει ότι τα objects τύπου "int" (από τη λέξη integers, που σημαίνει ακέραιοι αριθμοί) δεν έχουν μήκος. Οπότε τι κάνουμε τώρα; Μήπως να γράψουμε τον αριθμό ως ένα string; Τα strings έχουν μήκος, έτσι; + +{% filename %}command-line{% endfilename %} + +```python +>>> len(str(304023)) +6 +``` + +Δούλεψε! Χρησιμοποιήσαμε τη συνάρτηση `str` μέσα στην `len`. Η `str()` μετατρέπει τα πάντα σε strings. + +- Η συνάρτηση `str` μετατρέπει πράγματα σε **strings** +- Η συνάρτηση `int` μετατρέπει πράγματα σε **integers** + +> Σημαντικό: μπορούμε να μετατρέψουμε αριθμούς σε κείμενο (strings) αλλά όχι απαραίτητα το αντίστροφο. Τι θα συνέβαινε αν τρέχατε `int('hello')`; + +## Μεταβλητές + +Ένα σημαντικό έννοια στον προγραμματισμό είναι οι μεταβλητές. Μια μεταβλητή δεν είναι τίποτε άλλο από ένα όνομα που μπορεί να επαναχρησιμοποιηθεί αργότερα. Οι προγραμματιστές χρησιμοποιούν τις μεταβλητές για την αποθήκευση δεδομένων, κάνοντας τον κώδικα πιο ευανάγνωστο χωρίς να χρειάζεται να θυμούνται τι ήταν τι. + +Ας υποθέσουμε ότι θέλετε να δημιουργήσετε μια μεταβλητή με το όνομα `name`: + +{% filename %}command-line{% endfilename %} + +```python +>>> name = "Ola" +``` + +Γράφουμε name ίσον με Ola. + +Όπως θα παρατηρήσατε, το πρόγραμμα δεν επέστρεψε τίποτα όπως πριν. Πως ξέρουμε, λοιπόν, ότι η μεταβλητή υπάρχει; Πληκτρολογήστε`name` και μετά πιέστε `enter`: + +{% filename %}command-line{% endfilename %} + +```python +>>> name +'Ola' +``` + +Ναιιι! Η πρώτη σας μεταβλητή! :) Μπορείτε πάντα να αλλάξετε την τιμή αυτής της μεταβλητής: + +{% filename %}command-line{% endfilename %} + +```python +>>> name = "Sonja" +>>> name +'Sonja' +``` + +Μπορείτε να χρησιμοποιήσετε μεταβλητές σε συναρτήσεις: + +{% filename %}command-line{% endfilename %} + +```python +>>> len(name) +5 +``` + +Φοβερό, έτσι; Οι μεταβλητές μπορεί να είναι οτιδήποτε (ακόμα και αριθμοί). Δοκιμάστε το εξής: + +{% filename %}command-line{% endfilename %} + +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` + +Αλλά τι θα γινόταν αν χρησιμοποιούσαμε λάθος όνομα; Τι θα συμβεί; Ας το δοκιμάσουμε! + +{% 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 +``` + +Ένα σφάλμα! Όπως μπορείτε να δείτε, η Python έχει διαφορετικού τύπου σφάλματα (τα έχει κατατάξει σε κατηγορίες). Αυτό εδώ ονομάζεται **NameError**. Η Python θα σας εμφανίσει αυτό το σφάλμα αν προσπαθήσετε να χρησιμοποιήσετε κάποια μεταβλητή της οποίας το όνομα δεν έχει δηλωθεί. Αν εμφανίστηκε αυτό το σφάλμα νωρίτερα σε εσάς, δείτε τον κώδικά σας μήπως και έχετε κάνει λάθος σε κάποιο όνομα μεταβλητής. + +Παίξτε για λίγο με αυτό και δείτε τι μπορείτε να κάνετε! + +## Η συνάρτηση print + +Δοκιμάστε αυτό: + +{% filename %}command-line{% endfilename %} + +```python +>>> name = 'Maria' +>>> name +'Maria' +>>> print(name) +Maria +``` + +Όταν απλώς πληκτρολογείτε `name`, η Python ανταποκρίνεται με το λεγόμενο string *representation* της τιμής της μεταβλητής 'name', η οποία είναι τα γράμματα M-a-r-i-a, περικυκλωμένα με τα μονά "αυτάκια", ''. Όταν λέτε `print(name)`, η Python θα "εκτυπώσει στην οθόνη" τα περιεχόμενα της μεταβλητής, χωρίς τα "αυτάκια", κάτι το οποίο είναι πιο ωραίο. + +Όπως θα δούμε και αργότερα, η συνάρτηση `print()` είναι χρήσιμη όταν θέλουμε να εκτυπώσουμε πράγματα μέσα σε συναρτήσεις ή όταν θέλουμε να εκτυπώσουμε πράγματα σε πολλαπλές γραμμές αντί μιας. + +## Λίστες + +Πέρα από τα strings και τους αριθμούς, η Python προσφέρει αρκετά ακόμα διαφορετικούς τύπους objects. Παρακάωτ θα περιγράψουμε αυτό που αποκαλούμε λίστα (**list**). Οι λίστες είναι αυτό που φαντάζεστε: objects τα οποία είναι λίστες άλλων objects. :) + +Πηγαίνετε και δημιουργήστε μια λίστα: + +{% filename %}command-line{% endfilename %} + +```python +>>> [] +[] +``` + +Ναι, αυτή είναι μια κενή λίστα. Όχι πολύ χρήσιμη έτσι; Ας δημιουργήσουμε μια λίστα με αριθμούς. Δεν θέλουμε να επαναλαμβανόμαστε όλη την ώρα, οπότε θα βάλουμε τη λίστα μέσα σε μια μεταβλητή: + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery = [3, 42, 12, 19, 30, 59] +``` + +Τέλεια, έχουμε μια λίστα! Τι μπορούμε να κάνουμε με αυτή; Ας δούμε πόσοι αριθμοί υπάρχουν μέσα στη λίστα. Ξέρετε, μήπως, ποια συνάρτηση μπορούμε να χρησιμοποιήσουμε γι'αυτό; Το ξέρετε ήδη! + +{% filename %}command-line{% endfilename %} + +```python +>>> len(lottery) +6 +``` + +Ναι! Η συνάρτηση `len()` σας δίνει τον αριθμό των objects μέσα σε μια λίστα. Ωραίο, έτσι; Ίσως να μπορούμε να ταξινομήσουμε τους αριθμούς: + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.sort() +``` + +Αυτό δεν επιστρέφει τίποτα, απλώς άλλαξε τη σειρά με την οποία εμφανίζονται οι αριθμοί στη λίστα. Ας εκτυπώσουμε τη λίστα να δούμε πως άλλαξαν τα δεδομένα της: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery) +[3, 12, 19, 30, 42, 59] +``` + +Όπως βλέπετε, οι αριθμοί μέσα στη λίστα είναι πλέον ταξινομημένοι κατά αύξοντα αριθμό. Συγχαρητήρια! + +Ίσως να θέλουμε να αντιστρέψουμε αυτή τη σειρά. Ας το κάνουμε! + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.reverse() +>>> print(lottery) +[59, 42, 30, 19, 12, 3] +``` + +Αν θέλετε να προσθέσετε κάτι στη λίστα σας, μπορείτε να το κάνετε με την ακόλουθη εντολή: + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.append(199) +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +``` + +Αν θέλετε να εμφανίσετε μόνο το πρώτο στοιχείο της λίστας, μπορείτε να το κάνετε χρησιμοποιώντας τα λεγόμενα **indexes**. Ένα index είναι ένας αριθμός ο οποίος δηλώνει σε ποιο σημείο ένα στοιχείο υπάρχει σε μια λίστα. Οι προγραμματιστές προτιμούν να ξεκινούν από το 0, οπότε το πρώτο στοιχείο θα βρίσκεται στη θέση (index) 0, το επόμενο στη θέση 1 κοκ. Δοκιμάστε αυτό: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery[0]) +59 +>>> print(lottery[1]) +42 +``` + +Όπως μπορείτε να δείτε, μπορείτε να έχετε πρόσβαση στα διαφορετικά στοιχεία μια λίστας γνωρίζοντας το όνομα της λίστας και τη θέση (index) του κάθε στοιχείου, δηλώνοντας το μέσα σε αγκύλες ([]). + +Για να διαγράψετε κάτι από τη λίστα, θα χρειαστεί να χρησιμοποιήσετε τα **indexes** καθώς και την μέθοδο `pop()`. Δηλαδή, θα πρέπει να ξέρετε ποιο στοιχείο να διαγράψετε. Ας δοκιμάσουμε ένα παράδειγμα. Θα διαγράψουμε το πρώτο στοιχείο της λίστας. + +{% filename %}command-line{% 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] +``` + +Δούλεψε μια χαρά! + +Παίξτε λίγο παραπάνω: δοκιμάστε μερικές άλλες θέσεις (αριθμός μέσα στην αγκύλη) όπως 6, 7, 1000, -1, -6 ή -1000. Δείτε αν μπορείτε να προβλέψετε το αποτέλεσμα πριν πατήσετε enter. Συμφωνούν τα αποτελέσματα με την πρόβλεψη σας; + +Μπορείτε να βρείτε την λίστα με όλες διαθέσιμες μεθόδους για μια λίστα στο Python documentation: https://docs.python.org/3/tutorial/datastructures.html + +## Λεξικά + +> Για τους αναγνώστες στο σπίτι: αυτή η ενότητα καλύπτεται στο βίντεο [Python Basics: Dictionaries](https://www.youtube.com/watch?v=ZX1CVvZLE6c). + +Ένα λεξικό (dictionary ή όπως έχει επικρατήσει, dict εν συντομία) είναι όμοιο με μια λίστα αλλά έχετε πρόσβαση στις τιμές όχι κατά θέση (index) αλλά κατά ένα κλειδί (key). Ένα κλειδί μπορεί να είναι ένα string ή ένας αριθμός. Η σύνταξη για ένα κενό λεξικό είναι: + +{% filename %}command-line{% endfilename %} + +```python +>>> {} +{} +``` + +Αυτό σηλώνει ότι μόλις δημιουργήσατε ένα κενό dict. Συγχαρητήρια! + +Τώρα, προσπαθήστε να εκτελέσετε την ακόλουθη εντολή (αντικαθιστώντας με δικά σας στοιχεία): + +{% filename %}command-line{% endfilename %} + +```python +>>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} +``` + +Με αυτή την εντολή μόλις δημιουργήσατε μια μεταβλητή με το όνομα `participant` με τρια ζευγάρια κλειδι-τιμή (key value pairs): + +- Το πρώτο κλειδί είναι το `name` το οποίο αντιστοιχεί την τιμή `'Ola'` (είναι ένα `string` object), +- Το δεύτερο κλειδί με το όνομα `country` αντιστοιχεί στην τιμή `'Poland'` (άλλο ένα `string`), +- και το τρίτο κλειδί `favorite_numbers` αντιστοιχεί στην τιμή `[7, 42, 92]` (μια λίστα `list` με τρεις αριθμούς μέσα της). + +Μπορείτε να δείτε τις τιμές κάθε κλειδιού με την ακόλουθη σύνταξη: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(participant['name']) +Ola +``` + +Βλέπετε ότι είναι όμοια με μια λίστα. Απλώς δεν χριάζεται να θυμάστε τη θέση - μόνο το όνομα. + +Τι θα συμβεί αν ζητήσουμε μια τιμή ενός κλειδιού η οποία δεν υπάρχει; Μπορείτε να μαντέψετε; Ας δοκιμάσουμε να δούμε! + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> participant['age'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'age' +``` + +Είδατε, άλλο ένα σφάλμα το οποίο λέγεται **KeyError**. Η Python είναι αρκετά καλή σε αυτό. Δηλαδή στην περιγραφικότητα των σφαλμάτων της. Σας λέει ότι το κλειδί `'age'` δεν υπάρχει στο λεξικό. + +Πότε πρέπει να χρησιμοποιείτε λεξικό έναντι μιας λίστας; Αυτό είναι ένα καλό ερώτημα. Σκεφτείτε λίγο την απάντηση πριν προχωρήσετε. + +- Χρειάζεστε μια ταξινομημένη ακολουθία από στοιχεία; Η απάντηση είναι λίστα. +- Χρειάζεστε να συσχετίζετε κλειδιά ούτως ώστε να τα αναζητείτε αργότερα μόνο με το όνομα τους και όχι με τη θέση τους; Η απάντηση είναι dict. + +Τα dicts όπως και οι λίστες είναι *mutable*, που σημαίνει ότι μπορούν να αλλάξουν μετά τη δημιουργία τους. Μπορείτε να προσθέσετε ένα νέο κλειδί-τιμή στο λεξικό αφού δημιουργηθεί, όπως παρακάτω: + +{% filename %}command-line{% endfilename %} + +```python +>>> participant['favorite_language'] = 'Python' +``` + +Όπως στις λίστες, χρησιμοποιώντας τη μέθοδο `len()` σε λεξικά, θα πάρετε τον αριθμό των ζευγαριών κλειδί-τιμή μέσα σε ένα λεξικό. Γράφτε το παρακάτω: + +{% filename %}command-line{% endfilename %} + +```python +>>> len(participant) +4 +``` + +Ελπίζουμε να βγάζουν νόημα όλα αυτά μέχρι τώρα. :) Είστε έτοιμοι για περισσότερη διασκέδαση με τα λεξικά; Συνεχίστε να διαβάζετε για περισσότερα πράγματα που μπορείτε να κάνετε. + +Μπορείτε να χρησιμοποιήσετε την μέθοδο `pop()` για να διαγράψετε ένα στοιχείο (ζευγάρι από κλειδί-τιμή) από ένα dict. Για παράδειγμα, αν θέλετε να διαγράψετε το ζευγάρι με το κλειδί `'favorite_numbers'`, γράψτε την ακόλουθη εντολή: + +{% filename %}command-line{% endfilename %} + +```python +>>> participant.pop('favorite_numbers') +[7, 42, 92] +>>> participant +{'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +Όπως μπορείτε να δείτε από την έξοδο, το ζευγάρι του κλειδιού 'favorite_numbers' διαγράφηκε επιτυχώς. + +Επίσης, μπορείτε να αλλάξετε την τιμή σε μια τιμή μέσα σε ένα λεξικό (αλλά όχι το ίδιο το κλειδί). Δοκιμάστε το εξής: + +{% filename %}command-line{% endfilename %} + +```python +>>> participant['country'] = 'Germany' +>>> participant +{'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +Όπως βλέπετε, η τιμή του κλειδιού `'country'` αλλάξε από `'Poland'` σε `'Germany'`. :) Φοβερό έτσι; Μπράβο! Μόλις μάθατε άλλο ένα απίθανο πράγμα. + +### Περίληψη + +Τέλεια! Ξέρετε πολλά σχετικά με τον προγραμματισμό τώρα. Στην τελευταία ενότητα μάθατε τα εξής: + +- **errors** – μάθατε πως να διαβάζετε και να καταλαβαινέτε τα σφάλματα τα οποία εμφανίζονται αν η Python δεν καταλαβαίνει κάποια εντολή που της δώσατε +- **variables** – ονόματα για objects τα οποία σας επιτρέπουν να γράφετε κώδικα πιο εύκολα αλλά και να είναι ο κώδικας σας πιο ευανάγνωστος +- **lists** – λίστες από objects που αποθηκεύονται σε μια συγκεκριμένη σειρά +- **dictionaries** – αντικείμενα τα οποία αποθηκεύονται υπό τη μορφή ζευγαριού κλειδί-τιμή + +Ενθουσιασμένοι για το επόμενο μέρος; :) + +## Σύγκριση πραγμάτων + +> Για τους αναγνώστες στο σπίτι: αυτή η ενότητα καλύπτεται στο βίντεο [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4). + +Ένα μεγάλος μέρος του προγραμματισμού περιλαμβάνει τη σύγκριση πραγμάτων. Ποιο είναι το πιο εύκολο πράγμα να συγκρίνουμε; Οι αριθμοί! Ας δούμε πως: + +{% filename %}command-line{% endfilename %} + +```python +>>> 5 > 2 +True +>>> 3 < 1 +False +>>> 5 > 2 * 2 +True +>>> 1 == 1 +True +>>> 5 != 2 +True +``` + +Δώσαμε στην Python μερικούς αριθμούς προς σύγκριση. Όπως βλέπετε, όχι μόνο μπορεί να συγκρίνει αριθμούς αλλά και αποτελέσματα από μεθόδους. Καλό εε; + +Αναρρωτιέστε γιατί βάλαμε `==` (δύο ίσον σύμβολα) για να εξακριβώσουμε αν οι αριθμοί είναι ίσοι; Χρησιμοποιούμε το μονό ίσον `=` για να αναθέσουμε μια τιμή σε μια μεταβλητή. Πάντα, **πάντα** θα χρειάζεται να βάζετε διπλό ίσον – `==` – αν θέλετε να δείτε αν δύο πράγματα είναι ίσα μεταξύ τους. Αν οι τιμές τους, δηλαδή, είναι ίδιες. Μπορούμε επίσης να εξακριβώσουμε αν οι τιμές τους δεν είναι ίσες. Γι'αυτό χρησιμοποιούμε το σύμβολο `!=`, όπως φαίνεται παραπάνω. + +Ας δώσουμε στην Python δύο ακόμα εντολές: + +{% filename %}command-line{% endfilename %} + +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` + +Είδαμε ότι τα σύμβολα `>` και `<`, αλλά τα ακόλουθα σύμβολα τι σημαίνουν: `>=`, `<=`; Διαβάστε τα κάπως έτσι: + +- x `>` y σημαίνει: το x είναι μεγαλύτερο το y +- x `<` y σημαίνει: το x είναι μικρότερο του y +- x `<=` y σημαίνει: το x είναι μικρότερο ή ίσο του y +- x `>=` y σημαίνει: το x είναι μεγαλύτερο ή ίσο του y + +Τέλεια! Θέλετε να δοκιμάσετε άλλο ένα; Δοκιμάστε αυτό: + +{% filename %}command-line{% endfilename %} + +```python +>>> 6 > 2 and 2 < 3 +True +>>> 3 > 2 and 2 < 1 +False +>>> 3 > 2 or 2 < 1 +True +``` + +Μπορείτε να δώσετε στην Python όσα νούμερα θέλετε προς σύγκριση και θα σας δώσει την απάντηση! Πολύ καλό, έτσι; + +- **and** – αν χρησιμοποιήσετε τον operator `and`, τότε και οι δύο συγκρίσεις θα πρέπει να είναι αληθείς (True) για να είναι όλη η εντολή True +- **and** – αν χρησιμοποιήσετε τον operator `or`, τότε αρκεί μόνο μια από τις συγκρίσεις να είναι αληθής (True) για να είναι όλη η εντολή True + +Έχετε ακούσει την έκφραση "συγκρίνω μήλα με πορτοκάλια"; Ας το δοκιμάσουμε με την Python: + +{% 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' +``` + +Όπως ισχύει με την παραπάνω έκφραση στην καθομιλουμένη, έτσι και στην Python δεν είναι δυνατόν να συγκριθεί ένας αριθμός (`int`) με ένα string (`str`). Αντ' αυτού, εμφανίζεται ένα σφάλμα τύπου **TypeError** το οποίο μας λέει ότι οι δύο τύποι objects δεν μπορούν να συγκριθούν μεταξύ τους. + +## Λογικές τιμές + +Χωρίς να το θέλετε, μόλις μάθατε έναν νέο τύπο object στην Python. Ονομάζεται **Boolean**. + +Υπάρχουν μόνο δύο ειδών Boolean objects: + +- True +- False + +Αλλά για να το καταλάβει η Python θα πρέπει πάντα να το γράφετε ως 'True' (το πρώτο γράμμα κεφαλαίο με τα υπόλοιπα πεζά). Τα **true, TRUE, και tRUE δεν θα δουλέψουν – μόνο το True είναι σωστό.** (Το ίδιο ισχύει και για το 'False'.) + +Τα booleans μπορούν να είναι και μεταβλητές! Δείτε εδώ: + +{% filename %}command-line{% endfilename %} + +```python +>>> a = True +>>> a +True +``` + +Μπορείτε να το κάνετε και έτσι: + +{% filename %}command-line{% endfilename %} + +```python +>>> a = 2 > 5 +>>> a +False +``` + +Εξασκηθείτε και διασκεδάστε με τα Booleans δοκιμάζοντας τις ακόλουθες εντολές: + +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` + +Συγχαρητήρια! Τα Booleans είναι ένα από τα πιο διασκεδαστικά πράγματα στον προγραμματισμό και μόλις μάθατε πως να τα χρησιμοποιείτε! + +# Αποθήκευση! + +> Για τους αναγνώστες στο σπίτι: αυτή η ενότητα καλύπτεται στο βίντεο [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk). + +Τόση ώρα γράφαμε τον κώδικα στην κονσόλα η οποία μας περιορίζει στο να εισάγουμε μια γραμμή κάθε φορά. Τα περισσότερα προγράμματα αποθηκεύονται σε αρχεία και τρέχουν όταν τους ζητηθεί από τον **interpreter** ή τον **compiler** της αντίστοιχης γλώσσας προγραμματισμού. Τόση ώρα τρέχαμε τα προγράμματα μας σε μια γραμμή κάθε φορά μέσα στον Python **interpreter**. Θα χρειαστούμς περισσότερες από μια γραμμές κώδικα για τα επόμενα στάδια. Οπότε θα χρειαστεί εν συντομία να κάνουμε τα εξής: + +- Να φύγουμε από τον Python interpreter +- Να ανοίξουμε τον επεξεργαστή κώδικα της αρέσκειας μας +- Να αποθηκεύσουμε κάποιο κομμάτι κώδικα σε ένα python αρχείο (με την κατάληξη .py) +- Να το τρέξουμε! + +Για να φύγουμε από τον Python interpreter θα γράψουμε `exit()` + +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` + +Αυτό θα σας επαναφέρει στη γραμμή εντολών. + +Νωρίτερα, επιλέξαμε έναν επεξεργαστή κώδικα από την ενότητα [επεξεργαστής κώδικα](../code_editor/README.md). Θα χρειαστεί να ανοίξουμε τον επεξεργαστή κώδικα και να γράψουμε κώδικα σε ένα νέο αρχείο (ή αν χρησιμοποιείτε Chromebook, δημιουργήστε ένα νέο αρχείο μέσω του Cloud IDE και ανοίξτε το αρχείο): + +{% filename %}editor{% endfilename %} + +```python +print('Hello, Django girls!') +``` + +Προφανώς, είστε ένας αρκετά έμπειρος Python developer τώρα, οπότε γράφτε κάποιον κώδικα μέσα στο αρχείο. + +Τώρα θέλουμε να αποθηκεύσουμε το αρχείο και να του δώσουμε ένα περιγραφικό όνομα. Ας το ονομάσουμς **python_intro.py** και ας το αποθηκεύσουμε στην επιφάνεια εργασίας. Μπορούμε να ονομάσουμε το αρχείο όπως θέλουμε αλλά το σημαντικό εδώ είναι η κατάληξηξ **.py** που πρέπει να έχει. Η κατάληξη **.py** λέει στο λειτουργικό μας σύστημα ότι αυτό το αρχείο αποτελεί ένα **εκτελέσιμο Python αρχείο** και έτσι η Python μπορεί να το τρέξει. + +> **Σημείωση** Θα πρέπει να είδατε ήδη ένα από τα πιο ωραία πράγματα στους επεξεργαστές κώδικα: τα χρώματα! Στην Python κονσόλα, όλα ήταν το ίδιο χρώμα. Τώρα βλέπετε ότι η συνάρτηση `print` έχει διαφορετικό χρώμα από ένα string. Αυτό ονομάζεται "syntax highlighting" και είναι ένα πολύ χρήσιμο χαρακτηριστικό καθώς προγραμματίζετε. Τα χρώματα θα σας δίνουν βοήθεια, όπως ένα string που του λείπει ένα "αυτάκι" ή ένα τυπογραφικό λάθος (typo) σε κάποια λέξε κλειδί της Python όπως `def` κλπ). Αυτός είναι ένας λόγος που χρησιμοποιούμε έναν επεξεργαστή κώδικα. :) :) + +Με αποθηκευμένο το αρχείο, είναι ώρα να το τρέξουμε! Χρησιμοποιώντας τις δεξιότητες που μάθατε στη γραμμή εντολών, χρησιμοποιήστε την κονσόλα για να **αλλάξετε φάκελο** και να μεταβείτε στην επιφάνεια εργασίας. + + + +Σε Mac, η εντολή θα μοιάζει κάπως έτσι: + +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop + + + + + + +Σε Linux, θα μοιάζει κάπως έτσι (η λέξη "Desktop" ίσως να είναι μεταφρασμένη στη γλώσσα σας ως "Επιφάνεια Εργασίας"): + +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop + + + + + + +Στα Windows θα μοιάζει κάπως έτσι: + +{% filename %}command-line{% endfilename %} + + > cd %HomePath%\Desktop + + + + + + +Και στα Windows Powershell, θα μοιάζει κάπως έτσι: + +{% filename %}command-line{% endfilename %} + + > cd $Home\Desktop + + + + +Αν κολλήσετε, ζητήστε βοήθεια. Για αυτόν ακριβώς το λόγο βρίσκονται οι βοηθοί! + +Τώρα χρησιμοποιήστε την Python για να τρέξετε τον κώδικα στο αρχείο όπως κατώθι: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hello, Django girls! + + +Σημείωση: στα Windows η εντολή 'python3' δεν αναγνωρίζεται. Αντ'αυτού χρησιμοποιήστε την εντολή 'python': + +{% filename %}command-line{% endfilename %} + +```python +> python python_intro.py +``` + +Τέλεια! Μόλις τρέξατε το πρώτο σας Python πρόγραμμα το οποίο είναι αποθηκευμένο σε αρχείο. Αισθάνεστε ωραία; + +Μπορείτε, τώρα, να μεταβείτε σε ένα σημαντικό εργαλείο στον προγραμματισμό: + +## If … elif … else + +Μερικές φορές, πολλά πράγματα στον κώδικα θα πρέπει να εκτελούνται αν ισχύουν συγκεκριμένες συνθήκες. Γι'αυτό το λόγο η Python (και κάθε άλλη γλώσσα προγραμματισμού) έχει κάτι που ονομάζει **if statements**. + +Αντικαταστήστε τον κώδικα στο αρχείο **python_intro.py** με αυτό: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 3 > 2: +``` + +Αν το αποθηκεύσουμε και το τρέξουμε, θα δούμε το ακόλουθο σφάλμα: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + + $ python3 python_intro.py + File "python_intro.py", line 2 + ^ + SyntaxError: unexpected EOF while parsing + + +Η Python περιμένει από εμάς να της δώσουμε περαιτέρω οδηγίες για το τι θα γίνει (τι θα εκτελεστεί) αν η συνθήκε `3 > 2` είναι αληθής (ή αλλιώς `True`). Ας προσπαθήσουμε να εκτυπώσουμε τη λέξη "It works!". Αλλάξτε τον κώδικα στο αρχείο **python_intro.py** ως εξής: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 3 > 2: + print('It works!') +``` + +Παρατηρήστε ότι προσθέσαμε τέσσερα κενά (4 spaces) για να κάνουμε indent την τελευταία γραμμη. Πρέπει να το κάνουμε αυτό ούτως ώστε να πούμε στην Python τι να κάνει αν η συνθήκη είναι αληθής. Μπορείτε να βάλετε ένα διάστημα (έναν κενό χαρακτήρα) αλλά όλοι οι προγραμματιστές Python χρησιμοποιούν τέσσερα για να φαίνεται πιο όμορφο και ευανάγνωστο. Η χρήση του Tab λαμβάνεται ως 4 κενά αρκεί ο επεξεργαστής κώδικα να είναι ρυθμισμένος γι'αυτό. Όταν κάνετε την επιλογή σας (Tab ή κενοί χαρακτήρες), μην την αλλάξετε! Αν χρησιμοποιείτε τα 4 κενά τότε να χρησιμοποιείτε τα 4 κενά για πάντα. Αλλιώς θα προκύψουν προβλήματα (mixed Tabs and spaces). + +Αποθηκεύστε το και δοκιμάστε να το ξανατρέξετε: + +{% filename %}command-line{% endfilename %} + +```python +$ python3 python_intro.py +It works! +``` + +Σημείωση: θυμηθείτε ότι στα Windows η εντολή 'python3' δεν αναγνωρίζεται. Χρησιμοποιείτε την 'python' για να τρέχετε αρχεία. + +### Αν όμως η συνθήκη δεν είναι True; + +Στα προηγούμενα παραδείγματα, ο κώδικας έτρεχε μόνο όταν η σνυθήκη ήταν αληθής. Αλλά η Python έχει και άλλα statements όπως το `elif` και το `else`: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 5 > 2: + print('5 is indeed greater than 2') +else: + print('5 is not greater than 2') +``` + +Όταν αυτό τρέχει θα εκτυπώσει: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + 5 is indeed greater than 2 + + +Αν το 2 ήταν μεγαλύτερο του 5 τότε η δεύτερη εντολή θα έτρεχε. Ας δούμε πως λειτουργεί η `elif`: + +{% filename %}python_intro.py{% endfilename %} + +```python +name = 'Sonja' +if name == 'Ola': + print('Hey Ola!') +elif name == 'Sonja': + print('Hey Sonja!') +else: + print('Hey anonymous!') +``` + +και τρέξτε το: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hey Sonja! + + +Είδατε τι έγινε εδώ; Το `elif` σας επέτρεψε να προσθέσετε έξτρα συνθήκες σε περίπτωση που οι προηγούμενες αποτύχουν. + +Μπορείτε να προσθέσετε όσα `elif` θέλετε μετά το αρχικό `if`. Για παράδειγμα: + +{% filename %}python_intro.py{% endfilename %} + +```python +volume = 57 +if volume < 20: + print("It's kinda quiet.") +elif 20 <= volume < 40: + print("It's nice for background music") +elif 40 <= volume < 60: + print("Perfect, I can hear all the details") +elif 60 <= volume < 80: + print("Nice for parties") +elif 80 <= volume < 100: + print("A bit loud!") +else: + print("My ears are hurting! :(") +``` + +Η Python τρέχει κάθε τεστ με τη σειρά και εκτυπώνει: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Perfect, I can hear all the details + + +## Σχόλια + +Τα χόλια είναι γραμμές οι οποίοες ξεκινούν με την δίεση `#`. Μπορείτε να γράψετε ότι θέλετε μετά την δίεση `#` και πολύ απλά η Python θα το αγνοήσει. Τα σχόλια μπορούνα να κάνουν τον κώδικα σας πιο ευανάγνωστο σε άλλους προγραμματιστές και όχι μόνο. + +Ας δούμε πως φαίνεται: + +{% 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!") +``` + +Δεν χρειάζεται να γράφεται σχόλιο για κάθε γραμμή κώδικα (άλλωστε δεν είναι καλή πρακτική ούτως ή άλλως) αλλά τα σχόλια είναι χρήσιμα ως προς το να εξηγήσουν το τι κάνει ο κώδικας ή να δώσουν κάποιου είδους περίληψη όταν κάνετε κάτι περίπλοκο. + +### Περίληψη + +Στις τελευταίες ασκήσεις μάθατε τα εξής: + +- **να συγκρίνετε πράγματα** – στην Python μπορείτε να συγκρίνετε πράγματα χρησιμοποιώντας `>`, `>=`, `==`, `<=`, `<` και `and`, `or` +- **Boolean** – ένας τύπος object το οποίο μπορεί να πάρει μόνο δύο τιμές: `True` ή `False` +- **Αποθήκευση αρχείων** – αποθήκευση κώδικα σε αρχεία ούτως ώστε να τρέχετε μεγαλύτερου όγκου προγράμματα. +- **if … elif … else** – αυτά τα statements σας επιτρέπουν να εκτελείτε κώδικα υπό συγκεκριμένες συνθήκες. +- **σχόλια** - γραμμές στην Python οι οποίες δεν εκτελούνται και σας επιτρέπουν να κάνετε τον κώδικα σας πιο περιγραφικό και ευανάγνωστο + +Ώρα για το τελευταίο μέρος του κεφαλαίου! + +## Οι δικές σας συναρτήσεις! + +> Για τους αναγνώστες στο σπίτι: αυτή η ενότητα καλύπτεται στο βίντεο [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0). + +Θυμάστε τις συναρτήσεις όπως τη `len()` που εκτελούσατε; Λοιπόν, σας έχουμε καλά νέα! Θα μάθετε πως να δημιουργείτε τις δικές σας! + +Μια συνάρτηση είναι μια σειρά από οδηγίες που η Python πρέπει να εκτελέσει. Κάθε συνάρτηση ξεκινά με τη λέξη κλειδί της Python `def`, μετά ακολουθεί το όνομα αυτής και μετά δίνονται τυχόν παράμετροι. Ας το προσπαθήσουμε. Αντικαταστήστε τον κώδικα στο αρχείο **python_intro.py** με το ακόλουθο: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(): + print('Hi there!') + print('How are you?') + +hi() +``` + +Ωραία. Η πρώτη μας συνάρτηση είναι έτοιμη! + +Θα αναρρωτιέστε γιατί γράψαμε το όνομα της συνάρτησης στο τέλος του αρχείου. Αυτό γίνεται επειδή η Python διαβάζει το αρχείο και το τρέχει από την κορυφή έως το τέλος. Για να χρησιμοποιήσουμε, λοιπόν, την συνάρτηση μας θα πρέπει να την ξαναγράψουμε στο τέλος. + +Ας το τρέξουμε για να δούμε το αποτέλεσμα: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi there! + How are you? + + +Σημείωση: αν δεν δούλεψε, μην πανικοβάλεστε! Η έξοδος θα σας βοηθήσει να καταλάβετε το γιατί: + +- Αν λέβετε ένα σφάλμα τύπου `NameError`, τότε ίσως γράψατε κάτι λάθος όπως το όνομα της συνάρτηση στο τέλος του αρχείου. Επιβεβαιώστε ότι το όνομα στη δήλωση της συνάρτηση `def hi():` είναι το ίδιο με το όνομα όταν την καλείτε `hi()`. +- Αν λάβατε ένα σφάλμα τύπου `IndentationError`, ελέγξτε ότι και οι γραμμές που καλούνται οι δύο συναρτήσεις `print` έχουν τον ίδιο αριθμό κενών στην αρχή: η Python απαιτεί όλος ο κώδικας μέσα στις συναρτήσεις να είναι στοιχισμένος το ίδιο. +- Αν δεν βλέπετε κάποια έξοδο τότε είτε έχετε παραλείψει να καλέσετε την συνάρτηση χρησιμοποιώντας τις παρενθέσεις `hi()` είτε το έχετε κάνει αλλά η κλήση της συνάρτησης (hi()) έχει *κενό* στην αρχή και αποτελεί μέρος του κυρίου σώματος της συνάρτησης (def hi():). + +Ας φτιάξουμε την πρώτη μας συνάρτηση με παραμέτρους. Θα αλλάξουμε το προηγούμενο παράδειγμα συμπεριλαμβάνοντας ένα όνομα. Θα φτιάξουμε μια συνάρτηση που να λέει 'hi' στο πρόσωπο που την καλεί: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): +``` + +Όπως βλέπετε, δώσαμε μια παράμετρο στην συνάρτηση με το όνομα `name`: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + if name == 'Ola': + print('Hi Ola!') + elif name == 'Sonja': + print('Hi Sonja!') + else: + print('Hi anonymous!') + +hi() +``` + +Θυμηθείτε: Η συνάρτηση `print` είναι στοιχισμένη με 4 κενά μέσα στο statement `if`. Αυτό το κάνουμε διότι θέλουμε να εκτελεστεί η συνάρτηση όταν η συνθήκη στο if είναι αληθής. Ας δούμε πως δουλεύει τώρα: + +{% 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' + + +Ώπα, ένα σφάλμα. Ευτυχώς, η Python μας δίνει ένα αρκετά χρήσιμο σφάλμα. Μας λέει ότι η συνάρτηση `hi()` (αυτή που ορίσαμε) δέχεται μια απαραίτητη παράμετρο (με το όνομα `name`) και ότι ξεχάσαμε να την ορίσουμε καθώς την καλούσαμε. Ας το φτιάξουμε αυτό στο τέλος του αρχείου: + +{% filename %}python_intro.py{% endfilename %} + +```python +hi("Ola") +``` + +Και ας το τρέξουμε ξανά: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Ola! + + +Και αν μπορούμε να αλλάξουμε το όνομα; + +{% filename %}python_intro.py{% endfilename %} + +```python +hi("Sonja") +``` + +Και το τρέξουμε: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Sonja! + + +Τώρα τι νομίζετε ότι θα γίνει αν γράψετε άλλο όνομα εκεί μέσα; (Όχι το Ola ή το Sonja). Δοκιμάστε το και προβλέψτε την έξοδο. Θα εκτυπώσει το εξής: + +{% filename %}command-line{% endfilename %} + + Hi anonymous! + + +Αυτό είναι φοβερό, έτσι; Με αυτό τον τρόπο δεν χρειάζεται να επαναλαμβάνεστε κάθε φορά που θέλετε να αλλάξετε το όνομα του προσώπου που η συνάρτηση υποτίθεται ότι χαιρετά. Και γι'αυτό το λόγο χρησιμοποιούμε τις συναρτήσεις. Δεν θέλετε ποτέ να επαναλάβετε τον κώδικα σας! + +Ας κάνουμε κάτι πιο έξυπνο. Υπάρχουν περισσότερα ονόματα από δύο και το να γράφουμε συνθήκες για καθένα χωριστά καταντά κουραστικό και ευάλωτο σε λάθη. Αντικαταστήστε το περιεχόμενο του αρχείου σας με τα κατώθι: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + print('Hi ' + name + '!') + +hi("Rachel") +``` + +Ας τρέξουμε τον κώδικα τώρα: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Rachel! + + +Συγχαρητήρια! Μόλις μάθατε πως να γράφετε συναρτήσεις! :) + +## Επαναλήψεις + +> Για τους αναγνώστες στο σπίτι: αυτή η ενότητα καλύπτεται στο βίντεο [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0). + +Αυτό είναι το τελευταίο κομμάτι. Ήταν σύντομο, έτσι; :) + +Οι προγραμματιστές δεν θέλουν να επαναλαμβάνουν τα ίδια και τα ίδια. Ο προγραμματισμός έχει να κάνει με την αυτοματοποίηση των πραγμάτων. Οπότε δεν θέλουμε να χαιρετάμε κάθε πρόσωπο με το όνομα τους χειροκίνητα, έτσι; Εδώ, λοιπόν, έρχονται οι επαναλήψεις (ή loops ή βρόγχοι). + +Θυμάστε τις λίστες; Ας φτιάξουμε μια λίστα με ονόματε κοριτσιών: + +{% filename %}python_intro.py{% endfilename %} + +```python +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +``` + +Θέλουμε να τις χαιρετίσουμε όλες με το όνομα τους. Έχουμε, ήδη, μια συνάρτηση με το όνομα `hi`, οπότε θα χρησιμοποιήσουμε αυτή: + +{% filename %}python_intro.py{% endfilename %} + +```python +for name in girls: +``` + +Η λέξη κλειδί της Python `for` συμπεριφέρεται περίπου όπως το `if`. Το κυρίως σώμα του κώδικα που ακολουθεί θα πρέπει να είναι στοιχισμένο με 4 κενά. + +Αυτός θα είναι ο κώδικας που θα υπάρχει στο αρχείο: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + print('Hi ' + name + '!') + +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +for name in girls: + hi(name) + print('Next girl') +``` + +Και όταν το τρέχουμε: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Rachel! + Next girl + Hi Monica! + Next girl + Hi Phoebe! + Next girl + Hi Ola! + Next girl + Hi You! + Next girl + + +Όπως βλέπετε οτιδήποτε βάλτε μέσα σε ένα statement `for` με την ανάλογη στοίχιση θα επαναληφθεί για κάθε στοιχείο της λίστας `girls`. + +Μπορείτε να χρησιμοποιήσετε το `for` και για αριθμούς χρησιμοποιώντας της συνάρτηση `range`: + +{% filename %}python_intro.py{% endfilename %} + +```python +for i in range(1, 6): + print(i) +``` + +Το οποίο θα εκτυπώσει: + +{% filename %}command-line{% endfilename %} + + 1 + 2 + 3 + 4 + 5 + + +Η συνάρτηση `range` δημιουργεί μια λίστα από αριθμούς (αυτοί οι αριθμοί εισάγονται από εσάς ως παράμετροι). + +Σημειώστε ότι η δεύτερη παράμετρος δεν περιλαμβάνεται στην λίστα που επιστρέφει (δηλαδή το `range(1, 6)` θα μετρήσει από το 1 έως το 5, αλλά δεν θα συμπεριλάβει το 6). Αυτό γίνεται διότι η συνάρτηση "range" είναι τύπου κλειστό-ανοιχτό, δηλαδή συμπεριλαμβάνει την πρώτη τιμή αλλά όχι την τελευταία. + +## Περίληψη + +Αυτό ήταν. **Τα σπάτε!** Αυτό ήταν ένα δύσκολο κεφάλαιο, οπότε θα πρέπει να νιώθετε περίφανοι με τον εαυτό σας. Είμαστε πολύ περήφανοι που τα καταφέρατε μέχρι εδώ! + +Για τον επίσημο και πλήρης Python οδηγό επισκεφτείτε την σελίδα https://docs.python.org/3/tutorial/. Αυτό θα σας δώσει μια πιο ολοκληρωμένη και εις βάθος γνώση αυτής της γλώσσας προγραμματισμού. Γεια σας :) + +Ίσως θα θέλατε να κάνετε κάτι κάτι άλλο, πχ τεντωθείτε, να περπατήσετε λίγο, να ξεκουράσετε τα μάτια σας, πριν συνεχίσετε στο επόμενο κεφάλαιο. :) + +![Κεκάκι](images/cupcake.png) \ No newline at end of file diff --git a/el/python_introduction/images/cupcake.png b/el/python_introduction/images/cupcake.png new file mode 100644 index 00000000000..8c1820adee8 Binary files /dev/null and b/el/python_introduction/images/cupcake.png differ diff --git a/el/template_extending/README.md b/el/template_extending/README.md new file mode 100644 index 00000000000..422326b0782 --- /dev/null +++ b/el/template_extending/README.md @@ -0,0 +1,147 @@ +# Επεκτείνοντας τα template + +Ένα άλλο ωραίο πράγμα που προσφέρει το Django είναι η **επέκταση των templates**. Τι σημαίνει αυτό; Αυτό σημαίνει ότι μπορείτε να χρησιμοποιείτε τα ίδια κομμάτια HTML για διαφορετικές σελίδες του διαδυκτιακού σας τόπου. + +Τα templates σας βοηθάνε στο να επαναχρησιμοποιήσετε το ίδιο τμήμα HTML (την ίδια, δηλαδή, πληροφορία) σε περισσότερα από ένα μέρη. Δεν χρειάζεται να επαναλαμβάνεται τον εαυτό σας σε κάθε αρχείο. Και αν χρειαστεί να αλλάξετε κάτι, δεν χρειάζεται να το κάνετε σε κάθε template παρά μόνο σε ένα! + +## Δημιουργία ενός βασικού (base) template + +Το base template είναι το πιο βασικό template που μπορείτε να επεκτείνετε σε κάθε σελίδα του ιστότοπού σας. + +Ας δημιουργήσουμε ένα αρχείο `base.html` μέσα στο `blog/templates/blog/`: + + blog + └───templates + └───blog + base.html + post_list.html + + +Στη συνέχεια, άνοιξε το και να αντίγραψε τα πάντα από το αρχείο `post_list.html` στο `base.html`, όπως ακολούθως: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% load static %} + + + Django Girls blog + + + + + + + + +
+
+
+ {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
+ + +``` + +Στη συνέχεια στο αρχείο `base.html`, αντικαταστήστε τα περιεχόμενα των: ``(τα πάντα μεταξύ `` και ``) με αυτό: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ +``` + +{% raw %}Ίσως παρατηρήσατε ότι αυτό αντικατέστησε τα πάντα από το `{% for post in posts %}` μέχρι το `{% endfor %}` με αυτό: {% endraw %} + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% block content %} +{% endblock %} +``` + +Αλλά γιατί; Μόλις δημιουργήσατε ένα `block`! Χρησιμοποιήσατε ένα template tag με το όνομα `{% block %}` για να δημιουργήσετε μια περιοχή όπου μέσα θα εισαχθεί HTML. Η HTML θα έρθει από άλλο αρχείο template το οποίο κάνει extend (επεκτείνει) αυτό το template (`base.html`). Θα σας δείξουμε πως να το κάνετε αυτο σε λίγο. + +Αποθηκεύστε το template `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.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` + +Θέλουμε να χρησιμοποιήσουμε αυτό το κομμάτι ως μέρος του template μας για όλα τα blocks με περιεχόμενο. Ήρθε η ώρα να προσθέσουμε blocks σε αυτό το αρχείο! + +{% raw %}Πρέπει το όνομα του block να είναι το ίδιο με αυτό που δηλώσαμε στο template `base.html`. Πρέπει επίσης να συμπεριλάβουμε όλο τον κώδικα που ανήκει σε αυτά τα blocks. Για να γίνει αυτό, βάλτε τα όλα μεταξύ `{% block content %}` και `{% endblock %}`. Έτσι:{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +Μόνο ένα πράγμα έμεινε. Πρέπει να "συνδέσουμε" αυτά τα δύο templates μαζί. Αυτή είναι η έννοια της επέκτασης των template! Θα το κάνουμε αυτό προσθέτοντας τη λέξη-κλειδί "extends" στην αρχή του αρχείου. Κάπως έτσι: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +Αυτό ήταν! Αποθηκεύστε το αρχείο και επιβεβαιώστε ότι η ιστοσελίδα σας λειτουργεί όπως πριν. :) + +> Αν λέβετε κάποιο σφάλμα όπως `TemplateDoesNotExist`, αυτό σημαίνει ότι δεν υπάρχει το αρχείο `blog/base.html` και ότι ο `server` τρέχει στην κονσόλα. Προσπαθήστε να τον σταματήσετε (πιέζοντας Ctrl + C) και επανεκκινήστε τον τρέχοντας την εντολή `python manage.py runserver`. \ No newline at end of file diff --git a/el/whats_next/README.md b/el/whats_next/README.md new file mode 100644 index 00000000000..9c03c6a2bf8 --- /dev/null +++ b/el/whats_next/README.md @@ -0,0 +1,42 @@ +# Τι υπάρχει μετά; + +Επιβράβευσε τον εαυτό σου! **Είσαι φοβερή**. Είμαστε περήφανοι! <3 + +### Τι μπορείς να κάνεις τώρα; + +Κάνε ένα διάλλειμα και χαλάρωσε! Μόλις έφερες εις πέρας κάτι πραγματικά μεγάλο. + +Μετά, ακολούθησε την κοινότητα Django Girls στο [Facebook](http://facebook.com/djangogirls) ή/και στο [Twitter](https://twitter.com/djangogirls) ούτως ώστε να μένεις ενημερωμένος. + +### Μπορείς να προτείνεις τυχόν επιπρόσθετες πηγές; + +Ναι! Υπάρχουν *πολλές* πηγές στο διαδίκτυο σχετικά με την εκμάθηση γλωσσών προγραμματισμού όλων των ειδών. Ίσως να είναι δύσκολη η επιλογή του επόμενου βήματος αλλά μην ανησυχείτε. Σας καλύπτουμε. Όποια και αν ήταν τα ενδιαφέροντα σας προτού έρθετε στην κοινότητα των Django Girls και οποιαδήποτε ενδιαφέροντα αναπτύξατε κατά τη διάρκεια του οδηγού, παρακάτω σας παρουσιάζουμε μερικές δωρεάν πηγές (κάποιες από τις οποίες δεν είναι αμιγώς δωρεάν αλλά περιέχουν δωρεάν κομμάτια) τις οποίες μπορείτε να χρησιμοποιήσετε προκειμένου να πετύχετε τον στόχο σας. + +#### Django + +- Το άλλο μας βιβλίο, [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org/) +- [Ο επίσημος οδηγός του Django](https://docs.djangoproject.com/en/2.0/intro/tutorial01/) +- [Ξεκινώντας με το Django με μαθήματα βίντεο](http://www.gettingstartedwithdjango.com/) +- [Hello Web App: Learn How to Build a Web App](https://hellowebbooks.com/learn-django/) – το μάθημα δεν είναι δωρεάν αλλά μπορείτε να ζητήσετε μια δωρεάν eBook άδεια από την συγγραφέα Tracy Osborn στο + +#### HTML, CSS και JavaScript + +- [Μάθημα web development από την εταιρεία 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) – σε αυτό το γνωστό site, μπορείτε να παρακολουθήσετε τα περισσότερα μαθήματα δωρεάν αλλά για την απόκτηση κάποιου πιστοποιητικού τότε θα χρειαστεί να καταβάλετε κάποιο ποσό ανάλογα το μάθημα και το πιστοποιτικό +- [Μαθήματα για Python από το Coursera](https://www.coursera.org/specializations/python) – μερικά μαθήματα βίντεο είναι δωρεάν + +#### Δουλεύοντας με δεδομένα + +- [Μάθημα επιστημονικών δεδομένων από την εταιρία Codecademy](https://www.codecademy.com/learn/paths/data-science) +- [edX](https://www.edx.org/course/?search_query=python&subject=Data%20Analysis%20%26%20Statistics) – σε αυτό το γνωστό site, μπορείτε να παρακολουθήσετε τα περισσότερα μαθήματα δωρεάν αλλά για την απόκτηση κάποιου πιστοποιητικού τότε θα χρειαστεί να καταβάλετε κάποιο ποσό ανάλογα το μάθημα και το πιστοποιτικό +- [Dataquest](https://www.dataquest.io/) – οι πρώτες 30 "αποστολές" είναι δωρεάν + +Ανυπομονούμε να δούμε το επόμενο σας project! \ No newline at end of file diff --git a/en/README.md b/en/README.md index cb5c62b266d..419cf0c347f 100644 --- a/en/README.md +++ b/en/README.md @@ -1,9 +1,18 @@ # Django Girls Tutorial -[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial) > This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. > To view a copy of this license, visit https://creativecommons.org/licenses/by-sa/4.0/ +## Welcome +Welcome to the Django Girls Tutorial! We are happy to see you here. :) In this tutorial, we will take you on a journey under the hood of web technologies, offering you a glimpse of all the bits and pieces that need to come together to make the web work as we know it. + +As with all unknown things, this is going to be an adventure - but no worries, since you already worked up the courage to be here, you'll be just fine. :) + +{% if output.name != "ebook" %} +> Do you want to read this tutorial on your e-reader? +> Then [download the Django Girls Tutorial as an e-book in ePub format](../django-girls-tutorial_{{ book.language }}.epub). +{% endif %} + ## Introduction Have you ever felt that the world is more and more about technology to which you cannot (yet) relate? Have you ever wondered how to create a website but have never had enough motivation to start? Have you ever thought that the software world is too complicated for you to even try doing something on your own? @@ -16,19 +25,17 @@ We hope that we'll be able to make you love technology as much as we do! ## What will you learn during the tutorial? -Once you've finished the tutorial, you will have a simple, working web application: your own blog. We will show you how to put it online, so others will see your work! +Once you've finished the tutorial, you will have a small working web application: your own blog. We will show you how to put it online, so others will see your work! It will (more or less) look like this: ![Figure 0.1](images/application.png) -> If you work with the tutorial on your own and don't have a coach who will help you in case of any problem, we have a chat system for you: [![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial). We asked our coaches and previous attendees to be there from time to time and help others with the tutorial! Don't be afraid to ask your question there! - OK, [let's start at the beginning…](./how_the_internet_works/README.md) ## Following the tutorial at home -It is amazing to take part in a Django Girls workshop, but we are aware that it is not always possible to attend one. This is why we encourage you to try following this tutorial at home. For readers at home we are currently preparing videos that will make it easier to follow the tutorial on your own. It is still a work in progress, but more and more things will be covered soon at the [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed) YouTube channel. +It is amazing to take part in a Django Girls workshop, but we are aware that it is not always possible to attend one. This is why we encourage you to try following this tutorial at home. For readers at home, we are currently preparing videos that will make it easier to follow the tutorial on your own. It is still a work in progress, but more and more things will be covered soon at the [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed) YouTube channel. In every chapter already covered, there is a link that points to the correct video. @@ -37,10 +44,10 @@ In every chapter already covered, there is a link that points to the correct vid This tutorial is maintained by [DjangoGirls](https://djangogirls.org/). If you find any mistakes or want to update the tutorial please [follow the contributing guidelines](https://github.com/DjangoGirls/tutorial/blob/master/README.md). -## Would you like to help us translate the tutorial to other languages? +## Would you like to help us translate the tutorial into other languages? -Currently, translations are being kept on crowdin.com platform at: +Currently, translations are being kept on the crowdin.com platform at: https://crowdin.com/project/django-girls-tutorial -If your language is not listed on crowdin, please [open a new issue](https://github.com/DjangoGirls/tutorial/issues/new) informing us of the language so we can add it. +If your language is not listed on [crowdin](https://crowdin.com/), please [open a new issue](https://github.com/DjangoGirls/tutorial/issues/new) informing us of the language so we can add it. diff --git a/en/SUMMARY.md b/en/SUMMARY.md index 679a8744f74..f5ca8d54132 100644 --- a/en/SUMMARY.md +++ b/en/SUMMARY.md @@ -2,6 +2,16 @@ * [Introduction](README.md) * [Installation](installation/README.md) + * [Installation (Chromebook)](chromebook_setup/README.md) + * [Installation (macOS/Windows/Linux)](installation/README.md#macos-windows-linux) + * [Command Line](installation/README.md#intro-command-line) + * [Python](installation/README.md#python) + * [Code Editor](installation/README.md#code-editor) + * [Virtual Environment](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) * [How the Internet works](how_the_internet_works/README.md) * [Introduction to command line](intro_to_command_line/README.md) * [Python installation](python_installation/README.md) @@ -13,7 +23,7 @@ * [Django models](django_models/README.md) * [Django admin](django_admin/README.md) * [Deploy!](deploy/README.md) -* [Django urls](django_urls/README.md) +* [Django URLs](django_urls/README.md) * [Django views – time to create!](django_views/README.md) * [Introduction to HTML](html/README.md) * [Django ORM (Querysets)](django_orm/README.md) diff --git a/en/chromebook_setup/README.md b/en/chromebook_setup/README.md index a4843977603..cadeff050a0 100644 --- a/en/chromebook_setup/README.md +++ b/en/chromebook_setup/README.md @@ -1,5 +1,5 @@ # Chromebook setup -> **Note** If you already worked through the Installation steps, no need to do this again – you can skip straight ahead to [Introduction to Python](../python_introduction/README.md). +> **Note** If you already worked through the [installation steps](../installation/README.md), no need to do this again – you can skip straight ahead to [Introduction to Python](../python_introduction/README.md). -{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file +{% include "/chromebook_setup/instructions.md" %} diff --git a/en/chromebook_setup/images/codespace-auto-delete-off.png b/en/chromebook_setup/images/codespace-auto-delete-off.png new file mode 100644 index 00000000000..e978d379335 Binary files /dev/null and b/en/chromebook_setup/images/codespace-auto-delete-off.png differ diff --git a/en/chromebook_setup/images/codespace-preview.png b/en/chromebook_setup/images/codespace-preview.png new file mode 100644 index 00000000000..f50b449d48b Binary files /dev/null and b/en/chromebook_setup/images/codespace-preview.png differ diff --git a/en/chromebook_setup/images/create-new-codespace.png b/en/chromebook_setup/images/create-new-codespace.png new file mode 100644 index 00000000000..cd254212fe5 Binary files /dev/null and b/en/chromebook_setup/images/create-new-codespace.png differ diff --git a/en/chromebook_setup/images/create-new-repo.png b/en/chromebook_setup/images/create-new-repo.png new file mode 100644 index 00000000000..0684a12752a Binary files /dev/null and b/en/chromebook_setup/images/create-new-repo.png differ diff --git a/en/chromebook_setup/images/vscode-install-python.png b/en/chromebook_setup/images/vscode-install-python.png new file mode 100644 index 00000000000..ccf32591c0a Binary files /dev/null and b/en/chromebook_setup/images/vscode-install-python.png differ diff --git a/en/chromebook_setup/instructions.md b/en/chromebook_setup/instructions.md index d502e030b44..b986d832871 100644 --- a/en/chromebook_setup/instructions.md +++ b/en/chromebook_setup/instructions.md @@ -1,80 +1,32 @@ -You can [skip right over this section](http://tutorial.djangogirls.org/en/installation/#install-python) if you're not using a Chromebook. If you -are, your installation experience will be a little different. You can ignore the -rest of the installation instructions. +For people using a Chromebook or those with limited memory on their laptops, we recommend using a cloud IDE environment. This allows you to interact with the command line, Python, and Django directly through your browser, where a code editor is already installed. In case you using this instruction, some steps of the tutorial don't have to be done again ("Deploy/Git" [part](https://tutorial.djangogirls.org/en/deploy/#installing-git) ). You’ll find a more detailed explanation in the “Deploy/Git” section. -### Cloud 9 +Your installation experience will be a little different. -Cloud 9 is a tool that gives you a code editor and access to a computer running -on the Internet where you can install, write, and run software. For the duration -of the tutorial, Cloud 9 will act as your _local machine_. You'll still be -running commands in a terminal interface just like your classmates on OS X, -Ubuntu, or Windows, but your terminal will be connected to a computer running -somewhere else that Cloud 9 sets up for you. +1. **Go to [GitHub.com](https://github.com)** and sign up for a new, free user account. Be sure to remember your password (add it to your password manager, if you use one). -1. Install Cloud 9 from the [Chrome web store](https://chrome.google.com/webstore/detail/cloud9/nbdmccoknlfggadpfkmcpnamfnbkmkcp) -2. Go to [c9.io](https://c9.io) -3. Sign up for an account -4. Click _Create a New Workspace_ -5. Name it _django-girls_ -6. Select the _Blank_ (second from the right on the bottom row with orange logo) +2. **Create a GitHub project**. Visit [this](https://github.com/new) link, use "my-first-blog" name for your project, and make it public (needed for deployment, you can make it private later). Also, add a `README.md` and `.gitignore` file. -Now you should see an interface with a sidebar, a big main window with some -text, and a small window at the bottom that looks something like this: + ![](../chromebook_setup/images/create-new-repo.png) -{% filename %}Cloud 9{% endfilename %} -``` -yourusername:~/workspace $ -``` +3. **Start a Codespace**. Go to GitHub [Codespaces](https://github.com/codespaces/new) and select the repository you just created. Click "Create Codespace". -This bottom area is your _terminal_, where you will give the computer Cloud 9 -has prepared for you instructions. You can resize that window to make it a bit -bigger. + ![](../chromebook_setup/images/create-new-codespace.png) -### Virtual Environment + Wait a little bit and you'll see something like that: -A virtual environment (also called a virtualenv) is like a private box we can -stuff useful computer code into for a project we're working on. We use them to -keep the various bits of code we want for our various projects separate so -things don't get mixed up between projects. + ![](../chromebook_setup/images/codespace-preview.png) -In your terminal at the bottom of the Cloud 9 interface, run the following: + The [VSCode](https://code.visualstudio.com) editor will open for you automatically. If you see a notification that says "Install Python", please click on it. If not prompted, click the "Extensions" icon on the left sidebar in the Codespace editor. Search for "Python" and click "Install." -{% filename %}Cloud 9{% endfilename %} -``` -sudo apt install python3.5-venv -``` + ![](../chromebook_setup/images/vscode-install-python.png) -If this still doesn't work, ask your coach for some help. + The bash terminal (similar to Linux) is at the bottom of the page. -Next, run: + ![](../chromebook_setup/images/codespace-preview.png) -{% filename %}Cloud 9{% endfilename %} -``` -mkdir djangogirls -cd djangogirls -python3.5 -mvenv myvenv -source myvenv/bin/activate -pip install django~=1.10.0 -``` + By default, the GitHub Codespace environment will be deleted after 1 month (this applies only to the environment, not your code). To prevent auto-deletion, you can adjust the settings on the page: https://github.com/codespaces -(note that on the last line we use a tilde followed by an equal sign: ~=). + ![](../chromebook_setup/images/codespace-auto-delete-off.png) -### Github - -Make a [Github](https://github.com) account. - -### PythonAnywhere - -The Django Girls tutorial includes a section on what is called Deployment, -which is the process of taking the code that powers your new web application -and moving it to a publicly accessible computer (called a server) so other -people can see your work. - -This part is a little odd when doing the tutorial on a Chromebook since we're -already using a computer that is on the Internet (as opposed to, say, a laptop). -However, it's still useful, as we can think of our Cloud 9 workspace as a place -or our "in progress" work and Python Anywhere as a place to show off our stuff -as it becomes more complete. - -Thus, sign up for a new Python Anywhere account at -[www.pythonanywhere.com](https://www.pythonanywhere.com). +4. **Continue with the tutorial**. Follow the next steps from the section [Set up virtual environment and install Django](https://tutorial.djangogirls.org/en/installation/#virtualenv). + Follow than sections for Ubuntu/Linux. Use the Codespaces command line (terminal), accessible through your browser. diff --git a/en/code_editor/README.md b/en/code_editor/README.md index e9f908b2936..c1ff8c58248 100644 --- a/en/code_editor/README.md +++ b/en/code_editor/README.md @@ -4,8 +4,8 @@ You're about to write your first line of code, so it's time to download a code editor! -> **Note** If you're using a Chromebook, skip this chapter and make sure you follow the [Chromebook Setup](../chromebook_setup/README.md) instructions. +> **Note** If you're using a Chromebook, skip this chapter and make sure you follow the [Chromebook Setup](../chromebook_setup/README.md) instructions. The cloud IDE you chose (PaizaCloud Cloud IDE or AWS Cloud9) includes a code editor, and when you open a file in your IDE from the File menu, you will automatically be using the editor. -> **Note** You might have done this earlier in the Installation chapter – if so, you can skip right ahead to the next chapter! +> **Note** You might have done this earlier in the [Installation chapter](../installation/README.md) – if so, you can skip right ahead to the next chapter! {% include "/code_editor/instructions.md" %} diff --git a/en/code_editor/instructions.md b/en/code_editor/instructions.md index f00c716f82f..d162c6d307b 100644 --- a/en/code_editor/instructions.md +++ b/en/code_editor/instructions.md @@ -2,25 +2,23 @@ There are a lot of different editors and it largely boils down to personal prefe Our suggestions are below, but feel free to ask your coach what their preferences are – it'll be easier to get help from them. -## Gedit - -Gedit is an open-source, free editor, available for all operating systems. - -[Download it here](https://wiki.gnome.org/Apps/Gedit#Download) +## Visual Studio Code -## Sublime Text 3 +Visual Studio Code is a source code editor developed by Microsoft for Windows, Linux and macOS. It includes support for debugging, embedded Git control, syntax highlighting, intelligent code completion, snippets, and code refactoring. -Sublime Text is a very popular editor with a free evaluation period. It's easy to install and use, and it's available for all operating systems. +[Download it here](https://code.visualstudio.com/) -[Download it here](https://www.sublimetext.com/3) +## Gedit +Gedit is an open-source, free editor, available for all operating systems. -## Atom +[Download it here](https://wiki.gnome.org/Apps/Gedit#Download) -Atom is an extremely new code editor created by [GitHub](https://github.com/). It's free, open-source, easy to install and easy to use. It's available for Windows, OS X and Linux. +## Sublime Text -[Download it here](https://atom.io/) +Sublime Text is a very popular editor with a free evaluation period and it's available for all operating systems. +[Download it here](https://www.sublimetext.com/) ## Why are we installing a code editor? diff --git a/en/css/README.md b/en/css/README.md index 9a0051f2ca6..a5abd124e8c 100644 --- a/en/css/README.md +++ b/en/css/README.md @@ -16,15 +16,14 @@ It was written by programmers who worked for Twitter. Now it's developed by volu ## Install Bootstrap -To install Bootstrap, you need to add this to your `` in your `.html` file: +To install Bootstrap, open up your `.html` file in the code editor and add this to the `` section: {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - - + ``` -This doesn't add any files to your project. It just points to files that exist on the Internet. Just go ahead, open your website and refresh the page. Here it is! +This doesn't add any files to your project. It just points to files that exist on the Internet. So go ahead, open your website and refresh the page. Here it is! ![Figure 14.1](images/bootstrap1.png) @@ -38,7 +37,7 @@ Finally we will take a closer look at these things we've been calling __static f ### Where to put static files for Django -Django already knows where to find the static files for the built-in "admin" app. Now we just need to add some static files for our own app, `blog`. +Django already knows where to find the static files for the built-in "admin" app. Now we need to add some static files for our own app, `blog`. We do that by creating a folder called `static` inside the blog app: @@ -46,7 +45,8 @@ We do that by creating a folder called `static` inside the blog app: djangogirls ├── blog │ ├── migrations -│ └── static +│ ├── static +│   └── templates └── mysite ``` @@ -67,36 +67,37 @@ djangogirls Time to write some CSS! Open up the `blog/static/css/blog.css` file in your code editor. -We won't be going too deep into customizing and learning about CSS here. It's pretty easy and you can learn it on your own after this workshop. There is a recommendation for a free course to learn more at the end of this page. +We won't be going too deep into customizing and learning about CSS here. There is a recommendation for a free CSS course at the end of this page if you would like to learn more. + +But let's do at least a little. Maybe we could change the color of our headers? +To understand colors, computers use special codes. These codes start with `#` followed by 6 letters (A–F) and numbers (0–9). For example, the code for blue is `#0000FF`. You can find the color codes for many colors here: https://www.colorpicker.com/. You may also use predefined [named colors](https://developer.mozilla.org/en-US/docs/Web/CSS/named-color), such as `red` and `green`. -But let's do at least a little. Maybe we could change the color of our header? -To understand colors, computers use special codes. These codes start with `#` followed by 6 letters (A–F) and numbers (0–9). For example, the code for blue is `#0000FF`. You can find the color codes for many colors here: http://www.colorpicker.com/. You may also use [predefined colors](http://www.w3schools.com/colors/colors_names.asp), such as `red` and `green`. In your `blog/static/css/blog.css` file you should add the following code: {% filename %}blog/static/css/blog.css{% endfilename %} ```css -h1 a { - color: #FCA205; +h1 a, h2 a { + color: #C25100; } + ``` -`h1 a` is a CSS Selector. This means we're applying our styles to any `a` element inside of an `h1` element. So when we have something like `

link

`, the `h1 a` style will apply. In this case, we're telling it to change its color to `#FCA205`, which is orange. Of course, you can put your own color here! +`h1 a` is a CSS Selector. This means we're applying our styles to any `a` element inside of an `h1` element; the `h2 a` selector does the same thing for `h2` elements. So when we have something like `

link

`, the `h1 a` style will apply. In this case, we're telling it to change its color to `#C25100`, which is a dark orange. Or you can put your own color here, but make sure it has good contrast against a white background! In a CSS file we determine styles for elements in the HTML file. The first way we identify elements is with the element name. You might remember these as tags from the HTML section. Things like `a`, `h1`, and `body` are all examples of element names. -We also identify elements by the attribute `class` or the attribute `id`. Class and id are names you give the element by yourself. Classes define groups of elements, and ids point to specific elements. For example, you could identify the following tag by using the tag name `a`, the class `external_link`, or the id `link_to_wiki_page`: +We also identify elements by the attribute `class` or the attribute `id`. Class and id are names you give the element by yourself. Classes define groups of elements, and ids point to specific elements. For example, you could identify the following element by using the element name `a`, the class `external_link`, or the id `link_to_wiki_page`: ```html ``` -You can read more about [CSS Selectors at w3schools](http://www.w3schools.com/cssref/css_selectors.asp). - -We also need to tell our HTML template that we added some CSS. Open the `blog/templates/blog/post_list.html` file and add this line at the very beginning of it: +You can read more about [CSS Selectors at MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors). +We also need to tell our HTML template that we added some CSS. Open the `blog/templates/blog/post_list.html` file in the code editor and add this line at the very beginning of it: {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} ``` We're just loading static files here. :) @@ -106,32 +107,32 @@ Between the `` and `` tags, after the links to the Bootstrap CSS fi ```html ``` -The browser reads the files in the order they're given, so we need to make sure this is in the right place. Otherwise the code in our file may override code in Bootstrap files. +The browser reads the files in the order they're given, so we need to make sure this is in the right place. Otherwise the code in our file may be overridden by code in Bootstrap files. We just told our template where our CSS file is located. Your file should now look like this: {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} + Django Girls blog - - + - + {% for post in posts %} -
-

published: {{ post.published_date }}

-

{{ post.title }}

+
+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} @@ -158,17 +159,17 @@ Maybe we can customize the font in our header? Paste this into your `` in {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - + ``` -As before, check the order and place before the link to `blog/static/css/blog.css`. This line will import a font called *Lobster* from Google Fonts (https://www.google.com/fonts). +Again, check the order and place it before the link to `blog/static/css/blog.css`. This line will import a font called *Lobster* from Google Fonts (https://www.google.com/fonts). Find the `h1 a` declaration block (the code between braces `{` and `}`) in the CSS file `blog/static/css/blog.css`. Now add the line `font-family: 'Lobster';` between the braces, and refresh the page: {% filename %}blog/static/css/blog.css{% endfilename %} ```css -h1 a { - color: #FCA205; +h1 a, h2 a { + color: #C25100; font-family: 'Lobster'; } ``` @@ -180,47 +181,52 @@ Great! As mentioned above, CSS has a concept of classes. These allow you to name a part of the HTML code and apply styles only to this part, without affecting other parts. This can be super helpful! Maybe you have two divs that are doing something different (like your header and your post). A class can help you make them look different. -Go ahead and name some parts of the HTML code. Add a class called `page-header` to your `div` that contains your header, like this: +Go ahead and name some parts of the HTML code. Replace the `header` that contains your header with the following: {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - + ``` -And now add a class `post` to your `div` containing a blog post. +And now add a class `post` to your `article` containing a blog post. {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -
-

published: {{ post.published_date }}

-

{{ post.title }}

+
+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ ``` -We will now add declaration blocks to different selectors. Selectors starting with `.` relate to classes. There are many great tutorials and explanations about CSS on the Web that can help you understand the following code. For now, just copy and paste it into your `blog/static/css/blog.css` file: +We will now add declaration blocks to different selectors. Selectors starting with `.` relate to classes. There are many great tutorials and explanations about CSS on the Web that can help you understand the following code. For now, copy and paste it into your `blog/static/css/blog.css` file: {% 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; } @@ -232,11 +238,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; @@ -247,9 +256,28 @@ 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; + margin-left: 15px; +} + +.btn-secondary:hover { + color: #FFFFFF; + background-color: #C25100; +} ``` Then surround the HTML code which displays the posts with declarations of classes. Replace this: @@ -257,11 +285,11 @@ Then surround the HTML code which displays the posts with declarations of classe {% 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 %} ``` @@ -269,21 +297,21 @@ in the `blog/templates/blog/post_list.html` with this: {% 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 %}
-
+
``` Save those files and refresh your website. @@ -295,7 +323,6 @@ Look at the code we just pasted to find the places where we added classes in the Don't be afraid to tinker with this CSS a little bit and try to change some things. Playing with the CSS can help you understand what the different things are doing. If you break something, don't worry – you can always undo it! -We really recommend taking this free online [Codeacademy HTML & CSS course](https://www.codecademy.com/tracks/web). It can help you learn all about making your websites prettier with CSS. +We really recommend taking the free online courses "Basic HTML & HTML5" and "Basic CSS" on [freeCodeCamp](https://learn.freecodecamp.org/). They can help you learn all about making your websites prettier with HTML and CSS. Ready for the next chapter?! :) - diff --git a/en/css/images/bootstrap1.png b/en/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/en/css/images/bootstrap1.png and b/en/css/images/bootstrap1.png differ diff --git a/en/css/images/color2.png b/en/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/en/css/images/color2.png and b/en/css/images/color2.png differ diff --git a/en/css/images/final.png b/en/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/en/css/images/final.png and b/en/css/images/final.png differ diff --git a/en/css/images/font.png b/en/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/en/css/images/font.png and b/en/css/images/font.png differ diff --git a/en/css/images/margin2.png b/en/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/en/css/images/margin2.png and b/en/css/images/margin2.png differ diff --git a/en/deploy/README.md b/en/deploy/README.md index 6887afca282..d114936911f 100644 --- a/en/deploy/README.md +++ b/en/deploy/README.md @@ -4,23 +4,35 @@ Until now, your website was only available on your computer. Now you will learn how to deploy it! Deploying is the process of publishing your application on the Internet so people can finally go and see your app. :) -As you learned, a website has to be located on a server. There are a lot of server providers available on the internet. We will use one that has a relatively simple deployment process: [PythonAnywhere](https://pythonanywhere.com/). PythonAnywhere is free for small applications that don't have too many visitors so it'll definitely be enough for you now. +As you learned, a website has to be located on a server. There are a lot of server providers available on the internet, we're going to use [PythonAnywhere](https://www.pythonanywhere.com/). PythonAnywhere is free for small applications that don't have too many visitors so it'll definitely be enough for you now. The other external service we'll be using is [GitHub](https://www.github.com), which is a code hosting service. There are others out there, but almost all programmers have a GitHub account these days, and now so will you! -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. +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. + +The deployment process can be illustrated as follows: + +![](../deploy/images/deployment_local.png) + +If you’re using a **Chromebook** and [GitHub Codespaces](https://github.com/codespaces), your setup will look a bit different. All code-related changes are made not locally on your **Chromebook**, but in the Cloud Environment provided by GitHub. + +The deployment process on **Chromebook** and Cloud environment can be illustrated as follows: + +![](../deploy/images/deployment_cloud.png) # Git -> **Note** If you already did the Installation steps, there's no need to do this again – you can skip to the next section and start creating your Git repository. +> **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" %} +> **Note** If you're using a **Chromebook** and have already completed the **Chromebook** Installation [part](../chromebook_setup/README.md), you've already created the repository and can **skip** all commands from the "Starting our Git repository" and "Ignoring files" chapters. You can continue from the "First Git commands" chapter. While you’re welcome to read these chapters, the Terminal commands can be skipped. + ## Starting our Git repository Git tracks changes to a particular set of files in what's called a code repository (or "repo" for short). Let's start one for our project. Open up your console and run these commands, in the `djangogirls` directory: -> **Note** Check your current working directory with a `pwd` (Mac OS X/Linux) or `cd` (Windows) command before initializing the repository. You should be in the `djangogirls` folder. +> **Note** Check your current working directory with a `pwd` (macOS/Linux) or `cd` (Windows) command before initializing the repository. You should be in the `djangogirls` folder. {% filename %}command-line{% endfilename %} ``` @@ -29,36 +41,68 @@ Initialized empty Git repository in ~/djangogirls/.git/ $ git config --global user.name "Your Name" $ git config --global user.email you@example.com ``` +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). -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 again ever). +### 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__ -myvenv + +# Env +.env +myvenv/ +venv/ + +# Database db.sqlite3 -/static + +# 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. -> **Note** The dot at the beginning of the file name is important! If you're having any difficulty creating it (Macs don't like you to create files that begin with a dot via the Finder, for example), then use the "Save As" feature in your editor; it's bulletproof. +> **Note** The dot at the beginning of the file name is important! If you're having any difficulty creating it (Macs don't like you to create files that begin with a dot via the Finder, for example), then use the "Save As" feature in your editor; it's bulletproof. And be sure not to add `.txt`, `.py`, or any other extension to the file name -- it will only be recognized by Git if the name is just `.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. + -> **Note** One of the files you specified in your `.gitignore` file is `db.sqlite3`. That file is your local database, where all or your posts are stored. We don't want to add this to your repository because your website on PythonAnywhere is going to be using a different database. That 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 you created so far are going to stay and only be available locally, but you're going to have to add them again 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. +### First Git commands 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 master +On branch main -Initial commit +No commits yet Untracked files: (use "git add ..." to include in what will be committed) @@ -67,6 +111,7 @@ Untracked files: blog/ manage.py mysite/ + requirements.txt nothing added to commit but untracked files present (use "git add" to track) ``` @@ -75,224 +120,88 @@ And finally we save our changes. Go to your console and run these commands: {% filename %}command-line{% endfilename %} ``` -$ git add --all . +$ 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!) +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). + +### Creating a Personal Access Token + +Now follow the instructions from GitHub to [create a personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic). +The token should have the 'repo' scope. +Copy the value of the token, and save it somewhere safe (like a password manager). -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. +### Creating a new repository - +Back on the GitHub homepage, +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. -> **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 just stick with the name `my-first-blog`. +![](images/new_github_repo.png) -On the next screen, you'll be shown your repo's clone URL. Choose the "HTTPS" version, copy it, and we'll paste it into the terminal shortly: +> **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: + +![](images/github_get_repo_url_screenshot.png) 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): +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). {% filename %}command-line{% endfilename %} ``` $ git remote add origin https://github.com//my-first-blog.git -$ git push -u origin master +$ git push -u origin HEAD ``` -Enter your GitHub username and password and you should see something like this: +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). +Use the Personal Access Token you created earlier, +not your account password. + +After entering credentials you should see something like this: {% 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. +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. :) - - -# Setting up our blog on PythonAnywhere - -> **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" %} - - -## Pulling our code down on PythonAnywhere - -When you've signed up for PythonAnywhere, you'll be taken to your dashboard or "Consoles" page. Choose the option to start a "Bash" console – that's the PythonAnywhere version of a console, just like the one on your computer. - -> **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. - -Let's pull down our code from GitHub and onto PythonAnywhere by creating a "clone" of our repo. Type the following into the console on PythonAnywhere (don't forget to use your GitHub username in place of ``): - -{% filename %}PythonAnywhere command-line{% endfilename %} -``` -$ git clone https://github.com//my-first-blog.git -``` - -This will pull down a copy of your code onto PythonAnywhere. Check it out by typing `tree my-first-blog`: - -{% filename %}PythonAnywhere command-line{% endfilename %} -``` -$ 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 -``` - - -### Creating a virtualenv on PythonAnywhere - -Just like you did on your own computer, you can create a virtualenv on PythonAnywhere. In the Bash console, type: - -{% filename %}PythonAnywhere command-line{% endfilename %} -``` -$ cd my-first-blog - -$ virtualenv --python=python3.5 myvenv -Running virtualenv with interpreter /usr/bin/python3.5 -[...] -Installing setuptools, pip...done. - -$ source myvenv/bin/activate - -(myvenv) $ pip install django~=1.10.0 -Collecting django -[...] -Successfully installed django-1.10.4 -``` - - -> **Note** The `pip install` step can take a couple of minutes. Patience, patience! But if it takes more than five minutes, something is wrong. Ask your coach. - - - -### Creating the database on PythonAnywhere - -Here's another thing that's different between your own computer and the server: it uses a different database. So the user accounts and posts can be different on the server and on your computer. - -We can initialize the database on the server just like we did the one on your own computer, with `migrate` and `createsuperuser`: - -{% filename %}PythonAnywhere command-line{% endfilename %} -``` -(mvenv) $ python manage.py migrate -Operations to perform: -[...] - Applying sessions.0001_initial... OK -(mvenv) $ python manage.py createsuperuser -``` - -## Publishing our blog as a web app - -Now our code is on PythonAnywhere, our virtualenv is ready, and the database is initialized. We're ready to publish it as a web app! - -Click back to the PythonAnywhere dashboard by clicking on its logo, and then click on the **Web** tab. Finally, hit **Add a new web app**. - -After confirming your domain name, choose **manual configuration** (N.B. – *not* the "Django" option) in the dialog. Next choose **Python 3.5**, and click Next to finish the wizard. - -> **Note** Make sure you choose the "Manual configuration" option, not the "Django" one. We're too cool for the default PythonAnywhere Django setup. ;-) - - -### Setting the virtualenv - -You'll be taken to the PythonAnywhere config screen for your webapp, which is where you'll need to go whenever you want to make changes to the app on the server. - - - -In the "Virtualenv" section, click the red text that says "Enter the path to a virtualenv", and enter `/home//my-first-blog/myvenv/`. Click the blue box with the checkmark to save the path before moving on. - -> **Note** Substitute your own PythonAnywhere username as appropriate. If you make a mistake, PythonAnywhere will show you a little warning. - - -### Configuring the WSGI file - -Django works using the "WSGI protocol", a standard for serving websites using Python, which PythonAnywhere supports. The way we configure PythonAnywhere to recognize our Django blog is by editing a WSGI configuration file. - -Click on the "WSGI configuration file" link (in the "Code" section near the top of the page – it'll be named something like `/var/www/_pythonanywhere_com_wsgi.py`), and you'll be taken to an editor. - -Delete all the contents and replace them with something like this: - -{% filename %}<your-username>_pythonanywhere_com_wsgi.py{% endfilename %} -```python -import os -import sys - -path = '/home//my-first-blog' # use your own PythonAnywhere 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 django.contrib.staticfiles.handlers import StaticFilesHandler -application = StaticFilesHandler(get_wsgi_application()) -``` - -> **Note** Don't forget to substitute in your own PythonAnywhere username where it says ``. -> **Note** In line four, we make sure Python anywhere knows how to find our application. It is very important that this path name is correct, and especially that there are no extra spaces here. Otherwise you will see an "ImportError" in the error log. - -This file's job is to tell PythonAnywhere where our web app lives and what the Django settings file's name is. - -The `StaticFilesHandler` is for dealing with our CSS. This is taken care of automatically for you during local development by the `runserver` command. We'll find out a bit more about static files later in the tutorial, when we edit the CSS for our site. - -Hit **Save** and then go back to the **Web** tab. - -We're all done! Hit the big green **Reload** button and you'll be able to go view your application. You'll find a link to it at the top of the page. - - -## Debugging tips - -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 tab](https://www.pythonanywhere.com/web_app_setup/). See if there are any error messages in there; the most recent ones are at the bottom. Common problems include: - -- Forgetting one of the steps we did in the console: creating the virtualenv, activating it, installing Django into it, migrating the database. - -- Making a mistake in the virtualenv path on the Web tab – there will usually be a little red error message on there, if there is a problem. - -- Making a mistake in the WSGI configuration file – did you get the path to your my-first-blog folder right? - -- Did you pick the same version of Python for your virtualenv as you did for your web app? Both should be 3.5. - -There are also some [general debugging tips on the PythonAnywhere wiki](https://www.pythonanywhere.com/wiki/DebuggingImportError). +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. :) -And remember, your coach is here to help! +{% include "/deploy/pythonanywhere.md" %} -# You are live! +# 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. +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, just like that! +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! diff --git a/en/deploy/images/deployment_cloud.png b/en/deploy/images/deployment_cloud.png new file mode 100644 index 00000000000..6cead7a07ad Binary files /dev/null and b/en/deploy/images/deployment_cloud.png differ diff --git a/en/deploy/images/deployment_local.png b/en/deploy/images/deployment_local.png new file mode 100644 index 00000000000..ae87eca532f Binary files /dev/null and b/en/deploy/images/deployment_local.png differ diff --git a/en/deploy/images/github_get_repo_url_screenshot.png b/en/deploy/images/github_get_repo_url_screenshot.png index 62a29f5f8d7..ee1560b1e85 100644 Binary files a/en/deploy/images/github_get_repo_url_screenshot.png and b/en/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/en/deploy/images/new_github_repo.png b/en/deploy/images/new_github_repo.png index 64011e59a52..997b7fe129c 100644 Binary files a/en/deploy/images/new_github_repo.png and b/en/deploy/images/new_github_repo.png differ diff --git a/en/deploy/images/pythonanywhere_account.png b/en/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/en/deploy/images/pythonanywhere_account.png differ diff --git a/en/deploy/images/pythonanywhere_bash_console.png b/en/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..68eb2a030e1 Binary files /dev/null and b/en/deploy/images/pythonanywhere_bash_console.png differ diff --git a/en/deploy/images/pythonanywhere_beginner_account_button.png b/en/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/en/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/en/deploy/images/pythonanywhere_create_api_token.png b/en/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..abae45ae37a Binary files /dev/null and b/en/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/en/deploy/images/pythonanywhere_web_tab_virtualenv.png b/en/deploy/images/pythonanywhere_web_tab_virtualenv.png deleted file mode 100644 index 97e87e7b07b..00000000000 Binary files a/en/deploy/images/pythonanywhere_web_tab_virtualenv.png and /dev/null differ diff --git a/en/deploy/install_git.md b/en/deploy/install_git.md index 4f9b223e977..5325080cc89 100644 --- a/en/deploy/install_git.md +++ b/en/deploy/install_git.md @@ -1,44 +1,40 @@ -Git is a "version control system" used by a lot of programmers. This software can track changes to files over time so that you can recall specific versions later. A bit like the "track changes" feature in Microsoft Word, but much more powerful. +Git is a "version control system" used by a lot of programmers. This software can track changes to files over time so that you can recall specific versions later. A bit like the "track changes" feature in word processor programs (e.g., Microsoft Word or LibreOffice Writer), but much more powerful. ## Installing Git - -You can download Git from [git-scm.com](https://git-scm.com/). You can hit "next" on all steps except for one; in the fifth step entitled "Adjusting your PATH environment", choose "Use Git and optional Unix tools from the Windows Command Prompt" (the bottom option). Other than that, the defaults are fine. Checkout Windows-style, commit Unix-style line endings is good. +You can download Git from [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). Other than that, the defaults are fine. Checkout Windows-style, commit Unix-style line endings is good. +Do not forget to restart the command prompt or PowerShell after the installation finished successfully. - -Download Git from [git-scm.com](https://git-scm.com/) and just follow the instructions. +Download Git from [https://git-scm.com/download/mac](https://git-scm.com/download/mac) and follow the instructions. > **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) - - - - -{% filename %}command-line{% endfilename %} -```bash -$ sudo apt-get install git -``` +> It is recommended to install using brew (you may need to install homebrew if you don't already have it): +> ```brew install git``` +> +> Please note that some Mac M1/M2/M3 users may have the error `zsh: command not found: brew`. In that case, please follow [this](https://stackoverflow.com/a/66019047) or [this](https://mac.install.guide/homebrew/zsh-command-not-found-brew) to fix the error. - {% filename %}command-line{% endfilename %} ```bash -$ sudo yum install git +$ sudo apt install git ``` - {% filename %}command-line{% endfilename %} @@ -48,7 +44,7 @@ $ sudo dnf install git - {% filename %}command-line{% endfilename %} diff --git a/en/deploy/pythonanywhere.md b/en/deploy/pythonanywhere.md new file mode 100644 index 00000000000..eb884d2cb8b --- /dev/null +++ b/en/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/5.1/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](https://help.pythonanywhere.com/pages/DebuggingImportError). + +And remember, your coach is here to help! diff --git a/en/deploy/signup_pythonanywhere.md b/en/deploy/signup_pythonanywhere.md index 1c45f14224b..f4eefc3bf7c 100644 --- a/en/deploy/signup_pythonanywhere.md +++ b/en/deploy/signup_pythonanywhere.md @@ -1,7 +1,21 @@ +PythonAnywhere is a service for running Python code on servers "in the cloud". We'll use +it for hosting our site, live and on the Internet. -Next it's time to sign up for a free "Beginner" account on PythonAnywhere. +We will be hosting the blog we're building on PythonAnywhere. Sign up for a "Beginner" account on PythonAnywhere (the free tier is fine, you don't need a credit card). * [www.pythonanywhere.com](https://www.pythonanywhere.com/) +![The PythonAnywhere signup page showing button to create a free 'Beginner' account](../deploy/images/pythonanywhere_beginner_account_button.png) -> **Note** When choosing your username here, bear in mind that your blog's URL will take the form `yourusername.pythonanywhere.com`, so choose either your own nickname, or a name for what your blog is all about. +> **Note** When choosing your username here, bear in mind that your blog's URL will take the form `yourusername.pythonanywhere.com`, so choose either your own nickname or a name for what your blog is all about. Also, be sure to remember your password (add it to your password manager, if you use one). + + +## Creating a PythonAnywhere API token + +This is something you only need to do once. When you've signed up for PythonAnywhere, you'll be taken to your dashboard. Find the link near the top right to your "Account" page: + +![Account link on the top right on the page](../deploy/images/pythonanywhere_account.png) + +then select the tab named "API token", and hit the button that says "Create new API token". + +![The API token tab on the Account page](../deploy/images/pythonanywhere_create_api_token.png) diff --git a/en/django/README.md b/en/django/README.md index f57843e8c97..acb6a9f2358 100644 --- a/en/django/README.md +++ b/en/django/README.md @@ -22,6 +22,6 @@ Imagine a mail carrier with a letter. She is walking down the street and checks In the *view* function, all the interesting things are done: we can look at a database to look for some information. Maybe the user asked to change something in the data? Like a letter saying, "Please change the description of my job." The *view* can check if you are allowed to do that, then update the job description for you and send back a message: "Done!" Then the *view* generates a response and Django can send it to the user's web browser. -Of course, the description above is a little bit simplified, but you don't need to know all the technical things yet. Having a general idea is enough. +The description above is a little bit simplified, but you don't need to know all the technical things yet. Having a general idea is enough. -So instead of diving too much into details, we will simply start creating something with Django and we will learn all the important parts along the way! +So instead of diving too much into details, we will start creating something with Django and we will learn all the important parts along the way! diff --git a/en/django_admin/README.md b/en/django_admin/README.md index 6caf5fb025c..f21c8cdc9d8 100644 --- a/en/django_admin/README.md +++ b/en/django_admin/README.md @@ -2,7 +2,7 @@ To add, edit and delete the posts we've just modeled, we will use Django admin. -Let's open the `blog/admin.py` file and replace its contents with this: +Let's open the `blog/admin.py` file in the code editor and replace its contents with this: {% filename %}blog/admin.py{% endfilename %} ```python @@ -22,13 +22,21 @@ To log in, you need to create a *superuser* - a user account that has control ov > Remember, to write new commands while the web server is running, open a new terminal window and activate your virtualenv. We reviewed how to write new commands in the Your first Django project! chapter, in the Starting the web server section. -When prompted, type your username (lowercase, no spaces), email address, and password. Don't worry that you can't see the password you're typing in – that's how it's supposed to be. Just type it in and press `enter` to continue. The output should look like this (where the username and email should be your own ones): - -{% filename %}command-line{% endfilename %} +{% filename %}macOS or 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 +``` + +When prompted, type your username (lowercase, no spaces), email address, and password. **Don't worry that you can't see the password you're typing in – that's how it's supposed to be.** Type it in and press `enter` to continue. The output should look like this (where the username and email should be your own ones): + +``` +Username: ola +Email address: ola@example.com Password: Password (again): Superuser created successfully. @@ -38,12 +46,12 @@ Return to your browser. Log in with the superuser's credentials you chose; you s ![Django admin](images/django_admin3.png) -Go to Posts and experiment a little bit with it. Add five or six blog posts. Don't worry about the content – you can simply copy-paste some text from this tutorial to save time. :) +Go to Posts and experiment a little bit with it. Add five or six blog posts. Don't worry about the content –- it's only visible to you on your local computer -- you can copy-paste some text from this tutorial to save time. :) Make sure that at least two or three posts (but not all) have the publish date set. It will be helpful later. ![Django admin](images/edit_post3.png) -If you want to know more about Django admin, you should check Django's documentation: https://docs.djangoproject.com/en/1.10/ref/contrib/admin/ +If you want to know more about Django admin, you should check Django's documentation: https://docs.djangoproject.com/en/5.1/ref/contrib/admin/ This is probably a good moment to grab a coffee (or tea) or something to eat to re-energize yourself. You created your first Django model – you deserve a little break! diff --git a/en/django_admin/images/django_admin3.png b/en/django_admin/images/django_admin3.png index 25bcc4edda8..fb221bd18e1 100644 Binary files a/en/django_admin/images/django_admin3.png and b/en/django_admin/images/django_admin3.png differ diff --git a/en/django_admin/images/edit_post3.png b/en/django_admin/images/edit_post3.png index 34f2a195ec5..57299b6f5af 100644 Binary files a/en/django_admin/images/edit_post3.png and b/en/django_admin/images/edit_post3.png differ diff --git a/en/django_admin/images/login_page2.png b/en/django_admin/images/login_page2.png index 85137f4d162..c16d1aa4289 100644 Binary files a/en/django_admin/images/login_page2.png and b/en/django_admin/images/login_page2.png differ diff --git a/en/django_forms/README.md b/en/django_forms/README.md index 10d51478e4b..f49dd5620ef 100644 --- a/en/django_forms/README.md +++ b/en/django_forms/README.md @@ -15,7 +15,7 @@ blog └── forms.py ``` -OK, let's open it and type the following code: +OK, let's open it in the code editor and type the following code: {% filename %}blog/forms.py{% endfilename %} ```python @@ -27,10 +27,10 @@ class PostForm(forms.ModelForm): class Meta: model = Post - fields = ('title', 'text',) + fields = ('title', 'text') ``` -We need to import Django forms first (`from django import forms`) and, obviously, our `Post` model (`from .models import Post`). +We need to import Django forms first (`from django import forms`) and our `Post` model (`from .models import Post`). `PostForm`, as you probably suspect, is the name of our form. We need to tell Django that this form is a `ModelForm` (so Django will do some magic for us) – `forms.ModelForm` is responsible for that. @@ -44,67 +44,79 @@ So once again we will create a link to the page, a URL, a view and a template. ## Link to a page with the form -It's time to open `blog/templates/blog/base.html`. We will add a link in `div` named `page-header`: +Before we add the link, we need some icons to use as buttons for the link. 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/` + +> Note: To download the SVG image, open the context menu on the link (usually by right-clicking on it) and select "Save link as". 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. Now we can use this icon file inside the base template as follows. In the `div` element inside `header` section, we will add a link before the `h1` element: {% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + + {% include './icons/file-earmark-plus.svg' %} + ``` -Note that we want to call our new view `post_new`. The class `"glyphicon glyphicon-plus"` is provided by the bootstrap theme we are using, and will display a plus sign for us. +Note that we want to call our new view `post_new`. The [SVG icon](https://icons.getbootstrap.com/icons/file-earmark-plus/) is provided by the [Bootstrap Icons](https://icons.getbootstrap.com/) and it will display a page icon with plus sign. We use a Django template directive called `include`. This will inject the file's content into the Django template. The web browser knows how to handle this type of content without any further processing. + +> You can download all the Bootstrap icons [here](https://github.com/twbs/icons/releases/download/v1.11.3/bootstrap-icons-1.11.3.zip). Unzip the file and copy all the SVG image files into a new folder inside `blog/templates/blog/` called `icons`. That way you can access an icon like `pencil-fill.svg` using the file path `blog/templates/blog/icons/pencil-fill.svg` -After adding the line, your HTML file should now look like this: +After editing the line, your HTML file should now look like this: {% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} + Django Girls blog - - - + + - -
+ +
-
+
{% block content %} {% endblock %}
-
+
``` -After saving and refreshing the page http://127.0.0.1:8000 you will obviously see a familiar `NoReverseMatch` error, right? +After saving and refreshing the page http://127.0.0.1:8000 you will see a familiar `NoReverseMatch` error. Is that the case? Good! ## URL -We open `blog/urls.py` and add a line: +We open `blog/urls.py` in the code editor and add a line: {% filename %}blog/urls.py{% endfilename %} ```python -url(r'^post/new/$', views.post_new, name='post_new'), +path('post/new/', views.post_new, name='post_new'), ``` And the final code will look like this: {% 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\d+)/$', 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'), ] ``` @@ -112,7 +124,7 @@ After refreshing the site, we see an `AttributeError`, since we don't have the ` ## post_new view -Time to open the `blog/views.py` file and add the following lines with the rest of the `from` rows: +Time to open the `blog/views.py` file in the code editor and add the following lines with the rest of the `from` rows: {% filename %}blog/views.py{% endfilename %} ```python @@ -132,14 +144,14 @@ To create a new `Post` form, we need to call `PostForm()` and pass it to the tem ## Template -We need to create a file `post_edit.html` in the `blog/templates/blog` directory. To make a form work we need several things: +We need to create a file `post_edit.html` in the `blog/templates/blog` directory, and open it in the code editor. To make a form work we need several things: -- We have to display the form. We can do that with (for example) a simple {% raw %}`{{ form.as_p }}`{% endraw %}. -- The line above needs to be wrapped with an HTML form tag: `...`. +- We have to display the form. We can do that with (for example) {% raw %}`{{ form.as_p }}`{% endraw %}. +- The line above needs to be wrapped with an HTML form element: `
...
`. - We need a `Save` button. We do that with an HTML button: ``. - And finally, just after the opening `
` tag we need to add {% raw %}`{% csrf_token %}`{% endraw %}. This is very important, since it makes your forms secure! If you forget about this bit, Django will complain when you try to save the form: -![CSFR Forbidden page](images/csrf2.png) +![CSRF Forbidden page](images/csrf2.png) OK, so let's see how the HTML in `post_edit.html` should look: @@ -148,10 +160,10 @@ OK, so let's see how the HTML in `post_edit.html` should look: {% extends 'blog/base.html' %} {% block content %} -

New post

+

New post

{% csrf_token %} {{ form.as_p }} - +
{% endblock %} ``` @@ -168,7 +180,7 @@ The answer is: nothing. We need to do a little bit more work in our *view*. ## Saving the form -Open `blog/views.py` once again. Currently all we have in the `post_new` view is the following: +Open `blog/views.py` once again in the code editor. Currently all we have in the `post_new` view is the following: {% filename %}blog/views.py{% endfilename %} ```python @@ -177,7 +189,7 @@ def post_new(request): return render(request, 'blog/post_edit.html', {'form': form}) ``` -When we submit the form, we are brought back to the same view, but this time we have some more data in `request`, more specifically in `request.POST` (the naming has nothing to do with a blog "post"; it's to do with the fact that we're "posting" data). Remember how in the HTML file, our `
` definition had the variable `method="POST"`? All the fields from the form are now in `request.POST`. You should not rename `POST` to anything else (the only other valid value for `method` is `GET`, but we have no time to explain what the difference is). +When we submit the form, we are brought back to the same view, but this time the `request` parameter is different. If we look at the `request.method` it will be `"POST"` (method for sending forms) instead of `"GET"` (method for requesting pages) and the `request.POST` attribute will contain all the fields from the form. The naming has nothing to do with a blog "post"; it's to do with the fact that we're "posting" data. So in our *view* we have two separate situations to handle: first, when we access the page for the first time and we want a blank form, and second, when we go back to the *view* with all form data we just typed. So we need to add a condition (we will use `if` for that): @@ -196,7 +208,7 @@ It's time to fill in the dots `[...]`. If `method` is `POST` then we want to con form = PostForm(request.POST) ``` -Easy! The next thing is to check if the form is correct (all required fields are set and no incorrect values have been submitted). We do that with `form.is_valid()`. +The next thing is to check if the form is correct (all required fields are set and no incorrect values have been submitted). We do that with `form.is_valid()`. We check if the form is valid and if so, we can save it! @@ -269,13 +281,19 @@ Django is taking care to validate that all the fields in our form are correct. I ## Edit form -Now we know how to add a new form. But what if we want to edit an existing one? This is very similar to what we just did. Let's create some important things quickly. (If you don't understand something, you should ask your coach or look at the previous chapters, since we covered all these steps already.) +Now we know how to add a new post. But what if we want to edit an existing one? This is very similar to what we just did. Let's create some important things quickly. (If you don't understand something, you should ask your coach or look at the previous chapters, since we covered all these steps already.) + +First, let's save the icon which represents the edit button. Download [pencil-fill.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/pencil-fill.svg) and save it to the location `blog/templates/blog/icons/`. -Open `blog/templates/blog/post_detail.html` and add the line +Open `blog/templates/blog/post_detail.html` in the code editor and add the following code inside `article` element: {% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html - + ``` so that the template will look like this: @@ -285,29 +303,33 @@ so that the template will look like this: {% extends 'blog/base.html' %} {% block content %} -
+
+ {% endblock %} ``` -In `blog/urls.py` we add this line: +Open `blog/urls.py` in the code editor, and add this line: {% filename %}blog/urls.py{% endfilename %} ```python - url(r'^post/(?P\d+)/edit/$', views.post_edit, name='post_edit'), + path('post//edit/', views.post_edit, name='post_edit'), ``` We will reuse the template `blog/templates/blog/post_edit.html`, so the last missing thing is a *view*. -Let's open `blog/views.py` and add this at the very end of the file: +Let's open `blog/views.py` in the code editor and add this at the very end of the file: {% filename %}blog/views.py{% endfilename %} ```python @@ -326,7 +348,7 @@ def post_edit(request, pk): return render(request, 'blog/post_edit.html', {'form': form}) ``` -This looks almost exactly the same as our `post_new` view, right? But not entirely. For one, we pass an extra `pk` parameter from urls. Next, we get the `Post` model we want to edit with `get_object_or_404(Post, pk=pk)` and then, when we create a form, we pass this post as an `instance`, both when we save the form… +This looks almost exactly the same as our `post_new` view, right? But not entirely. For one, we pass an extra `pk` parameter from `urls`. Next, we get the `Post` model we want to edit with `get_object_or_404(Post, pk=pk)` and then, when we create a form, we pass this post as an `instance`, both when we save the form… {% filename %}blog/views.py{% endfilename %} ```python @@ -352,25 +374,29 @@ Feel free to change the title or the text and save the changes! Congratulations! Your application is getting more and more complete! -If you need more information about Django forms, you should read the documentation: https://docs.djangoproject.com/en/1.10/topics/forms/ +If you need more information about Django forms, you should read the documentation: https://docs.djangoproject.com/en/5.1/topics/forms/ ## Security -Being able to create new posts just by clicking a link is awesome! But right now, anyone who visits your site will be able to make a new blog post, and that's probably not something you want. Let's make it so the button shows up for you but not for anyone else. +Being able to create new posts by clicking a link is awesome! But right now, anyone who visits your site will be able to make a new blog post, and that's probably not something you want. Let's make it so the button shows up for you but not for anyone else. -In `blog/templates/blog/base.html`, find our `page-header` `div` and the anchor tag you put in there earlier. It should look like this: +Open `blog/templates/blog/base.html` in the code editor, find our `div` inside `header` and the anchor element you put in there earlier. It should look like this: {% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + + {% include './icons/file-earmark-plus.svg' %} + ``` -We're going to add another `{% if %}` tag to this, which will make the link show up only for users who are logged into the admin. Right now, that's just you! Change the `` tag to look like this: +We're going to add another `{% if %}` tag to this, which will make the link show up only for users who are logged into the admin. Right now, that's just you! Change the `` element to look like this: {% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% if user.is_authenticated %} - + + {% include './icons/file-earmark-plus.svg' %} + {% endif %} ``` @@ -378,11 +404,13 @@ This `{% if %}` will cause the link to be sent to the browser only if the user r Remember the edit icon we just added to our detail page? We also want to add the same change there, so other people won't be able to edit existing posts. -Open `blog/templates/blog/post_detail.html` and find this line: +Open `blog/templates/blog/post_detail.html` in the code editor and find this line: {% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html - + + {% include './icons/pencil-fill.svg' %} + ``` Change it to this: @@ -390,22 +418,24 @@ Change it to this: {% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html {% if user.is_authenticated %} - + + {% include './icons/pencil-fill.svg' %} + {% endif %} ``` -Since you're likely logged in, if you refresh the page, you won't see anything different. Load the page in a different browser or an incognito window, though, and you'll see that the link doesn't show up, and the icon doesn't display either! +Since you're likely logged in, if you refresh the page, you won't see anything different. Load the page in a different browser or an incognito window (called "InPrivate" in Windows Edge), though, and you'll see that the link doesn't show up, and the icon doesn't display either! ## One more thing: deploy time! Let's see if all this works on PythonAnywhere. Time for another deploy! -* First, commit your new code, and push it up to Github: +* First, commit your new code, and push it up to GitHub: {% filename %}command-line{% endfilename %} ``` $ git status -$ git add --all . +$ git add . $ git status $ git commit -m "Added views to create/edit blog post inside the site." $ git push @@ -413,14 +443,17 @@ $ git push * Then, in a [PythonAnywhere Bash console](https://www.pythonanywhere.com/consoles/): -{% filename %}command-line{% endfilename %} +{% filename %}PythonAnywhere command-line{% endfilename %} ``` -$ cd my-first-blog +$ cd ~/.pythonanywhere.com $ git pull [...] ``` -* Finally, hop on over to the [Web tab](https://www.pythonanywhere.com/web_app_setup/) and hit **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/) (use the menu button in the upper right of the console) and hit **Reload**. Refresh your https://subdomain.pythonanywhere.com blog to see the changes. -And that should be it! Congrats :) +And that should be it. Congrats! :) diff --git a/en/django_forms/images/csrf2.png b/en/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/en/django_forms/images/csrf2.png and b/en/django_forms/images/csrf2.png differ diff --git a/en/django_forms/images/drafts.png b/en/django_forms/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/en/django_forms/images/drafts.png and b/en/django_forms/images/drafts.png differ diff --git a/en/django_forms/images/edit_button2.png b/en/django_forms/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/en/django_forms/images/edit_button2.png and b/en/django_forms/images/edit_button2.png differ diff --git a/en/django_forms/images/edit_form2.png b/en/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/en/django_forms/images/edit_form2.png and b/en/django_forms/images/edit_form2.png differ diff --git a/en/django_forms/images/form_validation2.png b/en/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/en/django_forms/images/form_validation2.png and b/en/django_forms/images/form_validation2.png differ diff --git a/en/django_forms/images/new_form2.png b/en/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/en/django_forms/images/new_form2.png and b/en/django_forms/images/new_form2.png differ diff --git a/en/django_forms/images/post_create_error.png b/en/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/en/django_forms/images/post_create_error.png and b/en/django_forms/images/post_create_error.png differ diff --git a/en/django_installation/README.md b/en/django_installation/README.md index a7dd67281c8..e5e8b62d653 100644 --- a/en/django_installation/README.md +++ b/en/django_installation/README.md @@ -2,6 +2,6 @@ > **Note** If you're using a Chromebook, skip this chapter and make sure you follow the [Chromebook Setup](../chromebook_setup/README.md) instructions. -> **Note** If you already worked through the Installation steps then you've already done this – you can go straight to the next chapter! +> **Note** If you already worked through the [installation steps](../installation/README.md) then you've already done this – you can go straight to the next chapter! {% include "/django_installation/instructions.md" %} diff --git a/en/django_installation/instructions.md b/en/django_installation/instructions.md index cab81d763e6..55c709a01a2 100644 --- a/en/django_installation/instructions.md +++ b/en/django_installation/instructions.md @@ -8,13 +8,13 @@ is copyrighted by Markus Zapke-Gründemann et al. ## Virtual environment -Before we install Django we will get you to install an extremely useful tool to help keep your coding environment tidy on your computer. It's possible to skip this step, but it's highly recommended. Starting with the best possible setup will save you a lot of trouble in the future! +Before we install Django we will get you to install an extremely useful tool to help keep your coding environment tidy on your computer. It's possible to skip this step, but it's highly recommended to follow it. Starting with the best possible setup will save you a lot of trouble in the future! So, let's create a **virtual environment** (also called a *virtualenv*). Virtualenv will isolate your Python/Django setup on a per-project basis. This means that any changes you make to one website won't affect any others you're also developing. Neat, right? -All you need to do is find a directory in which you want to create the `virtualenv`; your home directory, for example. On Windows it might look like `C:\Users\Name\` (where `Name` is the name of your login). +All you need to do is find a directory in which you want to create the `virtualenv`; your home directory, for example. On Windows, it might look like `C:\Users\Name\` (where `Name` is the name of your login). -> __NOTE:__ On Windows, make sure that this directory does not contain accented or special characters; if your username contains accented characters, use a different directory, for example `C:\djangogirls`. +> __NOTE:__ On Windows, make sure that this directory does not contain accented or special characters; if your username contains accented characters, use a different directory, for example, `C:\djangogirls`. For this tutorial we will be using a new directory `djangogirls` from your home directory: @@ -31,24 +31,24 @@ We will make a virtualenv called `myvenv`. The general command will be in the fo $ python3 -m venv myvenv ``` - -To create a new `virtualenv`, you need to open the console (we told you about that a few chapters ago – remember?) and run `C:\Python35\python -m venv myvenv`. It will look like this: +To create a new `virtualenv`, you need to open the command prompt and run `python -m venv myvenv`. It will look like this: {% filename %}command-line{% endfilename %} ``` -C:\Users\Name\djangogirls> C:\Python35\python -m venv myvenv +C:\Users\Name\djangogirls> python -m venv myvenv ``` -where `C:\Python35\python` is the directory in which you previously installed Python and `myvenv` is the name of your `virtualenv`. You can use any other name, but stick to lowercase and use no spaces, accents or special characters. It is also good idea to keep the name short – you'll be referencing it a lot! +Where `myvenv` is the name of your `virtualenv`. You can use any other name, but stick to lowercase and use no spaces, accents or special characters. It is also a good idea to keep the name short – you'll be referencing it a lot! - -Creating a `virtualenv` on both Linux and OS X is as simple as running `python3 -m venv myvenv`. +We can create a `virtualenv` on both Linux and macOS by running `python3 -m venv myvenv`. It will look like this: {% filename %}command-line{% endfilename %} @@ -56,21 +56,21 @@ It will look like this: $ python3 -m venv myvenv ``` -`myvenv` is the name of your `virtualenv`. You can use any other name, but stick to lowercase and use no spaces. It is also good idea to keep the name short as you'll be referencing it a lot! +`myvenv` is the name of your `virtualenv`. You can use any other name, but stick to lowercase and use no spaces. It is also a good idea to keep the name short as you'll be referencing it a lot! > __NOTE:__ On some versions of Debian/Ubuntu you may receive the following error: >{% 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-get install python3-venv +> apt install python3-venv >You may need to use sudo with that command. After installing the python3-venv package, recreate your virtual environment. >``` > > In this case, follow the instructions above and install the `python3-venv` package: >{% filename %}command-line{% endfilename %} >``` ->$ sudo apt-get install python3-venv +>$ sudo apt install python3-venv >``` > __NOTE:__ On some versions of Debian/Ubuntu initiating the virtual environment like this currently gives the following error: @@ -84,8 +84,8 @@ $ python3 -m venv myvenv >{% filename %}command-line{% endfilename %} >``` ->$ sudo apt-get install python-virtualenv ->$ virtualenv --python=python3.5 myvenv +>$ sudo apt install python-virtualenv +>$ virtualenv --python=python{{ book.py_version }} myvenv >``` > __NOTE:__ If you get an error like @@ -99,16 +99,17 @@ $ python3 -m venv myvenv > >{% filename %}command-line{% endfilename %} >``` ->sudo apt install python3.5-venv +>sudo apt install python{{ book.py_version }}-venv >``` + ## Working with virtualenv -The command above will create a directory called `myvenv` (or whatever name you chose) that contains our virtual environment (basically a bunch of directory and files). +The command above will create a directory called `myvenv` (or whatever name you chose) that contains our virtual environment (basically a bunch of directories and files). - Start your virtual environment by running: @@ -118,18 +119,27 @@ Start your virtual environment by running: C:\Users\Name\djangogirls> myvenv\Scripts\activate ``` -> __NOTE:__ on Windows 10 you might get an error in the Windows PowerShell that says `execution of scripts is disabled on this system`. In this case, open another Windows PowerShell with the "Run as Administrator" option. Then try typing the following command before starting your virtual environment: +> __NOTE:__ On Windows 10 you might get an error in the Windows PowerShell that says `execution of scripts is disabled on this system`. In this case, open another Windows PowerShell with the "Run as Administrator" option. Then try typing the following command before starting your virtual environment: > >{% 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 +> 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 https://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 +>``` + + + +> __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 >``` +>The advantage is that you don't have to switch between editor windows and command-line windows - Start your virtual environment by running: @@ -141,7 +151,7 @@ $ source myvenv/bin/activate Remember to replace `myvenv` with your chosen `virtualenv` name! -> __NOTE:__ sometimes `source` might not be available. In those cases try doing this instead: +> __NOTE:__ If the command `source` is not available, try doing this instead: > >{% filename %}command-line{% endfilename %} >``` @@ -156,7 +166,7 @@ When working within a virtual environment, `python` will automatically refer to OK, we have all important dependencies in place. We can finally install Django! -## Installing Django +## Installing Django {#django} Now that you have your `virtualenv` started, you can install Django. @@ -164,40 +174,61 @@ Before we do that, we should make sure we have the latest version of `pip`, the {% filename %}command-line{% endfilename %} ``` -(myvenv) ~$ pip install --upgrade pip +(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 }} ``` -Then run `pip install django~=1.10.0` (note that we use a tilde followed by an equal sign: `~=`) to install Django. +Now, run `pip install -r requirements.txt` to install Django. {% filename %}command-line{% endfilename %} ``` -(myvenv) ~$ pip install django~=1.10.0 -Collecting django~=1.10.0 - Downloading Django-1.10.4-py2.py3-none-any.whl (6.8MB) -Installing collected packages: django -Successfully installed django-1.10.4 +(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 }} ``` - -> If you get an error when calling pip on Windows platform, 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.) +> 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.) - -> Your command line might freeze after when you try to install Django. If this happens, instead of the above command use: +> 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 django~=1.10.0 +>C:\Users\Name\djangogirls> python -m pip install -r requirements.txt >``` - > 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. diff --git a/en/django_models/README.md b/en/django_models/README.md index e2acd37cf9b..2177db5139f 100644 --- a/en/django_models/README.md +++ b/en/django_models/README.md @@ -66,19 +66,24 @@ You can think of a model in the database as a spreadsheet with columns (fields) To keep everything tidy, we will create a separate application inside our project. It is very nice to have everything organized from the very beginning. To create an application we need to run the following command in the console (from `djangogirls` directory where `manage.py` file is): -{% filename %}command-line{% endfilename %} +{% filename %}macOS and Linux:{% endfilename %} ``` (myvenv) ~/djangogirls$ python manage.py startapp blog ``` +{% filename %}Windows:{% endfilename %} +``` +(myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog +``` + You will notice that a new `blog` directory is created and it contains a number of files now. The directories and files in our project should look like this: ``` djangogirls ├── blog -│   ├── __init__.py │   ├── admin.py │   ├── apps.py +│   ├── __init__.py │   ├── migrations │   │   └── __init__.py │   ├── models.py @@ -86,14 +91,19 @@ djangogirls │   └── views.py ├── db.sqlite3 ├── manage.py -└── mysite - ├── __init__.py - ├── settings.py - ├── urls.py - └── wsgi.py +├── mysite +│   ├── asgi.py +│   ├── __init__.py +│   ├── settings.py +│   ├── urls.py +│   └── wsgi.py +├── myvenv +│   └── ... +└── requirements.txt + ``` -After creating an application, we also need to tell Django that it should use it. We do that in the file `mysite/settings.py`. We need to find `INSTALLED_APPS` and add a line containing `'blog',` just above `]`. So the final product should look like this: +After creating an application, we also need to tell Django that it should use it. We do that in the file `mysite/settings.py` -- open it in your code editor. We need to find `INSTALLED_APPS` and add a line containing `'blog',` just above `]`. So the final product should look like this: {% filename %}mysite/settings.py{% endfilename %} ```python @@ -112,22 +122,21 @@ INSTALLED_APPS = [ In the `blog/models.py` file we define all objects called `Models` – this is a place in which we will define our blog post. -Let's open `blog/models.py`, remove everything from it, and write code like this: +Let's open `blog/models.py` in the code editor, remove everything from it, and write code like this: {% filename %}blog/models.py{% endfilename %} ```python +from django.conf import settings from django.db import models from django.utils import timezone class Post(models.Model): - author = models.ForeignKey('auth.User') + 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() @@ -155,7 +164,7 @@ Now we define the properties we were talking about: `title`, `text`, `created_da - `models.DateTimeField` – this is a date and time. - `models.ForeignKey` – this is a link to another model. -We will not explain every bit of code here since it would take too much time. 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/1.10/ref/models/fields/#field-types). +We will not explain every bit of code here since it would take too much time. 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/5.1/ref/models/fields/#field-types). What about `def publish(self):`? This is exactly the `publish` method we were talking about before. `def` means that this is a function/method and `publish` is the name of the method. You can change the name of the method if you want. The naming rule is that we use lowercase and underscores instead of spaces. For example, a method that calculates average price could be called `calculate_average_price`. @@ -173,10 +182,12 @@ The last step here is to add our new model to our database. First we have to mak ``` (myvenv) ~/djangogirls$ python manage.py makemigrations blog Migrations for 'blog': - blog/migrations/0001_initial.py: - - Create model Post + blog/migrations/0001_initial.py + - Create model Post ``` +**Note:** Remember to save the files you edit. Otherwise, your computer will execute the previous version which might give you unexpected error messages. + Django prepared a migration file for us that we now have to apply to our database. Type `python manage.py migrate blog` and the output should be as follows: {% filename %}command-line{% endfilename %} @@ -185,7 +196,6 @@ Django prepared a migration file for us that we now have to apply to our databas Operations to perform: Apply all migrations: blog Running migrations: - Rendering model states... DONE Applying blog.0001_initial... OK ``` diff --git a/en/django_orm/README.md b/en/django_orm/README.md index 6de912b09d3..b14ceb944c7 100644 --- a/en/django_orm/README.md +++ b/en/django_orm/README.md @@ -7,7 +7,7 @@ In this chapter you'll learn how Django connects to the database and stores data 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. -It's easiest to learn by example. Let's try this, shall we? +It's easier to learn by example. Let's try this, shall we? ## Django shell @@ -27,7 +27,7 @@ The effect should be like this: >>> ``` -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, of course. +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. ### All objects @@ -49,12 +49,12 @@ Oops! An error showed up. It tells us that there is no Post. It's correct – we >>> from blog.models import Post ``` -This is simple: we import the model `Post` from `blog.models`. Let's try displaying all posts again: +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? @@ -83,23 +83,24 @@ What users do we have in our database? Try this: {% filename %}command-line{% endfilename %} ```python >>> User.objects.all() -[] +]> ``` -This is the superuser we created earlier! Let's get an instance of the user now: +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 %} ```python -me = User.objects.get(username='ola') +>>> me = User.objects.get(username='ola') ``` -As you can see, we now `get` a `User` with a `username` that equals 'ola'. Neat! Of course, you have to adjust this line to use your own username. +As you can see, we now `get` a `User` with a `username` that equals 'ola'. Neat! Now we can finally create our post: {% filename %}command-line{% endfilename %} ```python >>> Post.objects.create(author=me, title='Sample title', text='Test') + ``` Hurray! Wanna check if it worked? @@ -107,7 +108,7 @@ Hurray! Wanna check if it worked? {% filename %}command-line{% endfilename %} ```python >>> Post.objects.all() -[, , ] +, , ]> ``` There it is, one more post in the list! @@ -125,7 +126,7 @@ A big part of QuerySets is the ability to filter them. Let's say we want to find {% 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? @@ -133,7 +134,7 @@ Or maybe we want to see all the posts that contain the word 'title' in the `titl {% filename %}command-line{% endfilename %} ```python >>> Post.objects.filter(title__contains='title') -[, ] +, ]> ``` > **Note** There are two underscore characters (`_`) between `title` and `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". @@ -144,7 +145,7 @@ You can also get a list of all published posts. We do this by filtering all the ```python >>> from django.utils import timezone >>> Post.objects.filter(published_date__lte=timezone.now()) -[] + ``` 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: @@ -161,12 +162,12 @@ And then publish it with our `publish` method: >>> post.publish() ``` -Now try to get list of published posts again (press the up arrow button three times and hit `enter`): +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()) -[] +]> ``` @@ -177,7 +178,7 @@ QuerySets also allow you to order the list of objects. Let's try to order them b {% filename %}command-line{% endfilename %} ```python >>> Post.objects.order_by('created_date') -[, , , ] +, , , ]> ``` We can also reverse the ordering by adding `-` at the beginning: @@ -185,16 +186,21 @@ We can also reverse the ordering by adding `-` at the beginning: {% filename %}command-line{% endfilename %} ```python >>> Post.objects.order_by('-created_date') -[, , , ] +, , , ]> ``` -### Chaining QuerySets +### Complex queries through method-chaining -You can also combine QuerySets by **chaining** them together: +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') +, , , ]> ``` This is really powerful and lets you write quite complex queries. diff --git a/en/django_start_project/README.md b/en/django_start_project/README.md index 925c37f9408..8d069809101 100644 --- a/en/django_start_project/README.md +++ b/en/django_start_project/README.md @@ -7,18 +7,18 @@ tutorial](http://django-marcador.keimlink.de/) licensed under the Creative Commo Attribution-ShareAlike 4.0 International License. The django-marcador tutorial is copyrighted by Markus Zapke-Gründemann et al. -We're going to create a simple blog! +We're going to create a small blog! The first step is to start a new Django project. Basically, this means that we'll run some scripts provided by Django that will create the skeleton of a Django project for us. This is just a bunch of directories and files that we will use later. The names of some files and directories are very important for Django. You should not rename the files that we are about to create. Moving them to a different place is also not a good idea. Django needs to maintain a certain structure to be able to find important things. > Remember to run everything in the virtualenv. If you don't see a prefix `(myvenv)` in your console, you need to activate your virtualenv. We explained how to do that in the __Django installation__ chapter in the __Working with virtualenv__ part. Typing `myvenv\Scripts\activate` on Windows or -`source myvenv/bin/activate` on Mac OS X or Linux will do this for you. +`source myvenv/bin/activate` on macOS or Linux will do this for you. - + -In your Mac OS X or Linux console, you should run the following command. **Don't forget to add the period (or dot) `.` at the end!** +In your macOS or Linux console, you should run the following command. **Don't forget to add the period (or dot) `.` at the end!** {% filename %}command-line{% endfilename %} ``` @@ -32,18 +32,18 @@ The `(myvenv) ~/djangogirls$` part shown here is just example of the prompt that - + On Windows you should run the following command. **(Don't forget to add the period (or dot) `.` at the end)**: {% filename %}command-line{% endfilename %} ``` -(myvenv) C:\Users\Name\djangogirls> django-admin.py startproject mysite . +(myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . ``` > The period `.` is crucial because it tells the script to install Django in your current directory (for which the period `.` is a short-hand reference). -> **Note** When typing the command above, remember that you only type the part which starts by `django-admin.py`. -The (myvenv) C:\Users\Name\djangogirls>` part shown here is just example of the prompt that will be inviting your input on your command line. +> **Note** When typing the command above, remember that you only type the part which starts by `django-admin.exe`. +The `(myvenv) C:\Users\Name\djangogirls>` part shown here is just example of the prompt that will be inviting your input on your command line. @@ -51,16 +51,20 @@ The (myvenv) C:\Users\Name\djangogirls>` part shown here is just example of the ``` djangogirls -├───manage.py -└───mysite - settings.py - urls.py - wsgi.py - __init__.py +├── manage.py +├── mysite +│   ├── asgi.py +│   ├── __init__.py +│   ├── settings.py +│   ├── urls.py +│   └── wsgi.py +├── myvenv +│   └── ... +└── requirements.txt ``` -> **Note**: in your directory structure, you will also see your `venv` directory that we created before. +> **Note**: in your directory structure, you will also see your `myvenv` directory that we created before. -`manage.py` is a script that helps with management of the site. With it we will be able (amongst other things) to start a web server on our computer without installing anything else. +`manage.py` is a script that helps with management of the site. With it we will be able (among other things) to start a web server on our computer without installing anything else. The `settings.py` file contains the configuration of your website. @@ -73,6 +77,10 @@ Let's ignore the other files for now as we won't change them. The only thing to Let's make some changes in `mysite/settings.py`. Open the file using the code editor you installed earlier. +**Note**: Keep in mind that `settings.py` is a regular file, like any other. You can open it from inside the code editor, using the "File -> Open" menu action. This should get you the usual window in which you can navigate to your `settings.py` file and select it. Alternatively, you can open the file by navigating to the `djangogirls/` folder on your desktop and right-clicking on it. Then, select your code editor from the list. Selecting the editor is important as you might have other programs installed that can open the file but will not let you edit it. + +#### Changing the Timezone + It would be nice to have the correct time on our website. Go to [Wikipedia's list of time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) and copy your relevant time zone (TZ) (e.g. `Europe/Berlin`). In `settings.py`, find the line that contains `TIME_ZONE` and modify it to choose your own timezone. For example: @@ -82,25 +90,85 @@ In `settings.py`, find the line that contains `TIME_ZONE` and modify it to choos TIME_ZONE = 'Europe/Berlin' ``` -We'll also need to add a path for static files. (We'll find out all about static files and CSS later in the tutorial.) Go down to the *end* of the file, and just underneath the `STATIC_URL` entry, add a new one called `STATIC_ROOT`: +> **Note**: Timezones should be in the Region/City format, so eg "EDT" is not valid, but "America/Detroit" is. + + +#### Changing the Language + +A language code consist of the language, e.g. `en` for English or `de` for German, and the country code, e.g. `de` for Germany or `ch` for Switzerland. If English is not your native language, you can add this to change the default buttons and notifications from Django to be in your language. So you would have "Cancel" button translated into the language you defined here. [Django comes with a lot of prepared translations](https://docs.djangoproject.com/en/5.1/ref/settings/#language-code). + +If you want a different language, change the language code by changing the following line: {% filename %}mysite/settings.py{% endfilename %} ```python -STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') +LANGUAGE_CODE = 'de-ch' ``` -When `DEBUG` is `True` and `ALLOWED_HOSTS` is empty, the host is validated against `['localhost', '127.0.0.1', '[::1]']`. This won't -match our hostname on PythonAnywhere once we deploy our application so we will change the following setting: + +#### Other settings + +We'll also need to add a path for static files. +(We'll find out all about static files and CSS later in the tutorial.) +Go down to the *end* of the file, +and just underneath the `STATIC_URL` entry, add a new one called `STATIC_ROOT`: {% filename %}mysite/settings.py{% endfilename %} ```python -ALLOWED_HOSTS = ['127.0.0.1', '.pythonanywhere.com'] +STATIC_URL = 'static/' +STATIC_ROOT = BASE_DIR / 'static' +``` + +When `DEBUG` is `True` and `ALLOWED_HOSTS` is empty, the host is validated against `['localhost', '127.0.0.1', '[::1]']`. +This won't match our hostname on PythonAnywhere once we deploy our application so we will change the following setting: + +{% filename %}mysite/settings.py{% endfilename %} +```python +ALLOWED_HOSTS = ['localhost', '127.0.0.1', '.pythonanywhere.com'] ``` > **Note**: If you're using a Chromebook, add this line at the bottom of your settings.py file: > `MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'` +> Also add `.amazonaws.com` to the `ALLOWED_HOSTS` if you are using cloud9 + +> If you are hosting your project on `Glitch.com`, let us protect the Django secret key that needs to +> remain confidential (otherwise, anyone remixing your project could see it): +> +> * First, we are going to create a random secret key. +> Open the Glitch terminal again, and type the following command: +> +> {% filename %}command-line{% endfilename %} +> ```bash +> python -c 'from django.core.management.utils import get_random_secret_key; \ +> print(get_random_secret_key())' +> ``` +> This should display a long random string, perfect to use as a secret key for your brand new Django web site. +> We will now paste this key into a `.env` file that Glitch will only show you if you are the owner of the web site. +> +> * Create a file `.env` at the root of your project and add the following property in it: +> +> {% filename %}.env{% endfilename %} +> ```bash +> # Here, inside the single quotes, you can cut and paste the random key generated above +> SECRET='3!0k#7ds5mp^-x$lqs2%le6v97h#@xopab&oj5y7d=hxe511jl' +> ``` +> * Then update the Django settings file to inject this secret value and set the Django web site name: +> +> {% filename %}mysite/settings.py{% endfilename %} +> ```python +> import os +> +> SECRET_KEY = os.getenv('SECRET') +> ``` +> * And a little further down in the same file, we inject the name of your new Glitch website: +> +> {% filename %}mysite/settings.py{% endfilename %} +> ```python +> ALLOWED_HOSTS = [os.getenv('PROJECT_DOMAIN') + ".glitch.me"] +> ``` +> The `PROJECT_DOMAIN` value is automatically generated by Glitch. +> It will correspond to the name of your project. + ## Set up a database There's a lot of different database software that can store data for your site. We'll use the default one, `sqlite3`. @@ -112,7 +180,7 @@ This is already set up in this part of your `mysite/settings.py` file: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'NAME': BASE_DIR / 'db.sqlite3', } } ``` @@ -123,13 +191,13 @@ To create a database for our blog, let's run the following in the console: `pyth ``` (myvenv) ~/djangogirls$ python manage.py migrate Operations to perform: - Apply all migrations: auth, admin, contenttypes, sessions + 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 @@ -137,6 +205,11 @@ Running migrations: 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 ``` @@ -156,6 +229,13 @@ If you are on a Chromebook, use this command instead: {% filename %}Cloud 9{% endfilename %} ``` (myvenv) ~/djangogirls$ python manage.py runserver 0.0.0.0:8080 +``` +or this one if you are using Glitch: + +{% filename %}Glitch.com terminal{% endfilename %} +``` +$ refresh + ``` If you are on Windows and this fails with `UnicodeDecodeError`, use this command instead: @@ -166,28 +246,34 @@ If you are on Windows and this fails with `UnicodeDecodeError`, use this command ``` -Now all you need to do is check that your website is running. Open your browser (Firefox, Chrome, Safari, Internet Explorer or whatever you use) and enter this address: +Now you need to check that your website is running. Open your browser (Firefox, Chrome, Safari, Internet Explorer or whatever you use) and enter this address: {% filename %}browser{% endfilename %} ``` http://127.0.0.1:8000/ ``` -If you're using a Chromebook, you'll always visit your test server by accessing: +If you're using a Chromebook and Cloud9, instead click the URL in the pop-up window that should have appeared in the upper right corner of the command window where the web server is running. The URL will look something like: {% filename %}browser{% endfilename %} ``` -https://django-girls-.c9users.io +https://.vfs.cloud9.us-west-2.amazonaws.com +``` +or on Glitch: ``` +https://name-of-your-glitch-project.glitch.me +``` + +You can open this in another browser window and you should see the Django install worked page. Congratulations! You've just created your first website and run it using a web server! Isn't that awesome? -![It worked!](images/it_worked2.png) +![Install worked!](images/install_worked.png) -While the web server is running, you won't see a new command-line prompt to enter additional commands. The terminal will accept new text but will not execute new commands. This is because the web server continuously runs in order to listen for incoming requests. +Note that a command window can only run one thing at a time, and the command window you opened earlier is running the web server. As long as the web server is running and waiting for additional incoming requests, the terminal will accept new text but will not execute new commands. > We reviewed how web servers work in the How the Internet works chapter. -To type additional commands while the web server is running, open a new terminal window and activate your virtualenv. To stop the web server, switch back to the window in which it's running and press CTRL+C - Control and C buttons together (on Windows, you might have to press Ctrl+Break). +To type additional commands while the web server is running, open a new terminal window and activate your virtualenv -- to review instructions on how to open a second terminal window, see [Introduction to the command line](../intro_to_command_line/README.md). To stop the web server, switch back to the window in which it's running and press CTRL+C - Control and C keys together (on Windows, you might have to press Ctrl+Break). Ready for the next step? It's time to create some content! diff --git a/en/django_start_project/images/install_worked.png b/en/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..c20c9c973c0 Binary files /dev/null and b/en/django_start_project/images/install_worked.png differ diff --git a/en/django_start_project/images/it_worked2.png b/en/django_start_project/images/it_worked2.png deleted file mode 100644 index 4412ecfc49e..00000000000 Binary files a/en/django_start_project/images/it_worked2.png and /dev/null differ diff --git a/en/django_templates/README.md b/en/django_templates/README.md index baa1eca32b4..6086ba883d5 100644 --- a/en/django_templates/README.md +++ b/en/django_templates/README.md @@ -6,7 +6,7 @@ Time to display some data! Django gives us some helpful built-in __template tags 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 template tags__ allow us to transfer Python-like things into HTML, so you can build dynamic websites faster and easier. Cool! +__Django template tags__ allow us to transfer Python-like things into HTML, so you can build dynamic websites faster. Cool! ## Display post list template @@ -19,7 +19,7 @@ To print a variable in Django templates, we use double curly brackets with the v {{ posts }} ``` -Try this in your `blog/templates/blog/post_list.html` template. Replace everything from the second `
` to the third `
` with `{{ posts }}`. Save the file, and refresh the page to see the results: +Try this in your `blog/templates/blog/post_list.html` template. Open it up in the code editor, and replace the existing `
` elements with `{{ posts }}`. Save the file, and refresh the page to see the results: ![Figure 13.1](images/step1.png) @@ -27,7 +27,7 @@ As you can see, all we've got is this: {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -[, ] +, ]> ``` This means that Django understands it as a list of objects. Remember from __Introduction to Python__ how we can display lists? Yes, with for loops! In a Django template you do them like this: @@ -47,16 +47,16 @@ It works! But we want the posts to be displayed like the static posts we created {% 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 %} ``` @@ -64,20 +64,20 @@ It works! But we want the posts to be displayed like the static posts we created ![Figure 13.3](images/step3.png) -Have you noticed that we used a slightly different notation this time (`{{ post.title }}` or `{{ post.text }})`? We are accessing data in each of the fields defined in our `Post` model. Also, the `|linebreaksbr` is piping the posts' text through a filter to convert line-breaks into paragraphs. +Have you noticed that we used a slightly different notation this time (`{{ post.title }}` or `{{ post.text }}`)? We are accessing data in each of the fields defined in our `Post` model. Also, the `|linebreaksbr` is piping the posts' text through a filter to convert line-breaks into paragraphs. ## One more thing 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… -* First, push your code to Github +* First, push your code to GitHub {% filename %}command-line{% endfilename %} ``` $ git status [...] -$ git add --all . +$ git add . $ git status [...] $ git commit -m "Modified templates to display posts from database." @@ -87,17 +87,19 @@ $ git push * Then, log back in to [PythonAnywhere](https://www.pythonanywhere.com/consoles/) and go to your **Bash console** (or start a new one), and run: -{% filename %}command-line{% endfilename %} +{% filename %}PythonAnywhere command-line{% endfilename %} ``` -$ cd my-first-blog +$ cd .pythonanywhere.com $ git pull [...] ``` -* Finally, hop on over to the [Web tab](https://www.pythonanywhere.com/web_app_setup/) and hit **Reload** on your web app. Your update should be live! 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. +(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. -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://yourname.pythonanywhere.com/admin. Then refresh your page to see if the post appears there. +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. :) diff --git a/en/django_templates/images/donut.png b/en/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/en/django_templates/images/donut.png and b/en/django_templates/images/donut.png differ diff --git a/en/django_templates/images/step1.png b/en/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/en/django_templates/images/step1.png and b/en/django_templates/images/step1.png differ diff --git a/en/django_templates/images/step2.png b/en/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/en/django_templates/images/step2.png and b/en/django_templates/images/step2.png differ diff --git a/en/django_templates/images/step3.png b/en/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/en/django_templates/images/step3.png and b/en/django_templates/images/step3.png differ diff --git a/en/django_urls/README.md b/en/django_urls/README.md index be8431deb42..961d3a0ea01 100644 --- a/en/django_urls/README.md +++ b/en/django_urls/README.md @@ -4,11 +4,11 @@ We're about to build our first webpage: a homepage for your blog! But first, let ## What is a URL? -A URL is simply a web address. You can see a URL every time you visit a website – it is visible in your browser's address bar. (Yes! `127.0.0.1:8000` is a URL! And `https://djangogirls.org` is also a URL.) +A URL is a web address. You can see a URL every time you visit a website – it is visible in your browser's address bar. (Yes! `127.0.0.1:8000` is a URL! And `https://djangogirls.org` is also a URL.) -![Url](images/url.png) +![URL](images/url.png) -Every page on the Internet needs its own URL. This way your application knows what it should show to a user who opens that URL. In Django we use something called `URLconf` (URL configuration). URLconf is a set of patterns that Django will try to match with the requested URL to find the correct view. +Every page on the Internet needs its own URL. This way your application knows what it should show to a user who opens that URL. In Django, we use something called `URLconf` (URL configuration). URLconf is a set of patterns that Django will try to match the requested URL to find the correct view. ## How do URLs work in Django? @@ -21,11 +21,11 @@ Let's open up the `mysite/urls.py` file in your code editor of choice and see wh [...] """ -from django.conf.urls import url from django.contrib import admin +from django.urls import path urlpatterns = [ - url(r'^admin/', admin.site.urls), + path('admin/', admin.site.urls), ] ``` @@ -33,37 +33,14 @@ As you can see, Django has already put something here for us. Lines between triple quotes (`'''` or `"""`) are called docstrings – you can write them at the top of a file, class or method to describe what it does. They won't be run by Python. -The admin URL, which you visited in previous chapter, is already here: +The admin URL, which you visited in the previous chapter, is already here: {% filename %}mysite/urls.py{% endfilename %} ```python - url(r'^admin/', admin.site.urls), + path('admin/', admin.site.urls), ``` -This line means that for every URL that starts with `admin/`, Django will find a corresponding *view*. In this case we're including a lot of admin URLs so it isn't all packed into this small file – it's more readable and cleaner. - -## Regex - -Do you wonder how Django matches URLs to views? Well, this part is tricky. Django uses `regex`, short for "regular expressions". Regex has a lot (a lot!) of rules that form a search pattern. Since regexes are an advanced topic, we will not go in detail over how they work. - -If you still wish to understand how we created the patterns, here is an example of the process – we will only need a limited subset of the rules to express the pattern we are looking for, namely: - -* `^` for the beginning of the text -* `$` for the end of the text -* `\d` for a digit -* `+` to indicate that the previous item should be repeated at least once -* `()` to capture part of the pattern - -Anything else in the URL definition will be taken literally. - -Now imagine you have a website with the address like `http://www.mysite.com/post/12345/`, where `12345` is the number of your post. - -Writing separate views for all the post numbers would be really annoying. With regular expressions, we can create a pattern that will match the URL and extract the number for us: `^post/(\d+)/$`. Let's break this down piece by piece to see what we are doing here: - -* **^post/** is telling Django to take anything that has `post/` at the beginning of the url (right after `^`) -* **(\d+)** means that there will be a number (one or more digits) and that we want the number captured and extracted -* **/** tells django that another `/` character should follow -* **$** then indicates the end of the URL meaning that only strings ending with the `/` will match this pattern +This line means that for every URL that starts with `admin/`, Django will find a corresponding *view*. In this case, we're including a lot of admin URLs so it isn't all packed into this small file – it's more readable and cleaner. ## Your first Django URL! @@ -72,55 +49,67 @@ Time to create our first URL! We want 'http://127.0.0.1:8000/' to be the home pa We also want to keep the `mysite/urls.py` file clean, so we will import URLs from our `blog` application to the main `mysite/urls.py` file. -Go ahead, add a line that will import `blog.urls`. Note that we are using the `include` function here so **you will need** to add that to the import on the first line of the file. +Go ahead, add a line that will import `blog.urls`. You will also need to change the `from django.urls…` line because we are using the `include` function here, so you will need to add that import to the line. Your `mysite/urls.py` file should now look like this: {% 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/', admin.site.urls), - url(r'', include('blog.urls')), + path('admin/', admin.site.urls), + path('', include('blog.urls')), ] ``` -Django will now redirect everything that comes into 'http://127.0.0.1:8000/' to `blog.urls` and look for further instructions there. - -Writing regular expressions in Python is always done with `r` in front of the string. This is a helpful hint for Python that the string may contain special characters that are not meant for Python itself, but for the regular expression instead. - +Django will now redirect everything that comes into 'http://127.0.0.1:8000/' to `blog.urls` and looks for further instructions there. ## blog.urls -Create a new empty file named `blog/urls.py`. All right! Add these first two lines: +Create a new empty file named `urls.py` in the `blog` directory, and open it in the code editor. All right! Add these first two lines: {% filename %}blog/urls.py{% endfilename %} ```python -from django.conf.urls import url +from django.urls import path from . import views ``` -Here we're importing Django's function `url` and all of our `views` from the `blog` application. (We don't have any yet, but we will get to that in a minute!) +Here we're importing Django's function `path` and all of our `views` from the `blog` application. (We don't have any yet, but we will get to that in a minute!) After that, we can add our first URL pattern: {% filename %}blog/urls.py{% endfilename %} ```python urlpatterns = [ - url(r'^$', views.post_list, name='post_list'), + path('', views.post_list, name='post_list'), ] ``` -As you can see, we're now assigning a `view` called `post_list` to the `^$` URL. This regular expression will match `^` (a beginning) followed by `$` (an end) – so only an empty string will match. That's correct, because in Django URL resolvers, 'http://127.0.0.1:8000/' is not a part of the URL. This pattern will tell Django that `views.post_list` is the right place to go if someone enters your website at the 'http://127.0.0.1:8000/' address. +As you can see, we're now assigning a `view` called `post_list` to the root URL. This URL pattern will match an empty string and the Django URL resolver will ignore the domain name (i.e., http://127.0.0.1:8000/) that prefixes the full URL path. This pattern will tell Django that `views.post_list` is the right place to go if someone enters your website at the 'http://127.0.0.1:8000/' address. The last part, `name='post_list'`, is the name of the URL that will be used to identify the view. This can be the same as the name of the view but it can also be something completely different. We will be using the named URLs later in the project, so it is important to name each URL in the app. We should also try to keep the names of URLs unique and easy to remember. If you try to visit http://127.0.0.1:8000/ now, then you'll find some sort of 'web page not available' message. This is because the server (remember typing `runserver`?) is no longer running. Take a look at your server console window to find out why. -![Error](images/error1.png) +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +``` + 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' +``` + +Your console is showing an error, but don't worry – it's actually pretty useful: It's telling you that there is __no attribute 'post_list'__. That's the name of the *view* that Django is trying to find and use, but we haven't created it yet. At this stage, your `/admin/` will also not work. No worries – we will get there. +If you see a different error message, try restarting your web server. To do that, in the console window that is running the web server, stop it by pressing Ctrl+C (the Control and C keys together). On Windows, you might have to press Ctrl+Break. Then you need to restart the web server by running a `python manage.py runserver` command. -Your console is showing an error, but don't worry – it's actually pretty useful: It's telling you that there is __no attribute 'post_list'__. That's the name of the *view* that Django is trying to find and use, but we haven't created it yet. At this stage your `/admin/` will also not work. No worries – we will get there. -> If you want to know more about Django URLconfs, look at the official documentation: https://docs.djangoproject.com/en/1.10/topics/http/urls/ +> If you want to know more about Django URLconfs, look at the official documentation: https://docs.djangoproject.com/en/5.1/topics/http/urls/ diff --git a/en/django_urls/images/error1.png b/en/django_urls/images/error1.png deleted file mode 100644 index 8bf6b9829a1..00000000000 Binary files a/en/django_urls/images/error1.png and /dev/null differ diff --git a/en/django_urls/images/url.png b/en/django_urls/images/url.png index 6cd1bd96291..c22441e930e 100644 Binary files a/en/django_urls/images/url.png and b/en/django_urls/images/url.png differ diff --git a/en/django_views/README.md b/en/django_views/README.md index 0b97f90e7af..4c0d860c6d9 100644 --- a/en/django_views/README.md +++ b/en/django_views/README.md @@ -2,13 +2,19 @@ Time to get rid of the bug we created in the last chapter! :) -A *view* is a place where we put the "logic" of our application. It will request information from the `model` you created before and pass it to a `template`. We'll create a template in the next chapter. Views are just Python functions that are a little bit more complicated than the ones we wrote in the __Introduction to Python__ chapter. +A *view* is a place where we put the "logic" of our application. The views do the following: + +1. Receive the `request` information (current user session and other stuff) as well as parameters parsed from the url (for example, the id of a blog post) +2. Fetch the information from the `model`, probably adding some logic (like filtering logic to show only the published posts) +3. Create a response by filling a `template` with the fetched info + +We'll create a template in the next chapter. Now we'll create a view. Technically, views are Python functions, exactly like the ones we wrote in the __Introduction to Python__ chapter. These functions take `request` as a parameter and return `HttpResponse`. You shouldn't worry about the type of the return value because another function from the Django framework will construct it for us. Views are placed in the `views.py` file. We will add our *views* to the `blog/views.py` file. ## blog/views.py -OK, let's open up this file and see what's in there: +OK, let's open up this file in our code editor and see what's in there: {% filename %}blog/views.py{% endfilename %} ```python @@ -21,7 +27,7 @@ Not too much stuff here yet. Remember that lines starting with `#` are comments – this means that those lines won't be run by Python. -The simplest *view* can look like this: +Let's create a *view* as the comment suggests. Add the following minimal view below it: {% filename %}blog/views.py{% endfilename %} ```python @@ -29,7 +35,7 @@ def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -As you can see, we created a function (`def`) called `post_list` that takes `request` and `return` a function `render` that will render (put together) our template `blog/post_list.html`. +As you can see, we created a function (`def`) called `post_list` that takes `request` and will `return` the value it gets from calling another function `render` that will render (put together) our template `blog/post_list.html`. Save the file, go to http://127.0.0.1:8000/ and see what we've got. @@ -39,4 +45,4 @@ Another error! Read what's going on now: This shows that the server is running again, at least, but it still doesn't look right, does it? Don't worry, it's just an error page, nothing to be scared of! Just like the error messages in the console, these are actually pretty useful. You can read that the *TemplateDoesNotExist*. Let's fix this bug and create a template in the next chapter! -> Learn more about Django views by reading the official documentation: https://docs.djangoproject.com/en/1.10/topics/http/views/ +> Learn more about Django views by reading the official documentation: https://docs.djangoproject.com/en/5.1/topics/http/views/ diff --git a/en/django_views/images/error.png b/en/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/en/django_views/images/error.png and b/en/django_views/images/error.png differ diff --git a/en/dynamic_data_in_templates/README.md b/en/dynamic_data_in_templates/README.md index 706f83c039a..450c82bed98 100644 --- a/en/dynamic_data_in_templates/README.md +++ b/en/dynamic_data_in_templates/README.md @@ -6,7 +6,7 @@ This is exactly what *views* are supposed to do: connect models and templates. I OK, so how will we achieve this? -We need to open our `blog/views.py`. So far `post_list` *view* looks like this: +We need to open our `blog/views.py` in our code editor. So far `post_list` *view* looks like this: {% filename %}blog/views.py{% endfilename %} ```python @@ -39,7 +39,7 @@ So now we want published blog posts sorted by `published_date`, right? We alread Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') ``` -Now we put this piece of code inside the `blog/views.py` file by adding it to the function `def post_list(request)`, but don't forget to first add `from django.utils import timezone`: +So, let's open the `blog/views.py` file in the code editor, and add this piece of code to the function `def post_list(request)` -- but don't forget to first add `from django.utils import timezone`: {% filename %}blog/views.py{% endfilename %} ```python @@ -52,7 +52,9 @@ def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -The last missing part is passing the `posts` QuerySet to the template context. Don't worry – we will cover how to display it in a later chapter. +To display our QuerySet on our blog's post list, we have two things left to do: +1. Pass the `posts` QuerySet to the template context, by changing the `render` function call. We'll do this now. +2. Modify the template to display the `posts` QuerySet. We'll cover this in a later chapter. Please note that we create a *variable* for our QuerySet: `posts`. Treat this as the name of our QuerySet. From now on we can refer to it by this name. @@ -73,4 +75,4 @@ def post_list(request): That's it! Time to go back to our template and display this QuerySet! -Want to read a little bit more about QuerySets in Django? You should look here: https://docs.djangoproject.com/en/1.9/ref/models/querysets/ +Want to read a little bit more about QuerySets in Django? You should look here: https://docs.djangoproject.com/en/5.1/ref/models/querysets/ diff --git a/en/extend_your_application/README.md b/en/extend_your_application/README.md index f94e2c5f99a..2928d86a0a9 100644 --- a/en/extend_your_application/README.md +++ b/en/extend_your_application/README.md @@ -1,6 +1,8 @@ +{% set warning_icon = '' %} + # Extend your application -We've already completed all the different steps necessary for the creation of our website: we know how to write a model, url, view and template. We also know how to make our website pretty. +We've already completed all the different steps necessary for the creation of our website: we know how to write a model, URL, view and template. We also know how to make our website pretty. Time to practice! @@ -10,38 +12,38 @@ We already have a `Post` model, so we don't need to add anything to `models.py`. ## Create a template link to a post's detail -We will start with adding a link inside `blog/templates/blog/post_list.html` file. So far it should look like this: +We will start with adding a link inside `blog/templates/blog/post_list.html` file. Open it in the code editor, and so far it should look like this: {% 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 content %} +{% endblock %} ``` -{% raw %}We want to have a link from a post's title in the post list to the post's detail page. Let's change `

{{ post.title }}

` so that it links to the post's detail page:{% endraw %} +{% raw %}We want to have a link from a post's title in the post list to the post's detail page. Let's change `

{{ post.title }}

` so that it links to the post's detail page:{% endraw %} -{% filename %}blog/templates/blog/post_list.html{% endfilename %} +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} ```html -

{{ post.title }}

+

{{ post.title }}

``` {% raw %}Time to explain the mysterious `{% url 'post_detail' pk=post.pk %}`. As you might suspect, the `{% %}` notation means that we are using Django template tags. This time we will use one that will create a URL for us!{% endraw %} -`blog.views.post_detail` is a path to a `post_detail` *view* we want to create. Please note: `blog` is the name of our application (the directory `blog`), `views` is from the name of the `views.py` file and the last bit – `post_detail` – is the name of the *view*. +The `post_detail` part means that Django will be expecting a URL in `blog/urls.py` with `name=post_detail`. -And how about `pk=post.pk`? `pk` is short for primary key, which is a unique name for each record in a database. Because we didn't specify a primary key in our `Post` model, Django creates one for us (by default, a number that increases by one for each record, i.e. 1, 2, 3) and adds it as a field named `pk` to each of our posts. We access the primary key by writing `post.pk`, the same way we access other fields (`title`, `author`, etc.) in our `Post` object! +And how about `pk=post.pk`? `pk` is short for primary key, which is a unique identifier for each record in a database. Every Django model has a field which serves as its primary key, and whatever other name it has, it can also be referred to as "pk". Because we didn't specify a primary key in our `Post` model, Django creates one for us (by default, a field named "id" holding a number that increases for each record, i.e. 1, 2, 3) and adds it as a field to each of our posts. We access the primary key by writing `post.pk`, the same way we access other fields (`title`, `author`, etc.) in our `Post` object! -Now when we go to http://127.0.0.1:8000/ we will have an error (as expected, since we don't have a URL or a *view* for `post_detail`). It will look like this: +Now when we go to http://127.0.0.1:8000/ we will have an error (as expected, since we do not yet have a URL or a *view* for `post_detail`). It will look like this: ![NoReverseMatch error](images/no_reverse_match2.png) @@ -51,41 +53,53 @@ Let's create a URL in `urls.py` for our `post_detail` *view*! We want our first post's detail to be displayed at this **URL**: http://127.0.0.1:8000/post/1/ -Let's make a URL in the `blog/urls.py` file to point Django to a *view* named `post_detail`, that will show an entire blog post. Add the line `url(r'^post/(?P\d+)/$', views.post_detail, name='post_detail'),` to the `blog/urls.py` file. The file should look like this: +Let's make a URL in the `blog/urls.py` file to point Django to a *view* named `post_detail`, that will show an entire blog post. Open the `blog/urls.py` file in the code editor, and add the line `path('post//', views.post_detail, name='post_detail'),` so that the file looks like this: -{% filename %}blog/urls.py{% endfilename %} +{% 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\d+)/$', views.post_detail, name='post_detail'), + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), ] ``` -This part ``^post/(?P\d+)/$`` looks scary, but no worries – we will explain it for you: -- it starts with `^` again – "the beginning". -- `post/` just means that after the beginning, the URL should contain the word __post__ and a __/__. So far so good. -- `(?P\d+)` – this part is trickier. It means that Django will take everything that you place here and transfer it to a view as a variable called `pk`. (Note that this matches the name we gave the primary key variable back in `blog/templates/blog/post_list.html`!) `\d` also tells us that it can only be a digit, not a letter (so everything between 0 and 9). `+` means that there needs to be one or more digits there. So something like `http://127.0.0.1:8000/post//` is not valid, but `http://127.0.0.1:8000/post/1234567890/` is perfectly OK! -- `/` – then we need a __/__ again. -- `$` – "the end"! +This part ``post//`` specifies a URL pattern – we will explain it for you: +- `post/` means that the URL should begin with the word __post__ followed by a __/__. So far so good. +- `` – this part is trickier. It means that Django expects an integer value and will transfer it to a view as a variable called `pk`. +- `/` – then we need a __/__ again before finishing the URL. That means if you enter `http://127.0.0.1:8000/post/5/` into your browser, Django will understand that you are looking for a *view* called `post_detail` and transfer the information that `pk` equals `5` to that *view*. OK, we've added a new URL pattern to `blog/urls.py`! Let's refresh the page: http://127.0.0.1:8000/ Boom! The server has stopped running again. Have a look at the console – as expected, there's yet another error! -![AttributeError](images/attribute_error2.png) +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +``` + 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' +``` -Do you remember what the next step is? Of course: adding a view! +Do you remember what the next step is? It's adding a view! ## Add a post's detail view -This time our *view* is given an extra parameter, `pk`. Our *view* needs to catch it, right? So we will define our function as `def post_detail(request, pk):`. Note that we need to use exactly the same name as the one we specified in urls (`pk`). Omitting this variable is incorrect and will result in an error! +This time our *view* is given an extra parameter, `pk`. Our *view* needs to catch it, right? So we will define our function as `def post_detail(request, pk):`. Note that this parameter must have the exact same name as the one we specified in `urls` (`pk`). Also note that omitting this variable is incorrect and will result in an error! + Now, we want to get one and only one blog post. To do this, we can use querysets, like this: -{% filename %}blog/views.py{% endfilename %} +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} ```python Post.objects.get(pk=pk) ``` @@ -94,7 +108,7 @@ But this code has a problem. If there is no `Post` with the given `primary key` ![DoesNotExist error](images/does_not_exist2.png) -We don't want that! But, of course, Django comes with something that will handle that for us: `get_object_or_404`. In case there is no `Post` with the given `pk`, it will display much nicer page, the `Page Not Found 404` page. +We don't want that! But luckily Django comes with something that will handle that for us: `get_object_or_404`. In case there is no `Post` with the given `pk`, it will display much nicer page, the `Page Not Found 404` page. ![Page not found](images/404_2.png) @@ -102,7 +116,9 @@ The good news is that you can actually create your own `Page not found` page and OK, time to add a *view* to our `views.py` file! -We should open `blog/views.py` and add the following code near the other `from` lines: +In `blog/urls.py` we created a URL rule named `post_detail` that refers to a view called `views.post_detail`. This means that Django will be expecting a view function called `post_detail` inside `blog/views.py`. + +We should open `blog/views.py` in the code editor and add the following code near the other `from` lines: {% filename %}blog/views.py{% endfilename %} ```python @@ -130,30 +146,30 @@ Oh no! Another error! But we already know how to deal with it, right? We need to ## Create a template for the post details -We will create a file in `blog/templates/blog` called `post_detail.html`. +We will create a file in `blog/templates/blog` called `post_detail.html`, and open it in the code editor. -It will look like this: +Enter the following code: {% 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 %} ``` Once again we are extending `base.html`. In the `content` block we want to display a post's published_date (if it exists), title and text. But we should discuss some important things, right? -{% raw %}`{% if ... %} ... {% endif %}` is a template tag we can use when we want to check something. (Remember `if ... else ..` from __Introduction to Python__ chapter?) In this scenario we want to check if a post's `published_date` is not empty.{% endraw %} +{% raw %}`{% if ... %} ... {% endif %}` is a template tag we can use when we want to check something. (Remember `if ... else ...` from __Introduction to Python__ chapter?) In this scenario we want to check if a post's `published_date` is not empty.{% endraw %} OK, we can refresh our page and see if `TemplateDoesNotExist` is gone now. @@ -161,14 +177,15 @@ OK, we can refresh our page and see if `TemplateDoesNotExist` is gone now. Yay! It works! -## One more thing: deploy time! -It'd be good to see if your website will still be working on PythonAnywhere, right? Let's try deploying again. +# Deploy time! + +It'd be good to see if your website still works on PythonAnywhere, right? Let's try deploying again. {% filename %}command-line{% endfilename %} ``` $ git status -$ git add --all . +$ git add . $ git status $ git commit -m "Added view and template for detailed blog post as well as CSS for the site." $ git push @@ -176,13 +193,31 @@ $ git push Then, in a [PythonAnywhere Bash console](https://www.pythonanywhere.com/consoles/): -{% filename %}command-line{% endfilename %} +{% filename %}PythonAnywhere command-line{% endfilename %} ``` -$ cd my-first-blog +$ cd ~/.pythonanywhere.com $ git pull [...] ``` -Finally, hop on over to the [Web tab](https://www.pythonanywhere.com/web_app_setup/) and hit **Reload**. +(Remember to substitute `` with your actual PythonAnywhere subdomain, without the angle-brackets.) + + +## Updating the static files on the server + +Servers like PythonAnywhere like to treat "static files" (like CSS files) differently from Python files, because they can optimise for them to be loaded faster. As a result, whenever we make changes to our CSS files, we need to run an extra command on the server to tell it to update them. The command is called `collectstatic`. + +Start by activating your virtualenv if it's not still active from earlier (PythonAnywhere uses a command called `workon` to do this, it's just like the `source myenv/bin/activate` command you use on your own computer): + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ workon .pythonanywhere.com +(ola.pythonanywhere.com)$ python manage.py collectstatic +[...] +``` + +The `manage.py collectstatic` command is a bit like `manage.py migrate`. We make some changes to our code, and then we tell Django to _apply_ those changes, either to the server's collection of static files, or to the database. + +In any case, we're now ready to hop on over to the ["Web" page](https://www.pythonanywhere.com/web_app_setup/) (from the menu button in the upper right of the console) and hit **Reload**, and then look at the https://subdomain.pythonanywhere.com page to see the result. -And that should be it! Congrats :) +And that should be it. Congrats! :) diff --git a/en/extend_your_application/images/404_2.png b/en/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/en/extend_your_application/images/404_2.png and b/en/extend_your_application/images/404_2.png differ diff --git a/en/extend_your_application/images/attribute_error2.png b/en/extend_your_application/images/attribute_error2.png deleted file mode 100644 index 05296adf4a5..00000000000 Binary files a/en/extend_your_application/images/attribute_error2.png and /dev/null differ diff --git a/en/extend_your_application/images/does_not_exist2.png b/en/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/en/extend_your_application/images/does_not_exist2.png and b/en/extend_your_application/images/does_not_exist2.png differ diff --git a/en/extend_your_application/images/no_reverse_match2.png b/en/extend_your_application/images/no_reverse_match2.png index 306926206f8..aba1c9c8980 100644 Binary files a/en/extend_your_application/images/no_reverse_match2.png and b/en/extend_your_application/images/no_reverse_match2.png differ diff --git a/en/extend_your_application/images/post_detail2.png b/en/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/en/extend_your_application/images/post_detail2.png and b/en/extend_your_application/images/post_detail2.png differ diff --git a/en/extend_your_application/images/post_list2.png b/en/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/en/extend_your_application/images/post_list2.png and b/en/extend_your_application/images/post_list2.png differ diff --git a/en/extend_your_application/images/template_does_not_exist2.png b/en/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/en/extend_your_application/images/template_does_not_exist2.png and b/en/extend_your_application/images/template_does_not_exist2.png differ diff --git a/en/how_the_internet_works/README.md b/en/how_the_internet_works/README.md index cfcc8482452..ad7bc9cce29 100644 --- a/en/how_the_internet_works/README.md +++ b/en/how_the_internet_works/README.md @@ -2,14 +2,14 @@ > For readers at home: this chapter is covered in the [How the Internet Works](https://www.youtube.com/watch?v=oM9yAA09wdc) video. -> This chapter is inspired by the talk "How the Internet works" by Jessica McKellar (http://web.mit.edu/jesstess/www/). +> This chapter is inspired by the talk "How the Internet works" by Jessica McKellar (https://web.mit.edu/jesstess/www/). We bet you use the Internet every day. But do you actually know what happens when you type an address like https://djangogirls.org into your browser and press `enter`? -The first thing you need to understand is that a website is just a bunch of files saved on a hard disk. Just like your movies, music, or pictures. +The first thing you need to understand is that a website consists of a bunch of files saved on a hard disk -- just like your movies, music, or pictures. However, there is one part that is unique for websites: they include computer code called HTML. -If you're not familiar with programming it can be hard to grasp HTML at first, but your web browsers (like Chrome, Safari, Firefox, etc.) love it. Web browsers are designed to understand this code, +If you're not familiar with programming, it can be hard to grasp HTML at first, but your web browsers (like Chrome, Safari, Firefox, etc.) love it. Web browsers are designed to understand this code, follow its instructions, and present these files that your website is made of, exactly the way you want. As with every file, we need to store HTML files somewhere on a hard disk. For the Internet, we use special, powerful computers called *servers*. They don't have @@ -21,11 +21,11 @@ We drew you a picture! It looks like this: ![Figure 1.1](images/internet_1.png) -Looks like a mess, right? In fact it is a network of connected machines (the above-mentioned *servers*). Hundreds of thousands of machines! Many, many kilometers of cables around the world! You can visit a Submarine Cable Map website (http://submarinecablemap.com) to see how complicated the net is. Here is a screenshot from the website: +Looks like a mess, right? In fact it is a network of connected machines (the above-mentioned *servers*). Hundreds of thousands of machines! Many, many kilometers of cables around the world! You can visit a Submarine Cable Map website (https://submarinecablemap.com) to see how complicated the net is. Here is a screenshot from the website: ![Figure 1.2](images/internet_3.png) -It is fascinating, isn't it? But obviously, it is not possible to have a wire between every machine connected to the Internet. So, to reach a machine (for example, the one where https://djangogirls.org is saved) we need to pass a request through many, many different machines. +It is fascinating, isn't it? But it is not possible to have a wire between every machine connected to the Internet. So, to reach a machine (for example, the one where https://djangogirls.org is saved) we need to pass a request through many, many different machines. It looks like this: @@ -37,9 +37,9 @@ Your letter goes to the post office closest to you. Then it goes to another that ![Figure 1.4](images/internet_4.png) -Yes, it is as simple as that. You send messages and you expect some response. Of course, instead of paper and pen you use bytes of data, but the idea is the same! +That's how it works - you send messages and you expect some response. Instead of paper and pen you use bytes of data, but the idea is the same! -Instead of addresses with a street name, city, zip code and country name, we use IP addresses. Your computer first asks the DNS (Domain Name System) to translate djangogirls.org into an IP address. It works a little bit like old-fashioned phonebooks where you can look up the name of the person you want to contact and find their phone number and address. +Instead of addresses with a street name, city, zip code and country name, we use IP addresses. Your computer first asks the DNS (Domain Name System) to translate `djangogirls.org` into an IP address. It works a little bit like old-fashioned phonebooks where you can look up the name of the person you want to contact and find their phone number and address. When you send a letter, it needs to have certain features to be delivered correctly: an address, a stamp, etc. You also use a language that the receiver understands, right? The same applies to the *data packets* you send to see a website. We use a protocol called HTTP (Hypertext Transfer Protocol). diff --git a/en/how_the_internet_works/images/internet_1.png b/en/how_the_internet_works/images/internet_1.png index 9c5bcf0b003..e289eac2b23 100644 Binary files a/en/how_the_internet_works/images/internet_1.png and b/en/how_the_internet_works/images/internet_1.png differ diff --git a/en/how_the_internet_works/images/internet_2.png b/en/how_the_internet_works/images/internet_2.png index dd5861f376f..e8cf8b77999 100644 Binary files a/en/how_the_internet_works/images/internet_2.png and b/en/how_the_internet_works/images/internet_2.png differ diff --git a/en/how_the_internet_works/images/internet_3.png b/en/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/en/how_the_internet_works/images/internet_3.png and b/en/how_the_internet_works/images/internet_3.png differ diff --git a/en/how_the_internet_works/images/internet_4.png b/en/how_the_internet_works/images/internet_4.png index 2661cec1b61..d4748ac48ef 100644 Binary files a/en/how_the_internet_works/images/internet_4.png and b/en/how_the_internet_works/images/internet_4.png differ diff --git a/en/html/README.md b/en/html/README.md index 10013ea29ea..a3dd63d8cee 100644 --- a/en/html/README.md +++ b/en/html/README.md @@ -2,13 +2,13 @@ What's a template, you may ask? -A template is a file that we can re-use to present different information in a consistent format – for example, you could use a template to help you write a letter, because although each letter might contain a different message and be addressed to a different person, they will share the same format. +A template is a file that we can re-use to present different information in a consistent format – for example, you could use a template to help you write a letter because although each letter might contain a different message and be addressed to a different person, they will share the same format. A Django template's format is described in a language called HTML (that's the HTML we mentioned in the first chapter, __How the Internet works__). ## What is HTML? -HTML is a simple code that is interpreted by your web browser – such as Chrome, Firefox or Safari – to display a web page for the user. +HTML is a code that is interpreted by your web browser – such as Chrome, Firefox or Safari – to display a web page for the user. HTML stands for "HyperText Markup Language". __HyperText__ means it's a type of text that supports hyperlinks between pages. __Markup__ means we have taken a document and marked it up with code to tell something (in this case, a browser) how to interpret the page. HTML code is built with __tags__, each one starting with `<` and ending with `>`. These tags represent markup __elements__. @@ -24,25 +24,28 @@ blog └───blog ``` -(You might wonder why we need two directories both called `blog` – as you will discover later, this is simply a useful naming convention that makes life easier when things start to get more complicated.) +(You might wonder why we need two directories both called `blog` – as you will discover later, this is a useful naming convention that makes life easier when things start to get more complicated.) And now create a `post_list.html` file (just leave it blank for now) inside the `blog/templates/blog` directory. See how your website looks now: http://127.0.0.1:8000/ -> If you still have an error `TemplateDoesNotExist`, try to restart your server. Go into command line, stop the server by pressing Ctrl+C (Control and C buttons together) and start it again by running a `python manage.py runserver` command. +> If you still have an error `TemplateDoesNotExist`, try to restart your server. Go to the command line, stop the server by pressing Ctrl+C (Control and C keys together) and start it again by running a `python manage.py runserver` command. ![Figure 11.1](images/step1.png) -No error anymore! Congratulations :) However, your website isn't actually publishing anything except an empty page, because your template is empty too. We need to fix that. +No error anymore! Congratulations! :) However, your website isn't actually publishing anything except an empty page, because your template is empty too. We need to fix that. -Add the following to your template file: +Open the new file in the code editor, and add the following: {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + +

Hi there!

It works!

+ ``` @@ -50,9 +53,10 @@ So how does your website look now? Visit it to find out: http://127.0.0.1:8000/ ![Figure 11.2](images/step3.png) -It worked! Nice work there :) +It worked. Nice work there! :) -- The most basic tag, ``, is always the beginning of any web page and `` is always the end. As you can see, the whole content of the website goes between the beginning tag `` and closing tag `` +- The line `` is not a HTML tag. It only declares the document type. Here, it informs the browser that document type is [HTML5](https://html.spec.whatwg.org/#the-doctype). This is always the beginning of any HTML5 file. +- The most basic tag, ``, is always the beginning of html content and `` is always the end. As you can see, the whole content of the website goes between the beginning tag `` and closing tag `` - `

` is a tag for paragraph elements; `

` closes each paragraph ## Head and body @@ -69,6 +73,7 @@ For example, you can put a web page title element inside the ``, like this {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + Ola's blog @@ -102,43 +107,52 @@ You can now have a little fun and try to customize your template! Here are a few - `

A paragraph of text

` - `text` emphasizes your text - `text` strongly emphasizes your text -- `
` goes to another line (you can't put anything inside br) +- `
` goes to another line (you can't put anything inside br and there's no closing tag) - `link` creates a link - `
  • first item
  • second item
` makes a list, just like this one! - `
` defines a section of the page +- `` defines a set of navigation links +- `
` specifies independent, self-contained content +- `
` defines a section in a document +- `
` specifies a header for a document or section +- `
` specifies the main content of a document +- `` defines some content aside from the content it is placed in (like a sidebar) +- `
` defines a footer for a document or section +- `` defines a specific time (or datetime) Here's an example of a full template, copy and paste it into `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.

-
+ ``` -We've created three `div` sections here. +We've created one `header` section and two `article` section here. -- The first `div` element contains the title of our blog – it's a heading and a link -- Another two `div` elements contain our blogposts with a published date, `h2` with a post title that is clickable and two `p`s (paragraph) of text, one for the date and one for our blogpost. +- The `header` element contains the title of our blog – it's a heading and a link +- The two `article` elements contain our blog posts with a published date in a `time` element, a `h2` element with a post title that is clickable and a `p` (paragraph) element for text of our blog post. It gives us this effect: @@ -152,7 +166,7 @@ What we really want to do is display real posts added in our Django admin – an It'd be good to see all this out and live on the Internet, right? Let's do another PythonAnywhere deploy: -### Commit, and push your code up to Github +### Commit, and push your code up to GitHub First off, let's see what files have changed since we last deployed (run these commands locally, not on PythonAnywhere): @@ -161,15 +175,13 @@ First off, let's see what files have changed since we last deployed (run these c $ git status ``` -Make sure you're in the `djangogirls` directory and let's tell `git` to include all the changes within this directory: +Make sure you're in the `djangogirls` directory and let's tell `git` to include all the changes in this directory: {% filename %}command-line{% endfilename %} ``` -$ git add --all . +$ git add . ``` -> __Note__ `--all` means that `git` will also recognize if you've deleted files (by default, it only recognizes new/modified files). Also remember (from chapter 3) that `.` means the current directory. - Before we upload all the files, let's check what `git` will be uploading (all the files that `git` will upload should now appear in green): {% filename %}command-line{% endfilename %} @@ -177,7 +189,7 @@ Before we upload all the files, let's check what `git` will be uploading (all th $ git status ``` -We're almost there, now it's time to tell it to save this change in its history. We're going to give it a "commit message" where we describe what we've changed. You can type anything you'd like at this stage, but it's helpful to type something descriptive so that you can remember what you've done in the future. +We're almost there, now it's time to tell it to save this change in its history. We're going to give it a "commit message" where we describe what we've changed. You can type anything you'd like at this stage, but it's helpful to type something descriptive so that, in the future, you can remember what you've done. {% filename %}command-line{% endfilename %} ``` @@ -197,16 +209,18 @@ $ git push * Open up the [PythonAnywhere consoles page](https://www.pythonanywhere.com/consoles/) and go to your **Bash console** (or start a new one). Then, run: -{% filename %}command-line{% endfilename %} +{% filename %}PythonAnywhere command-line{% endfilename %} ``` -$ cd ~/my-first-blog +$ cd ~/.pythonanywhere.com $ git pull [...] ``` -And watch your code get downloaded. If you want to check that it's arrived, you can hop over to the **Files tab** and view your code on PythonAnywhere. +You'll need to substitute `` with your actual PythonAnywhere subdomain name, without the angle-brackets. Your subdomain name is normally your PythonAnywhere user name, but in some cases it might be a bit different (such as if your user name contains capital letters). So if this command doesn't work, use the `ls` (list files) command to find your actual subdomain/folder name, and then `cd` to there. + +Now watch your code getting downloaded. If you want to check that it's arrived, you can hop over to the **"Files" page** and view your code on PythonAnywhere (you can reach other PythonAnywhere pages from the menu button on the console page). -* Finally, hop on over to the [Web tab](https://www.pythonanywhere.com/web_app_setup/) and hit **Reload** on your web app. +* Finally, hop on over to the ["Web" page](https://www.pythonanywhere.com/web_app_setup/) and hit **Reload** on your web app. Your update should be live! Go ahead and refresh your website in the browser. Changes should be visible. :) diff --git a/en/html/images/step1.png b/en/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/en/html/images/step1.png and b/en/html/images/step1.png differ diff --git a/en/html/images/step3.png b/en/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/en/html/images/step3.png and b/en/html/images/step3.png differ diff --git a/en/html/images/step4.png b/en/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/en/html/images/step4.png and b/en/html/images/step4.png differ diff --git a/en/html/images/step6.png b/en/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/en/html/images/step6.png and b/en/html/images/step6.png differ diff --git a/en/images/application.png b/en/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/en/images/application.png and b/en/images/application.png differ diff --git a/en/installation/README.md b/en/installation/README.md index 9f929e157bc..32d8b16c4ea 100644 --- a/en/installation/README.md +++ b/en/installation/README.md @@ -1,37 +1,65 @@ # If you're doing the tutorial at home -If you're doing the tutorial at home, not at one of the [Django Girls events](https://djangogirls.org/events/), you can completely skip this chapter now and go straight to the [How the Internet works?](../how_the_internet_works/README.md) chapter. +If you're doing the tutorial at home, not at one of the [Django Girls events](https://djangogirls.org/events/), you can completely skip this chapter now and go straight to the [How the Internet works](../how_the_internet_works/README.md) chapter. -This is because we cover these things in the whole tutorial anyway, and this is just an additional page that gathers all of the installation instructions in one place. The Django Girls event includes one "Installation evening" where we install everything so we don't need to bother with it during the workshop, so this is useful for us. - -If you find it useful, you can follow through this chapter too. But if you want to start learning things before installing a bunch of stuff on your computer, skip this chapter and we will explain the installation part to you later on. +This is because we cover installing things as they are needed in the tutorial -- this is just an additional page that gathers all of the installation instructions in one place (which is useful for some workshop formats). You can choose to install everything that is on this page right now if you wish. But if you want to start learning things before installing a bunch of stuff on your computer, skip this chapter and we will explain the installation parts to you later on, as they are needed. Good luck! +# If you're attending a workshop + +If you are attending one of the [Django Girls events](https://djangogirls.org/events/): +- Your workshop may have an "installation party" before the main workshop. If you are at an installation party, this page is for you! Follow the instructions here to get everything you need for the workshop installed, with the help of the coaches if needed. Then at the main workshop, you'll be able to skip installation instructions you'll encounter in the main tutorial when you get to them. +- The organizers of your workshop may have asked you to try at home to install everything on your computer before the workshop starts. If you have been asked to do that, this page is for you! Follow the instructions here, as best you can. Then at the main workshop, when you get to an installation step in the main tutorial, if you were not able to get that piece installed you can get help from your coach. +- If your workshop does not have an installation party (or you couldn't attend), and if the organizers didn't ask you to try to install everything before you arrived, skip this page and go straight to the [How the Internet works](../how_the_internet_works/README.md) chapter. You'll be installing everything you need as you work through the tutorial. + # Installation -In the workshop you will be building a blog, and there are a few setup tasks in the tutorial which would be good to work through beforehand so that you are ready to start coding on the day. +In this tutorial you will be building a blog. In order to do that, as you go through the tutorial you'll be instructed on how to +install various software on your computer and set up some online accounts as needed (if you are using local desktop environment) or instructed on how to create online accounts only (if you are using cloud development). This page gathers all of the installation and sign-up instructions in one place (which is useful for some workshop formats). + +# Chromebook Installation +To set up your Chromebook, follow the instructions below: {% include "/chromebook_setup/instructions.md" %} -# Install Python -{% include "/python_installation/instructions.md" %} -# Set up virtualenv and install Django -{% include "/django_installation/instructions.md" %} +# macOS, Windows, Linux Installation {#macos-windows-linux} +If you are not using a Chromebook, your experience will be a little different as you need to download and install some software locally as well as set up online accounts. + +To install software on your machine, follow the instructions below: + +## Brief intro to the command line {#intro-command-line} +Many of the steps below reference the "console", "terminal", "command window", or "command line" -- these all mean the same thing: a window on your computer where you can enter commands. When you get to the main tutorial, you'll learn more about the command line. For now, the main thing you need to know is how to open a command window and what it looks like: + +{% include "/intro_to_command_line/open_instructions.md" %} -# Install a code editor +### The Command-line Prompt + +Now you know how to open a command line, +we just need to understand what the "prompt" is. + +{% include "/intro_to_command_line/prompt.md" %} + + +## Install Python {#python} +{% include "/python_installation/instructions.md" %} + +## Install a code editor {#code-editor} {% include "/code_editor/instructions.md" %} -# Install Git +## Set up virtualenv and install Django {#virtualenv} +{% include "/django_installation/instructions.md" %} + +## Install Git {#git} {% include "/deploy/install_git.md" %} -# Create a GitHub account -Go to [GitHub.com](https://www.github.com) and sign up for a new, free user account. +## Create a GitHub account {#github-account} +Go to [GitHub.com](https://www.github.com) and sign up for a new, free user account. Be sure to remember your password (add it to your password manager, if you use one). -# Create a PythonAnywhere account +## Create a PythonAnywhere account {#pythonanywhere-account} {% include "/deploy/signup_pythonanywhere.md" %} diff --git a/en/intro_to_command_line/README.md b/en/intro_to_command_line/README.md index 04876858c79..49a9ca358ac 100644 --- a/en/intro_to_command_line/README.md +++ b/en/intro_to_command_line/README.md @@ -18,65 +18,21 @@ The window, which is usually called the __command line__ or __command-line inter To start some experiments we need to open our command-line interface first. - - - -Go to Start menu → All Programs → Accessories → Command Prompt. - - - - - - -Go to Applications → Utilities → Terminal. - - - - - -It's probably under Applications → Accessories → Terminal, but that may depend on your system. If it's not there, just Google it. :) - - - -## Prompt +{% include "/intro_to_command_line/open_instructions.md" %} You now should see a white or black window that is waiting for your commands. - +### The command-line Prompt +{% include "/intro_to_command_line/prompt.md" %} -If you're on Mac or Linux, you probably see `$`, just like this: - -{% filename %}command-line{% endfilename %} -``` -$ -``` - - - - - -On Windows, it's a `>` sign, like this: - -{% filename %}command-line{% endfilename %} -``` -> -``` - -Each command will be prepended by this sign and one space, but you don't have to type it. Your computer will do it for you. :) - -> Just a small note: in your case there may be something like `C:\Users\ola>` or `Olas-MacBook-Air:~ ola$` before the prompt sign, and this is 100% OK. - -The part up to and including the `$` or the `>` is called the *command line prompt*, or *prompt* for short. It prompts you to input something there. - -In the tutorial, when we want you to type in a command, we will include the `$` or `>`, and occasionally more to the left. You can ignore the left part and just type in the command which starts after the prompt. ## Your first command (YAY!) -Let's start with something simple. Type this command: +Let's start by typing this command: - + {% filename %}command-line{% endfilename %} ``` @@ -86,7 +42,7 @@ $ whoami - + {% filename %}command-line{% endfilename %} ``` @@ -109,13 +65,17 @@ As you can see, the computer has just printed your username. Neat, huh? :) ## Basics -Each operating system has a slightly different set of commands for the command line, so make sure to follow instructions for your operating system. Let's try this, shall we? +Each operating system has a slightly different set of commands for the command line, so make sure to follow instructions for your operating system. + +If you make a typo, you can use the left and right arrow keys to move your cursor, backspace and delete to edit the command. Most command lines don't support using the mouse to move the cursor. + +Let's try this, shall we? ### Current directory It'd be nice to know where are we now, right? Let's see. Type this command and hit `enter`: - + {% filename %}command-line{% endfilename %} @@ -129,14 +89,14 @@ $ pwd - + {% filename %}command-line{% endfilename %} ``` > cd C:\Users\olasitarska ``` -> Note: 'cd' stands for 'current directory'. +> Note: 'cd' stands for 'change directory'. With PowerShell you can use pwd just like on Linux or macOS. @@ -144,11 +104,29 @@ You'll probably see something similar on your machine. Once you open the command --- +### Learn more about a command + +Many commands you can type at the command prompt have built-in help that you can display and read! For example, to learn more about the current directory command: + + + +macOS and Linux have a `man` command, which gives you help on commands. Try `man pwd` and see what it says, or put `man` before other commands to see their help. The output of `man` is normally paged. Use the space bar to move to the next page, and `q` to quit looking at the help. + + + + + + +Adding a `/?` suffix to most commands will print the help page. You may need to scroll your command window up to see it all. Try `cd /?`. + + + + ### List files and directories So what's in it? It'd be cool to find out. Let's see: - + {% filename %}command-line{% endfilename %} ``` @@ -161,19 +139,20 @@ Music ``` - + {% 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 ... ``` +> Note: In PowerShell you can also use 'ls' like on Linux and macOS. --- @@ -182,7 +161,7 @@ Music Now, let's go to our Desktop directory: - + {% filename %}command-line{% endfilename %} ``` @@ -190,7 +169,23 @@ $ cd Desktop ``` - + + +{% filename %}command-line{% endfilename %} +``` +$ cd Desktop +``` + +Note that +the directory name "Desktop" might be translated +to the language of your Linux account. +If that's the case, you'll need to replace `Desktop` +with the translated name; +for example, `Schreibtisch` for German. + + + + {% filename %}command-line{% endfilename %} @@ -201,7 +196,7 @@ $ cd Desktop Check if it's really changed: - + {% filename %}command-line{% endfilename %} ``` @@ -210,7 +205,7 @@ $ pwd ``` - + {% filename %}command-line{% endfilename %} ``` @@ -221,7 +216,7 @@ C:\Users\olasitarska\Desktop Here it is! -> PRO tip: if you type `cd D` and then hit `tab` on your keyboard, the command line will automatically fill in the rest of the name so you can navigate faster. If there is more than one folder starting with "D", hit the `tab` button twice to get a list of options. +> PRO tip: if you type `cd D` and then hit `tab` on your keyboard, the command line will automatically fill in the rest of the name so you can navigate faster. If there is more than one folder starting with "D", hit the `tab` key twice to get a list of options. --- @@ -229,7 +224,7 @@ Here it is! How about creating a practice directory on your desktop? You can do it this way: - + {% filename %}command-line{% endfilename %} ``` @@ -237,7 +232,7 @@ $ mkdir practice ``` - + {% filename %}command-line{% endfilename %} @@ -246,7 +241,7 @@ $ mkdir practice ``` -This little command will create a folder with the name `practice` on your desktop. You can check if it's there just by looking on your Desktop or by running a `ls` or `dir` command! Try it. :) +This little command will create a folder with the name `practice` on your desktop. You can check if it's there by looking on your Desktop or by running a `ls` or `dir` command! Try it. :) > PRO tip: If you don't want to type the same commands over and over, try pressing the `up arrow` and `down arrow` on your keyboard to cycle through recently used commands. @@ -258,7 +253,7 @@ A small challenge for you: in your newly created `practice` directory, create a #### Solution: - + {% filename %}command-line{% endfilename %} ``` @@ -269,7 +264,7 @@ test ``` - + {% filename %}command-line{% endfilename %} @@ -277,7 +272,7 @@ test > cd practice > mkdir test > dir -05/08/2014 07:28 PM test +05/08/2020 07:28 PM test ``` @@ -291,7 +286,7 @@ We don't want to leave a mess, so let's remove everything we did until that poin First, we need to get back to Desktop: - + {% filename %}command-line{% endfilename %} ``` @@ -299,7 +294,7 @@ $ cd .. ``` - + {% filename %}command-line{% endfilename %} @@ -312,7 +307,7 @@ Using `..` with the `cd` command will change your current directory to the paren Check where you are: - + {% filename %}command-line{% endfilename %} ``` @@ -321,7 +316,7 @@ $ pwd ``` - + {% filename %}command-line{% endfilename %} @@ -335,7 +330,7 @@ Now time to delete the `practice` directory: > __Attention__: Deleting files using `del`, `rmdir` or `rm` is irrecoverable, meaning _the deleted files will be gone forever_! So be very careful with this command. - + {% filename %}command-line{% endfilename %} ``` @@ -343,7 +338,7 @@ $ rm -r practice ``` - + {% filename %}command-line{% endfilename %} @@ -355,7 +350,7 @@ practice, Are you sure ? Y Done! To be sure it's actually deleted, let's check it: - + {% filename %}command-line{% endfilename %} ``` @@ -363,7 +358,7 @@ $ ls ``` - + {% filename %}command-line{% endfilename %} @@ -376,7 +371,7 @@ $ ls That's it for now! You can safely close the command line now. Let's do it the hacker way, alright? :) - + {% filename %}command-line{% endfilename %} ``` @@ -384,7 +379,7 @@ $ exit ``` - + {% filename %}command-line{% endfilename %} @@ -410,10 +405,11 @@ move | mv | move file | **mo mkdir | mkdir | create a new directory | **mkdir testdirectory** rmdir (or del) | rm | delete a file | **del c:\test\test.txt** rmdir /S | rm -r | delete a directory | **rm -r testdirectory** +[CMD] /? | man [CMD] | get help for a command | **cd /?** (Windows) or **man cd** (Mac OS / Linux) These are just a very few of the commands you can run in your command line, but you're not going to use anything more than that today. -If you're curious, [ss64.com](http://ss64.com) contains a complete reference of commands for all operating systems. +If you're curious, [ss64.com](https://ss64.com) contains a complete reference of commands for all operating systems. ## Ready? diff --git a/en/intro_to_command_line/open_instructions.md b/en/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..75ac139f269 --- /dev/null +++ b/en/intro_to_command_line/open_instructions.md @@ -0,0 +1,27 @@ + + +Go to Launchpad → Other → Terminal. + + + + + +It's probably under Applications → Accessories → Terminal, or Applications → System → Terminal, but that may depend on your system. If it's not there, you can try to Google it. :) + + + + + +Depending on your version of Windows and your keyboard, one of the following should open a command window (you may have to experiment a bit, but you don't have to try all of these suggestions): +- Go to the Start menu or screen, and enter "Command Prompt" in the search field. +- Go to Start menu → Windows System → Command Prompt. +- Go to Start menu → All Programs → Accessories → Command Prompt. +- Go to the Start screen, hover your mouse in the lower-left corner of the screen, and click the down arrow that appears (on a touch screen, instead flick up from the bottom of the screen). The Apps page should open. Click on Command Prompt in the Windows System section. +- Hold the special Windows key on your keyboard and press the "X" key. Choose "Command Prompt" from the pop-up menu. +- Hold the Windows key and press the "R" key to get a "Run" window. Type "cmd" in the box, and click the OK key. + +![Type "cmd" in the "Run" window](../python_installation/images/windows-plus-r.png) + +Later in this tutorial, you will need to have two command windows open at the same time. However, on some versions of Windows, if you already have one command window open and you try to open a second one using the same method, it will instead point you to the command window you already have open. Try it now on your computer and see what happens! If you only get one command window, try one of the other methods in the list above. At least one of them should result in a new command window being opened. + + diff --git a/en/intro_to_command_line/prompt.md b/en/intro_to_command_line/prompt.md new file mode 100644 index 00000000000..8c0c2ca7aac --- /dev/null +++ b/en/intro_to_command_line/prompt.md @@ -0,0 +1,32 @@ + + + +If you're on Mac or Linux, you probably see a `$`, like this: + +{% filename %}command-line{% endfilename %} +``` +$ +``` + + + + + +On Windows, you probably see a `>`, like this: + +{% filename %}command-line{% endfilename %} +``` +> +``` + +Take a look at the Linux section just above now -- you'll see something more like that when you get to PythonAnywhere later in the tutorial. + + + +Each command will be prepended by a `$` or `>` and one space, but you should not type it. Your computer will do it for you. :) + +> Just a small note: in your case there may be something like `C:\Users\ola>` or `Olas-MacBook-Air:~ ola$` before the prompt sign, and this is 100% OK. + +The part up to and including the `$` or the `>` is called the *command line prompt*, or *prompt* for short. It prompts you to input something there. + +In the tutorial, when we want you to type in a command, we will include the `$` or `>`, and occasionally more to the left. Ignore the left part and only type in the command, which starts after the prompt. diff --git a/en/python_installation/README.md b/en/python_installation/README.md index 2b674d8d2c9..c2d343ec52b 100644 --- a/en/python_installation/README.md +++ b/en/python_installation/README.md @@ -4,13 +4,13 @@ We're finally here! But first, let us tell you what Python is. Python is a very popular programming language that can be used for creating websites, games, scientific software, graphics, and much, much more. -Python originated in the late 1980s and its main goal is to be readable by human beings (not only machines!). This is why it looks much simpler than other programming languages. This makes it easy to learn, but don't worry – Python is also really powerful! +Python originated in the late 1980s and its main goal is to be readable by human beings (not only machines!). This is why it looks simpler than other programming languages, but don't worry – Python is also really powerful! # Python installation > **Note** If you're using a Chromebook, skip this chapter and make sure you follow the [Chromebook Setup](../chromebook_setup/README.md) instructions. -> **Note** If you already worked through the Installation steps, there's no need to do this again – you can skip straight ahead to the next chapter! +> **Note** If you already worked through the [installation steps](../installation/README.md), there's no need to do this again – you can skip straight ahead to the next chapter! {% include "/python_installation/instructions.md" %} diff --git a/en/python_installation/images/add_python_to_windows_path.png b/en/python_installation/images/add_python_to_windows_path.png deleted file mode 100644 index 9510d6f2176..00000000000 Binary files a/en/python_installation/images/add_python_to_windows_path.png and /dev/null differ diff --git a/en/python_installation/images/python-installation-options.png b/en/python_installation/images/python-installation-options.png index 4cb886349a1..a6e9850cdc6 100644 Binary files a/en/python_installation/images/python-installation-options.png and b/en/python_installation/images/python-installation-options.png differ diff --git a/en/python_installation/images/windows-plus-r.png b/en/python_installation/images/windows-plus-r.png index d99a4d1ac20..4f8f7433381 100644 Binary files a/en/python_installation/images/windows-plus-r.png and b/en/python_installation/images/windows-plus-r.png differ diff --git a/en/python_installation/instructions.md b/en/python_installation/instructions.md index 9daadb7cd46..81bf30b727c 100644 --- a/en/python_installation/instructions.md +++ b/en/python_installation/instructions.md @@ -2,44 +2,45 @@ > This section is based on a tutorial by Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) -Django is written in Python. We need Python to do anything in Django. Let's start by installing it! We want you to install Python 3.5, so if you have any earlier version, you will need to upgrade it. +Django is written in Python. We need Python to do anything in Django. Let's start by installing it! We want you to install the latest version of Python 3, so if you have any earlier version, you will need to upgrade it. If you already have version {{ book.py_min_version }} or higher you should be fine. +Please install normal Python as follows, even when you have Anaconda installed on your computer. - + -First check whether your computer is running a 32-bit version or a 64-bit version of Windows at https://support.microsoft.com/en-au/kb/827218. You can download Python for Windows from the website https://www.python.org/downloads/windows/. Click on the "Latest Python 3 Release - Python x.x.x" link. If your computer is running a **64-bit** version of Windows, download the **Windows x86-64 executable installer**. Otherwise, download the **Windows x86 executable installer**. After downloading the installer, you should run it (double-click on it) and follow the instructions there. +First check whether your computer is running a 32-bit version or a 64-bit version of Windows, on the "System type" line of the System Info page. To reach this page, try one of these methods: +* Press the Windows key and Pause/Break key at the same time +* Open your Control Panel from the Windows menu, then navigate to System & Security, then System +* Press the Windows button, then navigate to Settings > System > About +* Search the Windows Start menu for "System Information". To do that, click the Start button or press the Windows key, then begin to type `System Information`. It will start making suggestions as soon as you type. You can select the entry once it shows up. -One thing to watch out for: During the installation you will notice a window marked "Setup". Make sure you tick the "Add Python 3.5 to PATH" checkbox and click on "Install Now", as shown here: +You can download Python for Windows from the website https://www.python.org/downloads/windows/. Click on the "Latest Python 3 Release - Python x.x.x" link. If your computer is running a **64-bit** version of Windows, download the **Windows x86-64 executable installer**. Otherwise, download the **Windows x86 executable installer**. After downloading the installer, you should run it (double-click on it) and follow the instructions there. -![Don't forget to add Python to the Path](../python_installation/images/python-installation-options.png) - -In upcoming steps, you'll be using the Windows Command Line (which we'll also tell you about). For now, if you need to type in some commands, go to Start menu → All Programs → Accessories → Command Prompt. You can also hold in the Windows key and press the "R"-key until the "Run" window pops up. To open the Command Line, type "cmd" and press enter in the "Run" window. (On newer versions of Windows, you might have to search for "Command Prompt" since it's sometimes hidden.) +One thing to watch out for: During the installation, you will notice a window marked "Setup". Make sure you tick the "Add Python {{ book.py_version }} to PATH" or 'Add Python to your environment variables" checkbox and click on "Install Now", as shown here (it may look a bit different if you are installing a different version): -![Type "cmd" in the "Run" window](../python_installation/images/windows-plus-r.png) +![Don't forget to add Python to the Path](../python_installation/images/python-installation-options.png) -Note: if you are using an older version of Windows (7, Vista, or any older version) and the Python 3.5.x installer fails with an error, you can try either: -1. install all Windows Updates and try to install Python 3.5 again; or -2. install an [older version of Python](https://www.python.org/downloads/windows/), e.g., [3.4.4](https://www.python.org/downloads/release/python-344/). +When the installation completes, you may see a dialog box with a link you can follow to learn more about Python or about the version you installed. Close or cancel that dialog -- you'll be learning more in this tutorial! -If you install an older version of Python, the installation screen may look a bit different than shown above. Make sure you scroll down to see "Add python.exe to Path", then click the button on the left and pick "Will be installed on local hard drive": +Note: If you are using an older version of Windows (7, Vista, or any older version) and the Python {{ book.py_version }} installer fails with an error, then install all Windows Updates and try to install Python again. If you still have the error, try installing Python version {{ book.py_min_release }} from [Python.org](https://www.python.org/downloads/windows/). -![Add Python to the Path, older versions](../python_installation/images/add_python_to_windows_path.png) +> Django {{ book.django_version }} needs Python {{ book.py_min_version }} or greater, which does not support Windows XP or earlier versions. - -> **Note** Before you install Python on OS X, you should ensure your Mac settings allow installing packages that aren't from the App Store. Go to System Preferences (it's in the Applications folder), click "Security & Privacy," and then the "General" tab. If your "Allow apps downloaded from:" is set to "Mac App Store," change it to "Mac App Store and identified developers." +> **Note** Before you install Python on macOS, you should ensure your Mac settings allow installing packages that aren't from the App Store. Go to System Preferences (it's in the Applications folder), click "Security & Privacy," and then the "General" tab. If your "Allow apps downloaded from:" is set to "Mac App Store," change it to "Mac App Store and identified developers." -You need to go to the website https://www.python.org/downloads/release/python-351/ and download the Python installer: +You need to go to the website https://www.python.org/downloads/ and download the latest Python installer: -* Download the *Mac OS X 64-bit/32-bit installer* file, -* Double click *python-3.5.1-macosx10.6.pkg* to run the installer. +* Download Python {{ book.py_release }}, +* Double click *python-{{ book.py_release }}-macos11.pkg* to run the installer. - It is very likely that you already have Python installed out of the box. To check if you have it installed (and which version it is), open a console and type the following command: @@ -47,40 +48,32 @@ It is very likely that you already have Python installed out of the box. To chec {% filename %}command-line{% endfilename %} ``` $ python3 --version -Python 3.5.1 +Python {{ book.py_release }} ``` -If you have a different 'micro version' of Python installed, e.g. 3.5.0, then you don't have to upgrade. If you don't have Python installed, or if you want a different version, you can install it as follows: - - - - - - -Type this command into your console: +If you have a different version of Python installed, at least {{ book.py_min_version }} (e.g. {{ book.py_min_release }}), then you don't have to upgrade. If you don't have Python installed, or if you want a different version, first check which Linux distribution you are using with the following command: {% filename %}command-line{% endfilename %} ``` -$ sudo apt-get install python3.5 +$ grep '^NAME=' /etc/os-release ``` - +Afterwards, depending on the result, follow one of the following installation guides below this section. - + + -Use this command in your console: +Type this command into your console: {% filename %}command-line{% endfilename %} ``` -$ sudo yum install python3 +$ sudo apt install python3 ``` - Use this command in your console: @@ -90,9 +83,11 @@ Use this command in your console: $ sudo dnf install python3 ``` +If you're on older Fedora versions you might get an error that the command `dnf` is not found. In that case, you need to use `yum` instead. + - Use this command in your console: @@ -104,15 +99,16 @@ $ sudo zypper install python3 -Verify the installation was successful by opening the *Terminal* application and running the `python3` command: +Verify the installation was successful by opening a command prompt and running the `python3` command: {% filename %}command-line{% endfilename %} ``` $ python3 --version -Python 3.5.1 +Python {{ book.py_release }} ``` +The version shown may be different from {{ book.py_release }} -- it should match the version you installed. -**NOTE:** If you're on Windows and you get an error message that `python3` wasn't found, try using `python` (without the `3`) and check if it still might be a version of Python 3.5. +**NOTE:** If you're on Windows and you get an error message that `python3` wasn't found, try using `python` (without the `3`) and check if it still might be a version of Python that is {{ book.py_min_version }} or higher. If that doesn't work either, you may open a new command prompt and try again; this happens if you use a command prompt that was opened before the Python installation. ---- diff --git a/en/python_introduction/README.md b/en/python_introduction/README.md index afa8945f2b1..e3798b6da3e 100644 --- a/en/python_introduction/README.md +++ b/en/python_introduction/README.md @@ -1,34 +1,20 @@ +{% set warning_icon = '' %} + # Introduction to Python > Part of this chapter is based on tutorials by Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). Let's write some code! -## 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 3.5.1 (...) -Type "help", "copyright", "credits" or "license" for more information. ->>> -``` +{% include "/python_introduction/prompt.md" %} ## Your first Python command! 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. -If you want to exit the Python console at any point, just type `exit()` or use the shortcut `Ctrl + Z` for Windows and `Ctrl + D` for Mac/Linux. Then you won't see `>>>` any longer. +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. -For now, we don't want to exit the Python console. We want to learn more about it. Let's start with something really simple. For example, try typing some math, like `2 + 3` and hit `enter`. +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`. {% filename %}command-line{% endfilename %} ```python @@ -99,7 +85,7 @@ or escaping the apostrophe with a backslash (`\`): "Runnin' down the hill" ``` -Nice, huh? To see your name in uppercase letters, simply type: +Nice, huh? To see your name in uppercase letters, type: {% filename %}command-line{% endfilename %} ```python @@ -134,7 +120,7 @@ These are the basics of every programming language you learn. Ready for somethin 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`: -{% filename %}command-line{% endfilename %} +{% filename %}{{ warning_icon }} command-line{% endfilename %} ```python >>> len(304023) Traceback (most recent call last): @@ -142,7 +128,9 @@ Traceback (most recent call last): TypeError: object of type 'int' has no len() ``` -We got our first error! 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? +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! + + 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? {% filename %}command-line{% endfilename %} ```python @@ -168,9 +156,9 @@ Let's say we want to create a new variable called `name`: >>> name = "Ola" ``` -You see? It's easy! It's simply: name equals Ola. +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? Simply enter `name` and hit `enter`: +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`: {% filename %}command-line{% endfilename %} ```python @@ -195,7 +183,7 @@ You can use it in functions too: 5 ``` -Awesome, right? Of course, variables can be anything – numbers too! Try this: +Awesome, right? Now, variables can be anything – numbers too! Try this: {% filename %}command-line{% endfilename %} ```python @@ -207,7 +195,7 @@ Awesome, right? Of course, variables can be anything – numbers too! Try this: But what if we used the wrong name? Can you guess what would happen? Let's try! -{% filename %}command-line{% endfilename %} +{% filename %}{{ warning_icon }} command-line{% endfilename %} ```python >>> city = "Tokyo" >>> ctiy @@ -292,7 +280,7 @@ Maybe we want to reverse that order? Let's do that! [59, 42, 30, 19, 12, 3] ``` -Easy, right? If you want to add something to your list, you can do this by typing this command: +If you want to add something to your list, you can do this by typing this command: {% filename %}command-line{% endfilename %} ```python @@ -322,6 +310,7 @@ To delete something from your list you will need to use __indexes__ as we learne >>> print(lottery[0]) 59 >>> lottery.pop(0) +59 >>> print(lottery) [42, 30, 19, 12, 3, 199] ``` @@ -371,7 +360,7 @@ See, it's similar to a list. But you don't need to remember the index – just t What happens if we ask Python the value of a key that doesn't exist? Can you guess? Let's try it and see! -{% filename %}command-line{% endfilename %} +{% filename %}{{ warning_icon }} command-line{% endfilename %} ```python >>> participant['age'] Traceback (most recent call last): @@ -381,33 +370,34 @@ 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. Just have a solution in mind before looking at the answer in the next line. +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. - Do you just need an ordered sequence of items? Go for a list. - Do you need to associate values with keys, so you can look them up efficiently (by key) later on? Use a dictionary. -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: +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: {% filename %}command-line{% endfilename %} ```python ->>> participant['favorite_language'] = 'Python' +>>> len(participant) +3 ``` -Like lists, using the `len()` method on the dictionaries returns the number of key–value pairs in the dictionary. Go ahead and type in this command: +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 %} ```python ->>> len(participant) -4 +>>> participant['favorite_language'] = 'Python' ``` I hope it makes sense up to now. :) Ready for some more fun with dictionaries? Read on for some amazing things. -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'`, just type in the following command: +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 %}command-line{% endfilename %} ```python >>> participant.pop('favorite_numbers') +[7, 42, 92] >>> participant {'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} ``` @@ -440,7 +430,7 @@ Excited for the next part? :) > 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, of course. Let's see how that works: +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 @@ -454,9 +444,11 @@ True True >>> 5 != 2 True +>>> len([1, 2, 3]) > len([4, 5]) +True ``` -We gave Python some numbers to compare. As you can see, not only can Python compare numbers, but it can also compare method results. Nice, huh? +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? 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. @@ -470,7 +462,7 @@ True False ``` -`>` and `<` are easy, but what do `>=` and `<=` mean? Read them like this: +We've seen `>` and `<`, but what do `>=` and `<=` mean? Read them like this: - x `>` y means: x is greater than y - x `<` y means: x is less than y @@ -496,12 +488,12 @@ You can give Python as many numbers to compare as you want, and it will give you Have you heard of the expression "comparing apples to oranges"? Let's try the Python equivalent: -{% filename %}command-line{% endfilename %} +{% filename %}{{ warning_icon }} command-line{% endfilename %} ```python >>> 1 > 'django' Traceback (most recent call last): File "", line 1, in -TypeError: unorderable types: int() > str() +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`). @@ -509,13 +501,13 @@ Instead, it shows a **TypeError** and tells us the two types can't be compared t ## Boolean -Incidentally, you just learned about a new type of object in Python. It's called __Boolean__, and it is probably the easiest type there is. +Incidentally, you just learned about a new type of object in Python. It's called __Boolean__. There are only two Boolean objects: - 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, of course.) +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: @@ -556,7 +548,7 @@ So far we've been writing all our python code in the interpreter, which limits u - Save some code into a new python file - Run it! -To exit from the Python interpreter that we've been using, simply type the `exit()` function +To exit from the Python interpreter that we've been using, type the `exit()` function {% filename %}command-line{% endfilename %} ```python @@ -566,7 +558,7 @@ $ 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: +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): {% filename %}editor{% endfilename %} ```python @@ -582,28 +574,54 @@ Now we need to save the file and give it a descriptive name. Let's call the file 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. + + On a Mac, the command will look something like this: {% filename %}command-line{% endfilename %} ``` $ cd ~/Desktop ``` + + + -On Linux, it will be like this (the word "Desktop" might be translated to your local language): +On Linux, it will be like this: {% filename %}command-line{% endfilename %} ``` $ cd ~/Desktop ``` -And on Windows, it will be like this: +(Remember that the word "Desktop" might be translated to your local language.) + + + + + +On Windows Command Prompt, it will be like this: {% filename %}command-line{% endfilename %} ``` > cd %HomePath%\Desktop ``` + + + + + +And on Windows Powershell, it will be like this: + +{% filename %}command-line{% endfilename %} +``` +> cd $Home\Desktop +``` + -If you get stuck, just ask for help. + +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: @@ -637,7 +655,7 @@ if 3 > 2: If we were to save and run this, we'd see an error like this: -{% filename %}command-line{% endfilename %} +{% filename %}{{ warning_icon }} command-line{% endfilename %} ``` $ python3 python_intro.py File "python_intro.py", line 2 @@ -653,7 +671,7 @@ if 3 > 2: print('It works!') ``` -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. +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: @@ -685,7 +703,7 @@ $ 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. Easy, right? Let's see how `elif` works: +If 2 were a greater number than 5, then the second command would be executed. Let's see how `elif` works: {% filename %}python_intro.py{% endfilename %} ```python @@ -770,7 +788,7 @@ Time for the last part of this chapter! 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 start with an easy one. Replace the code in **python_intro.py** with the following: +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 @@ -783,7 +801,7 @@ hi() Okay, our first function is ready! -You may wonder why we've written the name of the function at the bottom of the file. This is because Python reads the file and executes it from top to bottom. So in order to use our function, we have to re-write it at the bottom. +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: @@ -799,7 +817,7 @@ Note: if it didn't work, don't panic! The output will help you to figure why: - If you get an `IndentationError`, check that both of the `print` lines have the same whitespace at the start of a line: python wants all the code inside the function to be neatly aligned. - If there's no output at all, check that the last `hi()` *isn't* indented - if it is, that line will become part of the function too, and it will never get run. -Let's build our first function with parameters. We will use the previous example – a function that says 'hi' to the person running it – with a name: +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 @@ -823,7 +841,7 @@ hi() 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 %}command-line{% endfilename %} +{% filename %}{{ warning_icon }} command-line{% endfilename %} ``` $ python3 python_intro.py Traceback (most recent call last): @@ -873,7 +891,7 @@ 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? +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 @@ -915,7 +933,7 @@ We want to greet all of them by their name. We have the `hi` function to do that for name in girls: ``` -The ```for``` statement behaves similarly to the ```if``` statement; code below both of these need to be indented four spaces. +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: @@ -970,12 +988,15 @@ Which would print: `range` is a function that creates a list of numbers following one after the other (these numbers are provided by you as parameters). -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. +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. ## 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) diff --git a/en/python_introduction/images/cupcake.png b/en/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/en/python_introduction/images/cupcake.png and b/en/python_introduction/images/cupcake.png differ diff --git a/en/python_introduction/prompt.md b/en/python_introduction/prompt.md new file mode 100644 index 00000000000..27f422934c0 --- /dev/null +++ b/en/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/en/styles/website.css b/en/styles/website.css new file mode 100644 index 00000000000..917a9d65a50 --- /dev/null +++ b/en/styles/website.css @@ -0,0 +1,64 @@ + +/* add text to top menu items */ + +.book-header .fa::after { + text-transform: none; + font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; +} +.book-header .fa-align-justify::after { + content: ' Show Outline'; + text-transform: none; + font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; +} +.book.with-summary .book-header .fa-align-justify::after { + content: ' Hide Outline'; +} +.book-header .fa-globe::after { + content: ' Language'; +} +.book-header .fa-font::after { + content: ' Font Settings'; +} +@media (max-width:600px) { + .book-header .fa-font::after { + content: ' Font'; + } + .book-header .js-toolbar-action.pull-right { /* social sharing links */ + display: none; + } +} + +/* add text to the Next & Prev arrows */ + +.navigation-prev::after { + content: 'Previous'; + font-size: 20pt; + vertical-align: text-bottom; + line-height: 44px; +} +.navigation-next::after { + content: 'Next'; + font-size: 20pt; + vertical-align: text-bottom; + line-height: 44px; +} + +@media (max-width:1240px) { + /* on small viewports, the arrows are shown on the side, so move text around to look better */ + .navigation-next::after { + content: none; + } + .navigation-next::before { + content: 'Next'; + font-size: 20pt; + vertical-align: text-bottom; + line-height: 44px; + } +} + +/* fine tune text size to not overlap main body text on very specific viewport sizes */ +@media (min-width:1241px) and (max-width:1274px) { + .navigation-prev::after { + font-size: 16pt; + } +} diff --git a/en/template_extending/README.md b/en/template_extending/README.md index 17a13a46ce6..7fd9ab86ba7 100644 --- a/en/template_extending/README.md +++ b/en/template_extending/README.md @@ -18,39 +18,41 @@ blog post_list.html ``` -Then open it up and copy everything from `post_list.html` to `base.html` file, like this: +Then open it up in the code editor and copy everything from `post_list.html` to `base.html` file, like this: {% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} + Django Girls blog - - - + + - + -
+
-
+
{% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %}
-
+
``` @@ -60,17 +62,19 @@ Then in `base.html`, replace your whole `` (everything between `` an {% filename %}blog/templates/blog/base.html{% endfilename %} ```html - -
+ +
-
+
{% block content %} {% endblock %}
-
+
``` @@ -83,38 +87,38 @@ Then in `base.html`, replace your whole `` (everything between `` an ``` But why? You just created a `block`! You used the template tag `{% block %}` to make an area that will have HTML inserted in it. That HTML will come from another template that extends this template (`base.html`). We will show you how to do this in a moment. -Now save `base.html` and open your `blog/templates/blog/post_list.html` again. +Now save `base.html` and open your `blog/templates/blog/post_list.html` again in the code editor. {% raw %}You're going to remove everything above `{% for post in posts %}` and below `{% endfor %}`. When you're done, the file will look like this:{% endraw %} {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} ``` We want to use this as part of our template for all the content blocks. Time to add block tags to this file! -{% raw %}You want your block tag to match the tag in your `base.html` file. You also want it to include all the code that belongs in your content blocks. To do that, put everything between `{% block content %}` and `{% endblock content %}`. Like this:{% endraw %} +{% raw %}You want your block tag to match the tag in your `base.html` file. You also want it to include all the code that belongs in your content blocks. To do that, put everything between `{% block content %}` and `{% endblock %}`. Like this:{% endraw %} {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% block content %} {% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} {% endblock %} ``` @@ -127,17 +131,17 @@ Only one thing left. We need to connect these two templates together. This is w {% block content %} {% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} {% endblock %} ``` -That's it! Check if your website is still working properly. :) +That's it! Save the file, and check if your website is still working properly. :) > If you get the error `TemplateDoesNotExist`, that means that there is no `blog/base.html` file and you have `runserver` running in the console. Try to stop it (by pressing Ctrl+C – the Control and C keys together) and restart it by running a `python manage.py runserver` command. diff --git a/en/whats_next/README.md b/en/whats_next/README.md index 3b104f201b4..f4da68c799f 100644 --- a/en/whats_next/README.md +++ b/en/whats_next/README.md @@ -4,21 +4,37 @@ Congratulate yourself! __You're totally awesome__. We're proud! <3 ### What to do now? -Take a break and relax. You have just done something really huge. +Take a break and relax! You have just done something really huge. -After that, make sure to follow Django Girls on [Facebook](http://facebook.com/djangogirls) or [Twitter](https://twitter.com/djangogirls) to stay up to date. +After that, make sure to follow Django Girls on [Facebook](https://facebook.com/djangogirls) or [X](https://x.com/djangogirls) to stay up to date. ### Can you recommend any further resources? -Yes! First, go ahead and try our other book, called [Django Girls Tutorial: Extensions](https://djangogirls.gitbooks.io/django-girls-tutorial-extensions/content/). - -Later on, you can try the resources listed below. They're all very recommended! -- [Django's official tutorial](https://docs.djangoproject.com/en/1.10/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://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/) +Yes! There are a _lot_ of resources online for learning all kinds of programming skills – it can be pretty daunting to work out where to go next, but we've got you covered. Whatever your interests were before you came to Django Girls, and whatever interests you've developed throughout the tutorial, here are some free resources (or resources with large free components) you can use to get to where you want to be. + +#### Django +- Our other book, [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org/) +- [Django's official tutorial](https://docs.djangoproject.com/en/5.1/intro/tutorial01/) +- [Getting Started With Django video lessons](https://thekennethlove.com/videos/) +- [Django for Everybody Specialization](https://www.coursera.org/specializations/django) – some video lectures can be audited for free and you can earn a Coursera Certificate by taking these courses + + +#### HTML, CSS and JavaScript +- [Codecademy's web development course](https://www.codecademy.com/learn/paths/web-development) +- [freeCodeCamp](https://www.freecodecamp.org/) + +#### Python +- [Codecademy's Python course](https://www.codecademy.com/learn/learn-python) +- [Google's Python course](https://developers.google.com/edu/python/) +- [Learn Python The Hard Way book](https://learnpythonthehardway.org/book/) – the initial exercises are free +- [New Coder tutorials](http://newcoder.io/tutorials/) – this is a variety of practical examples of how you might use Python +- [edX](https://www.edx.org/course?search_query=python) – you can audit most courses for free, but if you want a certificate or credits towards a higher education qualification then that will cost money +- [Coursera's Python specialization](https://www.coursera.org/specializations/python) – some video lectures can be audited for free and you can earn a Coursera Certificate by taking these courses +- [Python for Everybody](https://www.py4e.com/) - a free and open version of the Coursera Python for Everybody specialization + +#### Working with data +- [Codecademy's data science course](https://www.codecademy.com/learn/paths/data-science) +- [edX](https://www.edx.org/course/?search_query=python&subject=Data%20Analysis%20%26%20Statistics) – you can audit most courses for free, but if you want a certificate or credits towards a higher education qualification then that will cost money +- [Dataquest](https://www.dataquest.io/) – the first 30 "missions" are free + +We can't wait to see what you build next! diff --git a/es/GLOSSARY.md b/es/GLOSSARY.md new file mode 100644 index 00000000000..9a6912eacf6 --- /dev/null +++ b/es/GLOSSARY.md @@ -0,0 +1,3 @@ +# editor de código + +Un editor de código es una aplicación que te permite escribir código y guardarlo en ficheros del disco de tu ordenador. Puedes ver dónde descargar uno en el [capítulo Editor de código](./code_editor/README.md) \ No newline at end of file diff --git a/es/README.md b/es/README.md index f701e82f95b..44b38f259c4 100755 --- a/es/README.md +++ b/es/README.md @@ -1,51 +1,51 @@ # Tutorial de 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) +[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial) > Este trabajo está bajo la licencia internacional Creative Commons Attribution-ShareAlike 4.0. Para ver una copia de esta licencia, visita el siguiente enlace https://creativecommons.org/licenses/by-sa/4.0/ -## Translation -This tutorial has been translated from English into Spanish by a wonderful group of volunteers. Special thanks goes to Victoria Martinez de la Cruz, Kevin Morales, Joshua Aranda, Silvia Frias, Leticia, Andrea Gonzalez, Adrian Manjarres, Rodrigo Caicedo, Maria Chavez, Marcelo Nicolas Manso, Rosa Durante, Moises, Israel Martinez Vargas, JuanCarlos_, N0890Dy, Ivan Yivoff, Khaterine Castellano, Erick Navarro, cyncyncyn, ZeroSoul13, Erick Aguayo, Ernesto Rico-Schmidt, Miguel Lozano, osueboy, dynarro and Geraldina Garcia Alvarez. +## Bienvenida/o + +¡Bienvenido/a al tutorial de las Django Girls! ¡Nos alegra que estés aquí :) En este tutorial, te llevaremos de viaje a las entrañas de la tecnología web, para que veas todas las piezas que se necesitan para que la web funcione. + +Como pasa con todas las cosas nuevas, va a ser una aventura - pero no te preocupes; una vez que te has decidido a empezar, te irá de maravilla :) ## Introducción -¿Alguna vez has sentido que el mundo está cada vez más cercano a la tecnología y de cierto modo te has quedado atrás? ¿Alguna vez te has preguntado cómo crear un sitio web pero nunca has tenido la suficiente motivación para empezar? ¿Has pensado alguna vez que el mundo del software es demasiado complicado para ti como para intentar hacer algo por tu cuenta? +¿Alguna vez has tenido la sensación de que el mundo es cada vez más tecnológico? ¿que cada vez lo entiendes menos? ¿Alguna vez te has planteado crear un sitio web pero no sabías por dónde empezar? ¿Has pensado alguna vez que el mundo del software es demasiado complicado como para intentar hacer algo por tu cuenta? -Bueno, ¡tenemos buenas noticias para ti! Programar no es tan difícil como aparenta y queremos mostrarte cuán divertido puede llegar a ser. +Bueno, ¡tenemos buenas noticias! Programar no es tan difícil como parece y queremos demostrarte lo divertido que puede llegar a ser. -Este tutorial no te convertirá en programador mágicamente. Si quieres ser buena en esto, necesitarás meses o incluso años de aprendizaje y práctica. Pero queremos mostrarte que programar o crear sitios web no es tan complicado como parece. Intentaremos explicar pequeñas partes lo mejor que podamos, de forma que no te sientas intimidada por la tecnología. +Este tutorial no te convertirá en programadora de la noche a la mañana. Si quieres ser buena en esto, necesitarás meses o incluso años de aprendizaje y práctica. Sin embargo queremos enseñarte que programar o crear sitios web no es tan complicado como parece. Intentaremos explicar las cosas lo mejor que podamos, para perderle el miedo a la tecnología. -¡Esperamos poder hacerte amar la tecnología tanto como nosotras lo hacemos! +¡Esperamos conseguir que te guste la tecnología tanto como a nosotras! ## ¿Qué aprenderás con este tutorial? -Cuando termines el tutorial, tendrás una aplicación web simple y funcional: tu propio blog. Te mostraremos como publicarla online, ¡así otros podrán ver tu trabajo! +Cuando termines el tutorial, tendrás una aplicación web sencilla y funcional: tu propio blog. Te mostraremos como ponerla en línea, ¡para que otros puedan ver tu trabajo! -Tendrá (más o menos) ésta apariencia: +Tendrá (más o menos) esta pinta: -![Figura 0.1][2] +![Figure 0.1](images/application.png) - [2]: images/application.png +> Si estás siguiendo este tutorial por tu cuenta y no tienes un mentor que te ayude en caso de dificultades, tenemos un chat para ti: [![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial). ¡Hemos pedido a mentores y asistentes de ediciones anteriores, que pasen por allí de vez en cuando para echar una mano a otras con el tutorial! ¡No tengas miedo de preguntar ahí! -> Si estás siguiendo este tutorial por tu cuenta y no tienes a nadie que te ayude en caso de surgir algún problema, tenemos un chat para ti: [![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). ¡Hemos pedido a nuestros tutores y participantes anteriores que estén ahí de vez en cuando para ayudar a otros con el tutorial! ¡No temas dejar tus preguntas allí! +Bien, [empecemos por el comienzo...](./how_the_internet_works/README.md) -Bien, [empecemos por el principio...][3] +## Seguir el tutorial desde casa - [3]: ./how_the_internet_works/README.md +Participar en un taller de Django Girls en vivo es genial, pero somos conscientes de que no siempre es posible hacerlo. Por eso, te recomendamos hacer este tutorial en casa. Para las que estáis en casa, estamos preparando vídeos que facilitarán seguir el tutorial por tu cuenta. Todavía está en progreso, pero cada vez hay más cosas explicadas en el canal de YouTube [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed) (Nota: en inglés). -## Sobre nosotros y cómo contribuir +En cada capítulo hay un enlace que lleva al vídeo correspondiente (si lo hay). -Este tutorial lo mantiene [DjangoGirls][4]. Si encuentras algún error o quieres actualizar el tutorial, por favor [sigue la guía de cómo contribuir][5]. +## Sobre nosotras y Cómo contribuir - [4]: https://djangogirls.org/ - [5]: https://github.com/DjangoGirls/tutorial/blob/master/README.md +Este tutorial lo mantiene [DjangoGirls](https://djangogirls.org/). Si encuentras algún error o quieres actualizar el tutorial, por favor [sigue la guía de cómo contribuir](https://github.com/DjangoGirls/tutorial/blob/master/README.md). ## ¿Te gustaría ayudarnos a traducir el tutorial a otros idiomas? -Actualmente, las traducciones se llevan a cabo sobre la plataforma crowdin.com en: +Actualmente, las traducciones se hacen en la plataforma crowdin.com, en el siguiente enlace: https://crowdin.com/project/django-girls-tutorial -Si tu idioma no esta listado en crowdin, por favor [abre un nuevo problema][6] informando el idioma así podemos agregarlo. - - [6]: https://github.com/DjangoGirls/tutorial/issues/new +Si tu idioma no aparece en la lista de [crowdin](https://crowdin.com/), por favor [abre un nuevo issue](https://github.com/DjangoGirls/tutorial/issues/new) con el idioma para que podamos añadirlo. \ No newline at end of file diff --git a/es/SUMMARY.md b/es/SUMMARY.md index fa7f9e5f3a0..7f7fcb716db 100755 --- a/es/SUMMARY.md +++ b/es/SUMMARY.md @@ -1,26 +1,35 @@ -# Índice +# Contenido -* [Introducción](README.md) -* [¿Cómo funciona Internet?](how_the_internet_works/README.md) -* [Introducción a la línea de comandos](intro_to_command_line/README.md) -* [Instalación de Python](python_installation/README.md) -* [Editor de código](code_editor/README.md) -* [Introducción a Python](python_introduction/README.md) -* [¿Qué es Django?](django/README.md) -* [Instalación de Django](django_installation/README.md) -* [Comenzar un proyecto en Django](django_start_project/README.md) -* [Modelos en Django](django_models/README.md) -* [Administrador de Django](django_admin/README.md) -* [¡Desplegar!](deploy/README.md) -* [Django urls](django_urls/README.md) -* [Vistas de Django - ¡Es hora de crear!](django_views/README.md) -* [Introducción a HTML](html/README.md) -* [ORM de Django (Querysets)](django_orm/README.md) -* [Datos dinámicos en plantillas](dynamic_data_in_templates/README.md) -* [Plantillas de Django](django_templates/README.md) -* [CSS - Hazlo bonito](css/README.md) -* [Extender plantillas](template_extending/README.md) -* [Amplía tu aplicación](extend_your_application/README.md) -* [Formularios en Django](django_forms/README.md) -* [Dominio](domain/README.md) -* [¿Qué sigue?](whats_next/README.md) +* [Introducción](README.md) +* [Instalación](installation/README.md) + * [Línea de Comandos](installation/README.md#command-line) + * [Python](installation/README.md#python) + * [Editor de texto](installation/README.md#code-editor) + * [Entorno Virtual](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) +* [Instalación (chromebook)](chromebook_setup/README.md) +* [Cómo funciona Internet](how_the_internet_works/README.md) +* [Introducción a la línea de comandos](intro_to_command_line/README.md) +* [Instalación de Python](python_installation/README.md) +* [Editor de código](code_editor/README.md) +* [Introducción a Python](python_introduction/README.md) +* [¿Qué es Django?](django/README.md) +* [Instalación de Django](django_installation/README.md) +* [¡Tu primer proyecto en Django!](django_start_project/README.md) +* [Modelos en Django](django_models/README.md) +* [Administrador de Django](django_admin/README.md) +* [¡Despliega!](deploy/README.md) +* [URLs en Django](django_urls/README.md) +* [Vistas en Django - ¡Hora de crear!](django_views/README.md) +* [Introducción a HTML](html/README.md) +* [ORM de Django (QuerySets)](django_orm/README.md) +* [Datos dinámicos en las plantillas](dynamic_data_in_templates/README.md) +* [Plantillas de Django](django_templates/README.md) +* [CSS - ¡Que quede bonito!](css/README.md) +* [Extendiendo plantillas](template_extending/README.md) +* [Amplía tu aplicación](extend_your_application/README.md) +* [Formularios de Django](django_forms/README.md) +* [¿Y ahora qué?](whats_next/README.md) diff --git a/es/chromebook_setup/README.md b/es/chromebook_setup/README.md new file mode 100644 index 00000000000..217da1f3ea0 --- /dev/null +++ b/es/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# Configuración de Chromebook + +> **Nota** Si ya ejecutaste todas las instrucciones indicadas durante la instalación, no es necesario volverlo a hacer - puedes omitir lo que sigue hasta la [Introducción a Python](../python_introduction/README.md). + +{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/es/chromebook_setup/instructions.md b/es/chromebook_setup/instructions.md new file mode 100644 index 00000000000..964ddd4cef1 --- /dev/null +++ b/es/chromebook_setup/instructions.md @@ -0,0 +1,73 @@ +Puedes [saltarte esta sección](http://tutorial.djangogirls.org/en/installation/#install-python) en caso de que no estés usando un Chromebook. Si lo usas, tu experiencia de instalación será algo diferente. Puedes ignorar el resto de las instrucciones de instalación. + +### IDE en la nube (PaizaCloud Cloud IDE, AWS Cloud9) + +Nube de IDE es una herramienta que te ofrece un editor de código y el acceso por medio de internet a una computadora donde puedes instalar, escribir y ejecutar el software. Durante este tutorial, el IDE en la nube te servirá como tu *máquina local*. Seguirás ejecutando comandos en una terminal igual que tus compañeros de clase en macOS, Ubuntu, o Windows, pero tu terminal en realidad estará conectada a una computadora trabajando en algún otro lugar, que el IDE en la nube configura para ti. Aquí están las instrucciones para IDEs en la nube (PaizaCloud Cloud IDE, AWS Cloud9). Puedes elegir uno de los IDEs en la nube, y seguir sus instrucciones. + +#### PaizaCloud Cloud IDE + +1. Ve a [PaizaCloud Cloud IDE](https://paiza.cloud/) +2. Crea una cuenta +3. Haz clic en *Nuevo Servidor* y elige la aplicación Django +4. Haz clic en el botón Terminal (en el lado izquierdo de la ventana) + +Ahora deberías ver una interfaz con una barra y botones en la izquierda. Haz click en al botón "Terminal" para abrir la ventana de la terminal con un símbolo de sistema como este: + +{% filename %}Terminal{% endfilename %} + + $ + + +La terminal en el IDE en la nube PaizaCloud está preparada para ejecutar tus instrucciones. Puedes redimensionar o maximizar la ventana para hacerla un poco más grande. + +#### AWS Cloud9 + +Actualmente Cloud 9 requiere que te registres con AWS y ingreses la información de la tarjeta de crédito. + +1. Instala Cloud 9 desde la [Chrome web store](https://chrome.google.com/webstore/detail/cloud9/nbdmccoknlfggadpfkmcpnamfnbkmkcp) +2. Ve a [c9.io](https://c9.io) y haz clic en *Get started with AWS Cloud9* +3. Regístrate en una cuenta AWS (requiere información de tarjeta de crédito, pero puedes usar gratis) +4. En el panel de control AWS, introduz *Cloud9* en la barra de búsqueda y haz clic en él +5. En el panel de control de la Cloud 9, haz clic en *Create environment* +6. Nómbralo *django-girls* +7. Mientras configuras los ajustes, selecciona *Create a new instance for environment (EC2)* para "Environment Type" y selecciona el valor *t2.micro* para "Instance type" (debería decir "Free-tier eligible."). La configuración de ahorro de costes por defecto está bien y puede mantener los otros valores por defecto. +8. Haz clic en *Next step* +9. Haz clic en *Create environment* + +Ahora deberías ver una interfaz con una barra, una gran ventana principal con algún texto y una ventana pequeña en la parte inferior que se vería así: + +{% filename %}bash{% endfilename %} + + yourusername:~/workspace $ + + +El área de abajo es tu terminal. Puedes usar el terminal para enviar instrucciones al ordenador remoto en Cloud 9. Puedes redimensionar o maximizar la ventana para hacerla un poco más grande. + +### Entorno Virtual + +Un entorno virtual (también llamado "virtualenv" o "vitual environment" en inglés) es un tipo de caja privada donde podemos introducir código para el proyecto en el cual estemos trabajando. Lo usamos para mantener separados los diferentes trozos de código de nuestros proyectos, de modo que no haya mezclas indeseadas entre los mismos. + +Ejecutar: + +{% filename %}Cloud 9{% endfilename %} + + mkdir djangogirls + cd djangogirls + python3.6 -mvenv myvenv + source myvenv/bin/activate + pip install django~={{ book.django_version }} + + +(nota que en la última línea usamos una virgulilla (~) seguida de un signo igual `~=`). + +### GitHub + +Hazte una cuenta de [GitHub](https://github.com). + +### PythonAnywhere + +El tutorial de Django Girls incluye una sección en lo que se conoce como Despliegue, lo cual se refiere al proceso de tomar el código que da vida a tu nueva aplicación web y moverlo a un ordenador de acceso público (llamado servidor) para que otras personas puedan ver tu trabajo. + +Esta parte del tutorial es algo extraña usando un Chromebook, pues ya estamos usando un computador conectado a Internet (contrario a, por ejemplo, un portátil). Sin embargo, aún es útil, ya que podemos pensar que nuestro espacio de trabajo en Cloud 9 como un repositorio para nuestro trabajo "en progreso" y Python Anywhere como un lugar donde mostrar nuestro trabajo más completo. + +Así que, registra una cuenta en Python Anywhere [www.pythonanywhere.com](https://www.pythonanywhere.com). \ No newline at end of file diff --git a/es/code_editor/README.md b/es/code_editor/README.md index 3f6c86b1f73..677874a96ec 100755 --- a/es/code_editor/README.md +++ b/es/code_editor/README.md @@ -1,43 +1,11 @@ # Editor de código -Estás a punto de escribir tu primera línea de código, así que ¡es hora de descargar un editor de código! +> Para los lectores en casa: este capitulo se explica en el vídeo [Instalando Python & Editor de Código](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s). -Hay muchos editores diferentes, cuál usar depende mucho de la preferencia personal. La mayoría de programadores de Python usan IDEs (Entornos de Desarrollo Integrados) complejos pero muy poderosos, como PyCharm. Sin embargo, como principiante, eso es probablemente menos conveniente; nuestras recomendaciones son igual de poderosas pero mucho mas simples. +Estás a punto de escribir tu primera línea de código, así que, ¡ya toca descargar un editor de código! -Nuestras sugerencias están listadas abajo, pero siéntete libre de preguntarle a tu tutor cuáles son sus preferencias - así será más fácil obtener su ayuda. +> **Nota** Si estás usando un Chromebook, omite este capítulo y asegúrate de seguir las instrucciones de [Instalación de Chromebook](../chromebook_setup/README.md). La nube IDE que elegiste (Paizacloud Cloud IDE o AWS cloud9) incluyen un editor de código, y cuando abres un archivo en tu IDE desde el menú de archivos, automáticamente estarás utilizando el editor. +> +> **Nota** Es posible que ya hayas hecho esto en el capítulo de instalación. Si es así, ¡puedes avanzar directamente al siguiente capítulo! -## Gedit - -Gedit es un editor de código abierto, gratis, disponible para todos los sistemas operativos. - -[Descárgalo aquí][1] - - [1]: https://wiki.gnome.org/Apps/Gedit#Download - -## Sublime Text 3 - -Sublime Text es un editor muy popular con un periodo de prueba gratis. Es fácil de instalar y está disponible para todos los sistemas operativos. - -[Descárgalo aquí][2] - - [2]: https://www.sublimetext.com/3 - -## Atom - -Atom es un editor de código muy nuevo creado por [GitHub][3]. Es gratis, de código abierto, fácil de instalar y fácil de usar. Está disponible para Windows, OSX y Linux. - - [3]: https://github.com/ - -[Descárgalo aquí][4] - - [4]: https://atom.io/ - -# ¿Por qué estamos instalando un editor de código? - -Puedes estar preguntándote por qué estamos instalando un editor especial, en lugar de usar un editor convencional como Word o Notepad. - -En primer lugar, el código tiene que ser **texto plano** y el problema de las aplicaciones como Word o Textedit es que en realidad no producen texto plano. Lo que generan es texto enriquecido (con tipografías y formato), usando formatos propios como rtf. - -La segunda razón es que los editores de código son herramientas especializadas y, como tales, tienen características muy útiles, como resaltar la sintáxis del código con diferentes colores de acuerdo a su significado o cerrar comillas por ti automáticamente. - -Veremos todo esto en acción más adelante. En breve empezarás a pensar en tu fiel editor de código como una de tus herramientas favoritas :) \ No newline at end of file +{% include "/code_editor/instructions.md" %} \ No newline at end of file diff --git a/es/code_editor/instructions.md b/es/code_editor/instructions.md new file mode 100644 index 00000000000..187a5d3a92d --- /dev/null +++ b/es/code_editor/instructions.md @@ -0,0 +1,37 @@ +Hay muchos editores diferentes y la elección es principalmente una cuestión de preferencia personal. La mayoría de programadores de Python usan IDEs (Entornos de Desarrollo Integrados) complejos pero muy potentes, como PyCharm. Sin embargo, como principiante, probablemente no es lo más aconsejable; nuestras recomendaciones son igualmente potentes pero mucho más simples. + +Abajo presentamos nuestras sugerencias pero también puedes preguntarle a tu mentora cuáles son las suyas -será más fácil que te ayude. + +## Visual Studio Code + +Visual Studio Code es un recurso de edición de código desarrollado por Microsoft para Windows, Linux y macOS. Esto incluye soporte para depuración, control de Git incrustado, sintaxis destacada, completación de código inteligente, fragmentos y refactorización de código. + +[Descárgalo aquí](https://code.visualstudio.com/download) + +## Gedit + +Gedit es un editor gratuito de código abierto, disponible para todos los sistemas operativos. + +[Descárgalo aquí](https://wiki.gnome.org/Apps/Gedit#Download) + +## Sublime Text + +Sublime Text es un editor muy popular con un periodo de prueba gratis, y está disponible para todos los sistemas operativos. + +[Descárgalo aquí](https://www.sublimetext.com/) + +## Atom + +Atom es otro editor popular. Es gratis, de código abierto y disponible para Windows, macOS and Linux. Atom está desarrollado por [Github](https://github.com/). + +[Descárgalo aquí](https://atom.io/) + +## ¿Por qué estamos instalando un editor de código? + +Tú podrías estar preguntándote por qué estamos instalando este especializado software editor de código en vez de usar algo como Word o Notepad. + +La primera razón es que el código necesita ser **texto plano**, y el problema con programas como Word y Textedit es que no producen texto plano, sino texto enriquecido (con fuentes y formatos), usando formatos personalizados como [RTF ( Formato del Texto Enriquecido, del inglés Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format). + +La segunda razón es que los editores de código están especializados para esta función, así ellos pueden proveer ayuda a características como destacar código con color acorde a su significado, o automáticamente cerrando etiquetas para ti. + +Veremos todo esto en acción más adelante. Pronto pensarás en convertir el editor de código en una de tus herramientas favoritas. :) diff --git a/es/css/README.md b/es/css/README.md index f252d90e6a3..158770ba9c1 100755 --- a/es/css/README.md +++ b/es/css/README.md @@ -1,58 +1,59 @@ -# CSS - ¡Hazlo bonito! +# CSS - ¡Que quede bonito! -Nuestro blog todavía se ve bastante feo, ¿verdad? ¡Es hora de hacerlo bonito! Vamos a usar CSS para eso. +Nuestro blog todavía es un poco feo, ¿no te parece? ¡Es hora de ponerlo bonito! Para eso, vamos a usar CSS. ## ¿Qué es CSS? -CSS (Cascading Style Sheets, que significa 'hojas de estilo en cascada') es un lenguaje utilizado para describir el aspecto y el formato de un sitio web escrito en lenguaje de marcado (como HTML). Trátalo como maquillaje para nuestra página web ;). +El lenguaje CSS (las siglas en inglés de Hojas de Estilos en Cascada, o Cascading Style Sheets) sirve para describir la apariencia de un sitio web escrito en un lenguaje de marcado (como HTML). Es como la capa de pintura para nuestra página web. ;) -Pero no queremos empezar de cero otra vez, ¿verdad? Una vez más, usaremos algo que ya ha sido realizado por programadores y publicado en Internet de forma gratuita. Ya sabes, reinventar la rueda no es divertido. +Pero no queremos empezar de cero otra vez, ¿verdad? De nuevo vamos a usar algo que otros programadores han publicado ya en Internet. Estar siempre reinventando la rueda no mola. ## ¡Vamos a usar Bootstrap! -Bootstrap es uno de los frameworks HTML y CSS más populares para desarrollar webs bonitas: https://getbootstrap.com/ +Bootstrap es uno de los frameworks de HTML y CSS más populares para desarrollar sitios web atractivos: https://getbootstrap.com/ -Lo escribieron programadores que trabajaban para Twitter y ahora lo desarrollan voluntarios de todo el mundo. +Lo escribieron programadores que trabajaban en Twitter. ¡Ahora lo mantienen y desarrollan voluntarios de todo el mundo! ## Instalar Bootstrap -Para instalar Bootstrap tienes que añadir esto al `` de tu fichero `.html` (`blog/templates/blog/post_list.html`): +Para instalar Bootstrap, abre tu fichero `.html` en el editor de código y añade esto a la sección ``: -```html - - -``` +{% filename %}blog/templates/blog/post_list.html{% endfilename %} -Esto no añade ningún fichero a tu proyecto. Simplemente apunta a ficheros que existen en Internet. Adelante, abre tu sitio web y actualiza la página. ¡Aquí está! +```html + + +``` -![Figure 14.1][1] +Esto no añade ningún archivo a tu proyecto. Solo apunta a archivos que existen en Internet. Así que adelante, accede a tu sitio web y refresca la página ¡Aquí la tienes! - [1]: images/bootstrap1.png +![Figura 14.1](images/bootstrap1.png) -¡Se ve mucho mejor! +¡Ya tiene mejor pinta! -## Ficheros estáticos en Django +## Archivos estáticos (static files) en Django -Finalmente nos vamos a fijar en estas cosas que hemos estado llamando **ficheros estáticos**. Los ficheros estáticos son todos tus CSS e imágenes; ficheros que no son dinámicos, por lo que su contenido no depende del contexto de la petición y serán iguales para todos los usuarios. +Finalmente nos vamos a fijar en esto que hemos estado llamando **archivos estáticos**. Los archivos estáticos son los archivos CSS e imágenes. Su contenido no depende del contexto de la petición y siempre será el mismo para todos los usuarios. -### Dónde poner los ficheros estáticos para Django +### Dónde poner los archivos estáticos en Django -Como has visto cuando hemos ejecutado `collectstatic` en el servidor, Django ya sabe dónde encontrar los ficheros estáticos para la aplicación "admin". Ahora necesitamos añadir algunos ficheros estáticos para nuestra propia aplicación, `blog`. +Django ya sabe dónde encontrar los archivos estáticos de la app "admin". Ahora necesitamos añadir los archivos estáticos de nuestra aplicación, `blog`. -Esto lo conseguimos creando una carpeta llamada `static` dentro de la aplicación blog: +Crearemos una carpeta llamada `static` dentro de la app blog: djangogirls ├── blog │ ├── migrations - │ └── static + │ ├── static + │ └── templates └── mysite -Django encontrará automáticamente cualquier carpeta que se llame "static" dentro de las carpetas de tus aplicaciones y podrá utilizar su contenido como ficheros estáticos. +Django encontrará automáticamente cualquier carpeta llamada "static" dentro de cualquiera de las carpetas de tus apps. Podrá usar su contenido como archivos estáticos. -## ¡Tu primer fichero CSS! +## ¡Tu primer archivo CSS! -Crea un nuevo directorio llamado `css` dentro de tu directorio `static`. Para añadir tu propio estilo a tu página web, crea un nuevo fichero llamado `blog.css` dentro de este directorio `css`. ¿Lista? +Vamos a crear un archivo CSS, para añadir tu propio estilo a la página. Crea un nuevo directorio llamado `css` dentro de la carpeta `static`. A continuación, crea un nuevo archivo llamado `blog.css` dentro de la carpeta `css`. ¿Listos? djangogirls └─── blog @@ -61,234 +62,244 @@ Crea un nuevo directorio llamado `css` dentro de tu directorio `static`. Para a └─── blog.css -¡Es hora de escribir algo de CSS! Abre el fichero `blog/static/css/blog.css` en tu editor de código. - -No vamos a entrar mucho en la personalización y el aprendizaje de CSS aquí porque es bastante fácil y lo puedes aprender por tu cuenta después de este taller. Recomendamos enormemente hacer este [curso de HTML y CSS en Codecademy][2] para aprender todo lo que necesitas saber sobre cómo hacer tus sitios web más bonitos con CSS. +¡Vamos a escribir algo de CSS! Abre el archivo `blog/static/css/blog.css` en el editor de código. - [2]: https://www.codecademy.com/tracks/web +No vamos a profundizar demasiado en cómo personalizar y aprender CSS. Pero te podemos recomendar un un curso gratuito de CSS al final de esta página por si quieres aprender más. -Pero vamos a hacer un poco al menos. ¿Tal vez podríamos cambiar el color de nuestro título? Los ordenadores utilizan códigos especiales para entender los colores. Empiezan con `#` y les siguen 6 letras (A-F) y números (0-9). Puedes encontrar códigos de color, por ejemplo, aquí: http://www.colorpicker.com/. También puedes utilizar [colores predefinidos][3] utilizando su nombre en inglés, como `red` y `green`. +Pero vamos a hacer al menos un poco. ¿Quizás podamos cambiar el color de nuestros encabezados? Los ordenadores utilizan códigos especiales para expresar los colores. Estos códigos empiezan con `#` seguidos por 6 letras (A-F) y números (0-9). Por ejemplo, el código del color azul es `#0000FF`. Puedes encontrar los códigos de muchos colores aquí: http://www.colorpicker.com/ y en otras páginas web. También puedes utilizar [colores predefinidos](http://www.w3schools.com/colors/colors_names.asp) utilizando su nombre en inglés, como `red` y `green`. - [3]: http://www.w3schools.com/cssref/css_colornames.asp +En el archivo `blog/static/css/blog.css` deberías añadir el siguiente código: -En tu fichero `blog/static/css/blog.css` deberías añadir el siguiente código: +{% filename %}blog/static/css/blog.css{% endfilename %} ```css - h1 a { - color: #FCA205; - } -``` +h1 a, h2 a { + color: #C25100; +} -`h1 a` es un selector CSS. Quiere decir que estamos aplicando nuestros estilos a cualquier elemento `a` que se encuentre dentro de un elemento `h1` (por ejemplo cuando tenemos en código algo como: `

enlace

`). En este caso le estamos diciendo que cambie el color a `#FCA205`, que es naranja. Por supuesto, ¡puedes poner tu propio color aquí! +``` -En un fichero CSS definimos los estilos para los elementos del fichero HTML. Los elementos se identifican por el nombre del elemento (es decir, `a`, `h1`, `body`), el atributo `class` (clase) o el atributo `id` (identificador). Class e id son nombres que le asignas tú misma al elemento. Las clases definen grupos de elementos y los ids apuntan a elementos específicos. Por ejemplo, la siguiente etiqueta se puede identificar con CSS usando el nombre `a`, la clase `external_link` o el id `link_to_wiki_page`: +`h1 a` es un selector CSS. Esto significa que estamos aplicando nuestros estilos a cualquier elemento de `a` dentro de un elemento de `h1`; el selector `h2 a` hace lo mismo para los elementos de `h2`. Así, cuando tenemos algo como `

link

`, se aplicará el estilo `h1 a`. En este caso, le estamos diciendo que cambie el color a un `#C25100`, que es un naranjo oscuro. O puedes poner tu propio color aqui, ¡pero asegúrate que tenga un buen contraste contra un fondo blanco! + +En un archivo CSS se definen los estilos de los elementos que aparecen en el archivo HTML. La primera forma de identificar los elementos es por su nombre. Puede que los recuerdes como 'tags' de la sección de HTML. Cosas como `a`, `h1`, y `body` son algunos ejemplos de nombres de elementos. También podemos identificar elementos por el atributo `class` o el atributo `id`. Los valores de "class" e "id" son nombres que das al elemento para poderlo identificar. Con el atributo "class" identificamos grupos de elementos del mismo tipo y con el atributo "id" identificamos un elemento específico. Por ejemplo, el siguiente elemento lo podrías identificar por su nombre de "tag" `a`, por su "class" `external_link`, o por su "id" `link_to_wiki_page`: ```html - -``` + +``` -Puedes leer más sobre [selectores de CSS en w3schools][4]. +Si quieres aprender más sobre los selectores CSS puedes consultar en [Selectores de CSS en w3schools](http://www.w3schools.com/cssref/css_selectors.asp). - [4]: http://www.w3schools.com/cssref/css_selectors.asp +También necesitamos decirle a nuestra plantilla HTML que hemos añadido código CSS. Abre el archivo `blog/templates/blog/post_list.html` en el editor de código y añade esta línea al principio del todo: -También necesitamos decirle a nuestra plantilla HTML que hemos añadido CSS. Abre el fichero `blog/templates/blog/post_list.html` y añade esta línea justo al principio: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - {% load staticfiles %} -``` +{% load static %} +``` + +Aquí solo estamos cargando archivos estáticos. :) Entre las etiquetas `` y ``, después de los enlaces a los archivos CSS de Bootstrap, añade esta línea: -Aquí sólo estamos cargando ficheros estáticos :). Luego, entre el `` y ``, después de los enlaces a los ficheros CSS de Bootstrap (el navegador lee los ficheros en el orden en que están, así que nuestro fichero podría sobrescribir partes del código de Bootstrap), añade la siguiente línea: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - -``` + +``` + +El navegador lee los archivos en el orden que le son dados, por lo que debemos asegurarnos de que está en el lugar correcto. De lo contrario, el código en nuestro archivo podría ser reemplazado por código en nuestros archivos Bootstrap. Le acabamos de decir a nuestra plantilla dónde se encuentra nuestro archivo CSS. -Le acabamos de decir a nuestra plantilla dónde se encuentra nuestro fichero CSS. +Ahora tu archivo debe tener este aspecto: -Ahora tu fichero debería tener este aspecto: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - {% load staticfiles %} - - - Django Girls blog - - - - - +{% load static %} + + + Django Girls blog + + + + + + + + {% for post in posts %}
-

Django Girls Blog

+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

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

published: {{ post.published_date }}

-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

-
- {% endfor %} - - -``` + {% endfor %} + + +``` -De acuerdo, ¡guarda el fichero y actualiza el sitio! +De acuerdo, ¡guarda el archivo y actualiza el sitio! -![Figure 14.2][5] +![Figura 14.2](images/color2.png) - [5]: images/color2.png +¡Buen trabajo! ¿Tal vez nos gustaría también dar un poco de aire a nuestro sitio web y aumentar el margen en el lado izquierdo?. ¡Vamos a intentarlo! -¡Buen trabajo! ¿Quizá nos gustaría darle un poco de aire a nuestro sitio web y aumentar también el margen en el lado izquierdo? ¡Vamos a intentarlo! +{% filename %}blog/static/css/blog.css{% endfilename %} ```css - body { - padding-left: 15px; - } -``` +body { + padding-left: 15px; +} +``` -Añade esto a tu CSS, guarda el fichero y ¡mira cómo funciona! +Añade esto a tu CSS, guarda el archivo y ¡mira cómo funciona! -![Figure 14.3][6] +![Figura 14.3](images/margin2.png) - [6]: images/margin2.png +¿Quizá podríamos personalizar la tipografía del título? Pega esto en la sección `` del archivo `blog/templates/blog/post_list.html`: -¿Quizá podríamos personalizar la tipografía del título? Pega esto en la sección `` del fichero `blog/templates/blog/post_list.html`: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - -``` + +``` -Esta línea va a importar una tipografía llamada *Lobster* de Google Fonts (https://www.google.com/fonts). +Como antes, revisa el orden y pon antes del enlace a `blog/static/css/blog.css`. Esta línea importará un estilo de letra llamada *Lobster* de Google Fonts (https://www.google.com/fonts). -Ahora añade la línea `font-family: 'Lobster';` en el fichero CSS `blog/static/css/blog.css` dentro del bloque de declaración `h1 a` (el código entre llaves `{` y `}`) y actualiza la página: +Encuentra el bloque de declaración (el código entre las llaves `{` y `}`) `h1 a` en el archivo CSS `blog/static/css/blog.css`. Ahora añade la línea `font-family: 'Lobster';` entre las llaves y actualiza la página: -```css - h1 a { - color: #FCA205; - font-family: 'Lobster'; - } -``` +{% filename %}blog/static/css/blog.css{% endfilename %} -![Figure 14.3][7] +```css +h1 a, h2 a { + color: #FCA205; + font-family: 'Lobster'; +} +``` - [7]: images/font.png +![Figura 14.3](images/font.png) ¡Genial! -Como se mencionó anteriormente, CSS tiene un concepto de clases que básicamente permite nombrar una parte del código HTML y aplicar estilos sólo a esta parte, sin afectar a otras. Es muy útil si tienes dos divs que hacen algo muy diferente (como el encabezado y la entrada) y no quieres que tengan el mismo aspecto. +Como ya hemos dicho, CSS tiene un concepto de clases. Las clases te permiten dar un nombre a una parte del código HTML para aplicar estilos solo a esta parte, sin afectar a otras. ¡Esto puede ser súper útil! Quizá tienes dos divs haciendo algo diferente (como el encabezado y el texto de tu publicación). Las clases pueden ayudarte a asignarles estilos distintos. + +Adelante, nombra algunas partes del código HTML. Añade una clase llamada `page-header` a tu `div` que contiene el encabezado, así: -¡Adelante! Nombra algunas partes del código HTML. Añade una clase llamada `page-header` al `div` que contiene el encabezado, así: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - -``` + +``` -Y ahora añade la clase `post` al `div` que contiene una entrada del blog. +Y ahora añade una clase `post` a tu `div` que contiene una publicación del blog. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -
-

published: {{ post.published_date }}

-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

-
-``` +
+

publicado: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+``` -Ahora añadiremos bloques de declaración a diferentes selectores. Los selectores que comienzan con `.` hacen referencia a las clases. Hay muchos tutoriales y explicaciones sobre CSS en la web que te ayudarán a entender el siguiente código. Por ahora, simplemente copia y pega este bloque de código en tu fichero `blog/static/css/blog.css`: +Ahora añadiremos bloques de declaración a varios selectores. Los selectores que comienzan con `.` hacen referencia a clases. Hay muchos tutoriales y explicaciones excelentes sobre CSS en la Web que te pueden ayudar a entender el código que sigue a continuación. Por ahora, copia y pega lo siguiente en tu archivo `blog/static/css/blog.css`: -```css - .page-header { - background-color: #ff9400; - margin-top: 0; - padding: 20px 20px 20px 40px; - } - - .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 { - font-family: 'Lobster', cursive; - } - - .date { - float: right; - color: #828282; - } - - .save { - float: right; - } - - .post-form textarea, .post-form input { - width: 100%; - } - - .top-menu, .top-menu:hover, .top-menu:visited { - color: #ffffff; - float: right; - font-size: 26pt; - margin-right: 20px; - } - - .post { - margin-bottom: 70px; - } - - .post h1 a, .post h1 a:visited { - color: #000000; - } -``` +{% filename %}blog/static/css/blog.css{% endfilename %} -Luego rodea el código HTML que muestra las entradas con las declaraciones de clases. Sustituye esto: +```css +.page-header { + background-color: #C25100; + margin-top: 0; + padding: 20px 20px 20px 40px; +} + +.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 { + font-family: 'Lobster', cursive; +} + +.date { + color: #828282; +} + +.save { + float: right; +} + +.post-form textarea, .post-form input { + width: 100%; +} + +.top-menu, .top-menu:hover, .top-menu:visited { + color: #ffffff; + float: right; + font-size: 26pt; + margin-right: 20px; +} + +.post { + margin-bottom: 70px; +} + +.post h2 a, .post h2 a:visited { + color: #000000; +} +``` + +Luego rodea el código HTML que muestra los posts con declaraciones de clases. Cambia esto: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - {% for post in posts %} -
-

published: {{ post.published_date }}

-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

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

publicado: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` en `blog/templates/blog/post_list.html` por esto: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html -
-
-
- {% for post in posts %} -
-
- {{ post.published_date }} -
-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

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

publicado: {{ post.published_date }}

- {% endfor %} -
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %}
-``` - -Guarda los ficheros y actualiza tu sitio. +
+``` -![Figure 14.4][8] +Guarda estos archivos y recarga tu sitio. - [8]: images/final.png +![Figura 14.4](images/final.png) -¡Bien! Se ve increíble, ¿verdad? En realidad el código que acabamos de pegar no es tan difícil de entender y deberías ser capaz de entender la mayoría sólo con leerlo. +¡Woohoo! Queda genial, ¿Verdad? Mira el código que acabamos de pegar para encontrar los lugares donde añadimos clases en el HTML y las usamos en el CSS. ¿Qué cambiarías si quisieras que la fecha fuera color turquesa? -No tengas miedo de jugar un poco con este CSS e intentar cambiar algunas cosas. Si rompes algo, no te preocupes, ¡siempre puedes deshacerlo! +No tengas miedo a experimentar con este CSS un poco y tratar de cambiar algunas cosas. Jugar con el CSS te puede ayudar a entender lo que hacen las distintas secciones. Si algo deja de funcionar, no te preocupes, ¡siempre puedes deshacerlo! -De cualquier forma, te volvemos a recomendar que hagas el [curso de HTML y CSS de Codeacademy][2] como una tarea post-taller para que aprendas todo lo que necesitas saber para hacer tus sitios web más bonitos con CSS. +Realmente te recomendamos seguir este [Curso de HTML y CSS de CodeAcademy](https://www.codecademy.com/tracks/web). Puede ayudarte a aprender todo lo que necesitas para hacer tus websites más bonitos con CSS. ¡¿Lista para el siguiente capítulo?! :) diff --git a/es/css/images/bootstrap1.png b/es/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/es/css/images/bootstrap1.png and b/es/css/images/bootstrap1.png differ diff --git a/es/css/images/color2.png b/es/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/es/css/images/color2.png and b/es/css/images/color2.png differ diff --git a/es/css/images/final.png b/es/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/es/css/images/final.png and b/es/css/images/final.png differ diff --git a/es/css/images/font.png b/es/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/es/css/images/font.png and b/es/css/images/font.png differ diff --git a/es/css/images/margin2.png b/es/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/es/css/images/margin2.png and b/es/css/images/margin2.png differ diff --git a/es/deploy/README.md b/es/deploy/README.md index c85530aff05..491bbd9f535 100755 --- a/es/deploy/README.md +++ b/es/deploy/README.md @@ -1,93 +1,83 @@ # ¡Despliega! -> **Nota**: El siguiente capítulo puede ser a veces un poco difícil de superar. Se persistente y acábalo. El despliegue es una parte importante del proceso en el desarrollo web. Este capítulo está situado en el medio del tutorial para que tu tutor pueda ayudarte a poner tu sitio web en línea, lo que puede ser un proceso algo más complicado. Esto significa que podrás acabar el tutorial por tu cuenta si se te acaba el tiempo. +> **Nota** El siguiente capítulo puede ser, a veces, un poco difícil de seguir. Ten paciencia y acábalo. El despliegue es una parte importante del proceso en el desarrollo de un sitio web. Este capítulo está a mitad del tutorial para que tu mentor pueda ayudarte a conseguir que tu sitio web esté online, algo que puede ser un poco complicado. Así, aunque se te acabe el tiempo, podrás terminar el tutorial por tu cuenta. -Hasta ahora tu sitio web estaba disponible sólo en tu ordenador, ¡ahora aprenderás cómo desplegarlo! El despliegue es el proceso de publicar tu aplicación en Internet para que la gente pueda acceder y ver tu aplicación :). +Hasta ahora, tu sitio web sólo está disponible en tu ordenador. ¡Ahora aprenderás como desplegarlo! El despliegue es el proceso de publicar tu aplicación en internet para que la gente pueda acceder y ver tu sitio web. :) -Como ya has aprendido, un sitio web tiene que estar en un servidor. Hay muchos proveedores, pero usaremos uno que tiene un proceso de despliegue relativamente simple: [PythonAnywhere][1]. PythonAnywhere es gratis para pequeñas aplicaciones que no tienen demasiados visitantes, definitivamente suficiente para este caso. +Como ya has aprendido, un sitio web tiene que estar en un servidor. Hay muchos proveedores de servidores disponibles en internet, nosotros vamos a usar [PythonAnywhere](https://www.pythonanywhere.com/). PythonAnywhere es gratuito para aplicaciones pequeñas que no tienen muchos visitantes, y con eso tendrás más que suficiente por ahora. - [1]: https://pythonanywhere.com/ +El otro servicio externo que vamos a utilizar es [GitHub](https://www.github.com), un servicio de almacenamiento de código. Hay otras opciones por ahí, pero hoy en día casi todas las programadoras y programadores tenemos una cuenta de GitHub, ¡y ahora tú también la vas a tener! -El otro servicio externo que vamos a utilizar es [GitHub][2], un servicio de alojamiento de código. Hay otras opciones por ahí, pero hoy en día casi todos los programadores tienen una cuenta de GitHub, ¡y ahora tú también la vas a tener! - - [2]: https://www.github.com - -Usaremos GitHub como paso intermedio para transportar nuestro código desde y hasta PythonAnywhere. +Estos tres lugares serán importantes para ti. Tu ordenador local será el lugar donde desarrollas y pruebas. Cuando estés contento con los cambios, subirás una versión de tu programa a GitHub. Tu sitio web estará en PythonAnywhere y para actualizarlo descargarás la última versión de tu código desde GitHub. # Git -Git es un "sistema de control de versiones" usado por muchos programadores - es un sistema que registra los cambios en los archivos a través del tiempo de forma tal que puedas acceder a versiones específicas cuando lo desees. Es muy similar a la opción de "registrar cambios" en Microsoft Word, pero mucho más poderoso. - -## Instalar Git - -### Windows +> **Nota** Si ya has realizado los pasos de instalación, no los tienes que repetir, puedes avanzar a la siguiente sección y empezar a crear tu repositorio de Git. -Puedes descargar Git de [git-scm.com][3]. Puedes hacer clic en "Next" para todos los pasos excepto en uno; en el quinto paso titulado "Adjusting your PATH environment", elije "Run Git and associated Unix tools from the Windows command-line" (la última opción). Aparte de eso, los valores por defecto funcionarán bien. "Checkout Windows-style, commit Unix-style line endings" también está bien. +{% include "/deploy/install_git.md" %} - [3]: https://git-scm.com/ +## Crear nuestro repositorio Git -### MacOS +Git sigue los cambios realizados a un grupo determinado de archivos en lo que llamamos un repositorio de código (abreviado "repo"). Vamos a crear uno para nuestro proyecto. Abre la consola y ejecuta los siguientes comandos en el directorio de `djangogirls`: -Descarga Git de [git-scm.com][3] y sigue las instrucciones. +> **Nota** Comprueba en qué directorio estás ahora mismo (es decir, el directorio de trabajo actual) con el comando `pwd` (OSX/Linux) o `cd` (Windows) antes de inicializar el repositorio. Deberías estar en la carpeta `djangogirls`. -### Linux - -Si no lo tienes ya instalado, git debería estar disponible a través del administrador de paquetes, prueba con: - - sudo apt-get install git - # o - sudo yum install git - - -## Iniciar nuestro repositorio Git - -Git rastrea los cambios realizados a un grupo determinado de ficheros en lo que llamamos un repositorio de código (o "repo" para abreviar). Iniciemos uno para nuestro proyecto. Abre la consola y ejecuta los siguientes comandos en el directorio de `djangogirls`: - -> **Nota**: Comprueba el directorio de trabajo actual con el comando `pwd` (OSX/Linux) o `cd` (Windows) antes de inicializar el repositorio. Deberías estar en la carpeta `djangogirls`. +{% filename %}command-line{% endfilename %} $ git init Initialized empty Git repository in ~/djangogirls/.git/ - $ git config user.name "Tu nombre" - $ git config user.email tú@ejemplo.com + $ git config --global user.name "Tu nombre" + $ git config --global user.email tu@ejemplo.com -Inicializar el repositorio git es algo que sólo necesitamos hacer una vez por proyecto (y no tendrás que volver a poner tu usuario y correo electrónico nunca más) +Inicializar el repositorio de git es algo que sólo tenemos que hacer una vez por proyecto (y no tendrás que volver a teclear tu nombre de usuario y correo electrónico nunca más). -Git llevará un registro de los cambios realizados en todos los ficheros y carpetas en este directorio, pero hay algunos ficheros que queremos que ignore. Esto lo hacemos creando un fichero llamado `.gitignore` en el directorio base. Abre tu editor y crea un nuevo fichero con el siguiente contenido: +Git llevará un seguimiento de los cambios realizados en todos los archivos y carpetas en este directorio, pero hay algunos archivos que queremos que ignore. Esto lo hacemos creando un archivo llamado `.gitignore` en el directorio base. Abre tu editor y crea un nuevo archivo con el siguiente contenido: + +{% filename %}.gitignore{% endfilename %} *.pyc + *~ __pycache__ myvenv db.sqlite3 + /static .DS_Store -Y guárdalo como `.gitignore` en la primera carpeta "djangogirls". +Y guárdalo como `.gitignore` en la carpeta "djangogirls". + +> **Nota** ¡El punto al principio del nombre del archivo es importante! Si tienes problemas para crearlo (a los Mac no les gusta que crees ficheros con un punto al principio del nombre usando el Finder por ejemplo), entonces usa la opción "Save As" o "Guardar como" de tu editor, esto funcionará seguro. Asegúrate de no añadir `.txt`, `.py`, o ninguna otra extensión al nombre de fichero -- Git solo lo reconocerá si se llama exactamente `.gitignore`, sin nada más. +> +> **Nota** Uno de los archivos especificados en tu `.gitignore` es `db.sqlite3`. Ese fichero es tu base de datos local, donde se almacenan los usuarios y publicaciones de tu blog. Vamos a seguir las buenas prácticas de programación web: vamos a usar bases de datos separadas para tu sitio local y tu sitio en producción en PythonAnywhere. La base de datos en PythonAnywhere podría ser SQLite, como en tu máquina de desarrollo, pero también podrías usar otro gestor de base de datos como MySQL o PostgreSQL que pueden soportar muchas más visitas que SQLite. En cualquier caso, al ignorar la base de datos SQLite en tu copia de GitHub, todos los posts y el super usuario que has creado hasta el momento solo estarán disponibles en local, y tendrás que crear nuevos usuarios y publicaciones en producción. Tu base de datos local es un buen campo de pruebas donde puedes probar diferentes cosas sin miedo a estropear o borrar las publicaciones reales de tu blog. -> **Nota**: ¡El punto al principio del nombre del fichero es importante! Si tienes dificultades para crearlo (a los Mac no les gusta que crees ficheros que empiezan por punto desde Finder, por ejemplo), usa la opción "Guardar como" en tu editor, eso no falla. +Te recomendamos utilizar el comando `git status` antes de `git add` o en cualquier momento en que no sepas muy bien lo que ha cambiado. Esto te ayudará a evitar sorpresas, como subir cambios o archivos que no queríamos subir. El comando `git status` muestra información sobre cualquier archivo no seguido ("untracked"), modificado ("modified"), preparado ("staged"), el estado de la rama y muchas cosas más. La salida debería ser parecida a esto: -Es buena idea utilizar el comando `git status` antes de `git add` o cuando no estés segura de lo que va a hacer, para evitar cualquier sorpresa (por ejemplo, añadir o hacer commit de ficheros no deseados). El comando `git status` devuelve información sobre los ficheros sin seguimiento (untracked), modificados, preparados (staged), el estado de la rama y mucho más. La salida debería ser similar a: +{% filename %}command-line{% endfilename %} $ git status On branch master - Initial commit + No commits yet Untracked files: (use "git add ..." to include in what will be committed) - .gitignore - blog/ - manage.py - mysite/ + .gitignore + blog/ + manage.py + mysite/ + requirements.txt nothing added to commit but untracked files present (use "git add" to track) Y finalmente guardamos nuestros cambios. Ve a la consola y ejecuta estos comandos: +{% filename %}command-line{% endfilename %} + $ git add --all . - $ git commit -m "Mi app Django Girls, primer commit" + $ git commit -m "Mi aplicación Django Girls, primer commit" [...] 13 files changed, 200 insertions(+) create mode 100644 .gitignore @@ -95,224 +85,137 @@ Y finalmente guardamos nuestros cambios. Ve a la consola y ejecuta estos comando create mode 100644 mysite/wsgi.py -## Enviar nuestro código a GitHub +## Subiendo tu código a Github -Visita [GitHub.com][4] y registra una nueva cuenta de usuario gratuita. Luego, crea un nuevo repositorio con el nombre "my-first-blog". Deja desmarcada la opción "Initialise with a README", deja la opción .gitignore en blanco (lo hemos hecho a mano) y deja la licencia como "None". +Vete a [GitHub.com](https://www.github.com) y regístrate para obtener una cuenta de usuario nueva y gratuita. (Si ya lo hiciste en la preparación del taller, ¡eso es genial!) Asegúrate de recordar tu contraseña (agrégala a tu administrador de contraseñas, si usas uno). - [4]: https://www.github.com +A continuación, crea un nuevo repositorio con el nombre "my-first-blog". Deja el checkbox "initialize with a README" sin marcar, deja la opción de .gitignore vacía (ya lo hemos hecho manualmente) y deja la licencia como None. -![][5] +![](images/new_github_repo.png) - [5]: images/new_github_repo.png +> **Nota** El nombre `my-first-blog` es importante - podrías escoger otro, pero va a salir muchas veces en las instrucciones que vienen a continuación, y vas a tener que acordarte de cambiarlo cada vez. Lo más fácil es quedarse con el nombre `my-first-blog`. -> **Nota** El nombre `my-first-blog` es importante. Podrías elegir otra cosa, pero va a aparecer muchas veces en las instrucciones que siguen y tendrías que sustituirlo cada vez. Probablemente sea más sencillo quedarte con el nombre `my-first-blog`. +En la siguiente pantalla, verás la URL para clonar el repo, que tendrás que usar en los comandos que van a continuación: -En la próxima pantalla verás la URL para clonar tu repositorio. Elige la versión "HTTPS", cópiala y en un momento la pegaremos en la consola: +![](images/github_get_repo_url_screenshot.png) -![][6] +Ahora necesitas enlazar el repositorio Git en tu ordenador con el repositorio de GitHub. - [6]: images/github_get_repo_url_screenshot.png +Escribe lo siguiente en la consola (cambia `` por tu nombre de usuario de GitHub, pero sin los símbolos < y > -- fíjate en que la URL debería coincidir con la URL para clonar el repo que acabas de ver): -Ahora tenemos que conectar el repositorio Git de tu ordenador con el que está en GitHub. +{% filename %}command-line{% endfilename %} $ git remote add origin https://github.com//my-first-blog.git $ git push -u origin master -Escribe tu nombre de usuario y contraseña de GitHub y deberías ver algo así: +Cuando hagas push a GitHub, te preguntará tu usuario y password de GitHub, y después de introducirlos, deberías ver algo como esto: + +{% 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 + To https://github.com/ola/my-first-blog.git + * [new branch] master -> master Branch master set up to track remote branch master from origin. - - -Tu código está ahora en GitHub. ¡Ve y míralo! Verás que está en buena compañía; [Django][7], el [Tutorial de Django Girls][8] y muchos otros grandes proyectos de código abierto también alojan su código en GitHub :) + - [7]: https://github.com/django/django - [8]: https://github.com/DjangoGirls/tutorial +Tu código ya está subido a GitHub. ¡Ve y compruébalo! Encontrarás que está en buena compañía - [Django](https://github.com/django/django), [Django Girls Tutorial](https://github.com/DjangoGirls/tutorial) y muchos otros proyectos de software libre están alojados en GitHub. :) # Configurar nuestro blog en PythonAnywhere -Es hora de registrar una cuenta gratuita de tipo "Beginner" en PythonAnywhere. - -* [www.pythonanywhere.com][9] - - [9]: https://www.pythonanywhere.com/ - -> **Nota**: Cuando elijas tu nombre de usuario ten en cuenta que la URL de tu blog tendrá la forma `nombredeusuario.pythonanywhere.com`, así que o bien elije tu propio apodo o bien un nombre que describa sobre qué trata tu blog. +## Crea una cuenta en PythonAnywhere -## Bajar nuestro código en PythonAnywhere +> **Nota** A lo mejor ya has creado una cuenta en PythonAnywhere durante los pasos de instalación. Si es así, no necesitas hacerlo otra vez. -Cuando te hayas registrado en PythonAnywhere serás redirigida a tu panel de control o página "Consoles". Elije la opción para iniciar una consola "Bash", que es la versión PythonAnywhere de una consola, como la que tienes en tu PC +{% include "/deploy/signup_pythonanywhere.md" %} -> **Nota**: PythonAnywhere está basado en Linux, por lo que si estás en Windows la consola será un poco distinta a la que tienes en tu ordenador. +## Configurar nuestro sitio en PythonAnywhere -Descarguemos nuestro código desde GitHub a PythonAnywhere mediante la creación de un "clon" del repositorio. Escribe lo siguiente en la consola de PythonAnywhere: +Vuelve al [dashboard de PythonAnywhere](https://www.pythonanywhere.com/) haciendo click en el logo, y escoge la opción de iniciar una consola "Bash" – esta terminal es como la que hay en tu ordenador, pero en el servidor de PythonAnywhere. - $ git clone https://github.com//my-first-blog.git +![La sección 'New Console' en la interfaz de PythonAnywhere con un botón para 'bash'](images/pythonanywhere_bash_console.png) -> **Nota**: No pongas los símbolos < y >, solo escribe tu usuario. +> **Nota** PythonAnywhere está basado en Linux, así que si estás en Windows, la consola será un poco distinta a la de tu ordenador. -Esto va a descargar una copia de tu código en PythonAnywhere. Compruébalo escribiendo: +Para desplegar una aplicación web en PythonAnywhere necesitas descargar tu código de GitHub y configurar PythonAnywhere para que lo reconozca y lo sirva como una aplicación web. Hay formas de hacerlo manualmente, pero PythonAnywhere tiene una herramienta automática que lo hará todo por nosotros. Lo primero, vamos a instalar la herramienta: - $ 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 - - -### Crear un virtualenv en PythonAnywhere - -Tal y como hiciste en tu propio ordenador, puedes crear un virtualenv en PythonAnywhere. En la consola Bash, escribe: +{% filename %}PythonAnywhere command-line{% endfilename %} - 20:20 ~ $ cd my-first-blog - - 20:20 ~ $ virtualenv --python=python3.4 myvenv - Running virtualenv with interpreter /usr/bin/python3.4 - [...] - Installing setuptools, pip...done. - - 20:20 ~ $ source myvenv/bin/activate - - (myvenv)20:20 ~ $ pip install django==1.8 whitenoise - Collecting django - [...] - Successfully installed django-1.8 whitenoise-1.0.6 + $ pip3.6 install --user pythonanywhere - +Eso debería mostrar en pantalla algunos mensajes como `Collecting pythonanywhere`, y finalmente una linea diciendo que ha terminado bien: `Successfully installed (...) pythonanywhere- (...)`. -### Recopilar ficheros estáticos +Ahora ejecutaremos el asistente para configurar automáticamente nuestra aplicación desde GitHub. Teclea lo siguiente en la consola de PythonAnywhere (no te olvides de usar tu propio nombre de usuario de GitHub en lugar de ``, para que la URL sea como la URL de clonar el repo de GitHub): -¿Te estabas preguntando qué es eso de "whitenoise"? Es una herramienta para servir los llamados "ficheros estáticos". Los ficheros estáticos funcionan de distinta forma en los servidores en comparación con cómo lo hacen en nuestro propio ordenador y necesitamos una herramienta como "whitenoise" para servirlos. +{% filename %}PythonAnywhere command-line{% endfilename %} -Aprenderemos un poco más sobre los ficheros estáticos más adelante, cuando editemos el CSS de nuestro sitio. - -Por ahora sólo necesitamos ejecutar en el servidor un comando adicional llamado "collectstatic". Le dice a Django que recopile todos los ficheros estáticos que necesita en el servidor. Por el momento, principalmente son los ficheros estáticos que hacen que el panel de administración esté bonito. - - 20:20 ~ $ 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 + $ pa_autoconfigure_django.py --python=3.6 https://github.com//my-first-blog.git -Escribe "yes", ¡y ahí va! ¿No te encanta hacer que las computadoras impriman páginas y páginas de texto imposible de entender? Siempre hago ruiditos para acompañarlo. Brp, brp brp... +A medida que se ejecuta, podrás ver lo que hace: - Copying '/home/edith/.virtualenvs/myvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/actions.min.js' - Copying '/home/edith/.virtualenvs/myvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/inlines.min.js' - [...] - Copying '/home/edith/.virtualenvs/myvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/css/changelists.css' - Copying '/home/edith/.virtualenvs/myvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/css/base.css' - 62 static files copied to '/home/edith/my-first-blog/static'. - +- Se descarga tu código de GitHub. +- Crea un virtualenv en PythonAnywhere, como el de tu propia computadora. +- Actualiza tus ficheros de settings con algunos settings de despliegue. +- Crea la base de datos en PythonAnywhere ejecutando el comando `manage.py migrate`. +- Configura los archivos estáticos (static) (luego hablaremos de éstos con más detalle). +- Y configura PythonAnywhere para publicar tu aplicación web a través de su API. -### Crear la base de datos en PythonAnywhere +En PythonAnywhere todos estos pasos están automatizados, pero son los mismos que tendrías que seguir en cualquier otro proveedor de servidores. -Aquí hay otra cosa que es diferente entre tu ordenador y el servidor: éste utiliza una base de datos diferente. Por lo tanto, las cuentas de usuario y las entradas pueden ser diferentes en el servidor y en tu ordenador. +Lo más importante que debes notar en este momento es que tu base de datos en PythonAnywhere está totalmente separada de tu base de datos en tu propia computadora, por lo que puedes tener diferentes publicaciones y cuentas de administrador. Como consecuencia, igual que lo hicimos en tu ordenador, tenemos que crear la cuenta de administrador con el comando `createsuperuser`. PythonAnywhere ya ha activado el virtualenv automáticamente, así que lo único que tienes que hacer es ejecutar: -Así que inicializamos la base de datos en el servidor igual que lo hicimos en nuestro ordenador, con `migrate` y `createsuperuser`: +{% filename %}PythonAnywhere command-line{% endfilename %} - (myvenv)20:20 ~ $ python manage.py migrate - Operations to perform: - [...] - Applying sessions.0001_initial... OK - - - (myvenv)20:20 ~ $ python manage.py createsuperuser + (ola.pythonanywhere.com) $ python manage.py createsuperuser -## Publicar nuestro blog como una aplicación web - -Ahora que nuestro código está en PythonAnywhere, el virtualenv está listo, los ficheros estáticos han sido recopilados y la base de datos está inicializada, estamos listas para publicarla como una aplicación web. - -Haz clic en el logo de PythonAnywhere para volver al panel principal, haz clic en la pestaña **Web** y pincha en **Add a new web app**. - -En la ventana de diálogo, después de confirmar el nombre de dominio, elije **manual configuration** (configuración manual) (NB la opción "Django" *no*). Luego, elije **Python 3.4** y haz clic en "Next" para terminar con el asistente. +Teclea las credenciales para tu usuario admin. Para evitar confusiones, te recomendamos usar el mismo nombre de usuario que usaste en tu ordenador local; aunque a lo mejor prefieres que la contraseña en PythonAnywhere sea más segura. -> **Nota** asegúrate de elegir la opción de "Manual configuration", no la de "Django". Somos demasiado buenas para la configuración por defecto de Django de PythonAnywhere ;-) +Ahora, si quieres, también puedes ver tu código en PythonAnywhere con el comando `ls`: -### Configurar el virtualenv +{% filename %}PythonAnywhere command-line{% endfilename %} -Serás redirigida a la pantalla de configuración de PythonAnywhere para tu aplicación web, a la que deberás acceder cada vez que quieras hacer cambios en la aplicación del servidor. - -![][10] - - [10]: images/pythonanywhere_web_tab_virtualenv.png - -En la sección "Virtualenv", haz clic en el texto rojo que dice "Enter the path to a virtualenv" (Introduce la ruta a un virtualenv) y escribe: `/home//my-first-blog/myvenv/` - -> **Nota**: sustituye tu propio nombre de usuario como corresponda. Si cometes un error, PythonAnywhere te mostrará una pequeña advertencia. ¡No olvides no teclear los simbolos < y >! - -### Configurar el fichero WSGI - -Django funciona utilizando el "protocolo WSGI", un estándar para servir sitios web usando Python, que PythonAnywhere soporta. La forma de configurar PythonAnywhere para que reconozca nuestro blog Django es editar un fichero de configuración WSGI. + (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 + -Haz clic en el enlace "WSGI configuration file" (en la sección "Code" en la parte de arriba de la página; se llamará algo parecido a `/var/www/_pythonanywhere_com_wsgi.py`) y te redirigirá al editor. +También puedes ir a la página de ficheros ("Files") y navegar por los ficheros y directorios usando el visor de PythonAnywhere. (Desde la página de la consola ("Console"), puedes ir a cualquier otra página de PythonAnywhere usando el botón de la esquina superior derecha. Desde el resto de páginas, también hay enlaces a las otras en la parte superior.) -Elimina todo el contenido actual y reemplázalo con algo como esto: +## ¡Ya estás en vivo! -``` python - import os - import sys - - path = '/home//my-first-blog' # aquí utiliza tu propio usuario, sin los simbolos < y > - 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()) -``` +¡Tu sitio ya debería estar online en internet! Haz click en la página "Web" de PythonAnywhere para obtener un enlace a él. Puedes compartir este enlace con quien tu quieras :) -> **Nota** no olvides sustituir tu propio nombre de usuario donde dice `` +> **Nota** Este es un tutorial para principiantes, y al desplegar este sitio hemos tomado algunos atajos que tal vez no sean las mejores prácticas desde el punto de vista de la seguridad. Si decide construir sobre este proyecto, o comenzar un nuevo proyecto, debe revisar la [lista de verificación de despliegue de Django](https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/) para obtener algunos consejos sobre cómo proteger su sitio. -Este fichero se encarga de decirle a PythonAnywhere dónde vive nuestra aplicación web y cómo se llama el fichero de configuración de Django. También configura la herramienta para ficheros estáticos "whitenoise". +## Consejos de depuración -Dale a **Save** y vuelve a la pestaña **Web**. +Si te sale un error al ejecutar el script `pa_autconfigure_django.py`, aquí hay algunas causas comunes: -¡Todo listo! Dale al botón verde grande que dice **Reload** y podrás ver tu aplicación. Verás un enlace a ella en la parte de arriba de la página. +- Te has olvidado de crear el token de API de PythonAnywhere. +- No has puesto bien la URL de GitHub. +- Si ves un error diciendo *"Could not find your settings.py*, es probable que no añadieras todos tus archivos a Git, y/o no los subiste a GitHub correctamente. Repasa la sección de Git más arriba. +- Si anteriormente te suscribiste a una cuenta de PythonAnywhere y tuviste un error con *collectstatic*, probablemente tengas una versión antigua de SQLite (por ejemplo, 3.8.2) en tu cuenta. En este caso, regístrate con una nueva cuenta e intenta los comandos en la sección PythonAnywhere anterior. -## Consejos de depuración +Si ves un error al visitar tu sitio, el primer lugar para ver qué está pasando es el **log de errores**. Encontrarás un enlace en la página ["Web"](https://www.pythonanywhere.com/web_app_setup/) de PythonAnywhere. Mira si hay algún mensaje de error allí; los más recientes están en la parte inferior. -Si aparece un error cuando intentas visitar tu sitio, el primer lugar que deberás revisar para obtener información de depuración es el **error log**; encontrarás un enlace a él en la pestaña Web de PythonAnywhere. Mira a ver si hay algún mensaje de error ahí. Los más recientes están al final. Los problemas más comunes incluyen +Hay también algunos [consejos generales de depuración en la página de ayuda de PythonAnywhere](http://help.pythonanywhere.com/pages/DebuggingImportError). -* olvidar alguno de los pasos que hicimos en la consola: crear el virtualenv, activarlo, instalar Django en él, ejecutar collectstatic, inicializar la base de datos -* cometer un error en la ruta del virtualenv en la pestaña Web; suele haber un mensajito de error de color rojo, si hay algún problema -* cometer un error en el fichero de configuración WSGI; ¿has puesto bien la ruta a la carpeta my-first-blog? +Y recuerda, ¡tu mentora está aquí para ayudar! -¡Tu tutor está ahí para ayudar! +# ¡Comprueba tu página! -# ¡Estás en vivo! +La página por defecto debería decir "It worked!", tal como dice en tu ordenador local. Prueba a añadir `/admin/` al final de la URL y llegarás a la página de administración. Entra con tu usuario y password, y verás que puedes añadir nuevas publicaciones en el servidor -- recuerda, los post que tenías en tu base de datos local no se han subido a al blog publicado en producción. -La página por defecto de tu sitio debería decir "Welcome to Django", igual que en tu PC local. Intenta añadir `/admin/` al final de la URL y te redirigirá al panel de administración. Ingresa con tu nombre de usuario y contraseña y verás que puedes añadir nuevas entradas en el servidor. +Después de crear algunas publicaciones, puedes volver a tu instalación local (no la de PythonAnywhere). A partir de ahora, trabaja en tu instalación local para hacer los siguientes cambios. Este es un flujo de trabajo típico en el desarrollo web – haz cambios localmente, sube (push) esos cambios a GitHub, y descarga (pull) tus cambios al servidor de publicación. Esto te permite trabajar y experimentar en local sin romper tu página publicada. Mola, ¿eh? -*¡Buen trabajo!* - los despliegues en el servidor son una de las partes más complejas del desarrollo web y muchas veces a la gente le cuesta varios días tenerlo funcionando. Pero tú tienes tu sitio en vivo, en Internet de verdad, ¡así como suena! +¡Date una *GRAN* palmada en la espalda! Desplegar a un servidor es una de las partes más complicadas de desarrollo web y a menudo la gente necesita varios días para que funcione del todo. Pero tú ya tienes tu sitio publicado, ¡en internet de verdad! \ No newline at end of file diff --git a/es/deploy/images/github_get_repo_url_screenshot.png b/es/deploy/images/github_get_repo_url_screenshot.png index 62a29f5f8d7..ee1560b1e85 100644 Binary files a/es/deploy/images/github_get_repo_url_screenshot.png and b/es/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/es/deploy/images/new_github_repo.png b/es/deploy/images/new_github_repo.png index 64011e59a52..d1f82e5d863 100644 Binary files a/es/deploy/images/new_github_repo.png and b/es/deploy/images/new_github_repo.png differ diff --git a/es/deploy/images/pythonanywhere_account.png b/es/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/es/deploy/images/pythonanywhere_account.png differ diff --git a/es/deploy/images/pythonanywhere_bash_console.png b/es/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..458b43f5d0d Binary files /dev/null and b/es/deploy/images/pythonanywhere_bash_console.png differ diff --git a/es/deploy/images/pythonanywhere_beginner_account_button.png b/es/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/es/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/es/deploy/images/pythonanywhere_create_api_token.png b/es/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..6e617d0a53e Binary files /dev/null and b/es/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/es/deploy/images/pythonanywhere_web_tab_virtualenv.png b/es/deploy/images/pythonanywhere_web_tab_virtualenv.png deleted file mode 100644 index 97e87e7b07b..00000000000 Binary files a/es/deploy/images/pythonanywhere_web_tab_virtualenv.png and /dev/null differ diff --git a/es/deploy/install_git.md b/es/deploy/install_git.md new file mode 100644 index 00000000000..906ce43c9ea --- /dev/null +++ b/es/deploy/install_git.md @@ -0,0 +1,52 @@ +Git es un "sistema de control de versiones" que utilizan muchos programadores. Este software puede seguir los cambios realizados en archivos a lo largo del tiempo de forma que más tarde puedas volver a cualquier versión anterior. Algo similar a la herramienta de "Control de Cambios" en los programas de tipo Word (por ejemplo, Microsoft Word o LibreOffice Writer), pero mucho más potente. + +## Instalar Git + + + +Puedes descargar Git desde [git-scm.com](https://git-scm.com/). Puedes hacer click en "Next" en todos los pasos excepto en dos: cuando se te pregunte que selecciones tu editor, selecciona Nano, y en el paso "adjusting your PATH environment", selecciona "Use Git and optional Unix tools from the Windows Command Prompt" (la última opción). Aparte de eso, los valores por defecto son correctos. "Checkout Windows-style, commit Unix-style line endings" tampoco necesita corrección. + +No olvides reiniciar el Símbolo del Sistema o el PowerShell una vez que la instalación se complete con éxito. + + + +Descarga Git de [git-scm.com](https://git-scm.com/) y sigue las instrucciones. + +> **Nota** Si estas usando OS X 10.6, 10.7 o 10.8, tendrás que instalar git desde aquí: [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) + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo apt install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo dnf install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$sudo zypper install git +``` + + \ No newline at end of file diff --git a/es/deploy/signup_pythonanywhere.md b/es/deploy/signup_pythonanywhere.md new file mode 100644 index 00000000000..03bdd1c7f53 --- /dev/null +++ b/es/deploy/signup_pythonanywhere.md @@ -0,0 +1,19 @@ +PythonAnywhere es un servicio para ejecutar código Python en servidores "en la nube". Lo vamos a usar para alojar nuestro sitio para que esté disponible en Internet. + +Almacenaremos del blog que estamos construyendo sobre Python Anywhere. Crea una cuenta como "Principiante/Beginner" en Python Anywhere (el modo gratuito está bien, no necesitas una tarjeta de crédito). + +* [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +![La pagina de entrada de Python Anywhere muestra el botón para crear una cuenta "Principiante"](../deploy/images/pythonanywhere_beginner_account_button.png) + +> **Nota** Cuando elijas un nombre de usuario, recuerda que la URL de tu blog tendrá la forma `tunombredeusuario.pythonanywhere.com`, así que lo mejor será usar tu apodo o elegir un nombre que indique de qué trata tu blog. Asegúrate también de recordar tu contraseña (añádela a tu gestor de contraseñas, si usas uno). + +## Crear un token para la API de PythonAnywhere + +Este paso solo necesita ser completado una vez. Una vez que te hayas registrado en PythonAnywhere, serás llevado a tu tablón principal. Encontrarás el enlace a la página de tu "Cuenta" en la esquina superior derecha: + +![Enlace de cuenta en la parte superior derecha de la página](../deploy/images/pythonanywhere_account.png) + +Después selecciona la lengueta llamada "API token", y haz click en el botón que dice "Crear nueva API token" + +![Lengüeta de la API token en la página de cuenta](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/es/django/README.md b/es/django/README.md index 782c575948f..4f3961707b2 100755 --- a/es/django/README.md +++ b/es/django/README.md @@ -1,27 +1,27 @@ # ¿Qué es Django? -Django (*gdh/ˈdʒæŋɡoʊ/jang-goh*) es un framework para aplicaciones web gratuito y open source, escrito en Python. Es un WEB framework - un conjunto de componentes que te ayudan a desarrollar sitios web más fácil y rápidamente. +Django (*gdh/ˈdʒæŋɡoʊ/jang-goh*) es un framework de aplicaciones web gratuito y de código abierto (open source) escrito en Python. Un framework web es un conjunto de componentes que te ayudan a desarrollar sitios web más fácil y rápidamente. -Verás, cuando estás construyendo un sitio web, frecuentemente necesitas un conjunto de componentes similares: una manera de manejar la autenticación de usuarios (registrarse, iniciar sesión, cerrar sesión), un panel de administración para tu sitio web, formularios, una forma de subir archivos, etc. +Cuando construyes un sitio web, siempre necesitas un conjunto de componentes similares: una manera de manejar la autenticación de usuarios (registrarse, iniciar sesión, cerrar sesión), un panel de administración para tu sitio web, formularios, una forma de subir archivos, etc. -Por suerte para ti, hace tiempo varias personas notaron que los desarrolladores web enfrentan problemas similares cuando construyen un sitio nuevo, por eso juntaron cabezas y crearon frameworks (Django es uno de ellos) que te ofrecen componentes listos para usarse. +Por suerte para nosotros, hace tiempo que otros desarrolladores se dieron cuenta de que siempre se enfrentaban a los mismos problemas cuando construían sitios web, y por eso se unieron y crearon frameworks (Django es uno de ellos) con componentes listos para usarse. -Los frameworks existen para ahorrarte tener que reinventar la rueda y ayudarte a aliviar la carga cuando construyes un sitio. +Los frameworks sirven para que no tengamos que reinventar la rueda cada vez y que podamos avanzar más rápido al construir un nuevo sitio. ## ¿Por qué necesitas un framework? -Para entender para que es Django, necesitamos mirar mas de cerca a los servidores. Lo primero es que el servidor necesita saber que quieres que te sirva una página web. +Para entender para qué sirve realmente Django, necesitamos fijarnos en cómo funcionan los servidores. Lo primero es que el servidor necesita enterarse de que tú quieres que te sirva una página web. -Imagina un buzón (puerto) el cual es monitoreado por cartas entrantes (peticiones). Esto es realizado por un servidor web. El servidor web lee la carta, y envía una respuesta con una página web. Pero cuando quieres enviar algo, tienes que tener algún contenido. Y Django es algo que te ayuda a crear el contenido. +Imagina un buzón (puerto) en el que alguien está constantemente mirando si hay cartas entrantes (peticiones). Esto es lo que hace un servidor web. El servidor web lee la carta, y envía una respuesta con la página web. Pero para enviar algo, tenemos que tener algún contenido. Y Django nos ayuda a crear ese contenido. ## ¿Qué sucede cuando alguien solicita una página web de tu servidor? -Cuando llega una petición a un servidor web, ésta es pasada a Django, el cual intenta averiguar lo que realmente es solicitado. Toma primero una dirección de página web y trata de averiguar qué hacer. Esta parte es realizada por el **urlresolver** de Django (ten en cuenta que la dirección de un sitio web es llamada URL - Uniform Resource Locator - así que el nombre *urlresolver* tiene sentido). Este no es muy inteligente - toma una lista de patrones y trata de encontrar la URL. Django comprueba los patrones de arriba hacia abajo y si algo coincide entonces Django le pasa la solicitud a la función asociada (que se llama *vista*). +Cuando llega una petición a un servidor web, esta es pasada a Django, quien intenta averiguar qué es lo realmente solicitado. Toma primero una dirección de página web e intenta averiguar qué hacer con ella. Esta parte es realizada por el **urlresolver** de Django (ten en cuenta que la dirección de un sitio web es llamada URL - Uniform Resource Locator; así que el nombre *urlresolver* tiene sentido). Este no es muy inteligente - toma una lista de patrones y trata de hacer coincidir la URL. Django comprueba los patrones de arriba hacia abajo y si algo coincide entonces Django le pasa la solicitud a la función asociada (que se llama *view (vista)*). -Imagina a un cartero llevando una carta. Ella está caminando por la calle y comprueba cada número de casa con el que está en la carta. Si coincide, ella deja la carta allí. ¡Así es como funciona el urlresolver! +Imagina a un cartero llevando una carta. Él está caminando por la calle y comprueba cada número de casa con el que está en la carta. Si coincide, deja la carta allí. Así es como funciona el urlresolver! -En la función de *vista* se hacen todas las cosas interesantes: podemos mirar a una base de datos para buscar alguna información. ¿Tal vez el usuario pidió cambiar algo en los datos? Como una carta diciendo "Por favor cambia la descripción de mi trabajo." La *vista* puede comprobar si tenes permitido hacer eso, entonces actualizar la descripción del trabajo para ti y devolverte un mensaje: "¡hecho!". Entonces la *vista* genera una respuesta y Django puede enviarla al navegador del usuario. +En la función de *view (vista)* se hacen todas las cosas interesantes: podemos mirar a una base de datos para buscar alguna información. ¿Tal vez el usuario pidió cambiar algo en los datos? Como una carta diciendo "Por favor cambia la descripción de mi trabajo." La *vista* puede comprobar si tienes permiso para hacerlo, actualizar la descripción de tu trabajo y devolver un mensaje: "¡Hecho!". Luego la *vista* genera una respuesta y Django puede enviarla al navegador del usuario. -Por supuesto, la descripción anterior esta simplificada un poco, pero no necesitas saber todas las cosas técnicas aun. Tener una idea general es suficiente. +Esta descripción es un poco simplista, pero de momento no necesitas saber todos los detalles técnicos, con tener una idea general es más que suficiente. -Así que en lugar de meternos demasiado en los detalles, ¡simplemente comenzaremos creando algo con Django y aprenderemos todas las piezas importantes en el camino! +Así que en lugar de detenernos demasiado en los detalles, vamos a empezar a crear algo con Django y ¡así aprenderemos las cosas importantes sobre la marcha! \ No newline at end of file diff --git a/es/django_admin/README.md b/es/django_admin/README.md index c340823c749..a2b07feae4a 100755 --- a/es/django_admin/README.md +++ b/es/django_admin/README.md @@ -1,48 +1,57 @@ # Administrador de Django -Para agregar, editar y borrar los posts que hemos modelado, utilizaremos el administrador de Django. +Para agregar, editar y borrar los posts que hemos modelado, usaremos el administrador (admin) de Django. -Vamos a abrir el archivo `blog/admin.py` y reemplazar su contenido con esto: +Abre el fichero `blog/admin.py` en el editor y reemplaza su contenido con esto: + +{% filename %}blog/admin.py{% endfilename %} ```python - from django.contrib import admin - from .models import Post - - admin.site.register(Post) +from django.contrib import admin +from .models import Post + +admin.site.register(Post) ``` Como puedes ver, importamos (incluimos) el modelo Post definido en el capítulo anterior. Para hacer nuestro modelo visible en la página del administrador, tenemos que registrar el modelo con `admin.site.register(Post)`. -Ok, es hora de ver tu modelo Post. Recuerda ejecutar `python manage.py runserver` en la consola para correr el servidor web. Ve al navegador y tipea la dirección http://127.0.0.1:8000/admin/. Verás una página de ingreso como la que sigue: +Ok, es hora de ver nuestro modelo Post. Recuerda ejecutar `python manage.py runserver` en la consola para correr el servidor web. Ve a tu navegador y escribe la dirección http://127.0.0.1:8000/admin/. Verás una página de inicio de sesión como esta: -![Página de inicio de sesión][1] +![Página de inicio de sesión](images/login_page2.png) - [1]: images/login_page2.png +Para iniciar sesión, deberás crear un *superusuario (superuser)*, que es un usuario que tiene control sobre todo el sitio. Vuelve a la línea de comandos, escribe `python manage.py createsuperuser` y pulsa enter. -Para poder ingresar deberás crear un *superusuario* - un usuario que tiene control sobre todo lo que hay en el sitio. Vuelve hacia atrás a tu línea de comandos y tipea `python manage.py createsuperuser`, presiona enter y tipea tu nombre de usuario (en minúsculas, sin espacios), dirección de email y contraseña cuando sean requeridos. No te preocupes que no puedes ver tu contraseña mientras la tipeas - así es como debe ser. Simplemente tipéala y presiona 'Enter' para continuar. La salida de este comando debería verse así (nombre de usuario y email deberían ser los tuyos): +> Recuerda, para escribir comandos mientras el servidor web está funcionando, abre una nueva terminal y activa el virtualenv. Revisamos cómo escribir nuevos comandos en el capítulo **Tu primer proyecto de Django!**, al inicio de la sección **Iniciando el servidor web**. + +{% filename %}macOS o 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 + + +Cuando te lo pida, escribe tu nombre de usuario (en minúscula, sin espacios), email y contraseña. **No te preocupes si no puedes ver la contraseña que estás tecleando - así es como debe ser.** Tecléalo y pulsa `intro` para continuar. Luego, verás algo así (donde username y email serán los que escribiste anteriormente): + + Username: ola + Email address: ola@example.com Password: Password (again): Superuser created successfully. -Vuelve a tu navegador e ingresa con las credenciales de super usuario que elegiste, ahora deberías poder ver el panel de administración de Django. - -![Administrador de Django][2] - - [2]: images/django_admin3.png +Vuelve a tu navegador. Entra con las credenciales de super usuario que escogiste; verás el panel de administrador de Django. -Ve a Posts y experimenta un poco con esto. Agrega cinco o seis posts del blog. No te preocupes por el contenido - puedes simplemente copiar y pegar texto de este tutorial en el contenido de tus posts para ahorrar tiempo :). +![Administrador de Django](images/django_admin3.png) -Asegúrate de que por lo menos dos o tres posts (pero no todos) tienen la fecha de publicación. Será útil luego. +Ve a 'Posts' y curiosea un poco. Añade cinco o seis publicaciones en tu blog. No te preocupes por el contenido -- solo será visible para ti en tu ordenador -- puedes copiar y pegar texto de este tutorial para ir más rápido. :) -![Administrador de Django][3] +Asegúrate de que al menos dos o tres posts (pero no todos) tengan la fecha de publicación definida. Esto será muy poderoso después. - [3]: images/edit_post3.png +![Administrador de Django](images/edit_post3.png) -Si quieres saber más sobre el administrador de Django, puedes visitar la documentación de Django: https://docs.djangoproject.com/en/1.8/ref/contrib/admin/ +Si desea saber más sobre el administrador de Django, debe consultar la documentación de Django: https://docs.djangoproject.com/en/2.2/ref/contrib/admin/ -Este probablemente sea un buen momento para tomar un café (o té) o algo para comer y re-energizarte. Creaste tu primer modelo de Django - ¡mereces un pequeño recreo! +Este posiblemente sea un buen momento para tomar un café (o té) o algo para comer y reenergizar tu cuerpo. Has creado tu primer modelo en Django - ¡Mereces un pequeño descanso! \ No newline at end of file diff --git a/es/django_admin/images/django_admin3.png b/es/django_admin/images/django_admin3.png index a450b4f9630..fb221bd18e1 100644 Binary files a/es/django_admin/images/django_admin3.png and b/es/django_admin/images/django_admin3.png differ diff --git a/es/django_admin/images/edit_post3.png b/es/django_admin/images/edit_post3.png index c8572a73e7d..57299b6f5af 100644 Binary files a/es/django_admin/images/edit_post3.png and b/es/django_admin/images/edit_post3.png differ diff --git a/es/django_admin/images/login_page2.png b/es/django_admin/images/login_page2.png index 47153ef6960..c16d1aa4289 100644 Binary files a/es/django_admin/images/login_page2.png and b/es/django_admin/images/login_page2.png differ diff --git a/es/django_forms/README.md b/es/django_forms/README.md index 8e9118ac1f1..2e4c49fa148 100755 --- a/es/django_forms/README.md +++ b/es/django_forms/README.md @@ -1,40 +1,42 @@ -# Formularios en Django +# Formularios de Django -Lo último que haremos en nuestro website es crear un apartado para agregar y editar posts en el blog. Django `admin` está bien, pero es bastante difícil de personalizar y hacerlo bonito. Con `forms` tendremos un poder absoluto sobre nuestra interfaz - ¡podemos hacer casi cualquier cosa que podamos imaginar! +Lo último que haremos en nuestro sitio web será crear una forma agradable de agregar y editar posts en el blog. El `admin` de Django está bien, pero es bastante difícil de personalizar y hacerlo bonito. Con `forms` tendremos un poder absoluto sobre nuestra interfaz; ¡podemos hacer casi cualquier cosa que podamos imaginar! -Lo bueno de Django forms es que podemos definirlo desde cero o creando un `ModelForm` y se guardará el resultado del formulario en el modelo. +Lo bueno de los formularios de Django es que podemos definirlos desde cero o crear un `ModelForm`, el cual guardará el resultado del formulario en el modelo. Esto es exactamente lo que queremos hacer: crearemos un formulario para nuestro modelo `Post`. -Como cada parte importante de Django, forms tienen su propio archivo: `forms.py`. +Como cada parte importante de Django, los formularios tienen su propio archivo: `forms.py`. -Tenemos que crear un archivo con este nombre en el directorio `blog`. +Necesitamos crear un archivo con este nombre en el directorio `blog`. blog └── forms.py -Ok, vamos a abrirlo y vamos a escribir el siguiente código: - +Vale, ábrelo en el editor de código y teclea lo siguiente: + +{% filename %}blog/forms.py{% endfilename %} + ```python - from django import forms - - from .models import Post - - class PostForm(forms.ModelForm): - - class Meta: - model = Post - fields = ('title', 'text',) -``` +from django import forms + +from .models import Post -Primero necesitamos importar Django forms (`from django import forms`) y, obviamente, nuestro modelo `Post` (`from .models import Post`). +class PostForm(forms.ModelForm): -`PostForm`, como probablemente sospechas, es el nombre del formulario. Necesitamos decirle a Django que este formulario es un `ModelForm` (así Django hará algo de magia para nosotros) - `forms.ModelForm` es responsable de ello. + class Meta: + model = Post + fields = ('title', 'text',) +``` + +Lo primero, necesitamos importar Django forms (`from django import forms`) y nuestro modelo `Post` (`from .models import Post`). -A continuación, tenemos `class Meta`, donde le decimos a Django qué modelo debe utilizar para crear este formulario (`model = Post`). +`PostForm`, como probablemente sospechas, es el nombre de nuestro formulario. Necesitamos decirle a Django que este formulario es un `ModelForm` (así Django hará algo de magia por nosotros) - `forms.ModelForm` es responsable de ello. -Finalmente, podemos decir que campo(s) queremos en nuestro formulario. En este escenario sólo queremos `title` y `text` - `author` será la persona que se ha autenticado (¡tú!) y `created_date` se definirá automáticamente cuando creemos un post (es decir en el código), ¿si? +Luego, tenemos `class Meta`, donde le decimos a Django qué modelo debe ser utilizado para crear este formulario (`model = Post`). + +Finalmente, podemos decir qué campo(s) deberían estar en nuestro formulario. En este escenario sólo queremos `title` y `text` para ser mostrados - `author` será la persona que está conectada (¡tú!) y `created_date` se definirá automáticamente cuando creemos un post (es decir, en el código), ¿cierto? ¡Y eso es todo! Todo lo que necesitamos hacer ahora es usar el formulario en una *view* y mostrarla en una plantilla. @@ -42,120 +44,130 @@ Una vez más vamos a crear: un enlace a la página, una dirección URL, una vist ## Enlace a una página con el formulario -Es hora de abrir `blog/templates/blog/base.html`. Vamos a añadir un enlace en `div` llamado `page-header`: +Ahora toca abrir el fichero `blog/templates/blog/base.html` en el editor. Vamos a añadir un enlace en el `div` llamado `page-header`: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - -``` + +``` + +Ten en cuenta que queremos llamar a nuestra nueva vista `post_new`. La clase `"glyphicon glyphicon-plus"` es proporcionada por el tema de bootstrap que estamos utilizando, y nos mostrará un signo de suma. -Ten en cuenta que queremos llamar a nuestra nueva vista `post_new`. +Después de agregar la línea, tu archivo html debería lucir de esta forma: -Después de agregar la línea, tu archivo html debería tener este aspecto: +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - {% load staticfiles %} - - - Django Girls blog - - - - - - - -
-
-
- {% block content %} - {% endblock %} -
+{% load static %} + + + Django Girls blog + + + + + + + +
+
+
+ {% block content %} + {% endblock %}
- - -``` +
+ + +``` -Luego de guardar y actualizar la página `http://127.0.0.1:8000` obviamente verás un error `NoReverseMatch` familiar, ¿verdad? +Después de guardar y refrescar la página http://127.0.0.1:8000 verás el - ya conocido - error `NoReverseMatch`. ¿Es así? ¡Vamos bien! ## URL -Abrimos `blog/urls.py` y añadimos una línea: +Abrimos `blog/urls.py` en el editor para añadir una línea: + +{% filename %}blog/urls.py{% endfilename %} ```python - url(r'^post/new/$', views.post_new, name='post_new'), -``` +path('post/new', views.post_new, name='post_new'), +``` Y el código final tendrá este aspecto: +{% filename %}blog/urls.py{% endfilename %} + ```python - from django.conf.urls import url - from . import views - - urlpatterns = [ -     url(r'^$', views.post_list), -     url(r'^post/(?P[0-9]+)/$', views.post_detail), -     url(r'^post/new/$', views.post_new, name='post_new'), - ] -``` +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), + path('post/new/', views.post_new, name='post_new'), +] +``` -Después de actualizar el sitio, veremos un `AttributeError`, puesto que no tenemos la vista `post_new` implementada. Vamos a añadirla ahora. +Después de actualizar el sitio, veremos un `AttributeError`, puesto que no tenemos la vista `post_new` implementada. Añadaáosla de una vez. ## Vista post_new -Es el momento de abrir el archivo `blog/views.py` y agregar las siguientes líneas al resto de las filas `from`: +Ahora abre el fichero `blog/views.py` en el editor y añade estas líneas con el resto de imports `from`: + +{% filename %}blog/views.py{% endfilename %} ```python - from .forms import PostForm -``` +from .forms import PostForm +``` -y nuestra *vista*: +Y ahora nuestra *vista*: + +{% filename %}blog/views.py{% endfilename %} ```python - def post_new(request): - form = PostForm() - return render(request, 'blog/post_edit.html', {'form': form}) -``` +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` Para crear un nuevo formulario `Post`, tenemos que llamar a `PostForm()` y pasarlo a la plantilla. Volveremos a esta *vista* pero, por ahora, vamos a crear rápidamente una plantilla para el formulario. ## Plantilla -Tenemos que crear un archivo `post_edit.html` en el directorio `blog/templates/blog`. Para hacer que un formulario funcione necesitamos varias cosas: +Tenemos que crear un fichero `post_edit.html` el el directorio `blog/templates/blog`, y abrirlo en el editor de código. Para hacer que un formulario funcione necesitamos varias cosas: -* tenemos que mostrar el formulario. Podemos hacerlo, por ejemplo, con un simple `{% raw %}{{ form.as_p }}{% endraw %}`. -* la línea anterior tiene que estar dentro de una etiqueta de formulario HTML: `...` -* necesitamos un botón `Guardar`. Lo hacemos con un botón HTML: `` -* y finalmente justo después de la apertura de `` necesitamos agregar `{% raw %}{% csrf_token %}{% endraw %}`. ¡Esto es muy importante ya que hace que tus formularios sean seguros! Django se quejará si te olvidas de esta parte cuando intentes guardar el formulario. +* Tenemos que mostrar el formulario. Podemos hacerlo, por ejemplo, con un sencillo {% raw %}`{{ form.as_p }}`{% endraw %}. +* La línea anterior tiene que estar dentro de una etiqueta de formuLario HTML: `
...
`. +* Necesitamos un botón `Guardar`. Lo hacemos con un botón HTML: ``. +* Finalmente justo después de abrir la etiqueta `
` tenemos que añadir {% raw %}`{% csrf_token %}`{% endraw %}. ¡Esto es muy importante ya que hace que tus formularios sean seguros! Si olvidas este pedazo, Django se molestará cuando intentes guardar el formulario: -![CSFR Forbidden page][1] +![CSFR Forbidden page](images/csrf2.png) - [1]: images/csrf2.png +Bueno, miremos lo que se debería ver el HTML en `post_edit.html`: -Bueno, vamos a ver cómo quedará el HTML en `post_edit.html`: +{% filename %}blog/templates/blog/post_edit.html{% endfilename %} ```html - {% extends 'blog/base.html' %} - - {% block content %} -

New post

- {% csrf_token %} - {{ form.as_p }} - -
- {% endblock %} -``` - -¡Es hora de actualizar! ¡Si! ¡Tu formulario se muestra! +{% extends 'blog/base.html' %} + +{% block content %} +

New post

+
{% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} +``` -![Nuevo formulario][2] +¡Es hora de actualizar! ¡Sí! ¡Tu formulario se muestra! - [2]: images/new_form2.png +![Nuevo formulario](images/new_form2.png) -Pero, ¡un momento! Si escribes algo en los campos `títle` y `text` y tratas de guardar los cambios - ¿qué pasará? +Pero, ¡un momento! Si escribes algo en los campos `title` y `text` y tratas de guardar los cambios - ¿qué pasará? ¡Nada! Una vez más estamos en la misma página y el texto se ha ido... no se añade ningún post nuevo. Entonces, ¿qué ha ido mal? @@ -163,206 +175,275 @@ La respuesta es: nada. Tenemos que trabajar un poco más en nuestra *vista*. ## Guardar el formulario -Abre `blog/views.py` una vez más. Actualmente, lo que tenemos en la vista `post_new` es: +Abre `blog/views.py` de nuevo en el editor. De momento todo lo que tenemos en la vista `post_new` es lo siguiente: + +{% filename %}blog/views.py{% endfilename %} ```python - def post_new(request): - form = PostForm() - return render(request, 'blog/post_edit.html', {'form': form}) -``` +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` Cuando enviamos el formulario somos redirigidos a la misma vista, pero esta vez tenemos algunos datos adicionales en `request`, más específicamente en `request.POST` (el nombre no tiene nada que ver con un post del blog, se refiere a que estamos "publicando" -en inglés, posting- datos). ¿Recuerdas que en el archivo HTML la definición de `
` tenía la variable `method="POST"`? Todos los campos del formulario estan ahora en `request.POST`. No deberías renombrar la variable `POST` (el único nombre que también es válido para la variable `method` es `GET`, pero no tenemos tiempo para explicar cuál es la diferencia). -En nuestra *view* tenemos dos posibles situaciones a contemplar. Primero: cuando accedemos a la página por primera vez y queremos un formulario en blanco. Segundo: cuando volvemos a la *view* con los datos del formulario que acabamos de escribir. Así que tenemos que añadir una condición (utilizaremos `if` para eso). +En nuestra *vista* tenemos dos situaciones distintas que manejar: primero, cuando accedemos a la página por primera vez y queremos un formulario vacío, y segundo, cuando regresamos a la *vista* con los datos del formulario que acabamos de ingresar. Así que tenemos que añadir una condición (utilizaremos `if` para eso): + +{% filename %}blog/views.py{% endfilename %} ```python - if request.method == "POST": - [...] - else: - form = PostForm() -``` +if request.method == "POST": + [...] +else: + form = PostForm() +``` + +Es hora de rellenar los puntos `[...]`. Si el `método` es `POST` entonces querremos construir el `PostForm` con datos del formulario, cierto? Lo haremos de la siguiente manera: -Es hora de llenar los puntos `[...]`. Si el `method` es `POST` queremos construir el `PostForm` con los datos del formulario, ¿no? Lo haremos con: +{% filename %}blog/views.py{% endfilename %} ```python - form = PostForm(request.POST) -``` +form = PostForm(request.POST) +``` -Fácil! Lo siguiente es verificar si el formulario es correcto (todos los campos necesarios están definidos y no hay valores incorrectos). Lo hacemos con `form.is_valid()`. +Lo siguiente es verificar si el formulario está correcto (si todos los campos necesarios están definidos y no hay valores incorrectos). Lo hacemos con `form.is_valid()`. Comprobamos que el formulario es válido y, si es así, ¡lo podemos salvar! +{% filename %}blog/views.py{% endfilename %} + ```python - if form.is_valid(): - post = form.save(commit=False) - post.author = request.user - post.save() -``` +if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() +``` -Básicamente, tenemos que hacer dos cosas aquí: guardamos el formulario con `form.save` y añadimos un autor (ya que no había ningún campo de `author` en el `PostForm` y este campo es obligatorio). `commit=False` significa que no queremos guardar el modelo `Post` todavía - queremos añadir el autor primero. La mayoría de las veces utilizarás `form.save()`, sin `commit=False`, pero en este caso, tenemos que hacerlo. `post.save()` conservará los cambios (añadiendo el autor) y se creará una nuevo post en el blog. +Básicamente, tenemos que hacer dos cosas: guardamos el formulario con `form.save` y añadimos una autora (ya que no había ningún campo de `author` en el `PostForm` y este campo es obligatorio). `commit=False` significa que no queremos guardar el modelo `Post` aún - queremos añadir la autora primero. La mayoría de las veces utilizarás `form.save()`, sin `commit=False`, pero en este caso, tenemos que hacerlo. `post.save()` conservará los cambios (añadiendo a autor) y se creará una nuevo post en el blog! -Por último, sería genial si podemos inmediatamente ir a la página `post_detail` del nuevo post de blog, ¿no? Para hacerlo necesitamos importar algo más: +Por último, sería genial si podemos inmediatamente ir a la página `post_detail` del nuevo post, ¿no? Para hacerlo necesitamos importar algo más: + +{% filename %}blog/views.py{% endfilename %} ```python - from django.shortcuts import redirect -``` +from django.shortcuts import redirect +``` -Agrégalo al principio del archivo. Y ahora podemos decir: vé a la página `post_detail` del post recién creado. +Agrégalo al principio del archivo. Y ahora podemos decir: "ve a la página `post_detail` del post recién creado": + +{% filename %}blog/views.py{% endfilename %} ```python - return redirect('blog.views.post_detail', pk=post.pk) -``` +return redirect('post_detail', pk=post.pk) +``` + +`post_detail` es el nombre de la vista a la que queremos ir. ¿Recuerdas que esta *view* requiere una variable `pk`? Para pasarlo a las vistas utilizamos `pk=post.pk`, donde `post` es el post recién creado! -`blog.views.post_detail` es el nombre de la vista a la que queremos ir. ¿Recuerdas que esta *view* requiere una variable `pk`? Para pasarlo a las vistas utilizamos `pk=post.pk`, donde `post` es el post recién creado. +Bien, hablamos mucho, pero probablemente queremos ver como se ve la *vista*, ¿verdad? -Bien, hablamos mucho, pero probablemente queremos ver como se ve ahora la *vista*, ¿verdad? +{% filename %}blog/views.py{% endfilename %} ```python - def post_new(request): - if request.method == "POST": - form = PostForm(request.POST) - if form.is_valid(): - post = form.save(commit=False) - post.author = request.user - post.published_date = timezone.now() - post.save() - return redirect('blog.views.post_detail', pk=post.pk) - else: - form = PostForm() - return render(request, 'blog/post_edit.html', {'form': form}) -``` - -Vamos a ver si funciona. Ve a la página http://127.0.0.1:8000/post/new/, añade un `title` y un `text`, guardalo... ¡y voilà! Se añade el nuevo post al blog y se nos redirige a la página de `post_detail`. - -Probablemente has visto que no hemos definido la fecha de publicación. Vamos a introducir un *botón publicar* en **Django Girls Tutorial: Extensions**. +def post_new(request): + if request.method == "POST": + form = PostForm(request.POST) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Veamos si funciona. Ve a la página http://127.0.0.1:8000/post/new/, añade un `title` y un `text`, guárdalo... y voilá! Se ha añadido el nuevo post al blog y somos redirigidos a la página de `post_detail`! + +Puede que hayas notado que estamos indicando la fecha de publicación antes de guardar el post. Más adelante introduciremos un *botón de publicar* en el libro **Django Girls Tutorial: Extensions**. ¡Eso es genial! +> Como recientemente hemos utilizado la interfaz de administrador de Django, el sistema piensa que estamos conectados. Hay algunas situaciones que podrían llevarnos a desconectarnos (cerrando el navegador, reiniciando la base de datos, etc.). Si estás recibiendo errores al crear un post que indican la falta de inicio de sesión de usuario, dirígete a la pagina de admin http://127.0.0.1:8000/admin e inicia sesión nuevamente. Esto resolverá el problema temporalmente. Hay un arreglo permanente esperándote en el capítulo **Tarea: ¡Añadir seguridad a tu sitio web!** después del tutorial principal. + +![Error de inicio de sesión](images/post_create_error.png) + ## Validación de formularios -Ahora, vamos a enseñarte qué tan bueno es Django forms. Un post del blog debe tener los campos `title` y `text`. En nuestro modelo `Post` no dijimos (a diferencia de `published_date`) que estos campos son requeridos, así que Django, por defecto, espera que estén definidos. +Ahora, vamos a enseñarte qué tan bueno es Django forms. Un post del blog debe tener los campos `title` y `text`. En nuestro modelo `Post` no dijimos (a diferencia de `published_date`) que estos campos no son requeridos, así que Django, por defecto, espera que estén definidos. Trata de guardar el formulario sin `title` y `text`. ¡Adivina qué pasará! -![Validación de formularios][3] - - [3]: images/form_validation2.png +![Validación de formularios](images/form_validation2.png) Django se encarga de validar que todos los campos en el formulario estén correctos. ¿No es genial? -> Como recientemente hemos utilizado la interfaz de administrador de Django, el sistema piensa que estamos conectadas. Hay algunas situaciones que podrían llevarnos a desconectarnos (cerrando el navegador, reiniciando la base de datos, etc.). Si estás recibiendo errores al crear un post que indican la falta de inicio de sesión de usuario, dirígete a la página de administración `http://127.0.0.1:8000/admin` e inicia sesión nuevamente. Esto resolverá el problema temporalmente. Hay un arreglo permanente esperándote en el capítulo **Tarea: ¡Añadir seguridad a tu sitio web!** después del tutorial principal. +## Editar formulario -![Error de inicio de sesión][4] +Ahora sabemos cómo agregar un nuevo formulario. Pero, ¿qué pasa si queremos editar uno existente? Es muy similar a lo que acabamos de hacer. Creemos rápidamente algunas cosas importantes. (si no entiendes algo, pregúntale a tu tutora o tutor, o revisa lo capítulos anteriores, son temas que ya hemos cubierto.) - [4]: images/post_create_error.png +Abre `blog/templates/blog/post_detail.html` en el editor de código y añade la línea -## Editar el formulario +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} -Ahora sabemos cómo agregar un nuevo formulario. Pero, ¿qué pasa si queremos editar uno existente? Es muy similar a lo que acabamos de hacer. Vamos a crear algunas cosas importantes rápidamente (si no entiendes algo, pregúntale a tu tutor o revisa lo capítulos anteriores, son temas que ya hemos cubierto). +```html + +``` -Abre el archivo `blog/templates/blog/post_detail.html` y añade esta línea: +para que la plantilla quede así: -```python - -``` - -para que la plantilla quede: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html - {% extends 'blog/base.html' %} - - {% block content %} -
+{% extends 'blog/base.html' %} + +{% block content %} +
{% if post.published_date %} - {{ post.published_date }} +
+ {{ post.published_date }} +
{% endif %} -
-

{{ post.title }}

+

{{ post.title }}

{{ post.text|linebreaksbr }}

- {% endblock %} -``` +
+{% endblock %} +``` -En el archivo `blog/urls.py` añadimos esta línea: +Abre `blog/urls.py` en el editor y añade esta línea: + +{% 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'), +``` Vamos a reusar la plantilla `blog/templates/blog/post_edit.html`, así que lo último que nos falta es una *view*. -Abramos el archivo `blog/views.py` y añadamos al final esta línea: +Abre `blog/views.py` en el editor de código y añade esto al final del todo: -```python - def post_edit(request, pk): - post = get_object_or_404(Post, pk=pk) - if request.method == "POST": - form = PostForm(request.POST, instance=post) - if form.is_valid(): - post = form.save(commit=False) - post.author = request.user - post.save() - return redirect('blog.views.post_detail', pk=post.pk) - else: - form = PostForm(instance=post) - return render(request, 'blog/post_edit.html', {'form': form}) -``` - -Esto se ve casi exactamente igual a nuestra view `post_new`, ¿no? Pero no del todo. Primero: pasamos un parámetro extra `pk` de los urls. Luego: obtenemos el modelo `Post` que queremos editar con `get_object_or_404(Post, pk=pk)` y después, al crear el formulario pasamos este post como una `instancia` tanto al guardar el formulario: +{% filename %}blog/views.py{% endfilename %} ```python - form = PostForm(request.POST, instance=post) -``` +def post_edit(request, pk): + post = get_object_or_404(Post, pk=pk) + if request.method == "POST": + form = PostForm(request.POST, instance=post) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm(instance=post) + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Esto se ve casi exactamente igual a nuestra view `post_new`, ¿no? Pero no del todo. Por un lado, pasamos un parámetro `pk` adicional de `urls`. Segundo: obtenemos el modelo `Post` que queremos editar con `get_object_or_404(Post, pk=pk)` y después, al crear el formulario pasamos este post como una `instancia` tanto al guardar el formulario… -como al abrir un formulario con este post para editarlo: +{% filename %}blog/views.py{% endfilename %} ```python - form = PostForm(instance=post) -``` +form = PostForm(request.POST, instance=post) +``` + +... y justo cuando abrimos un formulario con este post para editarlo: -Ok, ¡vamos a probar si funciona! Dirígete a la página `post_detail`. Debe haber ahí un botón para editar en la esquina superior derecha: +{% filename %}blog/views.py{% endfilename %} -![Botón editar][5] +```python +form = PostForm(instance=post) +``` - [5]: images/edit_button2.png +Ok, ¡vamos a probar si funciona! Dirígete a la página `post_detail`. Ahí debe haber un botón para editar en la esquina superior derecha: -Al dar click ahí, debes ver el formulario con nuestro post del blog: +![Botón editar](images/edit_button2.png) -![Editar formulario][6] +Al dar clic ahí, debes ver el formulario con nuestro post del blog: - [6]: images/edit_form2.png +![Editar formulario](images/edit_form2.png) ¡Siéntete libre de cambiar el título o el texto y guarda los cambios! ¡Felicitaciones! ¡Tu aplicación está cada vez más completa! -Si necesitas más información sobre los formularios de Django, debes leer la documentación: https://docs.djangoproject.com/en/1.8/topics/forms/ +Si necesitas más información sobre los formularios de Django, lee la documentación: https://docs.djangoproject.com/en/2.2/topics/forms/ -## Una cosa más: ¡Tiempo de implementación! +## Seguridad -Veamos si todo esto funciona en PythonAnywhere. ¡Tiempo de hacer otro despliegue! +¡Poder crear nuevas publicaciones haciendo click en un enlace es genial! Pero, ahora mismo, cualquiera que visite tu página podría publicar un nuevo post y seguro que eso no es lo que quieres. Vamos a hacer que el botón sea visible para ti pero no para nadie más. + +Abre `blog/templates/blog/base.html` en el editor, busca el `div` `page-header` y la etiqueta del enlace (anchor) que pusimos antes. Debería ser algo así: -* Primero, haz un commit con tu nuevo código y súbelo a GitHub +{% filename %}blog/templates/blog/base.html{% endfilename %} +```html + ``` -$ git status -$ git add --all . -$ git status -$ git commit -m "Added views to create/edit blog post inside the site." -$ git push + +Vamos a añadir otra etiqueta `{% if %}` que hará que el enlace sólo parezca para los usuarios que hayan iniciado sesión en el admin. Ahora mismo, ¡eres sólo tú! Cambia la etiqueta `` para que se parezca a esto: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% if user.is_authenticated %} + +{% endif %} ``` -* Luego, en una [consola Bash de PythonAnywhere][7] +Este `{% if %}` hará que el enlace sólo se envíe al navegador si el usuario que solicita la página ha iniciado sesión. Esto no protege completamente la creación de nuevas entradas, pero es un buen primer paso. Veremos más sobre seguridad en el libro de extensiones. + +Recuerdas el icono de "editar" que acabamos de añadir a nuestra página de detalles? También queremos añadir lo mismo aquí, así otras personas no podrán editar posts existentes. + +Abre `blog/templates/blog/post_detail.html` en el editor y busca esta línea: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + ``` -$ cd my-first-blog -$ git pull -[...] + +Cámbiala a lo siguiente: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% if user.is_authenticated %} + +{% endif %} ``` -* Finalmente, ve a la pestaña [Web][8] y haz click en **Reload**. +Dado que es probable que estés conectado, si actualizas la página, no verás nada diferente. Carga la página en un navegador diferente o en una ventana en modo incógnito ("privado" en Windows Edge) y verás que el link no aparece, y el icono tampoco! + +## Una cosa más: ¡Tiempo de despliegue! + +Veamos si todo esto funciona en PythonAnywhere. ¡Tiempo de hacer otro despliegue! + +* Lo primero, haz commit de tus últimos cambios y súbelo (push) a GitHub: + +{% filename %}command-line{% endfilename %} + + $ git status + $ git add --all . + $ git status + $ git commit -m "Added views to create/edit blog post inside the site." + $ git push + + +* Luego, en una [consola Bash de PythonAnywhere](https://www.pythonanywhere.com/consoles/) + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Recuerda sustituir `` con tu subdominio de PythonAnywhere real, sin los paréntesis angulares.) - [7]: https://www.pythonanywhere.com/consoles/ - [8]: https://www.pythonanywhere.com/web_app_setup/ +* Para terminar ve a ["Web" page](https://www.pythonanywhere.com/web_app_setup/) (usa el botón del menú de la esquina superior derecha, encima de la consola) y haz click en **Reload**. Recarga tu https://subdomain.pythonanywhere.com blog para ver los cambios. ¡Y eso debería ser todo! Felicidades :) diff --git a/es/django_forms/images/csrf2.png b/es/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/es/django_forms/images/csrf2.png and b/es/django_forms/images/csrf2.png differ diff --git a/es/django_forms/images/drafts.png b/es/django_forms/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/es/django_forms/images/drafts.png and b/es/django_forms/images/drafts.png differ diff --git a/es/django_forms/images/edit_button2.png b/es/django_forms/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/es/django_forms/images/edit_button2.png and b/es/django_forms/images/edit_button2.png differ diff --git a/es/django_forms/images/edit_form2.png b/es/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/es/django_forms/images/edit_form2.png and b/es/django_forms/images/edit_form2.png differ diff --git a/es/django_forms/images/form_validation2.png b/es/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/es/django_forms/images/form_validation2.png and b/es/django_forms/images/form_validation2.png differ diff --git a/es/django_forms/images/new_form2.png b/es/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/es/django_forms/images/new_form2.png and b/es/django_forms/images/new_form2.png differ diff --git a/es/django_forms/images/post_create_error.png b/es/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/es/django_forms/images/post_create_error.png and b/es/django_forms/images/post_create_error.png differ diff --git a/es/django_installation/README.md b/es/django_installation/README.md index 51205bb952f..03408eab6da 100755 --- a/es/django_installation/README.md +++ b/es/django_installation/README.md @@ -1,113 +1,7 @@ -# Instalación de Django +# Instalacion de Django -> Parte de este capitulo esta basado en los tutoriales de Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> **Nota** Si usas un Chromebook, omite este capítulo y asegúrate de seguir las instrucciones de [Chromebook Setup](../chromebook_setup/README.md). > -> Parte de este capítulo se basa en el [django-marcador tutorial][1] bajo licencia de Creative Commons Attribution-ShareAlike 4.0 internacional. El tutorial de django-marcador tiene derechos de autor de Markus Zapke-Gündemann et al. +> **Nota** Si ya has realizado los pasos de instalación, esto ya lo has hecho. ¡Puedes avanzar directamente al siguiente capítulo! - [1]: http://django-marcador.keimlink.de/ - -## Entorno virtual - -Antes de instalar Django, instalaremos una herramienta extremadamente útil que ayudará a mantener tu entorno de desarrollo ordenado en su computadora. Es posible omitir este paso, pero es muy recomendable no hacerlo - ¡comenzar con la mejor configuración posible ayudar a evitar muchos problemas en el futuro! - -Así que, vamos a crear un **entorno virtual** (también llamado un *virtualenv*). Aislará la configuración Python/Django con base en cada proyecto, lo que significa que cualquier cambio que realices en un sitio web no afectará a otros que también estés desarrollando. Genial, ¿no? - -Todo lo que necesitas hacer es encontrar un directorio en el que desees crear el `virtualenv`; tu directorio home, por ejemplo. En Windows puede verse como `C:\Users\Name` (donde `nombre` es el nombre de tu usuario). - -Para este tutorial usaremos un nuevo directorio `djangogirls` en tu directorio home: - - mkdir djangogirls - cd djangogirls - - -Haremos un virtualenv llamado `myvenv`. El comando general estará en el formato: - - python3 -m venv myvenv - - -### Windows - -Para crear un nuevo `virtualenv`, debes abrir la consola (te lo indicamos unos cuantos capítulos antes, ¿recuerdas?) y ejecuta `C:\Python34\python -m venv myvenv`. Se verá así: - - C:\Users\Name\djangogirls> C:\Python34\python -m venv myvenv - - -en donde `C:\Python34\python` es el directorio en el que instalaste Python previamente y `myvenv` es el nombre de tu `virtualenv`. Puedes utilizar cualquier otro nombre, pero asegúrate de usar minúsculas y no dejar espacios, acentos o caracteres especiales. También es una buena idea mantener el nombre corto. ¡Vas a referirte a él mucho! - -### Linux y OS X - -Crear un `virtualenv` en Linux y OS X es tan simple como ejecutar `python3 -m venv myvenv`. Se verá así: - - ~/djangogirls$ python3 -m venv myvenv - - -`myvenv` es el nombre de tu `virtualenv`. Puedes usar cualquier otro nombre, pero mantén el uso de minúsculas y no incluyas espacios. También es una buena idea mantener el nombre corto. ¡Vas a referirte a él mucho! - -> **Nota:** Actualmente, iniciar el entorno virtual en Ubuntu 14.04 de esta manera produce el siguiente error: -> -> Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 -> -> -> Para evitar esto, utiliza directamente el comando `virtualenv`. -> -> ~/djangogirls$ sudo apt-get install python-virtualenv -> ~/djangogirls$ virtualenv --python=python3.4 myvenv -> - -## Trabajar con virtualenv - -Este comando anterior creará un directorio llamado `myvenv` (o cualquier nombre que hayas escogido) que contiene nuestro entorno virtual (básicamente un montón de archivos y carpetas). Todo lo que queremos hacer ahora es iniciarlo ejecutando: - - C:\Users\Name\djangogirls> myvenv\Scripts\activate - - -en Windows, o: - - ~/djangogirls$ source myvenv/bin/activate - - -en OS X y Linux. - -¡Recuerda reemplazar `myvenv` con tu nombre de `virtualenv` que hayas elegido! - -> **Nota:** a veces el comando `source` podría no estar disponible. En esos casos trata de hacerlo esto: -> -> ~/djangogirls$ . myvenv/bin/activate -> - -Sabrás que tienes `virtualenv` iniciado cuando veas que aparece este mensaje en la consola: - - (myvenv) C:\Users\Name\djangogirls> - - -o: - - (myvenv) ~/djangogirls$ - - -¡Nota que el prefijo `(myvenv)` aparece! - -Cuando trabajes en un entorno virtual, `python` automáticamente se referirá a la versión correcta, de modo que puedes utilizar `python` en vez de `python3`. - -Tenemos todas las dependencias importantes en su lugar. ¡Finalmente podemos instalar Django! - -## Instalar Django - -Ahora que tienes tu `virtualenv` iniciado, puedes instalar Django usando `pip`. En la consola, ejecuta `pip install django==1.8` (fíjate que utilizamos un doble signo igual: `==`). - - (myvenv) ~$ pip install django==1.8 - Downloading/unpacking django==1.8 - Installing collected packages: django - Successfully installed django - Cleaning up... - - -En Windows - -> Si obtienes un error al ejecutar pip en Windows comprueba si la ruta de tu proyecto contiene espacios, acentos o caracteres especiales (por ejemplo, `C:\Users\User Name\djangogirls`). Si lo tiene, por favor considera moverla a otro lugar sin espacios, acentos o caracteres especiales (sugerencia: `C:\djangogirls`). Después de hacerlo ejecuta nuevamente el comando anterior. - -en Linux - -> Si obtienes un error al correr pip en Ubuntu 12.04 ejecuta `python -m pip install -U --force-reinstall pip` para arreglar la instalación de pip en el virtualenv. - -¡Eso es todo! ¡Ahora estás listo (por fin) para crear una aplicación Django! +{% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/es/django_installation/instructions.md b/es/django_installation/instructions.md new file mode 100644 index 00000000000..ef02551a181 --- /dev/null +++ b/es/django_installation/instructions.md @@ -0,0 +1,225 @@ +> Parte de esta sección está basada en tutoriales por Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> +> Parte de este capítulo está basada en el [django-marcador tutorial](http://django-marcador.keimlink.de/) bajo la licencia Creative Commons Attribution-ShareAlike 4.0 internacional. El tutorial de django-marcador tiene derechos de autor de Markus Zapke-Gündemann et al. + +## Entorno virtual + +Antes de instalar Django, instalaremos una herramienta extremadamente útil que ayudará a mantener tu entorno de desarrollo ordenado en tu computadora. Es posible saltarse este paso, pero es altamente recomendable. ¡Empezar con la mejor configuración posible te ahorrará muchos problemas en el futuro! + +Así que, vamos a crear un **entorno virtual** (también llamado un *virtualenv*). Virtualenv aísla tu configuración de Python/Django para cada proyecto. Esto quiere decir que cualquier cambio que hagas en un sitio web no afectará a ningún otro que estés desarrollando. Genial, ¿no? + +Todo lo que necesitas hacer es encontrar un directorio en el que quieras crear el `virtualenv`; tu directorio home, por ejemplo. En Windows, puede verse como `C:\Users\Name` (donde `Name` es el nombre de tu usuario). + +> **NOTA:** En Windows, asegúrate de que este directorio no contiene caracteres especiales o acentuados; si tu nombre de usuario contiene caracteres acentuados, usa un directorio distinto, por ejemplo `C:\djangogirls`. + +Para este tutorial usaremos un nuevo directorio `djangogirls` en tu directorio home: + +{% filename %}command-line{% endfilename %} + + $ mkdir djangogirls + $ cd djangogirls + + +Haremos un virtualenv llamado `myvenv`. El comando general estará en el formato: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + + + +Para crear un nuevo `virtualenv`, necesitas abrir una terminal "command prompt" y ejecutar `python -m venv myvenv`. Se verá así: + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls> python -m venv myvenv + + +Donde `myvenv` es el nombre de tu `virtualenv`. Puedes utilizar cualquier otro nombre, pero asegúrate de usar minúsculas y no usar espacios, acentos o caracteres especiales. También es una buena idea mantener el nombre corto. ¡Vas utilizarlo muchas vecesl! + + + + + +Podemos crear un `virtualenv` en Linux y macOS, es tan sencillo como ejecutar `python3 -m venv myvenv`. Se verá así: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + +`myvenv` es el nombre de tu `virtualenv`. Puedes usar cualquier otro nombre, pero sólo utiliza minúsculas y no incluyas espacios. También es una buena idea mantener el nombre corto. ¡Vas a referirte muchas veces a él! + +> **NOTA:** En algunas versiones de Debian/Ubuntu, puede que obtengas el siguiente error: +> +> {% filename %}command-line{% endfilename %} +> +> The virtual environment was not created successfully because ensurepip is not available. En sistemas Debian/Ubuntu, tendrás que instalar el paquete python3-venv usando el siguiente comando. +> apt-get install python3-venv +> Puede que tengas que usar sudo con este comando. Después de instalar el paquete python3-venv, vuelve a crear tu entorno virtual. +> +> +> En este caso, sigue las instrucciones anteriores e instala el paquete `python3-venv`: {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python3-venv +> +> +> **NOTA:** En algunas versiones de Debian/Ubuntu inicializar el entorno virtual de esta manera da el siguiente error: +> +> {% filename %}command-line{% endfilename %} +> +> Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 +> +> +> Para evitar esto, utiliza directamente el comando `virtualenv`. +> +> {% filename %}command-line{% endfilename %} +> +> $ sudo apt-get install python-virtualenv +> $ virtualenv --python=python3.6 myvenv +> +> +> **NOTA:** Si obtienes un error como +> +> {% filename %}command-line{% endfilename %} +> +> E: Unable to locate package python3-venv +> +> +> entonces ejecuta: +> +> {% filename %}command-line{% endfilename %} +> +> sudo apt install python3.6-venv +> + + + +## Trabajar con virtualenv + +El comando anterior creará un directorio llamado `myvenv` (o cualquier nombre que hayas elegido) que contiene nuestro entorno virtual (básicamente un montón de archivos y carpetas). + + + +Inicia el entorno virtual ejecutando: + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls> myvenv\Scripts\activate + + +> **Nota:** en 10 de Windows puedes obtener un error en Windows PowerShell que dice `execution of scripts is disabled on this system`. En este caso, abre otro Windows PowerShell con la opción "Ejecutar como administrador". Luego intenta escribir el siguiente comando antes de inicializar tu entorno virtual: +> +> {% 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 +> + +> **NOTA:** Para usuarios del popular editor VS Code, el cual viene con una terminal integrada basada en el poweshell de windows; si deseas añadir la terminal integrada, puedes arrancar el siguiente comando para activar tu entorno virtual: +> +> $ . myvenv\Scripts\activate.ps1 +> +> +> La ventaja es que no tienes que cambiar las ventanas entre el editor de código y la línea de comandos. + + + + + +Inicia el entorno virtual ejecutando: + +{% filename %}command-line{% endfilename %} + + $ source myvenv/bin/activate + + +¡Recuerda reemplazar `myvenv` con tu nombre de `virtualenv` que hayas elegido! + +> **NOTA:** a veces `source` podría no estar disponible. En ese caso trata hacerlo de esta forma: +> +> {% filename %}command-line{% endfilename %} +> +> $ . myvenv/bin/activate +> + + + +Sabrás que tienes `virtualenv` iniciado cuando veas que la línea de comando en tu consola tiene el prefijo `(myvenv)`. + +Cuando trabajes en un entorno virtual, `python` automáticamente se referirá a la versión correcta, de modo que puedes utilizar `python` en vez de `python3`. + +Ok, tenemos todas las dependencias importantes en su lugar. ¡Finalmente podemos instalar Django! + +## Instalar Django {#django} + +Ahora que tienes tu `virtualenv` iniciado, puedes instalar Django. + +Antes de hacer eso, debemos asegurarnos que tenemos la última versión de `pip`, el software que utilizamos para instalar Django: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~$ python -m pip install --upgrade pip + + +### Instalar paquetes con un fichero de requisitos (requirements) + +Un fichero de requisitos (requirements) tiene una lista de dependencias que se deben instalar mediante `pip install`: + +Primero crea un archivo `requirements.txt` dentro de tu directorio `djangogirls`, usando el editor de código que instalaste previamente. Lo puedes hacer mediante abriendo un nuevo archivo en el editor de código y guardándolo como `requirements.txt` en el directorio `djangogirls`. Tu directorio se verá así: + + djangogirls + └───requirements.txt + + +Dentro del fichero `djangogirls/requirements.txt` deberías tener el siguiente texto: + +{% filename %}djangogirls/requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +Ahora, ejecuta `pip install -r requirements.txt` para instalar Django. + +{% filename %}command-line{% endfilename %} + + (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.1MB) + Installing collected packages: Django + Successfully installed Django-{{ book.django_version }} + + + + +> Si obtienes un error cuando llamas al pip en la plataforma de Windows, por favor verifica si el nombre de ruta de tu proyecto contiene espacios, acentos o caracteres especiales (por ejemplo, `C:\Usuarios\NombreUsuario\djangogirls`). Si los tiene, utiliza otro en su lugar sin espacios, acentos o caracteres especiales (sugerencia: `C:\djangogirls`). Crea un nuevo virtualenv en el nuevo directorio, luego borra el viejo y trata de escribir el comando anterior otra vez. (Moviendo el directorio virtualenv no funcionará debido a que usa rutas absolutas.) + + + + + +> Tu línea de comando puede congelarse luego de intentar instalar Django. Si esto sucede, usa el siguiente comando: +> +> {% filename %}command-line{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> + + + + + +> Si obtienes un error cuando llamas pip en Ubuntu 12.04, por favor corre `python -m pip install -U --force-reinstall pip` para reparar la instalación de pip en el virtualenv. + + + +¡Eso es todo! Ahora estás lista (por fin) para crear una aplicación Django! diff --git a/es/django_models/README.md b/es/django_models/README.md index 792ee596c23..23c9db14d75 100755 --- a/es/django_models/README.md +++ b/es/django_models/README.md @@ -1,39 +1,41 @@ # Modelos en Django -Lo que queremos crear ahora es algo que va a almacenar todos los posts en nuestro blog. Pero para poder hacerlo tenemos que hablar un poco acerca de algo llamado `objetos`. +Lo que queremos crear ahora es algo que almacene todas las entradas de nuestro blog. Pero para poder hacerlo tenemos que hablar un poco sobre algo llamado `objetos`. ## Objetos -Hay un concepto en el mundo de la programación llamado `programación orientada a objetos`. La idea es que en lugar de escribir todo como una aburrida secuencia de instrucciones de programación podemos modelar cosas y definir cómo interactúan con las demás. +Hay un concepto en el mundo de la programación llamado `programación orientada a objetos`. La idea es que en lugar de escribir todo como una aburrida secuencia de instrucciones de programación podemos modelar cosas y definir cómo interactúan entre ellas. -Entonces ¿Qué es un objeto? Es un conjunto de propiedades y acciones. Suena raro, pero te daremos un ejemplo. +Entonces, ¿qué es un objeto? Es un conjunto de propiedades y acciones. Suena raro, pero te daremos un ejemplo. -Si queremos modelar un gato crearemos un objeto `Gato` que tiene algunas propiedades, como son por ejemplo`color`, `edad`, `estado de ánimo` (es decir, bueno, malo, sueño ;)), `dueño` (que es un objeto `Persona` o, tal vez, en el caso de que el gato sea callejero, esta propiedad estará vacía). +Si queremos modelar un gato crearemos un objeto `Gato` que tiene algunas propiedades como: `color`, `edad`, `temperamento` (como bueno, malo, o dormilón ;)), y `dueño` (este es un objeto `Persona` o en caso de un gato callejero, esta propiedad está vacía). -Y luego el `Gato` tiene algunas acciones: `ronronear`, `rasguñar` o `alimentarse` (en la cual daremos al gato algunos `ComidaDeGato`, que podría ser un objeto independiente con propiedades, como por ejemplo, `sabor`). +Luego, el `Gato` tiene algunas acciones como: `ronronear`, `arañar` o `alimentar` (en cuyo caso daremos al gato algo de `ComidaDeGato`, el cual debería ser un objeto aparte con propiedades como `sabor`). Gato --------- - color - edad - humor - dueño - ronronear() - rasguñar() - alimentarse(comida_de_gato) + color + edad + humor + dueño + ronronear() + rasguñar() + alimentarse(comida_de_gato) + + ComidaDeGato - ---------- + -------- sabor Básicamente se trata de describir cosas reales en el código con propiedades (llamadas `propiedades del objeto`) y las acciones (llamadas `métodos`). -Y ahora, ¿cómo modelamos los posts en el blog? Queremos construir un blog, ¿no? +Y ahora, ¿cómo modelamos las entradas en el blog? Queremos construir un blog, ¿no? -Tenemos primero que responder algunas preguntas: ¿Qué es un post de un blog? ¿Qué características debe tener? +Necesitamos responder a la pregunta: ¿Qué es una entrada de un blog? ¿Qué propiedades debería tener? -Bueno, seguro que nuestros posts necesitan un texto con su contenido y un título, ¿cierto? También sería bueno saber quién lo escribió, así que necesitamos un autor. Por último, queremos saber cuándo el post fue creado y publicado. +Bueno, seguro que nuestras entradas de blog necesitan un texto con su contenido y un título, ¿cierto? También sería bueno saber quién lo escribió, así que necesitamos un autor. Por último, queremos saber cuándo se creó y publicó la entrada. Post -------- @@ -48,121 +50,146 @@ Bueno, seguro que nuestros posts necesitan un texto con su contenido y un títul Así que vamos a necesitar el método `publicar`. -Puesto que ya sabemos lo que queremos lograr, ¡podemos empezar a moderlarlo en Django! +Puesto que ya sabemos lo que queremos lograr, ¡podemos empezar a modelarlo en Django! -## Modelo en Django +## Modelos en Django -Sabiendo qué es un objeto, podemos crear un modelo en Django para nuestros posts en el blog. +Sabiendo qué es un objeto, podemos crear un modelo en Django para nuestros entradas de blog. -Un modelo en Django es un tipo especial de objeto que se guarda en la `base de datos`. Una base de datos es una colección de datos. Allí es el lugar en el cual almacenarás la información sobre usuarios, posts del blog, etc. Utilizaremos una base de datos SQLite para almacenar nuestros datos. Este es el adaptador de base de datos predeterminada en Django -- será suficiente para nosotros por ahora. +Un modelo en Django es un tipo especial de objeto que se guarda en la `base de datos`. Una base de datos es una colección de datos. Es un lugar en el cual almacenarás la información sobre usuarios, tus entradas de blog, etc. Utilizaremos una base de datos SQLite para almacenar nuestros datos. Este es el adaptador de base de datos predeterminado en Django -- será suficiente para nosotros por ahora. -Piensa en el modelo en la base de datos como una hoja de cálculo con columnas (campos) y filas (datos). +Puedes pensar el modelo en la base de datos, como una hoja de cálculo con columnas (campos) y filas (datos). -### Creando una aplicación +### Crear una aplicación Para mantener todo en orden, crearemos una aplicación separada dentro de nuestro proyecto. Es muy bueno tener todo organizado desde el principio. Para crear una aplicación, necesitamos ejecutar el siguiente comando en la consola (dentro de la carpeta de `djangogirls` donde está el archivo `manage.py`): +{% filename %}macOS y Linux:{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py startapp blog -Vas a notar que se crea un nuevo directorio llamado `blog` y contiene una serie de archivos. Nuestros directorios y archivos en nuestro proyecto deberían parecerse a esto: +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + + +Notarás que se ha creado un nuevo directorio `blog` y ahora contiene una cantidad de archivos. Los directorios y archivos en nuestro proyecto deberían verse así: djangogirls - ├── mysite - | __init__.py - | settings.py - | urls.py - | wsgi.py + ├── blog + │   ├── __init__.py + │   ├── admin.py + │   ├── apps.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 + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + └── requirements.txt -Después de crear una aplicación también necesitamos decirle a Django que debe utilizarla. Lo hacemos en el archivo `mysite/settings.py`. Tenemos que encontrar `INSTALLED_APPS` y añadir una línea que contenga `'blog',` justo por encima de `)`. El producto final debe tener este aspecto: +Después de crear una aplicación, también necesitamos decirle a Django que debe utilizarla. Eso se hace en el fichero `mysite/settings.py` -- ábrelo en el editor. Tenemos que encontrar `INSTALLED_APPS` y agregar una línea que contiene `'blog.apps.BlogConfig',` justo por encima de `]`. El producto final debe tener este aspecto: + +{% filename %}mysite/settings.py{% endfilename %} ```python - INSTALLED_APPS = ( - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'blog', - ) +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog.apps.BlogConfig', +] ``` -### Creando el Modelo Post +### Crear el modelo del Post -En el archivo `blog/models.py` definimos todos los objetos llamados `Models` - este es un lugar en el cual definiremos nuestro modelo post. +En el archivo `blog/models.py` definimos todos los objetos llamados `Models`. Este es un lugar en el cual definiremos nuestra entrada del blog. -Vamos abrir `blog/models.py`, quitamos todo y escribimos un código como este: +Abre `blog/models.py` en el editor, borra todo, y escribe código como este: + +{% filename %}blog/models.py{% endfilename %} ```python - from django.db import models - from django.utils import timezone - - class Post(models.Model): - author = models.ForeignKey('auth.User') - title = models.CharField(max_length=200) - text = models.TextField() - created_date = models.DateTimeField( - default=timezone.now) - published_date = models.DateTimeField( - blank=True, null=True) - - def publish(self): - self.published_date = timezone.now() - self.save() - - def __str__(self): - return self.title -``` +from django.conf import settings +from django.db import models +from django.utils import timezone + + +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) + + def publish(self): + self.published_date = timezone.now() + self.save() + + def __str__(self): + return self.title +``` -> Vuelve a verificar que usaste dos guiones bajos (`_`) en cada lado del `str`. Estos se utilizan con frecuencia en Python y a veces también los llamamos "dunder" (diminutivo en inglés de "double-underscore"). +> Comprueba nuevamente que usas dos guiones bajos (`_`) en cada lado de `str`. Esta convención se usa en Python con mucha frecuencia y a veces también se llaman "dunder" (abreviatura de "double-underscore" o, en español, "doble guión bajo"). -Da un poco de miedo, ¿verdad? Pero no te preocupes, ¡vamos a explicar qué significan estas líneas! +Da un poco de miedo, ¿no? Pero no te preocupes, ¡vamos a explicar qué significan estas líneas! -Todas las líneas que comienzan con `from` o `import` son líneas para añadir algo de otros archivos. Así que en vez de copiar y pegar las mismas cosas en cada archivo, podemos incluir algunas partes con `from... import ...`. +Todas las líneas que comienzan con `from` o `import` son líneas para agregar algo de otros archivos. Así que en vez de copiar y pegar las mismas cosas en cada archivo, podemos incluir algunas partes con `from... import ...`. -`class Post(models.Model):` - esta línea define nuestro modelo (es un `objeto`). +`class Post(models.Model):`, esta línea define nuestro modelo (es un `objeto`). -* `class` es una palabra clave que indica que estamos definiendo un objeto. -* `Post` es el nombre de nuestro modelo. Podemos darle un nombre diferente (pero debemos evitar espacios en blanco y caracteres especiales). Una clase siempre comienza con su primera letra en mayúscula. -* `models.Model` significa que Post es un modelo de Django, así Django sabe que debe guardarlo en la base de datos. +- `class` es una palabra clave que indica que estamos definiendo un objeto. +- `Post` es el nombre de nuestro modelo. Podemos darle un nombre diferente (pero debemos evitar espacios en blanco y caracteres especiales). Siempre inicia el nombre de una clase con una letra mayúscula. +- `models.Model` significa que Post es un modelo de Django, así Django sabe que debe guardarlo en la base de datos. -Ahora definimos las propiedades que hablábamos: `title`, `text`, `created_date`, `published_date` y `author`. Para hacer eso tenemos que definir un tipo de campo (¿es texto? ¿un número? ¿una fecha? ¿una relación con otro objeto - es decir, un usuario?). +Ahora definimos las propiedades de las que hablábamos: `title`, `text`, `created_date`, `published_date` y `author`. Para ello tenemos que definir el tipo de cada campo (¿es texto? ¿un número? ¿una fecha? ¿una relación con otro objeto como un User (usuario)?) -* `models.CharField` - así es como defines un texto con un número limitado de caracteres. -* `models.TextField` - esto es para textos largos sin un límite. Será ideal para el contenido de un post, ¿verdad? -* `models.DateTimeField` - esto es fecha y hora. -* `modelos.ForeignKey` - este es un vínculo con otro modelo. +- `models.CharField`, así es como defines un texto con un número limitado de caracteres. +- `models.TextField`, este es para texto largo sin límite. Suena perfecto para el contenido de la entrada del blog, ¿no? +- `models.DateTimeField`, este es fecha y hora. +- `modelos.ForeignKey`, este es una relación (link) con otro modelo. -No vamos a explicar cada pedacito de código, ya que nos tomaría demasiado tiempo. Debes echar un vistazo a la documentación de Django si quieres saber más sobre los campos de los Modelos y cómo definir cosas diferentes a las descritas anteriormente (https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-types). +No vamos a explicar aquí cada pedacito de código porque nos tomaría demasiado tiempo. Deberías echar un vistazo a la documentación de Django si deseas obtener más información sobre los campos Modelo y cómo definir otras cosas distintas a las descritas anteriormente (https://docs.djangoproject.com/en/2.2/ref/models/fields/#field-types). -¿Y qué sobre `def publish(self):`? Es exactamente nuestro método `publish` que mencionamos anteriormente. `def` significa que se trata de una función o método. `publish` es el nombre del método. Puedes cambiarlo, si quieres. La regla es que usamos minúsculas y guiones bajos en lugar de espacios (es decir, si quieres tener un método que calcule el precio medio, este podría llamarse `calculate_average_price`). +¿Y qué sobre `def publish(self):`? Es exactamente el método `publish` que mencionábamos antes. `def` significa que es una función/método y `publish` es el nombre del método. Puedes cambiar el nombre del método, si quieres. La regla de nomenclatura es utilizar minúsculas y guiones bajos en lugar de espacios. Por ejemplo, un método que calcule el precio medio se podría llamar `calcular_precio_medio`. -Los métodos muy a menudo `devuelven` algo. Hay un ejemplo de esto en el método `__str__`. En este escenario, cuando llamamos a `__str__()` obtendremos un texto (**string**) con un título de Post. +Los métodos suelen devolver (`return`, en inglés) algo. Hay un ejemplo de esto en el método `__str__`. En este escenario, cuando llamemos a `__str__()` obtendremos un texto (**string**) con un título de Post. -Si algo todavía no está claro sobre modelos, ¡no dudes en preguntar a tu tutor! Sabemos que es muy complicado, sobre todo cuando estás entendiendo qué son funciones y objetos mientras sigues este documento. Con suerte, ¡todo tiene un poco más de sentido para ti ahora! +También, nota que ambos `def publish(self):`, y `def __str__(self):` son indentados dentro de nuestra clase. Porque Python es sensible a los espacios en blancos, necesitamos indentar nuestros métodos dentro de la clase. De lo contrario, los métodos no pertenecen a la clase, y puedes obtener un comportamiento inesperado. + +Si algo todavía no está claro sobre modelos, ¡no dudes en preguntar a tu guía! Sabemos que es complicado, sobre todo cuando aprendes lo que son funciones y objetos al mismo tiempo. Pero con suerte, ¡todo tiene un poco más de sentido para ti ahora! ### Crear tablas para los modelos en tu base de datos -El último paso es añadir nuestro nuevo modelo a nuestra base de datos. Primero tenemos que hacer que Django sepa que tenemos algunos cambios en nuestro modelo (acabamos de crearlo), escribe `python manage.py makemigrations blog`. Se verá así: +El último paso aquí es agregar nuestro nuevo modelo a la base de datos. Primero tenemos que hacer saber a Django que hemos hecho cambios en nuestro modelo. (Lo acabamos de crear!) Ve a tu terminal y escribe `python manage.py makemigrations blog`. Se verá así: + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py makemigrations blog Migrations for 'blog': - 0001_initial.py: + blog/migrations/0001_initial.py: + - Create model Post -Django preparará un archivo de migración que tenemos que aplicar ahora a nuestra base de datos escribiendo `python manage.py migrate blog`. El resultado debe ser: +**Nota:** Recuerda guardar los archivos que edites. De otro modo, tu computador ejecutará las versiones anteriores lo que puede ocasionar errores inesperados. + +Django preparó un archivo de migración que ahora tenemos que aplicar a nuestra base de datos. Escribe `python manage.py migrate blog` y el resultado debería ser: + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py migrate blog Operations to perform: @@ -171,4 +198,4 @@ Django preparará un archivo de migración que tenemos que aplicar ahora a nuest Applying blog.0001_initial... OK -¡Hurra! Nuestro modelo de Post está ahora en nuestra base de datos. Sería bueno verlo, ¿no? ¡Dirígete al siguiente capítulo para ver cómo luce tu Post! +¡Hurra! ¡Nuestro modelo Post ya está en nuestra base de datos! Estaría bien verlo, ¿no? ¡Salta al siguiente capítulo para ver qué aspecto tiene tu Post! \ No newline at end of file diff --git a/es/django_orm/README.md b/es/django_orm/README.md index c5890ec8f1f..c814d6d0bc5 100755 --- a/es/django_orm/README.md +++ b/es/django_orm/README.md @@ -4,143 +4,218 @@ En este capítulo aprenderás cómo Django se conecta a la base de datos y almac ## ¿Qué es un QuerySet? -Un QuerySet es, en esencia, una lista de objetos de un modelo determinado. Un QuerySet te permite leer los datos de una base de datos, filtrarlos y ordenarlos. +Un QuerySet es, en esencia, una lista de objetos de un modelo determinado. Un QuerySet te permite leer los datos de la base de datos, filtrarlos y ordenarlos. Es más fácil de aprender con ejemplos. Vamos a intentarlo, ¿de acuerdo? ## Django shell -Abre la consola y escribe este comando: +Abre tu consola local (no la de PythonAnywhere) y escribe este comando: + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py shell El resultado debería ser: - (InteractiveConsole) - >>> - +{% filename %}command-line{% endfilename %} + +```python +(InteractiveConsole) +>>> +``` -Ahora estás en la consola interactiva de Django. Es como la consola de Python, pero con un toque de magia Django :). Puedes utilizar todos los comandos Python aquí también, por supuesto. +Ahora estás en la consola interactiva de Django. Es como una consola de Python normal, pero con un poco de magia de Django. :) Aquí también se pueden usar todos los comandos de Python. -### Ver todos los objetos +### Todos los objetos Vamos a mostrar todos nuestros posts primero. Puedes hacerlo con el siguiente comando: - >>> Post.objects.all() - Traceback (most recent call last): - File "", line 1, in - NameError: name 'Post' is not defined - +{% filename %}command-line{% endfilename %} -¡Uy! Apareció un error. Nos dice que no hay ningún objeto Post. Esto es correcto, ¡nos olvidamos de importarlo primero! +```python +>>> Post.objects.all() +Traceback (most recent call last): + File "", line 1, in +NameError: name 'Post' is not defined +``` - >>> from blog.models import Post - +¡Uy! Apareció un error. Nos dice que Post no existe. Esto es correcto, ¡olvidamos importarlo! -Esto es simple: importamos el modelo `Post` de `blog.models`. Vamos a intentar mostrar todos los posts nuevamente: +{% filename %}command-line{% endfilename %} - >>> Post.objects.all() - [, ] - +```python +>>> from blog.models import Post +``` -Esta es una lista de las posts creadas anteriormente. Hemos creado estos posts usando la interfaz del administrador de Django. Sin embargo, ahora queremos crear nuevos posts usando Python, ¿cómo lo hacemos? +Vamos a importar el modelo `Post` de `blog.models`. Y probamos de nuevo a mostrar todas las publicaciones (posts): + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, ]> +``` + +¡Es la lista de posts que creamos anteriormente! Creamos estos posts usando la interfaz de administración de Django. Pero, ahora queremos crear nuevos posts usando Python, ¿cómo lo hacemos? ### Crear objetos Esta es la forma de crear un nuevo objeto Post en la base de datos: - >>> 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') +``` -Pero hay un ingrediente faltante: `me`. Necesitamos pasar una instancia del modelo `User` como autor. ¿Cómo hacemos eso? +Pero nos falta un ingrediente aquí: `me`. Tenemos que pasar una instancia del modelo `User` como autor. ¿Eso cómo se hace? Primero importemos el modelo User: - >>> from django.contrib.auth.models import User - +{% filename %}command-line{% endfilename %} -¿Qué usuarios tenemos en nuestra base de datos? Veamos: +```python +>>> from django.contrib.auth.models import User +``` - >>> User.objects.all() - [] - +¿Qué usuarios tenemos en nuestra base de datos? Prueba esto: -Este es el super usuario que creamos anteriormente, Vamos a obtener una instancia de ese usuario ahora: +{% filename %}command-line{% endfilename %} - me = User.objects.get(username='ola') - +```python +>>> User.objects.all() +]> +``` -Como puedes ver, hicimos un `get` de un `User` con el `username` que sea igual a 'ola'. ¡Genial! Acuérdate de poner tu nombre de usuario para obtener tu usuario. +¡Este es el superusuario que hemos creado antes! Ahora, vamos a obtener una instancia de este usuario (cambia el código para usar tu propio nombre de usuario): -Ahora finalmente podemos crear nuestro primer post: +{% filename %}command-line{% endfilename %} - >>> Post.objects.create(author=me, title='Sample title', text='Test') - +```python +>>> me = User.objects.get(username='ola') +``` + +Como ves, ya hemos obtenido (`get`) un usuario (`User`) cuyo `username` es igual a 'ola'. ¡Mola! + +Ahora, finalmente, podemos crear nuestra entrada: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') + +``` ¡Hurra! ¿Quieres probar si funcionó? - >>> Post.objects.all() - [, , ] - +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, , ]> +``` -### Agrega más posts +¡Ahí está, una entrada de blog más en la lista! -Ahora puedes divertirte un poco y añadir más posts para ver cómo funciona. Añade 2 ó 3 más y avanza a la siguiente parte. +### Agrega más entradas + +Ahora puedes divertirte un poco y agregar más entradas para ver cómo funciona. Agrega dos o tres más y avanza a la siguiente parte. ### Filtrar objetos -Una parte importante de los QuerySets es la habilidad para filtrarlos. Digamos que queremos encontrar todos los posts cuyo autor es el User ola. Usaremos `filter` en vez de `all` en `Post.objects.all()`. En los paréntesis estableceremos qué condición o conduciones deben cumplirse por un post del blog para terminar en nuestro queryset. En nuestro caso sería `author` es igual a `me`. La forma de escribirlo en Django es: `author=me`. Ahora nuestro bloque de código se ve como esto: +Una parte importante de los QuerySets es la habilidad para filtrar los resultados. Digamos que queremos encontrar todos los post del usuario ola. Usaremos `filter` en vez de `all` en `Post.objects.all()`. Entre paréntesis estableceremos qué condición (o condiciones) debe cumplir un post del blog para aparecer como resultado en nuestro queryset. En nuestro caso sería `author` es igual a `me`. La forma de escribirlo en Django es: `author=me`. Ahora nuestro bloque de código tiene este aspecto: - >>> Post.objects.filter(author=me) - [, , , ] - +{% filename %}command-line{% endfilename %} -¿O tal vez querramos ver todos los posts que contengan la palabra 'title' en el campo `title`? +```python +>>> Post.objects.filter(author=me) +, , , ]> +``` - >>> Post.objects.filter(title__contains='title') - [, ] - +¿O quizá queremos ver todas las entradas que contengan la palabra 'title' en el campo `title`? -> **Nota** Hay dos guiones bajos (`_`) entre `title` y `contains`. Django ORM utiliza esta sintaxis para separar los nombres de los campos ("title") y operaciones o filtros ("contains"). Si sólo utilizas un guión bajo, obtendrás un error como "FieldError: Cannot resolve keyword title_contains". +{% filename %}command-line{% endfilename %} -También puedes obtener una lista de todos los posts publicados. Lo hacemos filtrando los posts que tienen el campo `published_date` en el pasado: +```python +>>> Post.objects.filter(title__contains='title') +, ]> +``` - >>> from django.utils import timezone - >>> Post.objects.filter(published_date__lte=timezone.now()) - [] +> **Nota** Hay dos guiones bajos (`_`) entre `title` y `contains`. El ORM de Django utiliza esta sintaxis para separar los nombres de los campos ("title") de las operaciones o filtros ("contains"). Si sólo utilizas un guion bajo, obtendrás un error como "FieldError: Cannot resolve keyword title_contains". -Desafortunadamente, ninguno de nuestros posts han sido publicados todavía. ¡Vamos a cambiar esto! Primero obtén una instancia de un post que querramos publicar: +También puedes obtener una lista de todos los post publicados. Lo hacemos filtrando los post que tienen la fecha de publicación, `published_date`, en el pasado: - >>> post = Post.objects.get(id=1) - +{% filename %}command-line{% endfilename %} -¡Luego utiliza el método `publish` para publicarlo! +```python +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) + +``` - >>> post.publish() - +Por desgracia, el post que hemos añadido desde la consola de Python aún no está publicado. ¡Pero lo podemos cambiar! Primero obtén una instancia de la entrada que queremos publicar: -Ahora intenta obtener la lista de posts publicados nuevamente (presiona la tecla con la flecha hacia arriba 3 veces y presiona Enter): +{% filename %}command-line{% endfilename %} - >>> Post.objects.filter(published_date__lte=timezone.now()) - [] - +```python +>>> post = Post.objects.get(title="Sample title") +``` + +Y luego publícala con nuestro método `publish`: + +{% filename %}command-line{% endfilename %} + +```python +>>> post.publish() +``` + +Ahora vuelve a intentar obtener la lista de posts publicados (pulsa la tecla de "flecha arriba" tres veces y pulsa `enter`): + +{% filename %}command-line{% endfilename %} -### Ordenando objetos +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +]> +``` + +### Ordenar objetos Los QuerySets también te permiten ordenar la lista de objetos. Intentemos ordenarlos por el campo `created_date`: - >>> Post.objects.order_by('created_date') - [, , , ] - +{% filename %}command-line{% endfilename %} -También podemos invertir el ordenamiento agregando `-` al principio: +```python +>>> Post.objects.order_by('created_date') +, , , ]> +``` - >>> Post.objects.order_by('-created_date') - [, , , ] - +También podemos invertir el orden agregando `-` al principio: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.order_by('-created_date') +, , , ]> +``` + +### Consultas complejas a través de encadenamiento de métodos + +Como ves, algunos métodos en `Post.objects` devuelven un QuerySet. Los mismos métodos pueden ser llamados también en un QuerySet, y entonces devolverán un nuevo QuerySet. También puedes combinar QuerySets **encadenando** uno con otro: + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> +``` + +Es muy potente y te permite escribir consultas bastante complejas. + +¡Genial! ¡Ahora estás lista para la siguiente parte! Para cerrar la consola, escribe esto: -¡Genial! ¡Ahora estás lista para la siguiente parte! Para cerrar la consola, tipea: +{% filename %}command-line{% endfilename %} - >>> exit() - $ +```python +>>> exit() +$ +``` \ No newline at end of file diff --git a/es/django_start_project/README.md b/es/django_start_project/README.md index 0034c086129..1301c300bf9 100755 --- a/es/django_start_project/README.md +++ b/es/django_start_project/README.md @@ -1,119 +1,206 @@ # ¡Tu primer proyecto en Django! -> Parte de este capitulo esta basado en los tutoriales de Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> Parte de este capítulo se basa en tutoriales por Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). > -> Parte de este capítulo se basa en el [django-marcador tutorial][1] bajo licencia de Creative Commons Attribution-ShareAlike 4.0 internacional. El tutorial de django-marcador tiene derechos de autor de Markus Zapke-Gündemann et al. +> Parte de este capítulo está basado en el [tutorial django-marcador](http://django-marcador.keimlink.de/) bajo licencia de Creative Commons Attribution-ShareAlike 4.0 internacional. El tutorial de django-marcador tiene derechos de autor de Markus Zapke-Gündemann et al. - [1]: http://django-marcador.keimlink.de/ +¡Vamos a crear un blog sencillo! -¡Vamos a crear un simple blog! +El primer paso es iniciar un nuevo proyecto de Django. Básicamente, significa que vamos a lanzar unos scripts proporcionados por Django que nos crearán el esqueleto de un proyecto de Django. Son solo un montón de directorios y archivos que usaremos más tarde. -El primer paso para crearlo es iniciar un nuevo proyecto en Django. Básicamente, esto significa que podrás correr algunos scripts proporcionados por Django que crearán el esqueleto de un proyecto para nosotros: un montón de directorios y archivos que vamos a utilizar más adelante. +Los nombres de algunos archivos y directorios son muy importantes para Django. No deberías renombrar los archivos que estamos a punto de crear. Moverlos a un lugar diferente tampoco es buena idea. Django necesita mantener una cierta estructura para poder encontrar cosas importantes. -Los nombres de algunos archivos y directorios son muy importantes para Django. No deberías renombrar los archivos que estamos a punto de crear. Moverlos a un lugar diferente tampoco es una buena idea. Django tiene que mantener una cierta estructura para ser capaz de encontrar cosas importantes. +> Recuerda ejecutar todo en el virtualenv. Si no ves un prefijo `(myvenv)` en tu consola tienes que activar tu virtualenv. Explicamos cómo hacerlo en el capítulo de **Instalación de Django** en la sección **Trabajar con virtualenv**. Basta con escribir `myvenv\Scripts\activate` en Windows o `source myvenv/bin/activate` en Mac OS / Linux. -> Recuerda correr todo en el virtualenv. Si no ves un prefijo `(myvenv)` en tu consola necesitas activar tu virtualenv. Explicamos cómo hacer eso en el capítulo de **Instalación de Django** en la sección **Trabajando con virtualenv**. Puedes hacerlo escribiendo el siguiente comando: `myvenv\Scripts\activate` en Windows o `source myvenv/bin/activate` en Mac OS / Linux. -> -> **Nota** Verifica dos veces que hayas incluido el punto (`.`) al final del comando, es importante porque le dice al script que instale Django en el directorio actual. + + +En MacOS o Linux deberías ejecutar el siguiente comando en la consola. **no te olvides de añadir el punto `.` al final** -En la consola debes ejecutar (recuerda no escribir `(myvenv) ~/djangogirls$`, ¿ok?): +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ django-admin startproject mysite . -En Windows: +> El punto `.` es crucial porque le dice al script que instale Django en el directorio actual (para el cual el punto `.` sirve de abreviatura). +> +> **Nota** Cuando escribas los comandos de arriba acuérdate de que sólo tienes que escribir la parte que empieza por `django-admin`. La parte de `(myvenv) ~/djangogirls$` que mostramos aquí es sólo un ejemplo del mensaje que aparecerá en tu línea de comandos. + + + + + +En Windows debes ejecutar el siguiente comando. **(No olvides incluir el punto `.` al final)**: - (myvenv) C:\Users\Name\djangogirls> django-admin.py startproject mysite . +{% filename %}command-line{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . -> **Nota** Verifica dos veces que hayas incluido el punto (`.`) al final del comando, es importante porque le dice al script que instale Django en el directorio actual. -`django-admin.py` es un script que creará los archivos y directorios para ti. Ahora deberías tener una estructura de directorios parecida a esto: +> El punto `.` es crucial porque le dice al script que instale Django en el directorio actual (para el cual el punto `.` sirve de abreviatura). +> +> **Nota** Cuando teclees los comandos de arriba, recuerda que sólo tienes que escribir la parte que empieza por `django-admin.exe`. La parte de `(myvenv) C:\Users\Name\djangogirls>` que mostramos aquí es sólo un ejemplo del mensaje que aparecerá en tu línea de comandos. + + + +`django-admin.py` es un script que creará los archivos y directorios para ti. Ahora deberías tener una estructura de directorios parecida a esta: djangogirls ├───manage.py - └───mysite - settings.py - urls.py - wsgi.py - __init__.py + ├───mysite + │ settings.py + │ urls.py + │ wsgi.py + │ __init__.py + └───requirements.txt -`manage.py` es un script que ayuda con la administración del sitio. Con ello podremos iniciar un servidor web en nuestro ordenador sin necesidad de instalar nada más, entre otras cosas. +> **Nota**: en tu estructura de directorios, también verás el directorio `myvenv` que creamos anteriormente. + +`manage.py` es un script que ayuda con la administración del sitio. Con él podremos iniciar un servidor web en nuestro ordenador sin necesidad de instalar nada más, entre otras cosas. El archivo `settings.py` contiene la configuración de tu sitio web. -¿Recuerdas cuando hablamos de un cartero que debía comprobar donde entregar una carta? El archivo `urls.py` contiene una lista de los patrones utilizados por `urlresolver`. +Recuerdas cuando hablamos de una cartera que debía comprobar dónde entregar una carta? El archivo `urls.py` contiene una lista de los patrones utilizados por `urlresolver`. -Ignoremos los otros archivos por ahora - no los cambiaremos. ¡Lo único que debes recordar es no borrarlos por accidente! +Por ahora vamos a ignorar el resto de archivos porque no los vamos a cambiar. ¡Sólo acuérdate de no borrarlos accidentalmente! -## Cambiando la configuración +## Cambiar la configuración Vamos a hacer algunos cambios en `mysite/settings.py`. Abre el archivo usando el editor de código que has instalado anteriormente. -Sería bueno tener el horario correcto en nuestro sitio web. Ve a la [lista de husos horarios de Wikipedia][2] y copia tu zona horaria (TZ). (por ejemplo, `Europe/Berlin` ) +**Nota**: Ten en cuenta que `settings.py` es un archivo normal, como cualquier otro. Puedes abrirlo con el editor de texto, usando "file -> open" en el menu de acciones. Esto te debería llevar a la típica ventana donde puedes buscar el archivo `settings.py` y seleccionarlo. Como alternativa, puedes abrir el archivo haciendo click derecho en la carpeta djangogirls en tu escritorio. Luego, selecciona tu editor de texto en la lista. Elegir el editor es importante puesto que puede que tengas otros programas que pueden abrir el archivo pero que no te dejaran editarlo. + +Sería bueno tener el horario correcto en nuestro sitio web. Ve a [lista de Wikipedia de las zonas horarias](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) y copia tu zona horaria (TZ) (e.g. `Europa/Berlín`). + +En `settings.py`, encuentra la línea que contiene `TIME_ZONE` y modifícala para elegir tu zona horaria. Por ejemplo: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +TIME_ZONE = 'Europe/Berlin' +``` + +Un código de idioma tiene dos partes: el idioma, p.ej. `en` para inglés o `de` para alemán, y el código de país, p.ej. `de` para Alemania o `ch` para Suiza. Si tu idioma nativo no es el inglés, puedes añadir lo siguiente para cambiar el idioma de los botones y notificaciones de Django. Así tendrás el botón "Cancel" traducido al idioma que pongas aquí. [Django viene con muchas traducciones preparadas](https://docs.djangoproject.com/en/2.2/ref/settings/#language-code). + +Si quieres un idioma diferente, cambia el código de idioma cambiando la siguiente línea: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +LANGUAGE_CODE = 'es-es' +``` - [2]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +También tenemos que añadir una ruta para archivos estáticos. (Veremos todo acerca de archivos estáticos y CSS más adelante.) Ve al *final* del archivo, y justo debajo de la entrada `STATIC_URL`, añade una nueva llamada `STATIC_ROOT`: -En settings.py, encuentra la línea que contiene `TIME_ZONE` y modifícala para elegir tu propia zona horaria: +{% filename %}mysite/settings.py{% endfilename %} -``` python - TIME_ZONE = 'Europe/Berlin' +```python +STATIC_URL = '/static/' +STATIC_ROOT = BASE_DIR / 'static' ``` -Modificando "Europe/Berlin" como corresponda +Cuando `DEBUG` es `True` y `ALLOWED_HOST` esta vacío, el host es validado contra `['localhost', '127,0.0.1', '[::1]']`. Una vez despleguemos nuestra aplicación este no sera el mismo que nuestro nombre de host en PythonAnywhere así que cambiaremos la siguiente opción: -También necesitaremos agregar una ruta para los archivos estáticos (aprenderemos todo sobre los archivos estáticos y CSS más tarde en este tutorial). Ve hacia abajo hasta el *final* del archivo, y justo por debajo de la entrada `STATIC_URL`, agrega una nueva llamada `STATIC_ROOT`: +{% filename %}mysite/settings.py{% endfilename %} -``` python - STATIC_URL = '/static/' - STATIC_ROOT = os.path.join(BASE_DIR, 'static') +```python +ALLOWED_HOSTS = ['127.0.0.1', '.pythonanywhere.com'] ``` +> **Nota**: si estas usando un Chromebook, añade esta linea al final del archivo settings.py: `MESSAGE_STORAGE = +'django.contrib.messages.storage.session.SessionStorage'` +> +> Añade también `.c9users.io` a `ALLOWED_HOSTS` si estás usando cloud9. + ## Configurar una base de datos -Hay una gran variedad de opciones de bases de datos para almacenar los datos de tu sitio. Utilizaremos el que viene por defecto, `sqlite3`. +Hay una gran variedad de opciones de bases de datos para almacenar los datos de tu sitio. Utilizaremos la que viene por defecto, `sqlite3`. + +Esta ya está configurado en esta parte de tu archivo `mysite/settings.py`: -Esto ya está configurado en esta parte de tu archivo `mysite/settings.py`: +{% filename %}mysite/settings.py{% endfilename %} -``` python - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - } +```python +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', } +} ``` Para crear una base de datos para nuestro blog, ejecutemos lo siguiente en la consola: `python manage.py migrate` (necesitamos estar en el directorio de `djangogirls` que contiene el archivo `manage.py`). Si eso va bien, deberías ver algo así: +{% filename %}command-line{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py migrate Operations to perform: - Apply all migrations: admin, contenttypes, auth, sessions + Apply all migrations: auth, admin, 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 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 sessions.0001_initial... OK -¡Y listo! ¡Es hora de iniciar el servidor web y ver si nuestro sitio web está funcionando! +Y, ¡terminamos! ¡Es hora de iniciar el servidor web y ver si está funcionando nuestro sitio web! + +## Iniciar el servidor Debes estar en el directorio que contiene el archivo `manage.py` (en la carpeta `djangogirls`). En la consola, podemos iniciar el servidor web ejecutando `python manage.py runserver`: +{% filename %}command-line{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py runserver -Ahora todo lo que debes hacer es verificar que tu sitio esté corriendo - abre tu navegador (Firefox, Chrome, Safari, Internet Explorer o el que utilices) e ingresa la dirección: +Si estas usando un Chromebook, utiliza este comando: + +{% filename %}Cloud 9{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0.0.0.0:8080 + + +Si estás en Windows y te falla con un error `UnicodeDecodeError`, utiliza en su lugar este comando: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + + +Ahora necesitas revisar que tu website se está ejecutando. Abre tu navegador (Firefox, Chrome, Safari, Internet Explorer, o cualquiera que uses) y escribe esta dirección: + +{% filename %}browser{% endfilename %} http://127.0.0.1:8000/ -El servidor web se apropiará de tu consola hasta que lo termines manualmente: para tipear más comandos o abres una nueva terminal (y no te olvides de activar tu virtualenv allí también), o frena el servidor web yendo a la consola en la que está corriendo y presionando Ctrl+C - las teclas Control y C juntas (en Windows, deberás presionar Ctrl + Break). +Si estás usando una Chromebook y Cloud9, haga clic en la URL de la ventana emergente que debería haber aparecido en la esquina superior derecha de la ventana de comandos donde se está ejecutando el servidor web. La URL se verá parecida a: + +{% filename %}browser{% endfilename %} + + https://.vfs.cloud9.us-west-2.amazonaws.com + + +¡Enhorabuena! ¡Has creado tu primer sitio web y lo has iniciado usando un servidor web! ¿No es genial? + +![¡La instalación ha funcionado!](images/install_worked.png) -¡Felicitaciones! ¡Has creado tu primer sitio web y lo has ejecutado usando un servidor web! ¿No es genial? +Tenga en cuenta que una ventana de comandos sólo puede ejecutar una cosa a la vez, y la ventana de comandos que abrió antes está ejecutando el servidor web. Mientras el servidor web esté corriendo y esperando solicitudes adicionales, la terminal aceptará nuevo texto pero no ejecutará nuevos comandos. -![¡Funcionó!][3] +> Miramos cómo funcionan los servidores web en el capítulo **Cómo funciona internet**. - [3]: images/it_worked2.png +Para escribir comandos adicionales mientras el servidor web está corriendo, abra una nueva ventana de terminal y active su virtualenv -- para revisar las instrucciones sobre cómo abrir una segunda ventana de terminal, vea [Introducción a la línea de comandos](../intro_to_command_line/README.md). Para parar el servidor web, ve a la ventana donde se esté ejecutando y pulsa CTRL+C, las teclas Control y C a la vez ( en Windows puede que tengas que pulsar Ctrl+Break). -¿Lista para el próximo paso? ¡Es momento de crear algo de contenido! +¿Preparada para el próximo paso? ¡Es momento de crear algo de contenido! diff --git a/es/django_start_project/images/install_worked.png b/es/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..4354c634ddb Binary files /dev/null and b/es/django_start_project/images/install_worked.png differ diff --git a/es/django_start_project/images/it_worked2.png b/es/django_start_project/images/it_worked2.png deleted file mode 100644 index 4412ecfc49e..00000000000 Binary files a/es/django_start_project/images/it_worked2.png and /dev/null differ diff --git a/es/django_templates/README.md b/es/django_templates/README.md index d39a3bcdf87..8c923c37b3a 100755 --- a/es/django_templates/README.md +++ b/es/django_templates/README.md @@ -1,106 +1,106 @@ # Plantillas de Django -¡Es hora de mostrar algunos datos! Django nos provee las útiles **template tags** para ello. +¡Es hora de mostrar algunos datos! Para ello Django incorpora unas etiquetas de plantillas, **template tags**, muy útiles. -## ¿Qué son las template tags? +## ¿Qué son las etiquetas de plantilla? -Verás, en HTML no puedes realmente poner código Python, porque los navegadores no lo entienden. Ellos sólo saben HTML. Sabemos que HTML es algo estático, mientras que Python es mucho más dinámico. +Verás, en HTML no se puede escribir código en Python porque los navegadores no lo entienden. Sólo saben HTML. Sabemos que HTML es bastante estático, mientras que Python es mucho más dinámico. -**Django template tags** nos permiten transferir cosas de Python como cosas en HTML, así que tu puedes construir sitios web dinámicos más rápido y fácil. +Las **etiquetas de plantilla de Django** nos permiten insertar elementos de Python dentro del HTML, para que puedas construir sitios web dinámicos más rápida y fácilmente. ¡Genial! -## Mostrar la plantilla post list +## Mostrar la plantilla lista de posts -En el capítulo anterior dimos a nuestra plantilla una lista de posts en la variable `posts`. Ahora lo mostraremos en HTML. +En el capítulo anterior le dimos a nuestra plantilla una lista de entradas en la variable `posts`. Ahora la vamos a mostrar en HTML. -Para imprimir una variable en una plantilla de Django, utilizamos llaves dobles con el nombre de la variable dentro, así: +Para imprimir una variable en una plantilla de Django, utilizamos llaves dobles con el nombre de la variable dentro, algo así: -``` html - {{ posts }} -``` +{% filename %}blog/templates/blog/post_list.html{% endfilename %} -Prueba esto en tu plantilla `blog/templates/blog/post_list.html` (reemplaza el segundo y el tercer par de etiquetas `
` con la línea `{{ posts }}`), guarda el archivo y actualiza la página para ver los resultados: +```html +{{ posts }} +``` -![Figura 13.1][1] +Prueba esto en la plantilla `blog/templates/blog/post_list.html`. Ábrela en el editor de código, y cambia todo desde el segundo `
` hasta el tercer `
` por `{{ posts }}`. Guarda el archivo y refresca la página para ver los resultados: - [1]: images/step1.png +![Figura 13.1](images/step1.png) -Como puedes ver, todo lo que obtenemos es esto: +Como puedes ver, lo que hemos conseguido es esto: - [, ] - +{% filename %}blog/templates/blog/post_list.html{% endfilename %} -Esto significa que Django lo entiende como una lista de objetos. ¿Recuerdas de **Introducción a Python** cómo podemos mostrar listas? Sí, ¡con los ciclos for! En una plantilla de Django, lo haces de esta manera: +```html +, ] > +``` -``` html - {% for post in posts %} - {{ post }} - {% endfor %} -``` +Significa que Django lo entiende como una lista de objetos. ¿Recuerdas de **Introducción a Python** cómo podemos mostrar listas? Sí, ¡con bucles for! En una plantilla de Django se hacen así: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} {{ post }}{% endfor %} +``` Prueba esto en tu plantilla. -![Figura 13.2][2] +![Figura 13.2](images/step2.png) + +¡Funciona! Pero queremos que se muestren como los post estáticos que creamos anteriormente en el capítulo de **Introducción a HTML**. Usted puede mezclar HTML y etiquetas de plantilla. Nuestro `body` se verá así: - [2]: images/step2.png +{% filename %}blog/templates/blog/post_list.html{% endfilename %} -¡Funciona! Pero queremos que se muestren como los posts estáticos que creamos anteriormente en el capítulo de **Introducción a HTML**. Puedes mezclar HTML y template tags. Nuestro `body` se verá así: +```html +
-``` html +{% for post in posts %}
-

Django Girls Blog

+

publicado: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

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

published: {{ post.published_date }}

-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

-
- {% endfor %} -``` - -Todo lo que pones entre `{% for %}` y `{% endfor %}` se repetirá para cada objeto en la lista. Actualiza tu página: +{% endfor %} +``` -![Figura 13.3][3] +{% raw %}Todo lo que pongas entre `{% for %}` y `{% endfor %}` se repetirá para cada objeto de la lista. Refresca la página:{% endraw %} - [3]: images/step3.png +![Figura 13.3](images/step3.png) -¿Has notado que utilizamos una notación diferente esta vez `{{ post.title }}` o `{{ post.text }}`? Estamos accediendo a datos en cada uno de los campos definidos en nuestro modelo `Post`. También el `|linebreaksbr` está dirigiendo el texto de los posts a través de un filtro para convertir saltos de línea en párrafos. +¿Has notado que utilizamos una notación diferente esta vez (`{{ post.title }}` o `{{ post.text }}`)? Estamos accediendo a los datos en cada uno de los campos definidos en nuestro modelo `Post`. También el `|linebreaksbr` está pasando el texto de los post a través de un filtro para convertir saltos de línea en párrafos. ## Una cosa más -Sería bueno ver si tu sitio web seguirá funcionando en la Internet pública, ¿verdad? Intentemos desplegándola en PythonAnywhere nuevamente. Aquí te dejamos un ayuda memoria... +Sería bueno ver si tu sitio web seguirá funcionando en la Internet pública, ¿no? Vamos a intentar desplegar de nuevo en PythonAnywhere. Aquí va un resumen de los pasos… -* Primero, sube tu código a GitHub +* Lo primero, sube tu código a GitHub -``` -$ git status -[...] -$ git add --all . -$ git status -[...] -$ git commit -m "Modified templates to display posts from database." -[...] -$ git push -``` +{% filename %}command-line{% endfilename %} + + $ git status + [...] + $ git add --all . + $ git status + [...] + $ git commit -m "Templates modificados para mostrar post desde base de datos." + [...] + $ git push + -* Luego, identifícate en [PythonAnywhere][4] y ve a tu **consola Bash** (o empieza una nueva), y ejecuta: +* Luego, vuelve a entrar en [PythonAnywhere](https://www.pythonanywhere.com/consoles/) y ve a tu **consola Bash** (o inicia una nueva), y ejecuta: -``` -$ cd my-first-blog -$ git pull -[...] -``` +{% filename %}PythonAnywhere command-line{% endfilename %} -* Finalmente, ve a la [pestaña Web][5] y presiona **Reload** en tu aplicación web. ¡Tu actualización debería poder verse! + $ cd .pythonanywhere.com + $ git pull + [...] + - [4]: https://www.pythonanywhere.com/consoles/ - [5]: https://www.pythonanywhere.com/web_app_setup/ +(Recuerda sustituir `` con tu subdominio de PythonAnywhere real, sin los paréntesis angulares.) -¡Felicidades! Ahora sigue adelante, trata de agregar un nuevo post usando el panel de administrador de Django (¡recuerda añadir published_date!) y luego actualiza tu página para ver si aparece tu nuevo post. +* Y finalmente, dirígete a la [página "Web"](https://www.pythonanywhere.com/web_app_setup/) y haz clic en **Reload** en tu aplicación web. (Para ir a otras páginas de PythonAnywhere desde la consola, haz clic en el botón de la esquina superior derecha.) Los cambios deberían estar visibles en https://subdomain.pythonanywhere.com -- ¡compruébalo en el navegador! Si ves distintas publicaciones en el sitio en PythonAnywhere de las que tienes en tu servidor local, es lo normal. Tienes dos bases de datos, una en tu ordenador local y otra en PythonAnywhere y no tienen por qué tener el mismo contenido. -¿Funciona como un encanto? ¡Estamos orgullosos! Aléjate de tu computadora por un rato, te has ganado un descanso. :) +¡Felicidades! Ahora intenta añadir un nuevo post en tu administrador de Django (recuerda añadir published_date!) Asegúrate de que estás en el administrador de Django de PytonAnywhere, https://tunombre.pythonanywhere.com/admin. Luego actualiza tu página para ver si los posts aparecen. -![Figura 13.4][6] +¿Funciona de maravilla? ¡Estamos orgullosas! Aléjate un rato del ordenador, te has ganado un descanso. :) - [6]: images/donut.png +![Figura 13.4](images/donut.png) \ No newline at end of file diff --git a/es/django_templates/images/donut.png b/es/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/es/django_templates/images/donut.png and b/es/django_templates/images/donut.png differ diff --git a/es/django_templates/images/step1.png b/es/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/es/django_templates/images/step1.png and b/es/django_templates/images/step1.png differ diff --git a/es/django_templates/images/step2.png b/es/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/es/django_templates/images/step2.png and b/es/django_templates/images/step2.png differ diff --git a/es/django_templates/images/step3.png b/es/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/es/django_templates/images/step3.png and b/es/django_templates/images/step3.png differ diff --git a/es/django_urls/README.md b/es/django_urls/README.md index 3ced93e3a42..3fb81908e7a 100755 --- a/es/django_urls/README.md +++ b/es/django_urls/README.md @@ -1,123 +1,103 @@ -# Django urls +# URLs en Django -Vamos a construir nuestra primera página web -- ¡una página de inicio para tu blog! Pero primero, vamos a aprender un poco sobre Django urls. +Estamos a punto de construir nuestra primera página web: ¡una página de inicio para el blog! Pero primero, vamos a aprender un poco acerca de las urls en Django. ## ¿Qué es una URL? -Una URL es simplemente una dirección web, puedes ver una URL cada vez que visitas cualquier sitio web - es visible en la barra de direcciones de tu navegador (¡Sí! `127.0.0.1:8000` es una URL. Y http://djangogirls.org es también una URL): +Una URL es una dirección de la web. Puedes ver una URL cada vez que visitas una página. Se ve en la barra de direcciones del navegador. (Sí! ¡`127.0.0.1:8000` es una URL! Y `https://djangogirls.org` también es una URL.) -![URL][1] +![URL](images/url.png) - [1]: images/url.png - -Cada página en Internet necesita su propia URL. De esta manera tu aplicación sabe lo que debe mostrar a un usuario que abre una URL. En Django se usa algo llamado `URLconf` (configuración de URL), un conjunto de patrones que Django intentará hacer coincidir con la dirección URL recibida para encontrar la vista correcta. +Cada página en Internet necesita su propia URL. De esta manera tu aplicación sabe lo que debe mostrar a un usuario que abre una URL. En Django utilizamos algo que se llama `URLconf` (configuración de URL). URLconf es un conjunto de patrones que Django intentará comparar con la URL recibida para encontrar la vista correcta. ## ¿Cómo funcionan las URLs en Django? -Vamos a abrir el archivo `mysite/urls.py` y ver cómo es: - -``` python - from django.conf.urls import include, url - from django.contrib import admin - - urlpatterns = [ - # Examples: - # url(r'^$', 'mysite.views.home', name='home'), - # url(r'^blog/', include('blog.urls')), - - url(r'^admin/', include(admin.site.urls)), - ] -``` - -Como puedes ver, Django ya puso algo aquí para nosotros. +Vamos a abrir el archivo `mysite/urls.py` en el editor de código de tu elección y veamos lo que tiene: -Las líneas que comienzan con `#` son comentarios - significa que esas líneas no serán ejecutadas por Python. Muy útil, ¿verdad? +{% filename %}mysite/urls.py{% endfilename %} -Ya está aquí la URL de admin, que visitaste en el capítulo anterior: +```python +"""mysite URL Configuration -``` python - url(r'^admin/', include(admin.site.urls)), -``` +[...] +""" +from django.contrib import admin +from django.urls import path -Esto significa que para cada URL que empieza con `admin/` Django encontrará su correspondiente *view*. En este caso estamos incluyendo en una sola línea muchas URLs de admin, así no está todo comprimido en este pequeño archivo - es más limpio y legible. - -## Regex +urlpatterns = [ + path('admin/', admin.site.urls), +] +``` -¿Te preguntas cómo Django coincide las direcciones URL con las vistas? Bueno, esta parte es difícil. Django utiliza `regex` -- expresiones regulares. Regex tiene muchas (¡un montón!) de normas que forman un patrón de búsqueda. Dado que las expresiones regulares son un tema avanzado, no entraremos en detalles sobre su funcionamiento. +Como puedes ver, Django ya puso algo aquí por nosotros. -Si te interesa entender cómo creamos esos patrones, aquí hay un ejemplo del proceso - solamente necesitaremos un subconjunto de reglas limitado para expresar el patrón que estamos buscando: +Líneas entre triples comillas (`'''` o `"""`) son llamadas docstrings - puedes escribirlos en la parte superior de un archivo, clase o método para describir lo que hace. No serán ejecutadas por Python. - ^ denota el principio del texto - $ denota el final del texto - \d representa un dígito - + indica que el ítem anterior debería ser repetido por lo menos una vez - () para encerrar una parte del patrón - +La URL de admin, que hemos visitado en el capítulo anterior ya está aquí: -Cualquier otra cosa en la definición del URL será tomada literalmente. +{% filename %}mysite/urls.py{% endfilename %} -Ahora imagina que tienes un sitio web con una dirección como esta: `http://www.mysite.com/post/12345/`, donde `12345` es el número de post. +```python + path('admin/', admin.site.urls), +``` -Escribir vistas separadas para todos los números de post sería realmente molesto. Con las expresiones regulares podemos crear un patrón que coincidirá la URL y extraerá el número para nosotras: `^post/(\d+)/$`. Analicemos esta expresión parte por parte para entender qué es lo que estamos haciendo aquí: +Esta línea dice que para cada URL que empieza con `admin/` Django encontrará su correspondiente *view*. En este caso estamos incluyendo muchas URLs admin así que no todo está empaquetado en este pequeño archivo. Es más limpio y legible. -* **^post/** le está diciendo a Django que tome cualquier cosa que tenga `post/` al principio del URL (justo antes de `^`) -* **(\d+)** significa que habrá un número (de uno o más dígitos) y que queremos que ese número sea capturado y extraído -* **/** le dice a Django que otro caracter `/` debería venir a continuación -* **$** indica el final del URL, lo que significa que sólo cadenas finalizando con `/` coincidirán con este patrón +## ¡Tu primera URL de Django! -## ¡Tu primer URL de Django! +¡Es hora de crear nuestra primera URL! Queremos que 'http://127.0.0.1:8000/' sea la página de inicio del blog y que muestre una lista de post. -¡Es hora de crear nuestro primer URL! Queremos que 'http://127.0.0.1:8000/' sea la página de inicio de nuestro blog y que muestre una lista de posts. +También queremos mantener limpio el archivo `mysite/urls.py`, así que vamos a importar las urls de nuestra aplicación `blog` en el archivo principal `mysite/urls.py`. -También queremos mantener el archivo `mysite/urls.py` limpio, así que importaremos URLs de nuestro `blog` al archivo `mysite/urls.py` principal. +Vamos, añade la línea para importar `blog.urls`. Tú también necesitarás cambiar la línea `desde django.urls...` porque estaremos usando la función `include` aquí, así que se necesitará añadir ese import a la línea. -Elimina las líneas comentadas (líneas comenzando con `#`) y agrega una línea que importará `blog.urls` en el url principal (`''`). +El archivo `mysite/urls.py` debería verse ahora así: -Tu archivo `mysite/urls.py` debería verse como este: +{% filename %}mysite/urls.py{% endfilename %} -``` python - from django.conf.urls import include, url - from django.contrib import admin - - urlpatterns = [ - url(r'^admin/', include(admin.site.urls)), - url(r'', include('blog.urls')), - ] -``` +```python +from django.contrib import admin +from django.urls import path, include -Django ahora redirigirá todo lo que vaya hacia 'http://127.0.0.1:8000/' a `blog.urls` y buscará más instrucciones allí. +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('blog.urls')), +] +``` -Cuando escribes expresiones regulares en Python acostúmbrate a poner `r` al principio de la cadena - esto es solamente una pista para que Python entienda que la cadena contenerá caracteres especiales que no son para ser interpretados por Python sino que son parte de la expresión regular. +Ahora Django redirigirá todo lo que entre a 'http://127.0.0.1:8000/' hacia `blog.urls` y buscará más instrucciones allí. ## blog.urls -Crea un nuevo archivo vacío `blog/urls.py`. ¡Muy bien! Agrega estas primeras dos líneas: +Crea un nuevo fichero vacío llamado `urls.py` en el directorio `blog`, y ábrelo en el editor de código. ¡Vale! Añade las dos primeras líneas: + +{% filename %}blog/urls.py{% endfilename %} -``` python - from django.conf.urls import include, url - from . import views +```python +from django.urls import path +from . import views ``` -Aquí solo estamos importando los métodos de Django y todas nuestras `views` del `blog` (todavía no tenemos ninguna, pero lo haremos en un minuto) +Aquí estamos importando la función de Django `path` y todos nuestras `views` desde la aplicación `blog` (no tenemos una aun, pero veremos eso en un minuto!) Luego de esto, podemos agregar nuestro primer patrón URL: -``` python - urlpatterns = [ - url(r'^$', views.post_list), - ] -``` +{% filename %}blog/urls.py{% endfilename %} -Como puedes ver, ahora estamos asignando una `view` llamada `post_list` al URL `^$`. Esta expresión regular coincidirá con `^` (un inicio) seguido de `$` (un final) - por lo tanto, sólo una cadena vacía coincidirá. Y esto es correcto, ya que en los URL resolvers de Django 'http://127.0.0.1:8000/' no es parte del URL. Este patrón mostrará a Django que `views.post_list` es el lugar correcto al que ir si alguien ingresa a tu sitio web con la dirección 'http://127.0.0.1:8000/'. +```python +urlpatterns = [ + path('', views.post_list, name='post_list'), +] +``` -¿Todo bien? Abre http://127.0.0.1:8000/ en tu navegador para ver el resultado. +Como puedes ver, estamos asociando una vista (`view`) llamada `post_list` a la URL raíz. Este patrón de URL coincidirá con una cadena vacía y el solucionador de URL de Django ignorará el nombre de dominio (es decir, http://127.0.0.1:8000/) que prefija la ruta de URL completa. Este patrón le dirá a Django que `views.post_list` es el lugar correcto al que ir si alguien entra a tu sitio web con la dirección 'http://127.0.0.1:8000/'. -![Error][2] +La última parte `name='post_list'` es el nombre de la URL que se utilizará para identificar a la vista. Puede coincidir con el nombre de la vista pero también puede ser algo completamente distinto. Utilizaremos las URL con nombre más delante en el proyecto así que es importante darle un nombre a cada URL de la aplicación. También deberíamos intentar mantener los nombres de las URL únicos y fáciles de recordar. - [2]: images/error1.png +Si tratas de visitar http://127.0.0.1:8000/ ahora, encontrarás un mensaje de error 'web page not available' a algo así. Esto es porque el servidor (¿recuerdas que escribimos `runserver`?) ya no está funcionando. Mira la ventana de la consola del servidor para saber por qué. -No hay más un "It works", ¿verdad? No te preocupes, es solamente una página de error, ¡nada que nos asuste! De hecho, son bastante útiles: +![Error](images/error1.png) -Puedes leer que no hay ningún **atributo 'post_list'**. ¿*post_list* te recuerda algo? ¡Así es como llamamos a nuestra vista! Esto significa que todo está en su lugar, sólo que no creamos nuestra *view* todavía. No te preocupes, ya llegaremos a eso. +La consola esta mostrando un error, pero no te preocupes - de hecho es muy útil: está diciendote que **no existe el atributo 'post_list'**. Ese es el nombre del *view* que Django está tratando de encontrar y usar, pero aún no lo hemos creado. En esta etapa tu `/admin/` tampoco funcionará. No te preocupes, ya llegaremos a eso. Si ves un error diferente, intenta reiniciar el servidor web. Para hacerlo, en la ventana de la consola que ejecuta el servidor web, deténgalo presionando Ctrl+C (las teclas juntas Control y C). En Windows, es posible que deba presionar Ctrl+Break. Luego, debe reiniciar el servidor web ejecutando el comando `python manage.py runserver`. -> Si quieres saber más sobre Django URLconfs, mira la documentación oficial: https://docs.djangoproject.com/en/1.8/topics/http/urls/ +> Si quieres saber más sobre URLconfs de Django, mira la documentación oficial: https://docs.djangoproject.com/en/2.2/topics/http/urls/ \ No newline at end of file diff --git a/es/django_urls/images/error1.png b/es/django_urls/images/error1.png index cc17593d19d..50618fca3fe 100644 Binary files a/es/django_urls/images/error1.png and b/es/django_urls/images/error1.png differ diff --git a/es/django_urls/images/url.png b/es/django_urls/images/url.png index 6cd1bd96291..c22441e930e 100644 Binary files a/es/django_urls/images/url.png and b/es/django_urls/images/url.png differ diff --git a/es/django_views/README.md b/es/django_views/README.md index e62bd13fb42..ac297798f76 100755 --- a/es/django_views/README.md +++ b/es/django_views/README.md @@ -1,38 +1,44 @@ -# Vistas de Django - ¡Es hora de crear! +# Vistas en Django - ¡Hora de crear! -Es hora de deshacerse del error que hemos creado en el capítulo anterior :) +Es hora de deshacerse del error que hemos creado en el capítulo anterior! :) -Una *View* es un lugar donde ponemos la "lógica" de nuestra aplicación. Se solicitará información del `model` que creaste anteriormente y se pasará a una `view` que crearás en el próximo capítulo. Las vistas son sólo métodos de Python que son un poco más complicados que lo que hicimos en el capítulo de **Introducción a Python**. +Una *View* es un lugar donde ponemos la "lógica" de nuestra aplicación. Pedirá información del `modelo` que has creado antes y se la pasará a la `plantilla`. Crearemos una plantilla en el próximo capítulo. Las vistas son sólo métodos de Python que son un poco más complicados que los que escribimos en el capítulo **Introducción a Python**. Las Vistas se colocan en el archivo `views.py`. Agregaremos nuestras *views* al archivo `blog/views.py`. ## blog/views.py -Bien, vamos abrir este archivo y ver lo que contiene: +Vale, abre este fichero en el editor y mira lo que hay en él: -``` python - from django.shortcuts import render - - # Create your views here. +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render + +# Create your views here. ``` -No demasiadas cosas aquí todavía. La *view* más simple puede ser como esto: +No hay demasiadas cosas aquí todavía. -``` python - def post_list(request): - return render(request, 'blog/post_list.html', {}) -``` +Recuerda que las líneas que comienzan con `#` son comentarios - significa que Python no las ejecutará. -Como puedes ver, hemos creado un método (`def`) llamado `post_list` que toma un `request` y hace un `return` de un método `render` que renderizará (construirá) nuestra plantilla `blog/post_list.html`. +Creemos una *vista (view)* como sugiere el comentario. Añade la siguiente mini-vista por debajo: -Guarda el archivo, dirígete a http://127.0.0.1:8000/ y veamos lo que tenemos ahora. +{% filename %}blog/views.py{% endfilename %} -¡Otro error! Leamos lo que está pasando ahora: +```python +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` -![Error][1] +Como puedes ver, hemos creado una función (`def`) llamada `post_list` que acepta `request` y `return` una función `render` que reproduce (construye) nuestra plantilla `blog/post_list.html`. + +Guarda el archivo, ve a http://127.0.0.1:8000/ y mira lo que hemos hecho. + +¡Otro error! Leamos lo que está pasando ahora: - [1]: images/error.png +![Error](images/error.png) -Este es uno fácil: *TemplateDoesNotExist*. ¡Vamos a arreglar este error creando una plantilla en el siguiente capítulo! +Esto demuestra que el servidor está funcionando otra vez, al menos, pero todavía no se ve bien, ¿no? No te preocupes, es sólo una página de error, ¡nada que temer! Al igual que los mensajes de error en la consola, estos son realmente muy útiles. Puedes leer que la *TemplateDoesNotExist*. Vamos a corregir este error y crear una plantilla en el próximo capítulo! -> Aprende más acerca de las views de Django leyendo la documentación oficial: https://docs.djangoproject.com/en/1.8/topics/http/views/ +> Obtenga más información sobre las vistas de Django leyendo la documentación oficial: https://docs.djangoproject.com/en/2.2/topics/http/views/ \ No newline at end of file diff --git a/es/django_views/images/error.png b/es/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/es/django_views/images/error.png and b/es/django_views/images/error.png differ diff --git a/es/domain/README.md b/es/domain/README.md deleted file mode 100755 index 85d8363fca1..00000000000 --- a/es/domain/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# Dominio - -PythonAnywhere te ha dado un dominio gratuito, pero tal vez no quieras tener ".pythonanywhere.com" al final de la URL de tu blog. Quizás quieras que tu blog viva en "www.infinite-kitten-pictures.org" o "www.3d-printed-steam-engine-parts.com" o "www.antique-buttons.com" o "www.mutant-unicornz.net", o lo que quieras que sea. - -Aquí hablaremos brevemente sobre cómo obtener un dominio y veremos cómo vincularlo a tu aplicación web en PythonAnywhere. Sin embargo, deberías saber que la mayoría de los dominios son de pago, y PythonAnywhere te cobrará un valor adicional para usar tu propio nombre de dominio -- no es demasiado dinero en total, pero es probablemente algo que quieras hacer sólo si estás muy comprometida con la causa. - -## ¿Donde registrar un dominio? - -Un dominio típico cuesta alrededor de 15 dólares estadounidenses anuales. Hay opciones más baratas y más caras, dependiendo del proveedor. Hay una gran cantidad de empresas a las que puedes comprar un dominio: una simple [búsqueda en google][1] dará cientos de opciones. - - [1]: https://www.google.com/search?q=register%20domain - -Nuestra opción favorita es [I want my name][2]. Ellos se promocionan como una opción "indolora para el manejo de dominios" y realmente lo son. - - [2]: https://iwantmyname.com/ - -También puedes obtener dominios gratuitos. [dot.tk][3] es un lugar para obtener uno, pero deberíamos advertirte que los dominios gratuitos a veces se sienten algo "baratos" -- si tu sitio va a ser un sitio para un negocio profesional, seguramente quieras considerar comprar un dominio "apropiado" que termine en `.com`. - - [3]: http://www.dot.tk - -## Cómo apuntar tu dominio a PythonAnywhere - -Si elegiste la opción de *iwantmyname.com*, haz click en `Domains` en el menú y elije tu nuevo dominio. Luego encuentra el vínculo a `manage DNS records`: - -![][4] - - [4]: images/4.png - -Ahora necesitas encontrar este formulario: - -![][5] - - [5]: images/5.png - -Y completarlo con los siguientes detalles: - Hostname: www - Type: CNAME - Value: tu dominio de PythonAnywhere (por ejemplo, djangogirls.pythonanywhere.com) - TTL: 60 - -![][6] - - [6]: images/6.png - -En la parte inferior, haz click en el botón "Agregar" y guarda los cambios. - -> **Nota** Si utilizaste un proveedor de dominios diferente, la interfaz exacta para encontrar tus configuraciones de DNS / CNAME será diferente, pero tu objetivo es el mismo: configurar un CNAME que apunte a tu nuevo dominio en `yourusername.pythonanywhere.com`. - -Puede tomar unos minutos para tu dominio para empezar a funcionar, ¡sé paciente! - -## Configura el dominio a través de la aplicación web en PythonAnywhere - -También necesitarás decirle a PythonAnywhere que quieres usar tu dominio personalizado. - -Ve a la página [PythonAnywhere Accounts][7] y haz una actualización del tipo de cuenta. La opción más económica (el plan "Hacker") está bien para empezar. Siempre puedes elegir un plan con mayores prestaciones después cuando te vuelvas super-famosa y tengas millones de visitas. - - [7]: https://www.pythonanywhere.com/account/ - -Luego, ve a la pestaña [Web][8] y anota un par de cosas: - - [8]: https://www.pythonanywhere.com/web_app_setup/ - -* Copia la **ruta a tu virtualenv** y ponla en algún lugar seguro -* Abre tu **archivo de configuración WSGI**, copia el contenido, y pégalo en algún lugar seguro - -Luego, haz click en **Delete** de tu vieja aplicación web. No te preocupes, esto no eliminará tu código, solamente cambiará el dominio *yourusername.pythonanywhere.com*. Luego, crea una nueva aplicación web y sigue estos pasos: - -* Ingresa tu nombre de dominio -* Elije "configuración manual" -* Elije Python 3.4 -* ¡Y listo! - -Cuando seas redirigida a la pestaña web. - -* Pega la ruta al virtualenv que guardaste anteriormente -* Abre tu nuevo archivo de configuración WSGI y pega el contenido de tu viejo archivo de configuración - -Haz click en actualizar, ¡deberías ver que tu sitio está en línea en el nuevo dominio! - -Si te encuentras con algún problema, haz click en el vínculo "Send feedback" en el sitio de PythonAnywhere, y uno de sus amigables administradores te contactará para ayudarte en breve. diff --git a/es/domain/images/1.png b/es/domain/images/1.png deleted file mode 100644 index 97a06e28f2a..00000000000 Binary files a/es/domain/images/1.png and /dev/null differ diff --git a/es/domain/images/2.png b/es/domain/images/2.png deleted file mode 100644 index 604fd5b02c8..00000000000 Binary files a/es/domain/images/2.png and /dev/null differ diff --git a/es/domain/images/3.png b/es/domain/images/3.png deleted file mode 100644 index c941c0d231d..00000000000 Binary files a/es/domain/images/3.png and /dev/null differ diff --git a/es/domain/images/4.png b/es/domain/images/4.png deleted file mode 100644 index dcbe145b271..00000000000 Binary files a/es/domain/images/4.png and /dev/null differ diff --git a/es/domain/images/5.png b/es/domain/images/5.png deleted file mode 100644 index 778765053e5..00000000000 Binary files a/es/domain/images/5.png and /dev/null differ diff --git a/es/domain/images/6.png b/es/domain/images/6.png deleted file mode 100644 index 52a0bb87c4c..00000000000 Binary files a/es/domain/images/6.png and /dev/null differ diff --git a/es/dynamic_data_in_templates/README.md b/es/dynamic_data_in_templates/README.md index f991de7c0b5..c96bf39cef2 100755 --- a/es/dynamic_data_in_templates/README.md +++ b/es/dynamic_data_in_templates/README.md @@ -1,72 +1,81 @@ -# Datos dinámicos en las plantillas +# Datos dinámicos en plantillas -Tenemos diferentes piezas en su lugar: el modelo `Post` está definido en `models.py`, tenemos a `post_list` en `views.py` y la plantilla agregada. ¿Pero cómo haremos realmente para que nuestros posts aparezcan en nuestra plantilla HTML? Porque eso es lo que queremos hacer: tomar algún contenido (modelos guardados en la base de datos) y mostrarlo adecuadamente en nuestra plantilla, ¿no? +Tenemos diferentes piezas en su lugar: el modelo `Post` está definido en `models.py`, tenemos a `post_list` en `views.py` y la plantilla agregada. ¿Pero cómo haremos realmente para que nuestros posts aparezcan en nuestra plantilla HTML? Porque eso es lo que queremos, tomar algún contenido (modelos guardados en la base de datos) y mostrarlo adecuadamente en nuestra plantilla, ¿no? -Esto es exactamente lo que las *views* se supone que hacen: conectar modelos con plantillas. En nuestra *view* `post_list` necesitaremos tomar los modelos que deseamos mostrar y pasarlos a una plantilla. Así que básicamente en una *view* decidimos qué (modelo) se mostrará en una plantilla. +Esto es exactamente lo que las *views* se supone que hacen: conectar modelos con plantillas. En nuestra *view* `post_list` necesitaremos tomar los modelos que deseamos mostrar y pasarlos a una plantilla. En una *vista* decidimos qué (modelo) se mostrará en una plantilla. -Muy bien, ahora ¿cómo lo hacemos? +Muy bien, entonces ¿cómo lo logramos? -Necesitamos abrir nuestro archivo `blog/views.py`. Hasta ahora la *view* `post_list` se ve así: +Tenemos que abrir `blog/views.py` en el editor. De momento `post_list` *view* tiene esto: + +{% filename %}blog/views.py{% endfilename %} ```python - from django.shortcuts import render - - def post_list(request): - return render(request, 'blog/post_list.html', {}) +from django.shortcuts import render + +def post_list(request): + return render(request, 'blog/post_list.html', {}) ``` ¿Recuerdas cuando hablamos de incluir código en diferentes archivos? Ahora tenemos que incluir el modelo que definimos en el archivo `models.py`. Agregaremos la línea `from .models import Post` de la siguiente forma: +{% filename %}blog/views.py{% endfilename %} + ```python - from django.shortcuts import render - from .models import Post +from django.shortcuts import render +from .models import Post ``` -El punto después de `from` indica el *directorio actual* o la *aplicación actual*. Como `views.py` y `models.py` están en el mismo directorio, simplemente usamos `.` y el nombre del archivo (sin `.py`). Ahora importamos el nombre del modelo (`Post`). +El punto antes de `models` indica el *directorio actual* o la *aplicación actual*. Ambos, `views.py` y `models.py` están en el mismo directorio. Esto significa que podemos utilizar `.` y el nombre del archivo (sin `.py`). Ahora importamos el nombre del modelo (`Post`). -¿Pero ahora qué sigue? Para tomar publicaciones reales del modelo `Post`, necesitamos algo llamado `QuerySet` (conjunto de consultas). +¿Pero ahora qué sigue? Para tomar posts reales del modelo `Post`, necesitamos algo llamado `QuerySet`. ## QuerySet -Ya debes estar familiarizada con la forma en que funcionan los QuerySets. Hablamos de ellos en el capítulo [Django ORM (QuerySets)][1]. +Ya debes estar familiarizada con la forma en que funcionan los QuerySets. Hablamos de ellos en el capítulo [Django ORM (QuerySets)](../django_orm/README.md). - [1]: ../django_orm/README.md +Así que ahora nos interesa tener una lista de post publicados ordenados por `published_date` (fecha de publicación), ¿no? ¡Ya lo hicimos en el capítulo QuerySets! -Entonces ahora nos interesa obtener una lista de entradas del blog que han sido publicadas y ordenadas por `published_date` (fecha de publicación), ¿no? ¡Ya hicimos eso en el capítulo 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') +``` -Ahora pondremos este bloque de código en el archivo `blog/views.py`, agregándolo a la función `def post_list(request)`: +Abre `blog/views.py` en el editor, y añade este trozo de código a la función `def post_list(request)` -- pero no te olvides de añadir `from django.utils import timezone` antes: + +{% filename %}blog/views.py{% endfilename %} ```python - from django.shortcuts import render - from django.utils import timezone - from .models import Post - - def post_list(request): - posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') - return render(request, 'blog/post_list.html', {}) +from django.shortcuts import render +from django.utils import timezone +from .models import Post + +def post_list(request): +    posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +    return render(request, 'blog/post_list.html', {}) ``` -Observa que creamos una *variable* en nuestro QuerySet: `posts`. Tómala como el nombre de nuestro QuerySet. De aquí en adelante vamos a referirnos al QuerySet con ese nombre. +La última parte es pasar el QuerySet `posts` a la plantilla context. No te preocupes, enseñaremos cómo mostrarlo más adelante. -La última parte es pasar el QuerySet `posts` a la plantilla (veremos cómo mostrarla en el siguiente capítulo). +Fíjate en que creamos una *variable* para el QuerySet: `posts`. Trátala como si fuera el nombre de nuestro QuerySet. De aquí en adelante vamos a referirnos al QuerySet con ese nombre. -En la función `render` ya tenemos el parámetro `request` (todo lo que recibimos del usuario via Internet) y el archivo `'blog/post_list.html'` como plantilla. El último parámetro, que se ve así: `{}` es un campo en el que podemos agregar algunas cosas para que la plantilla las use. Necesitamos nombrarlos (los seguiremos llamando `'posts'` por ahora :)). Se debería ver así: `{'posts': posts}`. Observa que la parte que va antes de `:` está entre comillas `''`. +En la función `render` tenemos el parámetro `request` (todo lo que recibimos del usuario via Internet) y otro parámetro dándole el archivo de la plantilla (`'blog/post_list.html'`). El último parámetro, que se ve así: `{}` es un lugar en el que podemos agregar algunas cosas para que la plantilla las use. Necesitamos nombrarlos (los seguiremos llamando `'posts'` por ahora). :) Se debería ver así: `{'posts': posts}`. Fíjate en que la parte antes de `:` es una cadena; tienes que envolverla con comillas: `"`. Finalmente nuestro archivo `blog/views.py` debería verse así: +{% filename %}blog/views.py{% endfilename %} + ```python - from django.shortcuts import render - from django.utils import timezone - from .models import Post - - def post_list(request): - posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') - return render(request, 'blog/post_list.html', {'posts': posts}) +from django.shortcuts import render +from django.utils import timezone +from .models import Post + +def post_list(request): +    posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +    return render(request, 'blog/post_list.html', {'posts': posts}) ``` ¡Terminamos! Ahora regresemos a nuestra plantilla y mostremos este QuerySet. -Si quieres leer un poco más acerca de QuerySets en Django, puedes darle un vistazo a: https://docs.djangoproject.com/en/1.8/ref/models/querysets/ +¿Quieres leer un poco más sobre QuerySets en Django? Debería mirar aquí: https://docs.djangoproject.com/en/2.2/ref/models/querysets/ \ No newline at end of file diff --git a/es/extend_your_application/README.md b/es/extend_your_application/README.md index 82b030b1aaf..f5c523f1709 100755 --- a/es/extend_your_application/README.md +++ b/es/extend_your_application/README.md @@ -1,6 +1,8 @@ -# Amplía tu aplicación +{% set warning_icon = '' %} -Ya hemos completado todos los pasos necesarios para la creación de nuestro sitio web: sabemos cómo escribir un model, url, view y template. También sabemos cómo hacer que nuestro sitio web se vea lindo. +# Extiende tu aplicación + +Ya hemos completado todos los diferentes pasos necesarios para la creación de nuestro sitio web: sabemos cómo escribir un modelo, URL, vista y plantilla. También sabemos cómo hacer que nuestro sitio web sea bonito. ¡Hora de practicar! @@ -8,191 +10,205 @@ Lo primero que necesitamos en nuestro blog es, obviamente, una página para most Ya tenemos un modelo `Post`, así que no necesitamos añadir nada a `models.py`. -## Crea un enlace en la plantilla +## Crea un enlace a la página de detalle de una publicación + +Empezaremos añadiendo un enlace al fichero `blog/templates/blog/post_list.html`. Ábrelo en el editor; de momento debería tener este contenido: {% filename %}blog/templates/blog/post_list.html{% endfilename %} -Vamos a empezar añadiendo un enlace dentro del archivo `blog/templates/blog/post_list.html`. Hasta el momento debería verse así: -``` html - {% extends 'blog/base.html' %} +```html +{% extends 'blog/base.html' %} - {% block content %} - {% for post in posts %} -
-
- {{ post.published_date }} -
-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

+{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }}
- {% endfor %} - {% endblock content %} +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} ``` -Queremos tener un enlace a una página de detalle sobre el título del post. Vamos a cambiar `

{{ post.title }}

` dentro del enlace: +{% raw %}Queremos tener un enlace del título de una publicación en la lista de publicaciones al detalle de la misma. Cambiemos `

{{ post.title }}

` para enlazarla a la página detalle del post:{% endraw %} + +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} + +```html +

{{ post.title }}

``` -

{{ post.title }}

-``` -Es hora de explicar el misterioso `{% url 'blog.views.post_detail' pk=post.pk %}`. Como probablemente sospeches, la notación `{% %}` significa que estamos utilizando Django template tags. ¡Esta vez vamos a utilizar uno que va a crear una dirección URL para nosotros! +{% raw %}Es hora de explicar el misterioso`{% url 'post_detail' pk=post.pk %}`. Como probablemente sospeches, la notación `{% %}` significa que estamos utilizando Django template tags. ¡Esta vez usaremos uno que creará un URL para nosotros!{% endraw %} + +La parte de`post_detail` significa que Django estará esperando un URL en `blog/urls.py` con el nombre=post_detail -`blog.views.post_detail` es una ruta hacia `post_detail` *view* que queremos crear. Por favor nota: `blog` es el nombre de nuestra aplicación (el `blog` de directorio), `views` es el nombre del archivo `views.py` y `post_detail` es el nombre de la *view*. +¿Y ahora qué pasa con `pk=post.pk`? `pk` se refiere a primary key (clave primaria), la cual es un nombre único por cada registro en una base de datos. Debido a que no especificamos una llave primaria en nuestro modelo `Post`, Django creará una por nosotros (por defecto, un número que incrementa una unidad por cada registro, por ejemplo, 1, 2, 3) y lo añadirá como un campo llamado `pk` a cada uno de nuestros posts. Accedemos a la clave primaria escribiendo `post.pk`, del mismo modo en que accedemos a otros campos (`título`, `autor`, etc.) en nuestro objeto `Post`! -Ahora cuando vayamos a: http://127.0.0.1:8000/ tendremos un error (como era de esperar, ya que no tenemos una dirección URL o una *view* para `post_detail`). Se verá así: +Ahora cuando vayamos a: http://127.0.0.1:8000/ tendremos un error (como era de esperar, ya que no tenemos una URL o una *vista* para `post_detail`). Se verá así: -![NoReverseMatch error][1] +![NoReverseMatch error](images/no_reverse_match2.png) - [1]: images/no_reverse_match2.png +## Crea una URL al detalle de una publicación -¡Vamos a crear una URL en `urls.py` para nuestro *view* `post_detail`! +Vamos a crear una URL en `urls.py` para nuestra *view* `post_detail`! -### URL: http://127.0.0.1:8000/post/1/ +Queremos que el detalle de la primera entrada se visualice en esta **URL**: http://127.0.0.1:8000/post/1/ -Queremos crear una URL que apunte a Django a una *view* denominada `post_detail`, que mostrará una entrada del blog. Agrega la línea `url (r'^post/(?P[0-9]+)/$', views.post_detail),` al archivo `blog/urls.py`. Debería tener este aspecto: +Vamos a crear una URL en el fichero `blog/urls.py` que dirija a Django hacia una *vista* llamada `post_detail`, que mostrará una entrada de blog completa. Abre el fichero `blog/urls.py` en el editor, y añade la línea `path('post//', views.post_detail, name='post_detail'),` para que el fichero quede así: -``` python -from django.conf.urls import url +{% filename %}{{ warning_icon }} blog/urls.py{% endfilename %} + +```python +from django.urls import path from . import views urlpatterns = [ - url(r'^$', views.post_list), - url(r'^post/(?P[0-9]+)/$', views.post_detail), + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), ] ``` -Ese da un poco de miedo, pero no te preocupes - lo explicaremos para -ti: -- comienza con `^` otra vez, "el principio". -- `post/` sólo significa que después del comienzo, la dirección URL debe contener la palabra **post** y **/**. Hasta ahora, bien. -- `(?P[0-9]+)` - esta parte es más complicada. Significa que Django llevará todo lo que coloques aquí y lo transferirá a una vista como una variable llamada `pk`. `[0-9]` también nos dice que sólo puede ser un número, no una letra (todo debería estar entre 0 y 9). `+` significa que tiene que haber uno o más dígitos. Entonces algo como `http://127.0.0.1:8000/post//` no es válido, pero `http://127.0.0.1:8000/post/1234567890/` es perfectamente aceptable! -- `/` - entonces necesitamos **/** de nuevo -- `$` - ¡"el final"! +Esta parte `post//` especifica un patrón de URL – ahora lo explicamos: -Eso significa que si entras en `http://127.0.0.1:8000/post/5/` en tu navegador, Django entenderá que estás buscando una *view* denominada `post_detail` y transferirá la información de `pk` que es igual a `5` a esa *view*. +- `post/` significa que la URL debería empezar con la palabra **post** seguida por una **/**. Hasta aquí bien. +- `` – esta parte tiene más miga. Significa que Django buscará un número entero y se lo pasará a la vista en una variable llamada `pk`. +- `/` – necesitamos otra **/** al final de la URL. -`pk` es la abreviación de `primary key`. Este nombre se utiliza a menudo en proyectos de Django. Pero puedes nombrar tus variables como te guste (recuerda: ¡minúsculas y `_` en lugar de espacios en blanco!). Por ejemplo en lugar de `(?.¿P[0-9]+)` podríamos tener la variable `post_id`, así que esto lo verías como: `(?P [0-9]+)`. +Esto quiere decir que si pones `http://127.0.0.1:8000/post/5/` en tu navegador, Django entenderá que estás buscando una *vista* llamada `post_detail` y transferirá la información de que `pk` es igual a `5` a esa *vista*. -¡Bien! ¡Actualiza la página: http://127.0.0.1:8000/ ¡Boom! ¡Sin embargo vemos otro error! Como era de esperarse. +OK, ¡hemos añadido un nuevo patrón de URL a `blog/urls.py`! Actualizamos la página: http://127.0.0.1:8000/ y, ¡boom! El servidor vuelve a dejar de funcionar. Echa un vistazo a la consola – como era de esperar, ¡hay otro error! -![AttributeError][2] +![AttributeError](images/attribute_error2.png) - [2]: images/attribute_error2.png +¿Recuerdas cuál es el próximo paso? ¡Añadir una vista! -¿Te acuerdas del próximo paso? Por supuesto: ¡agregar una view! +## Añade la vista de detalle de la publicación -## post_detail view +Esta vez nuestra *vista* tomará un parámetro adicional `pk`. Nuestra *vista* necesita recibirlo, ¿verdad? Así que definiremos nuestra función como `def post_detail (request, pk):`. Tenga en cuenta que necesitamos usar exactamente el mismo nombre que el que especificamos en `urls` (`pk`). ¡Omitir esta variable es incorrecto y resultará en un error! -Esta vez nuestra *view* tomará un parámetro adicional `pk`. Nuestra *view* necesita recibirla, ¿cierto? Entonces definiremos nuestra función como `def post_detail (request, pk):`. Ten en cuenta que tenemos que usar exactamente el mismo nombre que especificamos en las urls (`pk`). ¡Omitir esta variable es incorrecto y resultará en un error! +Ahora, queremos obtener solo un post. Para ello podemos usar querysets como este: -Ahora, queremos sólo un post del blog. Para ello podemos usar querysets como este: - -``` python - - Post.objects.get(pk=pk) +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} +```python +Post.objects.get(pk=pk) ``` -Pero este código tiene un problema. Si no hay ningún `Post` con `llave primaria` (`pk`) tendremos un error muy feo. - -![DoesNotExist error][3] +Pero este código tiene un problema. Si no hay ningún `Post` con esa `clave primaria` (`pk`), ¡tendremos un error muy feo! - [3]: images/does_not_exist2.png +![DoesNotExist error](images/does_not_exist2.png) -¡No queremos eso! Pero, por supuesto, Django viene con algo que se encargará de ese problema por nosotros: `get_object_or_404`. En caso de que no haya ningún `Post` con el dado `pk` se mostrará una más agradable página (`Page Not Found 404`). +¡No queremos eso! Por suerte, Django tiene una función que se encarga de eso: `get_object_or_404`. En caso de que no haya ningún `Post` con el `pk` dado se mostrará una página mucho más agradable, `Page Not Found 404`. -![Page not found][4] - - [4]: images/404_2.png +![Page not found](images/404_2.png) La buena noticia es que puedes crear tu propia página `Page Not Found` y diseñarla como desees. Pero por ahora no es tan importante, así que lo omitiremos. ¡Es hora de agregar una *view* a nuestro archivo `views.py`! -Deberíamos abrir `blog/views.py` y agregar el siguiente código: +En `blog/urls.py` creamos un regla de URL denominada `post_detail` que hace referencia a una vista llamada `view.post_detail`. Esto significa que Django va a estar esperando una función llamada `post_detail` de vista en `blog/views.py`. -```python +Deberíamos abrir `blog/views.py` en el editor y añadir el siguiente código cerca de los otros import `from`: - from django.shortcuts import render, get_object_or_404 +{% filename %}blog/views.py{% endfilename %} +```python +from django.shortcuts import render, get_object_or_404 ``` -Cerca de otras líneas `from`. Y en el final del archivo añadimos nuestra *view*: +Y al final del archivo agregamos nuestra *view*: + +{% filename %}blog/views.py{% endfilename %} ```python def post_detail(request, pk): -     post = get_object_or_404(Post, pk=pk) -     return render(request, 'blog/post_detail.html', {'post': post}) - -``` +    post = get_object_or_404(Post, pk=pk) +    return render(request, 'blog/post_detail.html', {'post': post}) +``` Sí. Es hora de actualizar la página: http://127.0.0.1:8000/ -![Post list view][5] +![Post list view](images/post_list2.png) - [5]: images/post_list2.png +¡Funcionó! Pero, ¿qué pasa cuando haces click en un enlace en el título del post? -¡Funcionó! Pero ¿qué pasa cuando haces click en un enlace en el título del post? +![TemplateDoesNotExist error](images/template_does_not_exist2.png) -![TemplateDoesNotExist error][6] +¡Oh, no! ¡Otro error! Pero ya sabemos cómo lidiar con eso, ¿no? ¡Tenemos que añadir una plantilla! - [6]: images/template_does_not_exist2.png +## Crear una plantilla para post detail -¡Oh no! ¡Otro error! Pero ya sabemos cómo lidiar con eso, ¿no? ¡Tenemos que añadir una plantilla! - -Crearemos un archivo en `blog/templates/blog` llamado `post_detail.html`. +Vamos crear un fichero en `blog/templates/blog` llamado `post_detail.html`, y abrirlo en el editor de código. Se verá así: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + ```html - {% extends 'blog/base.html' %} - - {% block content %} -     
-         {% if post.published_date %} -             
-                 {{ post.published_date }} -             
-         {% endif %} -         

{{ post.title }}

-         

{{ post.text|linebreaksbr }}

-     
- {% endblock %} +{% extends 'blog/base.html' %} + +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endblock %} ``` Una vez más estamos extendiendo `base.html`. En el bloque `content` queremos mostrar la fecha de publicación (si existe), título y texto de nuestros posts. Pero deberíamos discutir algunas cosas importantes, ¿cierto? -`{% if ... %} ... {% endif %}` es un template tag que podemos usar cuando querramos ver algo (¿recuerdas if ... else... del capítulo de **Introducción a Python**?). En este escenario queremos comprobar si el campo `published_date` de un post no está vacío. +{% raw %}`{% if ... %} ... {% endif %}` es un template tag que podemos usar cuando querramos ver algo. (Recuerdas `if ... else ..` del capítulo **Intruducción a Python**?) Ahora queremos mirar si la `published_date` de un post no esta vacía.{% endraw %} -Bien, podemos actualizar nuestra página y ver si `Page Not Found` se ha ido. +Bien, podemos actualizar nuestra página y ver si `TemplateDoesNotExist` se ha ido. -![Post detail page][7] - - [7]: images/post_detail2.png +![Post detail page](images/post_detail2.png) ¡Yay! ¡Funciona! -## Una cosa más: ¡Tiempo de implementación! +# ¡Hora de despliegue! Sería bueno verificar que tu sitio web aún funcionará en PythonAnywhere, ¿cierto? Intentemos desplegar de nuevo. -``` +{% filename %}command-line{% endfilename %} $ git status - $ git add --all . + $ git add -A . $ git status - $ git commit -m "Added views to create/edit blog post inside the site." + $ git commit -m "Agregadas vistas y plantilla para el detalle del post del blog así como también CSS para el sitio." $ git push + -``` +Luego, en una [consola Bash de PythonAnywhere](https://www.pythonanywhere.com/consoles/): -* Luego, en una [consola Bash de PythonAnywhere][8] +{% filename %}PythonAnywhere command-line{% endfilename %} -``` - $ cd my-first-blog - $ git pull [...] -``` + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Recuerda sustituir `` con tu subdominio de PythonAnywhere real, sin los paréntesis angulares.) + +## Actualizar los ficheros estáticos (static files) en el servidor + +Normalmente, los servidores como PythonAnywhere tratan los ficheros estáticos (como los ficheros CSS) de manera diferente a los ficheros de Python. Se llaman estáticos porque el servidor no debe ejecutarlos, sino servirlos tal cual. Y por ello se tratan por separado para servirlos más rápido. Como consecuencia, si cambiamos nuestros ficheros CSS, tenemos que ejecutar un comando extra en el servidor para decirle que los actualice. Este comando se llama `collectstatic`. + +Activa el virtualenv si no estaba activado de antes (en PythonAnywhere se usa el comando `workon`, es igual que el comando `source myenv/bin/activate` que usamos en local): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ workon .pythonanywhere.com + (ola.pythonanywhere.com)$ python manage.py collectstatic + [...] + -* Finalmente, ve a la pestaña [Web][9] y haz click en **Reload**. +El comando `manage.py collectstatic` es un poco como el comando `manage.py migrate`. Hacemos cambios en nuestro código y luego le decimos a Django que los *aplique*, bien a la colección de ficheros estáticos o bien a la base de datos. - [8]: https://www.pythonanywhere.com/consoles/ - [9]: https://www.pythonanywhere.com/web_app_setup/ +En cualquier caso, ahora estaremos listos para saltar sobre la [página "Web"](https://www.pythonanywhere.com/web_app_setup/) (desde el botón del menú en el lado superior derecho de la consola), realizar la **Recarga**, y mirar en la página https://subdomain.pythonanywhere.com para ver el resultado. ¡Y eso debería ser todo! Felicidades :) diff --git a/es/extend_your_application/images/404_2.png b/es/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/es/extend_your_application/images/404_2.png and b/es/extend_your_application/images/404_2.png differ diff --git a/es/extend_your_application/images/attribute_error2.png b/es/extend_your_application/images/attribute_error2.png index 6edcd9933c3..4b8262476d9 100644 Binary files a/es/extend_your_application/images/attribute_error2.png and b/es/extend_your_application/images/attribute_error2.png differ diff --git a/es/extend_your_application/images/does_not_exist2.png b/es/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/es/extend_your_application/images/does_not_exist2.png and b/es/extend_your_application/images/does_not_exist2.png differ diff --git a/es/extend_your_application/images/no_reverse_match2.png b/es/extend_your_application/images/no_reverse_match2.png index 306926206f8..aba1c9c8980 100644 Binary files a/es/extend_your_application/images/no_reverse_match2.png and b/es/extend_your_application/images/no_reverse_match2.png differ diff --git a/es/extend_your_application/images/post_detail2.png b/es/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/es/extend_your_application/images/post_detail2.png and b/es/extend_your_application/images/post_detail2.png differ diff --git a/es/extend_your_application/images/post_list2.png b/es/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/es/extend_your_application/images/post_list2.png and b/es/extend_your_application/images/post_list2.png differ diff --git a/es/extend_your_application/images/template_does_not_exist2.png b/es/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/es/extend_your_application/images/template_does_not_exist2.png and b/es/extend_your_application/images/template_does_not_exist2.png differ diff --git a/es/how_the_internet_works/README.md b/es/how_the_internet_works/README.md index 8a5e936cb93..a57e6a7e599 100755 --- a/es/how_the_internet_works/README.md +++ b/es/how_the_internet_works/README.md @@ -1,55 +1,47 @@ # ¿Cómo funciona Internet? -> Este capitulo está inspirado por la charla "How the Internet works" de Jessica McKellar (http://web.mit.edu/jesstess/www/). +> Para lectores en casa: este capítulo está cubierto en el video [¿Cómo funciona Internet?](https://www.youtube.com/watch?v=oM9yAA09wdc). +> +> Este capítulo está inspirado en la charla "How the Internet works" de Jessica McKellar (http://web.mit.edu/jesstess/www/). -Apostamos que utilizas Internet todos los días. Pero, ¿sabes lo que pasa cuando escribes una dirección como https://djangogirls.org en tu navegador y presionas 'Enter'? +Apostamos a que utilizas Internet todos los días. Pero, ¿sabes lo que pasa cuando escribes una dirección como http://djangogirls.org en tu navegador y presionas `enter`? -Lo primero que tienes que entender es que un sitio web es sólo un montón de archivos guardados en un disco duro. Al igual que tus películas, música o fotos. Sin embargo, los sitios web poseen una peculiaridad: ellos incluyen un código de computadoras llamado HTML. +La primera cosa que necesitas entender, es que una página web consiste de un puñado de archivos guardados en el disco duro -- como tus películas, música, o imágenes. Sin embargo, hay una parte que es única para los sitios web: ellos incluyen código computarizado llamado HTML. -Si no estás familiarizada con la programación, puede ser difícil de captar HTML al principio, pero tus navegadores web (como Chrome, Safari, Firefox, etc.) lo aman. Los navegadores web están diseñados para entender este código, seguir sus instrucciones y mostrar todos esos archivos de los cuales tu sitio web está hecho de la manera exacta como tu quieres que se muestren. +Si no estás familiarizada con la programación, puede ser difícil de comprender HTML a la primera, pero tus navegadores web (como Chrome, Safari, Firefox, etc.) lo aman. Los navegadores están diseñados para entender este código, seguir sus instrucciones y presentar estos archivos de los cuales está hecho tu sitio web, exactamente de la forma que quieres. -Como cualquier otro archivo, tenemos que guardar los archivos HTML en algún lugar de un disco duro. Para Internet, usamos unas computadoras especiales y poderosas llamadas *servidores*. Ellas no tienen una pantalla, mouse o teclado, debido a que su propósito es almacenar datos y servirlos. Por esa razón son llamados *servidores* -- porque ellos *sirven* los datos. +Como cualquier otro archivo, tenemos que guardar los archivos HTML en algún lugar de un disco duro. Para Internet, utilizamos equipos especiales, de gran alcance llamados *servidores*. Estos no tienen una pantalla, ratón o teclado, debido a que su propósito es almacenar datos y servirlos. Por esa razón son llamados *servidores* -- porque *sirven* los datos. -Ok, quizás te preguntes cómo luce Internet, ¿cierto? +OK, pero quieres saber cómo Internet se ve, ¿cierto? ¡Te hemos hecho una imagen! Luce algo así: -![Figura 1.1][1] +![Figura 1.1](images/internet_1.png) - [1]: images/internet_1.png +Parece un lío, ¿no? De hecho, es una red de máquinas interconectadas (los *servidores* que nombramos anteriormente). ¡Cientos de miles de máquinas! ¡Muchos, muchos kilómetros de cables alrededor del mundo! Puedes visitar el sitio web Submarine Cable Map (http://submarinecablemap.com/) y ver lo complicada que es la red. Aquí hay una captura de pantalla de la página web: -Parece un lío, ¿no? En realidad es una red de máquinas conectadas (los mencionados *servidores*). ¡Cientos de miles de máquinas! ¡Muchos, muchos kilómetros de cables alrededor del mundo! Puedes visitar el sitio web [Submarine Cable Map][2] (http://submarinecablemap.com/) donde se muestran las conexiones de cables submarinos alrededor del mundo y ver lo complicada que es la red. Aquí hay una captura de pantalla de la página web: +![Figura 1.2](images/internet_3.png) - [2]: http://submarinecablemap.com/ - -![Figura 1.2][3] - - [3]: images/internet_3.png - -Es fascinante, ¿no? Pero, obviamente, no es posible tener un cable entre cada máquina conectada a Internet. Así que, para llegar a una máquina (por ejemplo la que aloja a https://djangogirls.org) tenemos que pasar una solicitud a través de muchas máquinas diferentes. +Es fascinante, ¿no? Pero sería imposible tener un cable entre todas y cada una de las máquinas conectadas a internet. Así que, para llegar a una máquina (por ejemplo la que aloja http://djangogirls.org) tenemos que elevar una solicitud mediante una gran cantidad de máquinas diferentes. Se parece a esto: -![Figura 1.3][4] - - [4]: images/internet_2.png - -Imagina que cuando escribes https://djangogirls.org, estas enviando una carta que dice: "Queridos Django Girls, me gustaría ver su sitio web djangogrils.org. Por favor, envíenmelo!" +![Figura 1.3](images/internet_2.png) -Tu carta va hacia la oficina de correo más cercana. Luego va a otra un poco más cercana de su destinatario, luego a otra y a otra hasta que es entregada en su destino. La única cosa diferente es que si tu envías cartas (*paquetes de datos*) con frecuencia al mismo lugar, cada carta puede pasar por oficinas de correos (*routers*) totalmente diferentes, dependiendo de cómo se distribuyen en cada oficina. +Imagina que cuando escribes http://djangogirls.org, estas enviando una carta que dice: "Estimadas Django Girls, me gustaría ver su sitio web djangogirls.org. ¡Por favor, envíenmelo!" -![Figura 1.4][5] +Tu carta va hacia la oficina de correo más cercana. Luego va a otra que es un poco más cerca de su destinatario, luego otra y otra hasta que es entregada a su destino. La única cosa diferente es que si envías muchas cartas (*paquetes de datos*) al mismo lugar, cada una podría ir a través de oficinas de correos totalmente distintas (*routers*). Esto depende de cómo se distribuyen en cada oficina. - [5]: images/internet_4.png +![Figura 1.4](images/internet_4.png) -Sí, es tan simple como eso. Enviar mensajes y esperar alguna respuesta. Por supuesto, en vez de papel y lapicera usas bytes de datos, ¡pero la idea es la misma! +Así es como funciona - se envían mensajes y se espera una respuesta. En lugar de papel y lápiz, se usan bytes de datos, pero ¡la idea es la misma! -En lugar de direcciones con el nombre de la calle, ciudad, código postal y nombre del país, utilizamos direcciones IP. Tu computadora pide primero el DNS (Domain Name System - en español Sistema de Nombres de Dominio) para traducir djangogirls.org a una dirección IP. Funciona como los viejos directorios telefónicos donde puedes buscar el nombre de la persona que se deseas contactar y este nos muestra su número de teléfono y dirección. +En lugar de direcciones con el nombre de la calle, ciudad, código postal y nombre del país, utilizamos direcciones IP. Tu computadora pide primero el DNS (Domain Name System - en español Sistema de Nombres de Dominio) para traducir djangogirls.org a una dirección IP. Funciona en cierta manera como los viejos directorios telefónicos donde puedes buscar el nombre de la persona que se deseas contactar y encontrar su número de teléfono y dirección. -Cuando envías una carta, ésta necesita tener ciertas características para ser entregada correctamente: una dirección, sello, etc. También utilizas un lenguaje que el receptor pueda entender, ¿cierto? Lo mismo sucede con los *paquetes de datos* que envías para ver un sitio web: utilizas un protocolo llamado HTTP (Hypertext Transfer Protocol - en español Protocolo de Transferencia de Hipertexto). +Cuando envías una carta, esta necesita tener ciertas características para ser entregada correctamente: una dirección, sello, etc. También utilizas un lenguaje que el receptor pueda entender, ¿cierto? Lo mismo se aplica a los *paquetes de datos* que envía para ver un sitio Web. Utilizamos un protocolo llamado HTTP (Protocolo de transferencia de hipertexto). -Así que, básicamente, cuando tienes un sitio web necesitas tener un *servidor* (la máquina) donde vive. El *servidor* está esperando cualquier *solicitud* entrante (cartas que piden al servidor que envíe tu sitio web) y éste responde enviando tu sitio web (en otra carta). +Así que, básicamente, cuando tienes un sitio web necesitas tener un *servidor* (la máquina) donde este vive. Cuando el *servidor* recibe una *petición* entrante (en una carta), este envía su sitio de Internet (en otra carta). -Puesto que este es un tutorial de Django, seguro te preguntarás qué es lo que hace Django. Bueno, cuando envías una respuesta, no siempre quieres enviar lo mismo a todo el mundo. Es mucho mejor si tus cartas son personalizadas, especialmente para la persona que acaba de escribir, ¿cierto? Django nos ayuda con la creación de estas cartas personalizadas :). +Ya que este es un tutorial de Django, puede que te preguntes qué es lo que Django hace. Bueno, cuando envías una respuesta, no siempre quieres enviar lo mismo a todo el mundo. Es mucho mejor si tus cartas son personalizadas, especialmente para la persona que acaba de escribir, ¿cierto? Django nos ayuda con la creación de estas cartas personalizadas. :) -Basta de charlas, ¡pongamos manos a la obra! +Suficiente conversación - ¡tiempo de crear! \ No newline at end of file diff --git a/es/how_the_internet_works/images/internet_1.png b/es/how_the_internet_works/images/internet_1.png index 9c5bcf0b003..e289eac2b23 100644 Binary files a/es/how_the_internet_works/images/internet_1.png and b/es/how_the_internet_works/images/internet_1.png differ diff --git a/es/how_the_internet_works/images/internet_2.png b/es/how_the_internet_works/images/internet_2.png index dd5861f376f..e8cf8b77999 100644 Binary files a/es/how_the_internet_works/images/internet_2.png and b/es/how_the_internet_works/images/internet_2.png differ diff --git a/es/how_the_internet_works/images/internet_3.png b/es/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/es/how_the_internet_works/images/internet_3.png and b/es/how_the_internet_works/images/internet_3.png differ diff --git a/es/how_the_internet_works/images/internet_4.png b/es/how_the_internet_works/images/internet_4.png index 2661cec1b61..d4748ac48ef 100644 Binary files a/es/how_the_internet_works/images/internet_4.png and b/es/how_the_internet_works/images/internet_4.png differ diff --git a/es/html/README.md b/es/html/README.md index acfc1e723ae..31f71a3f908 100755 --- a/es/html/README.md +++ b/es/html/README.md @@ -2,15 +2,15 @@ Te estarás preguntando, ¿qué es una plantilla? -Una plantilla es un archivo que podemos reutilizar para presentar información diferente de forma consistente - por ejemplo, se podría utilizar una plantilla para ayudarte a escribir una carta, porque aunque cada carta puede contener un mensaje distinto y dirigirse a una persona diferente, compartirán el mismo formato. +Una plantilla es un archivo que podemos reutilizar para presentar información diferente de forma consistente - por ejemplo, podrías utilizar una plantilla para ayudarte a escribir una carta, porque aunque cada carta puede contener un mensaje distinto y dirigirse a una persona diferente, compartirán el mismo formato. -El formato de una plantilla de Django se describe en un lenguaje llamado HTML (que es el código HTML que mencionamos en el primer capítulo **Cómo funciona Internet**). +El formato de una plantilla de Django se describe en un lenguaje llamado HTML (el HTML que mencionamos en el primer capítulo **Cómo funciona Internet**). ## ¿Qué es HTML? -HTML es un simple código que es interpretado por tu navegador web - como Chrome, Firefox o Safari - para mostrar una página web al usuario. +HTML es un código simple que es interpretado por tu navegador web - como Chrome, Firefox o Safari - para mostrar una página web al usuario. -HTML significa HyperText Markup Language - en español, Lenguaje de Marcas de HyperTexto. **HyperText** significa que es un tipo de texto que soporta hipervínculos entre páginas. **Markup** significa que hemos tomado un documento y lo hemos marcado con código para decirle a algo (en este caso, un navegador) cómo interpretar la página. El código HTML está construido con **etiquetas**, cada una comenzando con `<` y terminando con `>`. Estas etiquetas de marcado son **elementos**. +HTML significa HyperText Markup Language - en español, Lenguaje de Marcas de HyperTexto. **HyperText** -hipertexto en español- significa que es un tipo de texto que soporta hipervínculos entre páginas. **Markup** significa que hemos tomado un documento y lo hemos marcado con código para decirle a algo (en este caso, un navegador) cómo interpretar la página. El código HTML está construido con **etiquetas**, cada una comenzando con `<` y terminando con `>`. Estas etiquetas representan **elementos** de marcado. ## ¡Tu primera plantilla! @@ -23,69 +23,69 @@ Las plantillas se guardan en el directorio de `blog/templates/blog`. Así que pr └───blog -(Tal vez te preguntes por qué necesitamos dos directorios llamados `blog` - como descubrirás más adelante, esto es simplemente una útil convención de nomenclatura que hace la vida más fácil cuando las cosas empiezan a complicarse más.) +(Tal vez te estés preguntando por qué necesitamos dos directorios llamados `blog` – como verás más adelante, es una convención de nombres que nos facilitará la vida cuando las cosas se pongan más complicadas.) Y ahora crea un archivo `post_list.html` (déjalo en blanco por ahora) dentro de la carpeta `blog/templates/blog`. Mira cómo se ve su sitio web ahora: http://127.0.0.1:8000/ -> Si todavía tienes un error `TemplateDoesNotExists`, intenta reiniciar el servidor. Ve a la línea de comandos, detén el servidor pulsando Ctrl + C (teclas Control y C juntas) y comienza de nuevo mediante la ejecución del comando `python manage.py runserver`. +> Si todavía tienes un error `TemplateDoesNotExist`, intenta reiniciar tu servidor. Ve a la consola, para el servidor pulsando Ctrl+C (las teclas Control y C a la vez) y reinícialo ejecuntado el comando `python manage.py runserver`. -![Figura 11.1][1] - - [1]: images/step1.png +![Figura 11.1](images/step1.png) ¡Ningún error más! Felicidades :) Sin embargo, por ahora, tu sitio web no está publicando nada excepto una página en blanco, porque la plantilla también está vacía. Tenemos que arreglarlo. -Añade lo siguiente a tu archivo de plantilla: +Abre un fichero nuevo en el editor y escribe lo siguiente: -``` html - -

Hi there!

-

It works!

- -``` +{% filename %}blog/templates/blog/post_list.html{% endfilename %} -¿Cómo luce ahora tu sitio web? Haz click para ver: http://127.0.0.1:8000/ +```html + + +

Hi there!

+

It works!

+ + +``` -![Figura 11.2][2] +Ahora, ¿cómo luce tu sitio web? Haz clic para verlo: http://127.0.0.1:8000/ - [2]: images/step3.png +![Figura 11.2](images/step3.png) ¡Funcionó! Buen trabajo :) -* La etiqueta más básica, ``, es siempre el principio de cualquier página web y `` es siempre el final. Como puedes ver, todo el contenido de la página web va desde el principio de la etiqueta `` y hasta la etiqueta de cierre `` -* `

` es una etiqueta para los elementos de párrafo; `

` cierra cada párrafo +* La etiqueta más básica, ``, siempre va al inicio de cualquier página web y `` va siempre al final. Como puedes ver, todo el contenido de la página web va desde el principio de la etiqueta `` y hasta la etiqueta de cierre `` +* `

` es una etiqueta para los elementos de párrafo; `

` cierra cada párrafo -## Cabeza & cuerpo +## Cabeza y cuerpo Cada página HTML también se divide en dos elementos: **head** y **body**. -* **head** es un elemento que contiene información sobre el documento que no se muestra en la pantalla. +* **head** es un elemento que contiene información sobre el documento que no se muestra en la pantalla. -* **body** es un elemento que contiene todo lo que se muestra como parte de la página web. +* **body** es un elemento que contiene todo lo que se muestra como parte de la página web. -Usamos `` para decirle al navegador acerca de la configuración de la página y `` para decir lo que realmente está en la página. +Usamos `` para decirle el navegador acerca de la configuración de la página y `` para decir lo que realmente está en la página. Por ejemplo, puedes ponerle un título a la página web dentro de la ``, así: -``` html - - - Ola's blog - - -

Hi there!

-

It works!

- - +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + Ola's blog + + +

Hi there!

+

It works!

+ + ``` Guarda el archivo y actualiza tu página. -![Figura 11.3][3] - - [3]: images/step4.png +![Figura 11.3](images/step4.png) ¿Observas cómo el navegador ha comprendido que "Ola's blog" es el título de tu página? Ha interpretado `Ola's blog` y colocó el texto en la barra de título de tu navegador (también se utilizará para marcadores y así sucesivamente). @@ -93,61 +93,62 @@ Probablemente también hayas notado que cada etiqueta de apertura coincide con u Es como poner cosas en cajas. Tienes una caja grande, ``; en su interior hay ``, y que contiene las cajas aún más pequeñas: `

`. -Tienes que seguir estas reglas de etiquetas de *cierre* y de *anidación* de elementos - si no lo haces, el navegador puede no ser capaz de interpretarlos correctamente y tu página se mostrará incorrectamente. +Tienes que seguir estas reglas de etiquetas de *cierre* y de *anidación* de elementos - si no lo haces, el navegador puede no ser capaz de interpretarlos apropiadamente y tu página se mostrará incorrectamente. ## Personaliza tu plantilla ¡Ahora puedes divertirte un poco y tratar de personalizar tu plantilla! Aquí hay algunas etiquetas útiles para eso: -* `

Un título

` - para tu título más importante -* `

Un subtítulo

` - para el título del siguiente nivel -* `

Un subsubtítulo

` - ... y así hasta `
` -* `texto` - pone en cursiva tu texto -* `texto` - pone en negrita tu texto -* `
` - un salto de línea (no puedes colocar nada dentro de br) -* `link` - crea un vínculo -* `
  • primer elemento
  • segundo elemento
` - crea una lista, ¡igual que esta! -* `
` - define una sección de la página - -Aquí hay un ejemplo de una plantilla completa: - -``` html - - - 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.

-
- - +* `

Un título

` - para tu título más importante +* `

Un subtítulo

` - para el título del siguiente nivel +* `

Un subsubtítulo

` - ... y así hasta `
` +* `

Un párrafo de texto

` +* `texto` - pone en cursiva tu texto +* `texto` - pone en negrita tu texto +* `
` va en otra línea (no puedes poner nada dentro de br y no hay etiqueta de cierre) +* `link` - crea un vínculo +* `
  • primer elemento
  • segundo elemento
` - crea una lista, ¡igual que esta! +* `
` - define una sección de la página + +Aquí va un ejemplo de una plantilla completa, cópialo y pégalo en `blog/templates/blog/post_list.html`: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + 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.

+
+ + ``` Aquí hemos creado tres secciones `div`. -* El primer elemento `div` contiene el título de nuestro blog - es un encabezado y un enlace -* Otros dos elementos `div` contienen nuestros posts con la fecha de publicación, `h2` con un título que es clickeable y dos `p` (párrafo) de texto, uno para la fecha y uno para nuestro post. +* El primer elemento `div` contiene el título de nuestro blog - es un encabezado y un enlace +* Otros dos elementos `div` contienen nuestras publicaciones (posts) del blog con su fecha de publicación, `h2` con el título del post que es clickable y dos `p`s (párrafos) de texto, uno para la fecha y otro para el contenido del post. Nos da este efecto: -![Figura 11.4][4] +![Figura 11.4](images/step6.png) - [4]: images/step6.png - -¡Yaaay! Pero hasta el momento, nuestra plantilla sólo muestra exactamente **la misma información** - considerando que antes hablábamos de plantillas que nos permitirían mostrar información **diferente** en el **mismo formato**. +¡Yaaay! Pero hasta el momento, nuestra plantilla sólo muestra exactamente **la misma información** - considerando que antes hablábamos de plantillas como permitiéndonos mostrar información **diferente** en el **mismo formato**. Lo que queremos realmente es mostrar posts reales añadidos en nuestra página de administración de Django - y ahí es a donde vamos a continuación. @@ -155,56 +156,62 @@ Lo que queremos realmente es mostrar posts reales añadidos en nuestra página d Sería bueno ver todo esto disponible en Internet, ¿no? Hagamos otro despliegue en PythonAnywhere: -### Haz un commit y sube tu código a GitHub +### Haz commit, y sube tu código a GitHub + +En primer lugar, vamos a ver qué archivos han cambiado desde la última puesta en marcha (ejecute estos comandos localmente, no en PythonAnywhere): -En primer lugar, veamos qué archivos han cambiado desde que hicimos el despliegue por última vez: +{% filename %}command-line{% endfilename %} $ git status -Asegúrate de que estás en el directorio `djangogirls` y vamos a decirle a `git` que incluya todos los cambios dentro de este directorio: +Asegúrate de que estás en el directorio `djangogirls` y vamos a decirle a `git` que incluya todos los cambios en este directorio: + +{% filename %}command-line{% endfilename %} $ git add --all . -> **Nota** `-A` (abreviatura de "all") significa que `git` también reconocerá si has eliminado archivos (por defecto, sólo reconoce archivos nuevos/modificados). También recuerda (del capítulo 3) que `.` significa el directorio actual. +> **Nota** `--all` significa que `git` tambien reconocerá si has borrado archivos (por defecto, solo reconoce archivos nuevos o modificados). También recuerda (del capítulo 3) que `.` significa el directorio actual. Antes de que subamos todos los archivos, vamos a ver qué es lo que `git` subirá (todos los archivos que `git` cargará deberían aparecer en verde): +{% filename %}command-line{% endfilename %} + $ git status Ya casi estamos, ahora es tiempo de decirle que guarde este cambio en su historial. Vamos a darle un "mensaje de commit" donde describimos lo que hemos cambiado. Puedes escribir cualquier cosa que te gustaría en esta etapa, pero es útil escribir algo descriptivo para que puedes recordar lo que has hecho en el futuro. +{% filename %}command-line{% endfilename %} + $ git commit -m "Cambie el HTML para la página." > **Nota** Asegúrate de usar comillas dobles alrededor del mensaje de commit. -Una vez que hicimos esto, subimos (push) nuestros cambios a PythonAnywhere: +Una vez hecho esto, subimos (push) los cambios a Github: + +{% filename %}command-line{% endfilename %} - git push + $ git push ### Descarga tu nuevo código a PythonAnywhere y actualiza tu aplicación web -* Abre la [página de consolas de PythonAnywhere][5] y ve a tu **consola Bash** (o comienza una nueva). Luego, ejecuta: - -``` -$ cd ~/my-first-blog -$ source myvenv/bin/activate -(myvenv)$ git pull -[...] -(myvenv)$ python manage.py collectstatic -[...] -``` +* Abre la [página de consolas de PythonAnywhere](https://www.pythonanywhere.com/consoles/) y ve a tu **consola Bash** (o comienza una nueva). Luego, ejecuta: - [5]: https://www.pythonanywhere.com/consoles/ +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + -Y mira cómo tu código se descarga. Si quieres comprobar que ya ha terminado, puedes ir a la pestaña **Files** y ver tu código en PythonAnywhere. +Necesitarás sustituir `` con tu actual nombre de subdominio PythonAnywhere, sin los paréntesis angulares o corchetes. Tu nombre de subdominio es normalmente tu nombre de usuario PythonAnywhere, pero en algunos casos puede ser un poco diferente (por ejemplo, si tu nombre de usuario contiene letras mayúsculas). Así, si este comando no funciona, usa el comando `ls`(listar archivos) para encontrar tu actual subdominio/nombre-carpeta, y muévete allí con `cd `. -* Finalmente, dirígete a la pestaña [Web][6] y selecciona **Reload** en tu aplicación web. +Ahora mira cómo se descarga tu código. Si quieres comprobar que efectivamente ha llegado bien, puedes ir a la **página "Files"** y ver tu código en PythonAnywhere (puedes ir a otras páginas de PythonAnywhere desde el botón de la esquina superior derecha de la página de la consola). - [6]: https://www.pythonanywhere.com/web_app_setup/ +* Finalmente, ve a la [página "Web"](https://www.pythonanywhere.com/web_app_setup/) y pulsa **Reload** en tu aplicación web. -¡Tu actualización debería estar en línea! Actualiza tu sitio web en el navegador. Ahora deberías poder ver tus cambios :) +¡Tu nueva versión ya debería estar publicada! Ve al navegador y refresca tu sitio web. Deberías ver los cambios. :) \ No newline at end of file diff --git a/es/html/images/step1.png b/es/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/es/html/images/step1.png and b/es/html/images/step1.png differ diff --git a/es/html/images/step3.png b/es/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/es/html/images/step3.png and b/es/html/images/step3.png differ diff --git a/es/html/images/step4.png b/es/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/es/html/images/step4.png and b/es/html/images/step4.png differ diff --git a/es/html/images/step6.png b/es/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/es/html/images/step6.png and b/es/html/images/step6.png differ diff --git a/es/images/application.png b/es/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/es/images/application.png and b/es/images/application.png differ diff --git a/es/installation/README.md b/es/installation/README.md new file mode 100644 index 00000000000..b1f2b98f99e --- /dev/null +++ b/es/installation/README.md @@ -0,0 +1,69 @@ +# Si estás haciendo el tutorial en casa + +Si estás haciendo el tutorial en casa, y no en uno de los [eventos de Django Girls](https://djangogirls.org/events/), puedes saltar este capítulo por completo e ir directamente al capítulo [¿cómo funciona Internet?](../how_the_internet_works/README.md). + +Esto es porque cubrimos las instalaciones de cosas a medida que se requieran en el tutorial -- esta es solamente una página adicional que reúne toda la información de instalación en un solo lugar (lo que es útil para algunos formatos de taller). Puedes escoger instalar todo lo que está en esta página ya mismo si lo deseas. Pero si quieres empezar a aprender cosas antes de instalar un grupo de materiales en tu computadora, salta este capítulo y te explicaremos las partes de la instalación luego, cuando sean necesarias. + +¡Buena suerte! + +# Si estás asistiendo a un workshop + +Si estás asistiendo a uno de los [Django Girls events](https://djangogirls.org/events/): + +* Tu workshop puede tener una "fiesta de instalación" antes del workshop principal. Si estás en un equipo de instalación, ¡ésta página es para ti! Sigue las instrucciones aquí para obtener todo lo que tu necesitas para el workshop de instalación, con la ayuda de los entrenadores si lo necesitas. Entonces en el workshop principal, tu estarás preparado para saltar las instrucciones de instalación que encontrarás en el tutorial principal cuando llegues a ellos. +* Los organizadores del taller pueden pedirte que en casa intentes instalar todo en tu computadora antes de iniciar el taller. Si has estado preguntando cómo hacer esto, ¡esta página es para ti! Sigue las instrucciones aquí, lo mejor puedas. Así, en el taller principal, cuando estés en uno de los pasos de la instalación del tutorial, y si no tenías esa pieza instalada, puedes pedir ayuda a una de tus entrenadoras. +* Si tu taller no tiene una sesión de instalación (o no pudiste asistir), y si los organizadores no te piden que intentes instalar todo antes de tu llegada, salta esta página y ve al capítulo [Cómo el internet funciona](../how_the_internet_works/README.md). Instalarás todo lo que necesitas para trabajar a lo largo del tutorial. + +# Instalación + +En este tutorial vas a construir un blog. Según cómo vayas a través del tutorial, serás instruida en cómo instalar varios softwares en tu computadora y configurar algunas cuentas online como sean necesarias. Esta página reune todas las instalaciones e instrucciones del registro en un lugar (el cual es útil para algunos formatos del taller). + + +{% include "/chromebook_setup/instructions.md" %} + + +# Breve introducción a la línea de comandos {#command-line} + +Muchos de los pasos citados abajo hacen referencia a la "consola", "terminal", "ventana de comandos", o "línea de comandos" -- todos éstos términos significan la misma cosa: una ventana en tu computadora donde puedes introducir comandos. Cuando estés en el tutorial principal, aprenderás más acerca de la línea de comandos. Por ahora, la parte principal que necesitas es saber cómo abrir una ventana de comandos y cómo luce: +{% include "/intro_to_command_line/open_instructions.md" %} + +# Instalar Python {#python} + +{% include "/python_installation/instructions.md" %} + +# Instala un Editor de Código {#code-editor} + +{% include "/code_editor/instructions.md" %} + +# Configura el entorno virtual (virtualenv) e instala Django {#virtualenv} + +{% include "/django_installation/instructions.md" %} + +# Instalar Git {#git} + +{% include "/deploy/install_git.md" %} + +# Crear una cuenta de GitHub {#github-account} + +Ve a [GitHub.com](https://www.github.com) y regístrate con una nueva y gratuita cuenta de usuario. Asegúrate de recordar tu contraseña (añádela a tu gestor de contraseñas, si usas uno). + +# Crear una cuenta de PythonAnywhere {#pythonanywhere-account} + +{% include "/deploy/signup_pythonanywhere.md" %} + +# Comienza a leer + +Felicitaciones, ¡tú tienes todo configurado y listo para avanzar! si aún tienes tiempo antes del taller, sería útil empezar a leer un poco de los capítulos iniciales: + +* [¿Cómo funciona internet?](../how_the_internet_works/README.md) + +* [Introducción a la línea de comandos](../intro_to_command_line/README.md) + +* [Introducción a Python](../python_introduction/README.md) + +* [¿Qué es Django?](../django/README.md) + +# ¡Disfrutar el taller! + +Cuando comiences el taller, estarás habilitada para ir directamente a [¡Tu primer proyecto en Django!](../django_start_project/README.md) porque ya cubriste el material en los capítulos anteriores. diff --git a/es/intro_to_command_line/README.md b/es/intro_to_command_line/README.md index de1565f63c0..ea94716486d 100755 --- a/es/intro_to_command_line/README.md +++ b/es/intro_to_command_line/README.md @@ -1,97 +1,153 @@ # Introducción a la interfaz de línea de comandos -Es emocionante, ¿verdad? Vas a escribir tu primera línea de código en pocos minutos :) +> Para los lectores en casa: este capítulo puede verse en el vídeo [Tu nuevo amigo: Línea de Comandos](https://www.youtube.com/watch?v=jvZLWhkzX-8). -**Permítenos presentarte a tu primer nuevo amigo: ¡la línea de comandos!** +Es emocionante, ¿verdad? ¡Vas a escribir tu primera línea de código en pocos minutos! :) + +**Permítenos presentarte a tu primer amigo nuevo: ¡la línea de comandos!** Los siguientes pasos te mostrarán cómo usar aquella ventana negra que todos los hackers usan. Puede parecer un poco aterrador al principio pero es solo un mensaje en pantalla que espera a que le des órdenes. +> **Nota** Ten en cuenta que a lo largo de este libro usamos los términos 'directorio' y 'carpeta' indistintamente pero son la misma cosa. + ## ¿Qué es la línea de comandos? -La ventana, que generalmente es llamada **línea de comandos** o **interfaz de línea de comandos**, es una aplicación basada en texto para ver, manejar y manipular archivos en tu computadora (como por ejemplo el Explorador de Windows o Finder en Mac, pero sin la interfaz gráfica). Otros nombres para la línea de comandos son: *cmd*, *CLI*, *símbolo del sistema*, *consola* o *terminal*. +La ventana, que generalmente es llamada **línea de comandos** ó **interfaz de línea de comandos**, es una aplicación basada en texto para ver, manejar y manipular archivos en tu ordenador. Similar a Windows Explorer o Finder en Mac, pero sin la interfaz gráfica. Otros nombres para la línea de comandos son: *cmd*, *CLI*, *prompt* -símbolo de sistema-, *console* -consola- o *terminal*. ## Abrir la interfaz de línea de comandos -Lo primero que debemos hacer para empezar a experimentar con nuestra interfaz de linea de comandos es abrirla. +Para empezar con algunos experimentos necesitarás abrir nuestra interfaz de línea de comandos en primer lugar. -### Windows +{% include "/intro_to_command_line/open_instructions.md" %} -Ir al menú Inicio → Todos los programas → Accesorios → Command Prompt +## Símbolo del Sistema (Prompt) -### Mac OS X +Ahora deberías ver una pantalla blanca o negra que espera a que introduzcas tus comandos. -Aplicaciones → Servicios → Terminal + -### Linux +Si estás en Mac o Linux, probablemente veas una `$`, como ésta: -Está probablemente en Aplicaciones → Accesorios → Terminal, pero eso depende de tu distribución. Si no lo encuentras, Googlealo :) +{% filename %}command-line{% endfilename %} -## Prompt + $ + -Ahora deberías ver una ventana blanca o negra que está esperando tus órdenes. + -Si estás en Mac o Linux, probablemente verás `$`, así: + - $ - +En Windows, probablemente veas un `>`, como éste: -En Windows, es un signo así `>`, como este: +{% filename %}command-line{% endfilename %} > -Cada comando será precedido por este signo y un espacio, pero no tienes que escribirlo. Tu computadora lo hará por ti :) +Echa un vistazo a la sección anterior sobre Linux -- podrás consultar más cuando llegues a PythonAnywhere más adelante en este tutorial. + + + +Cada comando vendrá precedido por un `$` o un `>` y un espacio, pero no debes escribirlos tú mismo. El ordenador lo hará por ti. :) + +> Solo una pequeña anotación: en tu caso puede que haya algo como `C:\Users\ola>` o `Olas-MacBook-Air:~ ola$` antes del símbolo de introducción, lo cual es 100% NORMAL. + +La parte superior incluye el `$` o el `>` que es llamado en la *línea de comandos*, o mas corto *prompt*. Introduce algo allí. + +En el tutorial, cuando queramos introducir un comando, incluye el `$` o `>`, y ocasionalmente más a la izquierda. Ignora la parte izquierda solamente escribiendo el comando, el cuál inicia después del prompt. + +## Tu primer comando (¡BIEN!) -> Sólo una pequeña nota: en tu caso, tal vez hay algo como `C:\Users\ola>` o `Olas-MacBook-Air:~ ola$` antes del prompt y eso es 100% correcto. En este tutorial lo simplificaremos lo más posible. +Comencemos tecleando este comando: -## Tu primer comando (¡YAY!) + -Vamos a empezar con algo simple. Escribe este comando: +{% filename %}command-line{% endfilename %} $ whoami -o + + + + +{% filename %}command-line{% endfilename %} > whoami -Y luego oprime la tecla Enter. Este es el resultado: + + +Y luego presiona `enter`. Esto será nuestro resultado: + +{% filename %}command-line{% endfilename %} $ whoami olasitarska -Como puedes ver, la computadora sólo te presentó tu nombre de usuario. Bien, ¿eh? :) +Como puedes ver, el computador solo ha impreso tu nombre de usuario. Ordenado, ¿ah? :) -> Trata de escribir cada comando, no copies y pegues. ¡Te acordarás más de esta manera! +> Intenta escribir cada comando; no copies y pegues. ¡De esta manera lo recordarás! -## Básicos +## Fundamentos -Cada sistema operativo tiene un conjunto diferente de comandos para la línea de comandos, así que asegúrate de seguir las instrucciones para tu sistema operativo. Vamos a intentarlo, ¿de acuerdo? +Cada sistema operativo tiene un poco diferente la configuración de los comandos para la consola, así que asegurate de seguir las instrucciones para tu sistema operativo. Intentemos esto, ¿Verdad? ### Directorio actual -Sería bueno saber dónde estamos ahora, ¿cierto? Vamos a ver. Escribe este comando y oprime Enter: +Sería bueno saber dónde estamos ahora, ¿Correcto? Veamos. Escribe éste comando y presiona `enter`: + + + +{% filename %}command-line{% endfilename %} $ pwd /Users/olasitarska -Si estás en Windows: +> Nota: 'pwd' es para imprimir el directorio de trabajo (print working directory). + + + + + +{% filename %}command-line{% endfilename %} > cd C:\Users\olasitarska -Probablemente verás algo similar en tu máquina. Una vez que abres la línea de comandos generalmente empiezas en el directorio home de tu usuario. +> Nota: 'cd' es para cambiar de directorio (change directory). Con la consola tu puedes usar pwd solo con Linux o macOS. -> Nota: 'pwd' significa 'print working directory' - en español, 'mostrar directorio de trabajo'. + + +Probablemente veremos algo similar en tu computador. Una vez que abres la consola o la línea de comandos, usualmente inicias en tu directorio principal. * * * -### Lista de archivos y directorios +### Aprende más sobre un comando + +¡Muchos comandos pueden escribirse en el prompt que tiene construido una ayuda que puedes leer! Por ejemplo, aprende más acerca de el comando del directorio actual: -¿Qué hay aquí? Sería bueno saber. Veamos: + + +macOS y Linux tienen un comando `man`, el cual te da una ayuda en comandos. Intenta `man pwd` y ve qué dice, o coloca `man` antes de otro comando para ver su ayuda. La salida de `man` nomalmentes es paginada. Usa la barra de espacio para moverte a la siguiente página, y `q` para salir de la ayuda. + + + + + +Añade un sufijo `/?` para más comandos que se imprimirán en la página de ayuda. Puedes hacer scroll a la ventana de comandos para verlos todos. Intenta `cd /?`. + + + +### Listar ficheros y directorios + +Así que, ¿en qué estamos? Estaría bien saberlo. Veamos: + + + +{% filename %}command-line{% endfilename %} $ ls Applications @@ -101,7 +157,11 @@ Probablemente verás algo similar en tu máquina. Una vez que abres la línea de ... -Windows: + + + + +{% filename %}command-line{% endfilename %} > dir Directory of C:\Users\olasitarska @@ -112,164 +172,265 @@ Windows: ... +> Nota: En consola tu puedes usar también 'ls' como en Linux y macOS. + * * * -### Cambia el directorio actual +### Cambiar el directorio actual + +Ahora, vamos a nuestro directorio de escritorio: + + -¿Quizás podemos ir a nuestro escritorio? +{% filename %}command-line{% endfilename %} $ cd Desktop -Windows: + - > cd Desktop + + +{% filename %}command-line{% endfilename %} + + $ cd Escritorio -Comprueba si realmente ha cambiado: +Nota que el nombre del directorio "Escritorio" puede ser traducido al lenguaje de tu cuenta de Linux. Si ese es el caso, necesitarás reemplazar `Escritorio` con la traducción del nombre; por ejemplo, `Desktop` para el inglés. + + - $ pwd - /Users/olasitarska/Desktop + + +{% filename %}command-line{% endfilename %} + + > cd Escritorio -Windows: + - > cd - C:\Users\olasitarska\Desktop +Verifica si está cambiado actualmente: + + + +{% filename %}command-line{% endfilename %} + + $ pwd /Users/olasitarska/Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd C:\Users\olasitarska\Desktop + + ¡Aquí está! -> Pro tip: si escribes `cd D` y luego oprimes `tab` en el teclado, la línea de comandos automáticamente completará el resto del nombre para que puedas navegar más rápido. Si hay más de una carpeta que empiece con "D", presiona el botón `tab` dos veces para obtener una lista de opciones. +> PRO tip: si escribes `cd D` y luego presionas `tab` en tu teclado, la línea de comandos automáticamente llenará el resto de el nombre por el que puedes navegar. Si hay mas que una carpeta iniciando con "D", presiona la tecla `tab` dos veces para obtener una lista de opciones. * * * -### Crear directorio +### Crear un directorio + +¿Cómo crear un práctico directorio para tu escritorio? Puedes hacerlo de esta manera: + + -¿Qué tal si creamos un directorio de Django Girls en tu escritorio? Puedes hacerlo de esta manera: +{% filename %}command-line{% endfilename %} - $ mkdir djangogirls + $ mkdir practice -Windows: + - > mkdir djangogirls + + +{% filename %}command-line{% endfilename %} + + > mkdir practice -Este pequeño comando creará una carpeta con el nombre `djangogirls` en tu escritorio. ¡Puedes comprobar si está allí buscando en tu escritorio o ejecutando el comando `ls` (si estás usando Mac o Linux) o `dir` (si estás usando Windows)! Inténtalo :) + + +Este pequeño comando creará una carpeta con el nombre `práctica` en tu computador. ¡Puedes verificar si está allí en tu Escritorio o ejecutando uno de los siguientes comandos `ls` o `dir`! Inténtalo. :) -> Pro tip: Si no quieres escribir una y otra vez los mismos comandos, prueba oprimiendo la `flecha arriba` y `flecha abajo` de tu teclado para ver recientes comandos utilizados. +> PRO tip: Si no quieres escribir el mismo comando una y otra vez, intenta presionando la `flecha arriba` y `flecha abajo` en tu teclado para regresar a través de los comandos recientemente usados. * * * -### ¡Ejercicios! +### ¡Ejercicio! -Un pequeño reto para ti: en el directorio recién creado `djangogirls` crea un directorio llamado `test`. Utiliza los comandos `cd` y `mkdir`. +Un pequeño reto para ti: en tu nuevo directorio creado `práctica`, crea un directorio llamado `prueba`. (Usa los comandos `cd` y `mkdir`.) #### Solución: - $ cd djangogirls - $ mkdir test + + +{% filename %}command-line{% endfilename %} + + $ cd practica + $ mkdir prueba $ ls + prueba -Windows: + + + - > cd djangogirls - > mkdir test - > dir - 08/05/2014 19:28 < DIR > test +{% filename %}command-line{% endfilename %} + + > cd practica + > mkdir prueba + > dir + 05/08/2014 07:28 PM prueba -¡Felicitaciones! :) + + +¡Felicidades! :) * * * -### Limpiar +### Limpieza -No queremos dejar un desorden, así que vamos a eliminar todo lo que hicimos hasta este momento. +No queremos dejar un enredo, así que removamos todo lo que hicimos hasta este momento. -En primer lugar, tenemos que volver al escritorio: +Primero, necesitamos regresar al Escritorio: + + + +{% filename %}command-line{% endfilename %} $ cd .. -Windows: + + + + +{% filename %}command-line{% endfilename %} > cd .. -`cd` `..` cambiará el directorio actual al directorio padre (que significa el directorio que contiene el directorio actual). + + +Usando los `..` con el comando `cd` cambiaremos tu actual directorio al directorio padre (que es el directorio que contiene tu directorio actual). -Revisa dónde estás: +Verifica dónde estás: - $ pwd - /Users/olasitarska/Desktop + + +{% filename %}command-line{% endfilename %} + + $ pwd /Users/olasitarska/Desktop -Windows: + - > cd - C:\Users\olasitarska\Desktop + + +{% filename %}command-line{% endfilename %} + + > cd C:\Users\olasitarska\Desktop -Ahora es hora de eliminar el directorio `djangogirls`. + + +Es hora de eliminar el directorio `practica`: -> **Atención**: Eliminar archivos utilizando `del`, `rmdir` o `rm` hace que no puedan recuperarse, lo que significa que los *archivos borrados desaparecerán para siempre* Debes ser muy cuidadosa con este comando. +> **Atención**: Si eliminas los archivos usando `del`, `rmdir` o `rm` no se podrán recuperar, esto significa ¡*el borrado de los archivos será para siempre*! Sé muy cuidados@ con este comando. - $ rm -r djangogirls + + +{% filename %}command-line{% endfilename %} + + $ rm -r practice -Windows: + + + - > rmdir/s djangogirls - djangogirls, ¿Estás seguro ? Y +{% filename %}command-line{% endfilename %} + + > rmdir /S practica + practica, ¿Estás segur@? Y -Hecho! Asegurémonos que en verdad fueron borrados, vamos a ver: + + +¡Hecho! Estás seguro que lo eliminaste realmente, verifica: + + + +{% filename %}command-line{% endfilename %} $ ls -Windows: + + + + +{% filename %}command-line{% endfilename %} > dir -### Salida + + +### Salir + +¡Eso es todo por ahora! Tú puedes ahora cerrar la línea de comandos o consola sin problemas. Hazlo como un hacker, ¿vale? :) -¡Esto es todo por ahora! Ahora puedes cerrar la línea de comandos sin problemas. Vamos a hacerlo al estilo hacker, ¿bien? :) + + +{% filename %}command-line{% endfilename %} $ exit -Windows: + + + + +{% filename %}command-line{% endfilename %} > exit -Genial, ¿no? :) + -## Índice +Genial, ¿no? :) -Aquí hay una lista de algunos comandos útiles: +## Resumen -| Comando (Windows) | Comando (Mac OS / Linux) | Descripción | Ejemplo | -| ----------------- | ------------------------ | ---------------------------- | ------------------------------------------------- | -| exit | exit | Cierra la ventana | **exit** | -| cd | cd | Cambia el directorio | **cd test** | -| dir | ls | Lista directorios/archivos | **dir** | -| copy | cp | Copia de archivos | **copy c:\test\test.txt c:\windows\test.txt** | -| move | mv | Mueve archivos | **move c:\test\test.txt c:\windows\test.txt** | -| mkdir | mkdir | Crea un nuevo directorio | **mkdir testdirectory** | -| del | rm | Elimina archivos/directorios | **del c:\test\test.txt** | +Aquí está un resumen de algunos comandos útiles: -Estos son solo algunos de los comandos que puedes ejecutar en la línea de comandos. No vas a usar nada más que esos por ahora. +| Comando (Windows) | Comando (Mac OS / Linux) | Descripción | Ejemplo | +| ----------------- | ------------------------ | ----------------------------- | ------------------------------------------------- | +| exit | exit | Cierra la ventana | **exit** | +| cd | cd | Cambia el directorio | **cd test** | +| cd | pwd | Mostrar el directorio actual | **cd** (Windows) o **pwd** (Mac OS / Linux) | +| dir | ls | Lista directorios/archivos | **dir** | +| copy | cp | Copia de archivos | **copy c:\test\test.txt c:\windows\test.txt** | +| move | mv | Mueve archivos | **move c:\test\test.txt c:\windows\test.txt** | +| mkdir | mkdir | Crea un nuevo directorio | **mkdir testdirectory** | +| rmdir (o del) | rm | Eliminar un archivo | **del c:\test\test.txt** | +| rmdir /S | rm -r | Eliminar un Directorio | **rm -r testdirectory** | +| [CMD] /? | man [CMD] | Obtener ayuda para un comando | **cd /?** (Windows) o **man cd** (Mac OS / Linux) | -Si tienes curiosidad, [ss64.com][1] contiene una referencia completa de comandos para todos los sistemas operativos. +Estos son solo algunos de los comandos que puedes ejecutar en tu línea de comando o consola, pero no usarás ninguno más por hoy. - [1]: http://ss64.com +Si eres curios@, [ss64.com](http://ss64.com) contiene una referencia completa de comandos para todos los sistemas operativos. -## ¿Lista? +## ¿Listo? -¡Vamos a sumergirnos en Python! +¡Vamos a bucear en Python! \ No newline at end of file diff --git a/es/intro_to_command_line/open_instructions.md b/es/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..91a4488b9c0 --- /dev/null +++ b/es/intro_to_command_line/open_instructions.md @@ -0,0 +1,29 @@ + + + +Dependiendo de tu versión de Windows y tu teclado, una de las opciones siguientes debería abrir una ventana de comandos (puede que necesites experimentar un poco, pero no se necesita probar todas estas sugerencias): + +- Ve al menú o pantalla de Inicio, y escribe "Símbolo del Sistema" en el cuadro de búsqueda. +- Ve a Menú de inicio → Windows System → Command Prompt. +- Ve al menú de Inicio → Todos los Programas → Accessorios → Símbolo del Sistema. +- Ve a la pantalla de Inicio, pasa el ratón sobre la esquina inferior izquierda de la pantalla, y haz click en la flecha hacia abajo (en una pantalla táctil, desliza hacia arriba desde la parte baja de la pantalla). La página de la Aplicación debería abrirse. Haz click en Símbolo del Sistema en la sección Sistema de Windows. +- Mantén la tecla especial de Windows de tu teclado y pulsa "X". Elige "Símbolo del Sistema" del menú emergente. +- Mantén pulsada la tecla de Windows y pulsa "R" para abrir una ventana "Ejecutar". Escribe "cmd" en la caja, y haz click en OK. + +![Escribe "cmd" en la ventana "Ejecutar"](../python_installation/images/windows-plus-r.png) + +Más adelante en este tutorial, necesitarás tener dos consolas de comandos abiertas a la misma vez. Sin embargo, en algunas versiones de Windows, si ya tienes abierta una ventana de comandos e intentas abrir otra usando el mismo método, simplemente maximizará la que ya tienes abierta. ¡Inténtalo ahora en tu ordenador y mira qué ocurre! Si solo se abre una ventana de comandos, intenta alguno de los otros métodos explicados anteriormente. Al menos uno de ellos debería abrir una nueva ventana de comandos. + + + + + +Ve a Aplicaciones → Utilidades → Terminal. + + + + + +Probablemente se encuentre en Aplicaciones → Accesorios → Terminal, o Aplicaciones → Sistema → Terminal, aunque esto dependerá de tu sistema. Si no lo encuentras allí, intenta buscarlo en Google. :) + + diff --git a/es/python_installation/README.md b/es/python_installation/README.md index 0fd71bdf85d..7aa0757f913 100755 --- a/es/python_installation/README.md +++ b/es/python_installation/README.md @@ -2,71 +2,14 @@ ¡Por fin estamos aquí! -Pero primero, déjenos decirte qué es Python. Python es un lenguaje de programación muy popular que puede utilizarse para la creación de sitios web, juegos, software académico, gráficos y mucho, mucho más. +Pero primero, déjanos decirte qué es Python. Python es un lenguaje de programación muy popular que puede ser usado para crear sitios web, juegos, software científico, gráficos, y más, mucho más. -Python se originó en la década de 1980 y su objetivo principal es ser legible por los seres humanos (¡no sólo para las máquinas!), por eso parece mucho más simple que otros lenguajes de programación. Esto hace que sea más fácil de aprender, pero no te preocupes, ¡Python es también muy poderoso! +Python se originó en la década de 1980 y su principal objetivo es ser legible por los seres humanos (¡no sólo por máquinas!). Por esta razón parece mucho más sencillo que otros lenguajes de programación, pero no te preocupes – ¡Python también es realmente poderoso! # Instalación de Python -> Este subcapítulo se basa en un tutorial de Geek Girls Carrots (https://github.com/ggcarrots/django-carrots/) +> **Nota** Si usas un Chromebook, omite este capítulo y asegúrate de seguir las instrucciones de [Chromebook Setup](../chromebook_setup/README.md). +> +> **Nota** Si ya has seguido los pasos de instalación, no hay necesidad de hacerlo nuevamente - ¡puedes saltar y continuar al siguiente capítulo! -Django está escrito en Python. Necesitamos Python para cualquier cosa en Django. ¡Vamos a empezar con la instalación! Queremos que instales Python 3.4, así que si tienes alguna versión anterior, deberás actualizarla. - -### Windows - -Puedes descargar Python para Windows desde el sitio web https://www.python.org/downloads/release/python-343/. Después de descargar el archivo ***.msi**, debes ejecutarlo (haz doble click en el archivo) y sigue las instrucciones. Es importante recordar la ruta (el directorio) donde se ha instalado Python. ¡Será necesario más adelante! - -Algo para tener en cuenta: en la segunda pantalla del asistente de instalación, llamada "Customize", asegúrate de ir hacia abajo y elegir la opción "Add python.exe to the Path", como en - -![No te olvides de agregar Python al Path][1] - - [1]: images/add_python_to_windows_path.png - -### Linux - -Es muy posible que ya tengas Python instalado. Para verificar que ya lo tienes instalado (y qué versión es), abre una consola y tipea el siguiente comando: - - $ python3 --version - Python 3.4.2 - - -Si no tienes Python instalado o si quieres una versión diferente, puedes instalarlo como sigue: - -#### Ubuntu - -Tipea este comando en tu consola: - - sudo apt-get install python3.4 - - -#### Fedora - -Usa este comando en tu consola: - - sudo yum install python3.4 - - -#### openSUSE - -Usa este comando en tu consola: - - sudo zypper install python3 - - -### OS X - -Debes ir al sitio web https://www.python.org/downloads/release/python-342/ y descargar el instalador de Python: - -* descarga el archivo *DMG* *Mac OS X 64-bit/32-bit installer*, -* haz doble click para abrirlo, -* doble click en *Python.mpkg* para ejecutar al instalador. - -Verifica que la instalación fue exitosa abriendo la *Terminal* y ejecutando el comando `python3`: - - $ python3 --version - Python 3.4.2 - - -* * * - -Si tienes alguna duda o si algo salió mal y no sabes cómo resolverlo - ¡pide ayuda a tu tutor! Algunas veces las cosas no salen tan fácilmente y es mejor pedir ayuda a alguien con más experiencia. +{% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/es/python_installation/images/add_python_to_windows_path.png b/es/python_installation/images/add_python_to_windows_path.png index 9510d6f2176..3266efb6177 100644 Binary files a/es/python_installation/images/add_python_to_windows_path.png and b/es/python_installation/images/add_python_to_windows_path.png differ diff --git a/es/python_installation/images/python-installation-options.png b/es/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..a0a6c65d81d Binary files /dev/null and b/es/python_installation/images/python-installation-options.png differ diff --git a/es/python_installation/images/windows-plus-r.png b/es/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/es/python_installation/images/windows-plus-r.png differ diff --git a/es/python_installation/instructions.md b/es/python_installation/instructions.md new file mode 100644 index 00000000000..b1823d67003 --- /dev/null +++ b/es/python_installation/instructions.md @@ -0,0 +1,121 @@ +> Para lectores en casa: este capitulo se cubre en el vídeo [Installing Python & Code Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA). +> +> Esta sección está basada en un tutorial de Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) + +Django está escrito en Python. Necesitamos Python para hacer cualquier cosa en Django. ¡Empecemos con instalarlo! Queremos que instales la última versión de Python 3, así que si tienes una versión anterior, necesitarás actualizarla. Si ya tienes la versión 3.4 o una superior, debería ir bien. + +Por favor, instala Python normalmente de la siguiente forma, incluso si tienes Anaconda instalada en el ordenador. + + + +Primero comprueba si tu ordenador ejecuta la versión 32 bits de Windows o la de 64, en "Tipo de sistema" en la página de "Acerca de". Para llegar a esta página, intenta uno de estos métodos: + +* Presiona la tecla de Windows y la tecla Pause/Break al mismo tiempo +* Abre el Panel de Control desde el menú de Windows, después accede a Sistema & y Seguridad, luego a Sistema +* Presiona el botón de Windows, luego accede a Configuración > Sistema > Acerca de + +Puedes descargar Python para Windows desde la siguiente web https://www.python.org/downloads/windows/. Clica en el enlace "Latest Python 3 Release -Python x.x.x". Si tu ordenador ejecuta la versión de **64 bits** de Windows, descarga **Windows x86-64 executable installer**. De lo contrario, descarga **Windows x86 executable installer**. Después de descargar el instalador, deberías ejecutarlo (dándole doble click) y seguir las instrucciones. + +Una cosa para tener en cuenta: Durante la instalación, verás una ventana de "Setup". Asegúrate de marcar las casillas "Add Python 3.6 to PATH" o "Add Python to your environment variables" y hacer click en "Install Now", como se muestra aquí (puede que se vea un poco diferente si estás instalando una versión diferente): + +![No te olvides de agregar Python al Path](../python_installation/images/python-installation-options.png) + +Cuando la instalación se complete, verás un cuadro de diálogo con un enlace que puedes seguir para saber más sobre Python o sobre la versión que has instalado. Cierra o cancela ese dialogo -- ¡Aprenderás más en ese tutorial! + +Nota: si estás usando una versión anterior de Windows (7, Vista o cualquier versión anterior) y el instalador de la versión 3.6.x de Python falla con un error, intenta también: + +1. instalar todas las actualizaciones de Windows e intenta instalar Python de nuevo; o +2. instalar una [versión de Python anterior](https://www.python.org/downloads/windows/), por ejemplo, [3.4.6](https://www.python.org/downloads/release/python-346/). + +Si instalas una versión anterior de Python, la pantalla de instalación puede ser un poco diferente a la mostrada arriba. Asegúrate de desplazarte hacia abajo para ver "Add python.exe to Path", después haz click en el botón de la izquierda y selecciona "Will be installed on local hard drive": + +![Añadir Python a Path, versiones más antiguas](../python_installation/images/add_python_to_windows_path.png) + + + + + +> **Nota** Antes de instalar Python en macOS, debes asegurarte de que la configuración del Mac permita instalar paquetes que no estén en la App Store. ve a preferencias del sistema (System Preferences, está en la carpeta Aplicaciones), da click en "Seguridad y privacidad" (Security & Privacy) y luego la pestaña "General". Si tu "Permitir aplicaciones descargadas desde:" (Allow apps downloaded from:) está establecida a "Mac App Store," cambia a "Mac App Store y desarrolladores identificados." (Mac App Store and identified developers) + +Necesitas ir a la página web https://www.python.org/downloads/release/python-361/ y descargar el instalador de Python: + +* Descarga el archivo *macOS 64-bit/32-bit installer*, +* Doble click en *python-3.6.1-macosx10.6.pkg* para ejecutar el instalador. + + + + + +Es muy posible que ya tengas instalado Python de serie. Para verificar que ya lo tienes instalado (y qué versión es), abre una consola y escribe el siguiente comando: + +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python 3.6.1 + + +Si tienes instalada una versión diferente de Python, al menos 3.4.0 (por ejemplo 3.6.0), entonces no tienes que actualizar. Si tu no has instalado Python, o si tu quieres una versión diferente, primero verifica que distribución de Linux estás usando con el siguiente comando: + +{% filename %}command-line{% endfilename %} + + $ grep ^NOMBRE= /etc/os-release + + +Después, dependiendo de el resultado, sigue una de las siguientes guías de instalación bajo ésta sección. + + + + + +Escribe este comando en tu consola: + +{% filename %}command-line{% endfilename %} + + $ sudo apt install python3 + + + + + + +Usa este comando en tu consola: + +{% filename %}command-line{% endfilename %} + + $ sudo dnf install python3 + + +Si estás en versiones antiguas de Fedora, puedes obtener un error que el comando `dnf` no se encuentra. En ese caso, necesitas usar `yum` en su lugar. + + + + + +Usa este comando en tu consola: + +{% filename %}command-line{% endfilename %} + + $ sudo zypper install python3 + + + + +Verifica si la instalación fue exitosa abriendo una terminal o consola, y corriendo el comando `python3`: + +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python 3.6.1 + + +La versión mostrada puede ser diferente desde 3.6.1 -- debería marcar la versión que instalaste. + +**NOTA:** Si está en Windows y recibe un mensaje de error que indica que `python3` no se encontró, intente usar `python` (sin el `3`) y compruebe si todavía podría ser una versión de Python que sea 3.4.0 o superior. Si eso tampoco funciona, puede abrir un nuevo símbolo del sistema e intentar nuevamente; Esto sucede si usa un símbolo del sistema abierto antes de la instalación de Python. + +* * * + +Si tienes alguna duda, o si ocurrió algún error y no tienes idea sobre qué hacer, ¡por favor pregunta a tu entrenador! Algunas veces las cosas no van bien y es mejor pedir ayuda a alguien con más experiencia. \ No newline at end of file diff --git a/es/python_introduction/README.md b/es/python_introduction/README.md index 0c324a40e7e..6d6ad0d33fb 100755 --- a/es/python_introduction/README.md +++ b/es/python_introduction/README.md @@ -1,505 +1,716 @@ +{% set warning_icon = ' ' %} + # Introducción a Python -> Parte de este capítulo se basa en tutoriales por Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> Parte de este capítulo se basa en tutoriales de Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). + +¡Escribamos algo de código! -¡Vamos a escribir algo de código! +## La Consola de Python -## Python prompt +> Para los lectores en casa: el vídeo [conceptos básicos de Python: enteros, cadenas, listas, variables y errores](https://www.youtube.com/watch?v=MO63L4s-20U) cubre esta parte. -Para empezar a jugar con Python, tenemos que abrir una *línea de comandos* en nuestra computadora. Ya sabes cómo hacerlo, lo aprendiste en el capítulo de [Introducción a la línea de comandos][1]. +Para empezar a jugar con Python, tenemos que abrir una *línea de comandos* en nuestra computadora. Deberías saber cómo hacerlo, pues lo aprendiste en el capítulo de [Introducción a la Línea de Comandos](../intro_to_command_line/README.md). - [1]: /intro_to_command_line/README.html +Una vez que estés lista, sigue las instrucciones a continuación. -Una vez que estés lista, sigue las siguientes instrucciones. +Queremos abrir una consola de Python, así que escribe `python` en Windows o `python3` en Mac OS/Linux y pulsa `intro`. -Queremos abrir una consola de Python, así que escribe `python3` y pulsa Enter. +{% filename %}command-line{% endfilename %} $ python3 - Python 3.4.2 (...) - Type "copyright", "credits" or "license" for more information. + Python 3.6.1 (...) + Type "help", "copyright", "credits" or "license" for more information. >>> ## ¡Tu primer comando en Python! -Después de ejecutar el comando de Python, el cursor cambia a `>>>`. Para nosotros esto significa que por ahora sólo podemos utilizar comandos en el lenguaje Python. No tienes que escribir el `>>>` - Python lo hará por ti. +Después de ejecutar el comando de Python, el cursor cambiará a `>>>`. Para nosotros esto significa que por ahora sólo podemos utilizar comandos del lenguaje Python. No tienes que escribir e`>>>` pues Python lo hará por ti. -Si deseas salir de la consola de Python en cualquier momento, simplemente escribe `exit()` o usa el atajo `Ctrl + Z` para Windows y `Ctrl + D` para Mac/Linux. Luego no verás más `>>>`. +Si deseas salir de la consola de Python en cualquier momento, solo escribe `exit()` o usa el atajo `Ctrl + Z` para Windows y `Ctrl + D` para Mac/Linux. Luego no verás más `>>>`. -Pero ahora no queremos salir de la consola de Python. Queremos aprender más sobre ella. Vamos a empezar con algo muy simple. Por ejemplo, trata de escribir algo de matemáticas, como `2 + 3` y pulsa Enter. +Por ahora, no queremos salir de la consola de Python. Deseamos aprender más sobre ella. Vamos a comenzar escribiendo algo de matemática, escribe `2 + 3` y oprime la tecla `enter`. - >>> 2 + 3 - 5 - +{% filename %}command-line{% endfilename %} -¡Bien! ¿Ves como salió la respuesta? ¡Python sabe matemáticas! Podrías intentar otros comandos como: - `4 * 5` - `5 - 1` - `40 / 2` +```python +>>> 2 + 3 +5 +``` -Diviértete con esto por un momento y luego vuelve aquí :). +¡Qué bien! ¿Ves cómo salió la respuesta? ¡Python sabe matemática! Puedes probar otros comandos como: -Como puedes ver, Python es una gran calculadora. Si te estás preguntando qué más puede hacer... +- `4 * 5` +- `5 - 1` +- `40 / 2` -## Strings +Para realizar una operación exponencial, digamos 2 elevado al cubo, escribimos: {% filename %}command-line{% endfilename %} -¿Y tu nombre? Escribe tu nombre de pila en frases como ésta: +```python +>>> 2 ** 3 +8 +``` - >>> "Ola" - 'Ola' - +Diviértete con esto por un momento y luego vuelve aquí. :) -¡Has creado tu primer string! Es una secuencia de caracteres que puede ser procesada por una computadora. El string (o en español, cadena) debe comenzar y terminar con el mismo carácter. Esto puede ser comillas simples (`'`) o dobles (`"`) - ellas le dicen a Python que lo que esta dentro es una cadena. +Como puedes ver, Python es una gran calculadora. Si te estás preguntando qué más puedes hacer… -Las cadenas pueden ser concatenadas. Prueba esto: +## Cadena de caracteres - >>> "Hola " + "Ola" - 'Hola Ola' - +¿Qué tal tu nombre? Escribe tu nombre entre comillas, así: -También puedes multiplicar las cadenas con un número: +{% filename %}command-line{% endfilename %} - >>> "Ola" * 3 - 'OlaOlaOla' - +```python +>>> "Ola" +'Ola' +``` -Si necesitas poner un apóstrofe dentro de tu cadena, tienes dos maneras de hacerlo. +¡Has creado tu primera cadena de texto! La misma es una secuencia de caracteres que puede ser procesada por una computadora. La cadena de texto (o string, en inglés) debe comenzar y terminar con el mismo carácter. Pueden ser comillas simples (`'`) o dobles (`"`) (¡no hay ninguna diferencia!) Las comillas le dicen a Python que lo que está dentro de ellas es una cadena de texto. -Usando comillas dobles: +Las cadenas pueden estar concatenadas. Prueba esto: - >>> "Runnin' down the hill" - "Runnin' down the hill" - +{% filename %}command-line{% endfilename %} -o escapando el apóstrofe con una barra invertida (`\`): +```python +>>> "Hola " + "Ola" +'Hola Ola' +``` - >>> 'Runnin\' down the hill' - "Runnin' down the hill" - +También puedes multiplicar las cadenas por un número: -Bien, ¿eh? Para ver tu nombre en letras mayúsculas, simplemente escribe: +{% filename %}command-line{% endfilename %} - >>> "Ola".upper() - 'OLA' - +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` -¡Usaste la **función** `upper` en tu cadena! Una función (como `upper()`) es un conjunto de instrucciones que Python tiene que realizar sobre un objeto determinado (`"Ola"`) una vez que se llama. +Si necesitas poner un apóstrofe dentro de una cadena, hay dos formas de hacerlo. -Si quisieras saber el número de letras que contiene tu nombre, también existe una función para esto. +Usar comillas dobles: - >>> len("Ola") - 3 - +{% filename %}command-line{% endfilename %} + +```python +>>> "Runnin' down the hill" +"Runnin' down the hill" +``` + +o escapar el apóstrofe con la diagonal inversa (``): + +{% filename %}command-line{% endfilename %} -Te preguntarás por qué a veces se llama a las funciones con un `.` al final de una cadena (como `"Ola".upper()`) y a veces se llama a una función y colocas la cadena entre paréntesis. Bueno, en algunos casos las funciones pertenecen a objetos, como `upper()`, que sólo puede ser utilizado sobre cadenas (upper() es una función de los objetos string). En este caso, llamamos **método** a esta función. Otra veces, las funciones no pertenecen a ningún objeto específico y pueden ser usados en diferentes objetos, como `len()`. Esta es la razón de por qué estamos pasando `"Ola"` como un parámetro a la función `len`. +```python +>>> 'Runnin\' down the hill' +"Runnin' down the hill" +``` + +Bien, ¿eh? Para ver tu nombre en letras mayúsculas, escribe: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola".upper() +'OLA' +``` + +¡Acabas de usar el **método** `upper` sobre tu cadena de texto! Un método (como `upper()`) es un conjunto de instrucciones que Python tiene que realizar sobre un objeto determinado (`"Ola"`) una vez que se le invoca. + +Si quieres saber el número de letras que contiene tu nombre, ¡también hay una **función** para eso! + +{% filename %}command-line{% endfilename %} + +```python +>>> len("Ola") +3 +``` + +Te preguntarás ¿por qué a veces se invoca a las funciones con un `.` al final de una cadena (como `"Ola".upper()`) y a veces se invoca a la función colocando la cadena entre paréntesis? Bueno, en algunos casos las funciones pertenecen a los objetos, como `upper()`, que sólo puede ser utilizada sobre cadenas. En este caso, a la función le llamamos **método**. Otra veces, las funciones no pertenecen a ningún objeto específico y pueden ser usadas en diferentes objetos, como `len()`. Esta es la razón de por qué estamos pasando `"Ola"` como un parámetro a la función `len`. ### Resumen -Ok, suficiente sobre las cadenas. Hasta ahora has aprendido sobre: +Ok, es suficiente sobre las cadenas. Hasta ahora has aprendido sobre: -* **la terminal** - teclear comandos (código) dentro de la terminal de Python resulta en respuestas de Python -* **números y strings** - en Python los números son usados para matemáticas y strings para objetos de texto -* **operadores** - como + y *, combina valores para producir uno nuevo -* **funciones** - como upper() y len(), realizan opciones sobre los objetos. +- **la terminal** - teclear comandos (código) en la terminal de Python resulta en respuestas de Python +- **números y strings** - en Python los números son usados para matemáticas y strings (cadenas de caracteres) para objetos de texto +- **operadores** - como `+` y `*`, combinan valores para producir uno nuevo +- **funciones** - como `upper()` y `len()`, ejecutan acciones sobre los objetos. -Estos son los conocimientos básicos que puedes aprender de cualquier lenguaje de programación. ¿Lista para algo un poco más difícil? ¡Apostamos que lo estás! +Estos son los conocimientos básicos que puedes aprender de cualquier lenguaje de programación. ¿Lista para algo más difícil? ¡Seguro que lo estás! ## Errores -Intentemos con algo nuevo. ¿Podríamos obtener la longitud de un número de la misma manera que obtuvimos la longitud de nuestro nombre? Teclea `len(304023)` y presiona Enter: +Vamos a intentar algo nuevo. ¿Podemos obtener la longitud de un número de la misma manera que pudimos averiguar la longitud de nuestro nombre? Escribe `len(304023)` y pulsa `enter`: - >>> len(304023) - Traceback (most recent call last): - File "", line 1, in - TypeError: object of type 'int' has no len() - +{% filename %}PythonAnywhere command-line{% endfilename %} -¡Obtuvimos nuestro primer error! Dice que los objetos de tipo "int" (números enteros) no tienen ninguna longitud. ¿Qué podemos hacer ahora? Quizás podemos escribir el numero como un string. Los strings tienen longitud, ¿cierto? +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` - >>> len(str(304023)) - 6 - +¡Pues tenemos nuestro primer error! El icono de {{ warning_icon }} es nuestra manera de darte un aviso de que el código que estás ejecutando no funciona como se espera. ¡Cometer errores (incluso algunos intencionales) son una parte importante del aprendizaje! -¡Funcionó! Utilizamos la función `str` dentro de la función `len`. `str()` convierte todo a strings. +Dicho error dice que los objetos de tipo "int" (números enteros) no tienen longitud. ¿Qué podemos hacer ahora? ¿Quizás podamos escribir el número como una cadena? Las cadenas tienen longitud, ¿verdad? -* La función `str` convierte cosas en **strings** -* La función `int` convierte cosas en **integers** +{% filename %}command-line{% endfilename %} -> Importante: podemos convertir números en texto, pero no podemos necesariamente convertir texto en números - ¿qué sería `int('hello')`? +```python +>>> len(str(304023)) +6 +``` + +¡Funcionó! Hemos utilizado la función `str` dentro de la función `len`. `str()` convierte todo en cadenas de texto. + +- La función `str` convierte cosas en cadenas, **strings** +- La función `int` convierte cosas en enteros, **integers** + +> Importante: podemos convertir números en texto, pero no necesariamente podemos convertir texto en números - ¿qué sería `int('hello')`? ## Variables -Un concepto importante en programación son las variables. Una variable no es más que un nombre para alguna cosa para que puedas usarla más tarde. Los programadores usan estas variables para almacenar datos, hacer su código más legible y así no tener que seguir recordando qué hace cada cosa. +Un concepto importante en la programación son las variables. Una variable no es más que un nombre para algo, de forma que puedas usarlo más tarde. Los programadores usan estas variables para almacenar datos, hacer su código más legible y para no tener que recordar qué es cada cosa. Supongamos que queremos crear una nueva variable llamada `name`: - >>> name = "Ola" - +{% filename %}command-line{% endfilename %} -¿Ves? ¡Es fácil! Es simplemente: name equivale a Ola. +```python +>>> name = "Ola" +``` -Como te has dado cuenta, el programa no regresa algo como lo hacia antes. Entonces, ¿Cómo sabemos que la variable existe realmente? Simplemente introduce `name` y pulsa Enter: +Indicamos que el nombre es igual a Ola. - >>> name - 'Ola' - +Como habrás notado, tu programa no devolvió nada como lo hacía antes. Así que ¿cómo sabemos que la variable existe realmente? Escribe `name` y pulsa `intro`: -¡Súper! Tu primer variable :). Siempre podrás cambiar a lo que se refiere: +{% filename %}command-line{% endfilename %} - >>> name = "Sonja" - >>> name - 'Sonja' - +```python +>>> name +'Ola' +``` -Puedes usarla dentro de funciones también: +¡Genial! ¡Tu primera variable :)! Siempre puedes cambiar a lo que se refiere: - >>> len(name) - 5 - +{% filename %}command-line{% endfilename %} + +```python +>>> name = "Sonja" +>>> name +'Sonja' +``` + +También puedes usarla dentro de funciones: + +{% filename %}command-line{% endfilename %} + +```python +>>> len(name) +5 +``` Increíble, ¿verdad? Por supuesto, las variables pueden ser cualquier cosa, ¡también números! Prueba esto: - >>> a = 4 - >>> b = 6 - >>> a * b - 24 - +{% filename %}command-line{% endfilename %} + +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` Pero ¿qué pasa si usamos el nombre equivocado? ¿Puedes adivinar qué pasaría? ¡Vamos a probar! - >>> city = "Tokyo" - >>> ctiy - Traceback (most recent call last): -   File "", line 1, in - NameError: name 'ctiy' is not defined - +{% 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 +``` ¡Un error! Como puedes ver, Python tiene diferentes tipos de errores y este se llama **NameError**. Python te dará este error si intentas utilizar una variable que no ha sido definida aún. Si más adelante te encuentras con este error, verifica tu código para ver si no has escrito mal una variable. -Juega con esto por un rato y mira que puedes hacer! +¡Juega con esto un rato y descubre qué puedes hacer! ## La función print Intenta esto: - >>> name = 'Maria' - >>> name - 'Maria' - >>> print(name) - Maria - +{% filename %}command-line{% endfilename %} + +```python +>>> name = 'Maria' +>>> name +'Maria' +>>> print(name) +Maria +``` -Cuando sólo escribes `name`, el intérprete de Python responde con la *representación* del string de la variable 'name', que son las letras M-a-r-i-a, rodeadas de comillas simples ''. Cuando dices `print(name)`, Python va a "imprimir" el contenido de la variable a la pantalla, sin las comillas, que es mejor. +Cuando sólo escribes `name`, el intérprete de Python responde con la *representación* en forma de cadena de la variable 'name', que son las letras M-a-r-i-a, rodeadas de comillas simples ''. Cuando dices `print(name)`, Python va a "imprimir" el contenido de la variable a la pantalla, sin las comillas, que es más claro. -Como veremos después, `print()` también es útil cuando queremos imprimir cosas desde adentro de las funciones, o bien cuando queremos imprimir cosas en múltiples líneas. +Como veremos después, `print()` también es útil cuando queremos imprimir cosas desde adentro de las funciones, o cuando queremos imprimir cosas en múltiples líneas. ## Listas -Además de string e integers, Python tiene toda clase de diferentes tipos de objetos. Ahora vamos a introducir uno llamado **list**. Las listas son exactamente lo que piensas que son: son objetos que son listas de otros objetos :) +Además de cadenas y enteros, Python tiene toda clase de tipos de objetos diferentes. Ahora vamos a introducir uno llamado **list**. Las listas son exactamente lo que piensas que son: objetos que son listas de otros objetos. :) Anímate y crea una lista: - >>> [] - [] - +{% filename %}command-line{% endfilename %} -Sí, esta lista está vacía. No es muy útil, ¿verdad? Vamos a crear una lista de números de lotería. No queremos repetir todo el tiempo, así que los pondremos en una variable también: +```python +>>> [] +[] +``` - >>> lottery = [3, 42, 12, 19, 30, 59] - +Sí, esta lista está vacía. No es muy útil, ¿verdad? Vamos a crear una lista de números de lotería. No queremos repetirnos todo el rato, así que la pondremos también en una variable: -Muy bien, ¡tenemos una lista! ¿Qué podemos hacer con ella? Vamos a ver cuántos números de lotería hay en la lista. ¿Tienes alguna idea de qué función deberías usar para eso? ¡Ya sabes esto! +{% filename %}command-line{% endfilename %} - >>> len(lottery) - 6 - +```python +>>> lottery = [3, 42, 12, 19, 30, 59] +``` + +Muy bien, ¡tenemos una lista! ¿Qué podemos hacer con ella? Vamos a ver cuántos números de lotería hay en la lista. ¿Tienes alguna idea de qué función deberías usar para eso? ¡Ya lo sabes! + +{% filename %}command-line{% endfilename %} + +```python +>>> len(lottery) +6 +``` ¡Sí! `len()` puede darte el número de objetos en una lista. Útil, ¿verdad? Tal vez la ordenemos ahora: - >>> lottery.sort() - +{% filename %}command-line{% endfilename %} -Esto no devuelve nada, sólo cambió el orden en que los números aparecen en la lista. Vamos a imprimir la lista otra vez y ver que pasó: +```python +>>> lottery.sort() +``` - >>> print(lottery) - [3, 12, 19, 30, 42, 59] - +No devuelve nada, sólo ha cambiado el orden en que los números aparecen en la lista. Vamos a imprimirla otra vez y ver qué ha pasado: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery) +[3, 12, 19, 30, 42, 59] +``` -Como puedes ver, los números en tu lista ahora están ordenados de menor a mayor. ¡Felicidades! +Como puedes ver, los números de tu lista ahora están ordenados de menor a mayor. ¡Enhorabuena! ¿Te gustaría invertir ese orden? ¡Vamos a hacerlo! - >>> lottery.reverse() - >>> print(lottery) - [59, 42, 30, 19, 12, 3] - +{% filename %}command-line{% endfilename %} -Fácil, ¿no? Si quieres añadir algo a tu lista, puedes hacerlo escribiendo este comando: +```python +>>> lottery.reverse() +>>> print(lottery) +[59, 42, 30, 19, 12, 3] +``` - >>> lottery.append(199) - >>> print(lottery) - [59, 42, 30, 19, 12, 3, 199] - +Si quieres añadir algo a tu lista, puedes hacerlo escribiendo este comando: -Si deseas mostrar sólo el primer número, puedes hacerlo mediante el uso de **indexes** (en español, índices). Un índice es el número que te dice dónde en una lista aparece un ítem. La computadora inicia la cuenta en 0, así que el primer objeto en tu lista está en el índice 0, el siguiente es 1, y así sucesivamente. Intenta esto: +{% filename %}command-line{% endfilename %} - >>> print(lottery[0]) - 59 - >>> print(lottery[1]) - 42 - +```python +>>> lottery.append(199) +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +``` + +Si deseas mostrar sólo el primer número, puedes hacerlo mediante el uso de **indexes** (en español, índices). Un índice es el número que te dice dónde en una lista aparece un ítem. Las programadoras y los programadores prefieren comenzar a contar desde 0, por lo tanto el primer objeto en tu lista está en el índice 0, el próximo esta en el 1, y así sucesivamente. Intenta esto: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery[0]) +59 +>>> print(lottery[1]) +42 +``` Como puedes ver, puedes acceder a diferentes objetos en tu lista utilizando el nombre de la lista y el índice del objeto dentro de corchetes. -Para diversión adicional, prueba algunos otros índices: 6, 7, 1000, -1, -6 ó -1000. A ver si se puedes predecir el resultado antes de intentar el comando. ¿Tienen sentido los resultados? +Para borrar algo de tu lista tendrás que usar **índices** como aprendimos anteriormente y la función `pop()`. Vamos a tratar de ejemplificar esto y reforzaar lo que aprendimos anteriormente; vamos a borrar el primer número de nuestra lista. + +{% filename %}command-line{% 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] +``` + +¡Funcionó de maravilla! + +Para diversión adicional, prueba algunos otros índices: 6, 7, 1000, -1, -6 ó -1000. A ver si puedes predecir el resultado antes de intentar el comando. ¿Tienen sentido los resultados? Puedes encontrar una lista de todos los métodos disponibles para listas en este capítulo de la documentación de Python: https://docs.python.org/3/tutorial/datastructures.html ## Diccionarios -Un diccionario es similar a una lista, pero accedes a valores usando una clave en vez de un índice. Una clave puede ser cualquier cadena o número. La sintaxis para definir un diccionario vacío es: +> Para lectores en casa: este capítulo está cubierto en el video [Bases de Python: Diccionarios](https://www.youtube.com/watch?v=ZX1CVvZLE6c). - >>> {} - {} - +Un diccionario es similar a una lista, pero accedes a valores usando una llave en vez de un índice. Una llave puede ser cualquier cadena o número. La sintaxis para definir un diccionario vacío es: + +{% filename %}command-line{% endfilename %} + +```python +>>> {} +{} +``` Esto demuestra que acabas de crear un diccionario vacío. ¡Hurra! -Ahora, trata escribiendo el siguiente comando (intenta reemplazando con propia información): +Ahora, trata escribiendo el siguiente comando (intenta reemplazando con tu propia información): - >>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} - +{% filename %}command-line{% endfilename %} + +```python +>>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} +``` -Con este comando, acabas de crear una variable `participant` con tres pares clave-valor: +Con este comando, acabas de crear una variable llamada `participant` con tres pares llave-valor: -* La clave `name` apunta al valor `'Ola'` (un objeto `string`), -* `country` apunta a `'Poland'` (otro `string`), -* y `favorite_numbers` apunta a `[7, 42, 92]` (una `list` con tres números en ella). +- La llave `name` apunta al valor `'Ola'` (un objeto `string`), +- `country` apunta a `'Poland'` (otro `string`), +- y `favorite_numbers` apunta a `[7, 42, 92]` (una `list` con tres números en ella). Puedes verificar el contenido de claves individuales con esta sintaxis: - >>> print(participant['name']) - Ola - +{% filename %}command-line{% endfilename %} + +```python +>>> print(participant['name']) +Ola +``` Lo ves, es similar a una lista. Pero no necesitas recordar el índice - sólo el nombre. ¿Qué pasa si le pedimos a Python el valor de una clave que no existe? ¿Puedes adivinar? ¡Pruébalo y verás! - >>> participant['age'] - Traceback (most recent call last): - File "", line 1, in - KeyError: 'age' - +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> participant['age'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'age' +``` ¡Mira, otro error! Este es un **KeyError**. Python te ayuda y te dice que la llave `'age'` no existe en este diccionario. -¿Cuándo utilizar un diccionario o una lista? Bueno, eso es un buen punto para reflexionar. Sólo ten una solución en mente antes de mirar la respuesta en la siguiente línea. +¿Cuando deberías usar un diccionario o una lista? Bueno, es un buen punto para reflexionar. Piensa sobre la respuesta, antes de mirar una solución en la siguiente línea. -* ¿Sólo necesitas una secuencia ordenada de elementos? Usa una lista. -* ¿Necesitas asociar valores con claves, así puedes buscarlos eficientemente (usando las claves) más adelante? Utiliza un diccionario. +- ¿Sólo necesitas una secuencia ordenada de elementos? Usa una lista. +- ¿Necesitas asociar valores con claves, así puedes buscarlos eficientemente (usando las claves) más adelante? Utiliza un diccionario. -Los diccionarios, como las listas, son *mutables*, lo que significa que pueden ser cambiados después de ser creados. Puedes agregar nuevos pares clave/valor en el diccionario después de que ha sido creado, por ejemplo: +Los diccionarios, como las listas, son *mutables*, lo que quiere decir que pueden ser modificados después de ser creados. Puedes agregar nuevos pares llave/valor a un diccionario luego de crearlo, como: - >>> participant['favorite_language'] = 'Python' - +{% filename %}command-line{% endfilename %} -Como en las listas, el método `len()` en los diccionarios, devuelve el número de pares clave-valor en el diccionario. Adelante, escribe el comando: +```python +>>> participant['favorite_language'] = 'Python' +``` - >>> len(participant) - 4 - +Como las listas, usando el método `len()` en los diccionarios devuelven el número de pares llave-valor en el diccionario. Adelante escribe el comando: -Espero tenga sentido hasta ahora. :) ¿Lista para más diversión con los diccionarios? Salta a la siguiente línea para algunas cosas sorprendentes. +{% filename %}command-line{% endfilename %} -Puedes utilizar el comando `pop()` para borrar un elemento en el diccionario. Por ejemplo, si deseas eliminar la entrada correspondiente a la clave `'favorite_numbers'`, sólo tienes que escribir el siguiente comando: +```python +>>> len(participant) +4 +``` - >>> participant.pop('favorite_numbers') - >>> participant - {'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} - +Espero tenga sentido hasta ahora. :) ¿Listo para más diversión con diccionarios? Salta a la siguiente línea para algunas cosas sorprendentes. -Como puedes ver en la salida, el par de clave-valor correspondiente a la clave 'favorite_numbers' ha sido eliminado. +Puedes utilizar el comando `pop()` para borrar un elemento en el diccionario. Por ejemplo, si deseas eliminar la entrada correspondiente a la clave `'favorite_numbers'`, tienes que escribir el siguiente comando: -Además de esto, también puedes cambiar un valor asociado a una clave ya creada en el diccionario. Teclea: +{% filename %}command-line{% 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'} +``` + +Como puedes ver en la salida, el par de llave-valor correspondiente a la llave 'favorite_numbers' ha sido eliminado. + +Además de esto, también puedes cambiar un valor asociado a una llave ya creada en el diccionario. Escribe: -Como puedes ver, el valor de la clave `'country'` ha sido modificado de `'Poland'` a `'Germany'`. :) ¿Emocionante? ¡Hurra! Has aprendido otra cosa asombrosa. +{% filename %}command-line{% endfilename %} + +```python +>>> participant['country'] = 'Germany' +>>> participant +{'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +Como puedes ver, el valor de la llave `'country'` ha sido modificado de `'Poland'` a `'Germany'`. :) ¿Emocionante? ¡Hurra! Has aprendido otra cosa asombrosa. ### Resumen ¡Genial! Sabes mucho sobre programación ahora. En esta última parte aprendiste sobre: -* **errors** - ahora sabes cómo leer y entender los errores que aparecen si Python no entiende un comando que le has dado -* **variables** - nombres para los objetos que te permiten codificar más fácilmente y hacer el código más legible -* **lists** - listas de objetos almacenados en un orden determinado -* **dictionaries** - objetos almacenados como pares clave-valor +- **errores** - ahora sabes cómo leer y entender los errores que aparecen si Python no entiende un comando +- **variables** - nombres para los objetos que te permiten codificar más fácilmente y hacer el código más legible +- **listas** - listas de objetos almacenados en un orden determinado +- **diccionarios** - objetos almacenados como pares llave-valor ¿Emocionada por la siguiente parte? :) ## Compara cosas -Una gran parte de la programación incluye comparar cosas. ¿Qué es lo más fácil para comparar? Números, por supuesto. Vamos a ver cómo funciona: - - >>> 5 > 2 - True - >>> 3 < 1 - False - >>> 5 > 2 * 2 - True - >>> 1 == 1 - True - >>> 5 != 2 - True - +> Para lectores en casa: este capítulo está cubierto en el vídeo [Bases de Python: Comparaciones](https://www.youtube.com/watch?v=7bzxqIKYgf4). + +Buena parte de la programación incluye comparar cosas. ¿Qué es lo más fácil para comparar? Números, por supuesto. Vamos a ver cómo funciona: + +{% filename %}command-line{% endfilename %} + +```python +>>> 5 > 2 +True +>>> 3 < 1 +False +>>> 5 > 2 * 2 +True +>>> 1 == 1 +True +>>> 5 != 2 +True +``` -Le dimos a Python algunos números para comparar. Como puedes ver, Python no sólo puede comparar números, sino que también puede comparar resultados de método. Bien, ¿eh? +Le dimos a Python algunos números para comparar. Como puedes ver, Python no sólo puede comparar números, sino que también puede comparar resultados de funciones. Bien, ¿eh? ¿Te preguntas por qué pusimos dos signos igual `==` al lado del otro para comparar si los números son iguales? Utilizamos un solo `=` para asignar valores a las variables. Siempre, **siempre** es necesario poner dos `==` Si deseas comprobar que las cosas son iguales entre sí. También podemos afirmar que las cosas no son iguales a otras. Para eso, utilizamos el símbolo `!=`, como mostramos en el ejemplo anterior. Da dos tareas más a Python: - >>> 6 >= 12 / 2 - True - >>> 3 <= 2 - False - +{% filename %}command-line{% endfilename %} -`>` y `<` son fáciles, pero ¿qué es significa `> =` y `< =`? Se leen así: +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` -* x `>` y significa: x es mayor que y -* x `<` y significa: x es menor que y -* x `<=` y significa: x es menor o igual que y -* x `>=` y significa: x es mayor o igual que y +Hemos visto `>` y `<`, pero, ¿qué significan `>=` y `<=`? Los puedes leer así: -¡Genial! ¿Quieres hacer uno mas? Intenta esto: +- x `>` y significa: x es mayor que y +- x `<` y significa: x es menor que y +- x `<=` y significa: x es menor o igual que y +- x `>=` y significa: x es mayor o igual que y - >>> 6 > 2 and 2 < 3 - True - >>> 3 > 2 and 2 < 1 - False - >>> 3 > 2 or 2 < 1 - True - +¡Genial! ¿Quieres hacer uno más? Intenta esto: + +{% filename %}command-line{% endfilename %} + +```python +>>> 6 > 2 and 2 < 3 +True +>>> 3 > 2 and 2 < 1 +False +>>> 3 > 2 or 2 < 1 +True +``` Puedes darle a Python todos los números para comparar que quieras, y siempre te dará una respuesta. Muy inteligente, ¿verdad? -* **and** - si utilizas el operador `and`, ambas comparaciones deben ser True para que el resultado de todo el comando sea True -* **or** - si utilizas el operador `or`, sólo una de las comparaciones tiene que ser True para que el resultado de todo el comando sea True +- **and** - si utilizas el operador `and`, ambas comparaciones deben ser True para que el resultado de todo el comando sea True +- **or** - si utilizas el operador `or`, sólo una de las comparaciones tiene que ser True para que el resultado de todo el comando sea True ¿Has oído la expresión "comparar manzanas con naranjas"? Vamos a probar el equivalente en Python: - >>> 1 > 'django' - Traceback (most recent call last): - File "", line 1, in - TypeError: unorderable types: int() > str() - +{% 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' +``` Aquí verás que al igual que en la expresión, Python no es capaz de comparar un número (`int`) y un string (`str`). En cambio, muestra un **TypeError** y nos dice que los dos tipos no se pueden comparar. ## Boolean -Por cierto, acabas de aprender acerca de un nuevo tipo de objeto en Python. Se llama un **Boolean** -- y es probablemente el tipo más simple que existe. +Incidentalmente, acabas de aprender sobre un nuevo tipo de objeto en Python. Se llama **Boolean** (booleano). + +Hay sólo dos objetos booleanos: -Hay sólo dos objetos Boolean: - True - False +- True - verdadero +- False - falso -Pero para que Python entienda esto, es necesario que siempre lo escribas como True (primera letra mayúscula, con el resto de la letras minúsculas). **true, TRUE, tRUE no funcionarán -- sólo True es correcto.** (Lo mismo aplica a False también, por supuesto.) +Pero para que Python entienda esto, siempre los tienes que escribir de modo 'True' (la primera letra en mayúscula, con el resto de las letras en minúscula). **true, TRUE, y tRUE no funcionarán – solamente True es correcta.** (Lo mismo aplica también para 'False'.) Los valores booleanos pueden ser variables, también. Ve el siguiente ejemplo: - >>> a = True - >>> a - True - +{% filename %}command-line{% endfilename %} + +```python +>>> a = True +>>> a +True +``` También puedes hacerlo de esta manera: - >>> a = 2 > 5 - >>> a - False - +{% filename %}command-line{% endfilename %} + +```python +>>> a = 2 > 5 +>>> a +False +``` Practica y diviértete con los booleanos ejecutando los siguientes comandos: -* `True and True` -* `False and True` -* `True or 1 == 1` -* `1 != 2` +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` ¡Felicidades! Los booleanos son una de las funciones más geniales en programación y acabas de aprender cómo usarlos. # ¡Guárdalo! -Hasta ahora hemos estado escribiendo nuestro código Python en el intérprete, lo cual nos limita a una línea de código a la vez. Normalmente los programas son guardados en archivos y son ejecutados por el **intérprete** o **compilador** de nuestro lenguaje de programación. Hasta ahora, hemos estado corriendo nuestros programas de a una línea por vez en el **intérprete** de Python. Necesitaremos más de una línea de código para las siguientes tareas, entonces necesitaremos hacer rápidamente lo que sigue: +> Para lectores en casa: este capítulo está cubierto en el vídeo [Bases de Python: Guardando archivos y condicionales](https://www.youtube.com/watch?v=dOAg6QVAxyk). -* Salir del intérprete de Python -* Abrir el editor de texto de nuestra elección -* Guardar algo de código en un nuevo archivo de Python -* ¡Ejecutarlo! +Hasta ahora hemos escrito todo nuestro código Python en el intérprete, lo cual nos limita a ingresar una línea de código a la vez. Normalmente los programas son guardados en archivos y son ejecutados por el **intérprete** o **compilador** de nuestro lenguaje de programación. Hasta ahora, hemos estado corriendo nuestros programas de a una línea por vez en el **intérprete** de Python. Necesitaremos más de una línea de código para las siguientes tareas, entonces necesitaremos hacer rápidamente lo que sigue: -Para salir del intérprete de Python que hemos estado usando, simplemente escribe la función exit(): +- Salir del intérprete de Python +- Abrir el editor de texto de nuestra elección +- Guardar algo de código en un nuevo archivo de Python +- ¡Ejecutarlo! - >>> exit() - $ - +Para salir del intérprete de Python que hemos estado usando, escribe `exit()` + +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` Esto te llevará de vuelta a la línea de comandos. -Anteriormente, elegimos un editor de código en la sección de [Editor de código][2]. Tendremos que abrir el editor ahora y escribir algo de código en un archivo nuevo: +Anteriormente, seleccionamos un editor de código de la sección editor de código. Necesitaremos abrir el editor ahora y escribir algo de código en un nuevo archivo (o si está usando un Chromebook, cree un nuevo archivo en el IDE de la nube y abra el archivo, que estará en el editor de código incluido): - [2]: ../code_editor/README.md +{% filename %}editor{% endfilename %} -``` python - print('Hello, Django girls!') +```python +print('Hello, Django girls!') ``` -> **Nota** Deberías notar una de las cosas más geniales de los editores de código: ¡los colores! En la consola de Python, todo era del mismo color, pero ahora puedes ver que la función `print` es de un color diferente del string que está adentro de ella. Eso se denomina "resaltado de sintaxis", y es una gran ayuda cuando estás programando. Presta atención a los colores, y obtendrás una pista cuando te olvides de cerrar un string o cometes un error al escribir una palabra clave (como el `def` en una función, que veremos abajo). Esta es una de las razones por las cuales usar un editor de código :) +Obviamente, ahora eres una desarrolladora Python muy experimentada, asi que sintete libre de escribir algo del código que has aprendido hoy. -Obviamente, ahora eres una desarrolladora Python muy experimentada, así que siéntete libre de escribir algo del código que has aprendido hoy. +Ahora tenemos que guardar el archivo y asignarle un nombre descriptivo. Vamos a llamar al archivo **python_intro.py** y guardarlo en tu escritorio. Podemos nombrar el archivo como queramos, pero la parte importante es asegurarse de que termina en **.py**. La extensión **.py** le dice a nuestro sistema operativo que es un **archivo ejecutable de python** y Python lo puede ejecutar. -Ahora tenemos que guardar el archivo y asignarle un nombre descriptivo. Vamos a llamar al archivo **python_intro.py** y guardarlo en tu escritorio. Podemos nombrar el archivo de cualquier manera que queramos, lo importante aquí es asegurarse que el archivo finalice con **.py**, esto le indica a nuestra computadora que este es un **archivo ejecutable de Python** y que Python puede correrlo. +> **Nota** Deberías notar una de las cosas más geniales de los editores de código: ¡los colores! En la consola de Python, todo era del mismo color, ahora deberías ver que la función `print` es de un color diferente a la cadena en su interior. Esto de denomina "sintaxis resaltada", y es una característica muy útil cuando se programa. El color de las cosas te dará pistas, como cadenas no cerradas o errores tipográficos en un nombre clave (como `def` en una función, que veremos a continuación). Esta es una de las razones por las cuales usar un editor de código. :) Con el archivo guardado, ¡es hora de ejecutarlo! Utilizando las habilidades que has aprendido en la sección de línea de comandos, utiliza la terminal para **cambiar los directorios** e ir al escritorio. + + En una Mac, el comando se verá algo como esto: - cd ~/Desktop +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop -En Linux, va a ser así (la palabra "Desktop" puede estar traducida a tu idioma): + + + + +En Linux, será así: + +{% filename %}command-line{% endfilename %} - cd ~/Desktop + $ cd ~/Desktop -Y en Windows, será así: +(Recuerde que la palabra "Desktop" puede traducirse a su idioma local.) - cd %HomePath%\Desktop + + + + +En la consola de Windows, ésto será como: + +{% filename %}command-line{% endfilename %} + + > cd %HomePath%\Desktop -Si te quedas atascada, sólo pide ayuda. + + + -y luego usa Python para ejecutar el código en el archivo como sigue: +Y en Windows Powershell, será así: + +{% filename %}command-line{% endfilename %} + + > cd $Home\Desktop + + + + +Si estás atascada, pide ayuda. ¡Eso es exactamente lo que hacen las entrenadoras! + +Ahora usa Python para ejecutar el código en el archivo como esto: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hello, Django girls! -¡Muy bien! Ejecutaste tu primer programa de Python desde un archivo. ¿No se siente increíble? +Nota: en Windows 'python3' no es reconocido como un comando. En su lugar, usa 'python' para ejecutar el archivo: -Ahora puedes moverte a una herramienta esencial en la programación: +{% filename %}command-line{% endfilename %} -## If...elif...else +```python +> python python_intro.py +``` -Un montón de cosas en el código sólo son ejecutadas cuando se cumplen las condiciones dadas. Por eso Python tiene algo llamado **sentencias if**. +¡Correcto! Ahora corriste tu primer programa de Python que fue guardado en un archivo. ¿Se siente increíble? -Reemplaza el código en tu archivo **python_intro.py** por esto: +Puedes ahora moverte a una herramienta esencial en programación: -``` python - if 3 > 2: +## If … elif … else + +Muchas de las cosas en código debería ser ejecutadas solo cuando las condiciones son conocidas. Eso es por qué Python lo ha llamado **sentencias if**. + +Reemplaza el código en tu archivo **python_intro.py** con esto: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 3 > 2: ``` -Si lo guardáramos y lo ejecutáramos, veríamos un error como este: +Si guardáramos y corriéramos esto, veríamos un error como éste: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} $ python3 python_intro.py File "python_intro.py", line 2 @@ -507,115 +718,194 @@ Si lo guardáramos y lo ejecutáramos, veríamos un error como este: SyntaxError: unexpected EOF while parsing -Python espera que le demos más instrucciones que se supone serán ejecutadas si la condición `3 > 2` resulta ser verdadera (o `True` en este caso). Intentemos hacer que Python imprima "It works!". Cambia tu código en el archivo **python_intro.py** para que se vea como esto: +Python nos espera dar nuevas instrucciones, las cuales son ejecutadas si la condición `3 > 2` torna a ser verdadera (o `True` para ese caso). Intentemos imprimir en Python "¡Funciona!". Cambia el código de tu archivo **python_intro.py** a esto: + +{% filename %}python_intro.py{% endfilename %} -``` python - if 3 > 2: - print('It works!') +```python +if 3 > 2: + print('It works!') ``` -¿Observas cómo hemos indentado la siguiente línea de código con 4 espacios? Tenemos que hacer esto para que Python sepa qué código ejecutar si la comparación resulta verdadera. Puedes poner un espacio, pero casi todos los programadores Python hacen 4 espacios para hacer que el código sea más legible. Un solo tab también contará como 4 espacios. +¿Notas cómo estamos indentando la siguiente línea de código con 4 espacios? Nosotros necesitamos hacer esto para que Python comprenda que el código se ejecuta si el resultado es verdadero. Tú puedes poner un espacio, pero prácticamente todos los programadores en Python ponen 4 espacios para hacer el código más legible. Un simple tabulador también contará como 4 espacios tan largos como tu editor de texto esté configurado. Cuando hagas tu elección, ¡no la cambies! Si ya identaste con 4 espacios, sigue haciendo futuras identaciones con 4 espacios también, de otra forma, puedes encontrar problemas. Guárdalo y ejecútalo de nuevo: - $ python3 python_intro.py - It works! - +{% filename %}command-line{% endfilename %} + +```python +$ python3 python_intro.py +It works! +``` + +Nota: Recuerda que en Windows, 'python3' no es reconocido como un comando. Desde ahora, reemplaza 'python3' con 'python' para ejecutar el archivo. -### ¿Qué pasa si la condición no es verdadera? +### ¿Qué pasa si una condición no es verdadera? -En ejemplos anteriores, el código fue ejecutado sólo cuando las condiciones eran ciertas. Pero Python también tiene declaraciones `elif` y `else`: +En previos ejemplos, el código fue ejecutado solamente cuando las condiciones eran Verdaderas. Pero Python también tiene sentencias `elif` y `else`: + +{% filename %}python_intro.py{% endfilename %} ```python - if 5 > 2: - print('5 is indeed greater than 2') - else: - print('5 is not greater than 2') +if 5 > 2: + print('5 is indeed greater than 2') +else: + print('5 is not greater than 2') ``` -Al ejecutar esto se imprimirá: +Cuando ésto se ejecuta, imprimirá: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py 5 is indeed greater than 2 -Si 2 fuera un número mayor que 5, entonces el segundo comando sería ejecutado. Fácil, ¿verdad? Vamos a ver cómo funciona `elif`: +Si 2 era mayor que el número 5, entonces el segundo comando sería ejecutado. Veamos cómo `elif` funciona: -``` python - name = 'Sonja' - if name == 'Ola': - print('Hey Ola!') - elif name == 'Sonja': - print('Hey Sonja!') - else: - print('Hey anonymous!') +{% filename %}python_intro.py{% endfilename %} + +```python +name = 'Sonja' +if name == 'Ola': + print('Hey Ola!') +elif name == 'Sonja': + print('Hey Sonja!') +else: + print('Hey anonymous!') ``` -y al ejecutarlo: +y ejecuta: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hey Sonja! -¿Ves lo que pasó ahí? +¿Ves qué sucedió allí? `elif` te deja añadir condiciones adicionales que se ejecutan si las condiciones previas fallan. + +Tú puedes añadir tantas sentencias `elif` como quieras, luego de tu sentencia inicial `if`. Por ejemplo: + +{% filename %}python_intro.py{% endfilename %} + +```python +volume = 57 +if volume < 20: + print("It's kinda quiet.") +elif 20 <= volume < 40: + print("It's nice for background music") +elif 40 <= volume < 60: + print("Perfect, I can hear all the details") +elif 60 <= volume < 80: + print("Nice for parties") +elif 80 <= volume < 100: + print("A bit loud!") +else: + print("Me duelen las orejas! :(") +``` + +Python corre a través de cada prueba secuencialmente e imprime: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Perfect, I can hear all the details + + +## Comentarios + +Los comentarios son líneas que comienzan con `#`. Tú puedes escribir lo que quieras tras el `#` y Python lo ignorará. Los comentarios pueden hacer que el código sea más fácil de entender para otras personas. + +Veamos cómo luce: + +{% filename %}python_intro.py{% endfilename %} + +```python +# Cambiar el volumen si esta muy alto o muy bajo +if volume < 20 or volume > 80: + volume = 50 + print("Mucho mejor!") +``` + +Tú no necesitas escribir un comentario para cada línea de código, pero ellos son útiles para explicar qué está haciendo el código, o proveer un resumen cuando se está haciendo algo complejo. ### Resumen -En los últimos tres ejercicios aprendiste acerca de: +En los últimos ejercicios aprendiste acerca de: -* **Comparar cosas** - en Python puedes comparar cosas haciendo uso de `>`, `>=`, `==`, `<=`, `<` y de los operatores `and` y `or` -* **Boolean** - un tipo de objeto que sólo puede tener uno de dos valores: `True` o `False` -* **Guardar archivos** - cómo almacenar código en archivos así puedes ejecutar programas más grandes -* **if... elif... else** - sentencias que te permiten ejecutar código sólo cuando se cumplen ciertas condiciones +- **Comparar cosas** - en Python puedes comparar cosas haciendo uso de `>`, `>=`, `==`, `<=`, `<` y de los operadores `and` y `or` +- **Boolean** - un tipo de objeto que sólo puede tener uno de dos valores: `True` o `False` +- **Guardar archivos** - almacenar código en archivos para que puedas ejecutar programas más grandes. +- **if... elif... else** - sentencias que te permiten ejecutar código sólo cuando se cumplen ciertas condiciones. +- **comentarios** - líneas que Python no ejecutará que permiten documentar el código -¡Es hora de leer la última parte de este capítulo! +¡Es tiempo para leer la última parte de este capítulo! ## ¡Tus propias funciones! -¿Recuerdas las funciones como `len()` que puedes ejecutar en Python? Bien, buenas noticias, ¡ahora aprenderás cómo escribir tus propias funciones! +> Para lectores en casa: este capítulo está cubierto en el vídeo [Bases de Python: Funciones](https://www.youtube.com/watch?v=5owr-6suOl0). -Una función es una secuencia de instrucciones que Python debe ejecutar. Cada función en Python comienza con la palabra clave `def`, se le asigna un nombre y puede tener algunos parámetros. Vamos a empezar con algo fácil. Reemplaza el código en **python_intro.py** con lo siguiente: +¿Recuerdas las funciones como `len()` que puedes ejecutar en Python? Bien, buenas noticias - ¡aprenderás cómo escribir tus propias funciones ahora! -``` python - def hi(): - print('Hi there!') - print('How are you?') - - hi() +Una función es una secuencia de instrucciones que Python debería ejecutar. Cada función en Python inicia con la palabra clave `def`, el nombre es dado, y puede tener algunos parámetros. Veamos. Reemplaza el código en **python_intro.py** con lo siguiente: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(): + print('Hi there!') + print('How are you?') + +hi() ``` -Bien, ¡nuestra primera función está lista! +Okay, ¡nuestra primera función está lista! -Te preguntarás por qué hemos escrito el nombre de la función en la parte inferior del archivo. Esto es porque Python lee el archivo y lo ejecuta desde arriba hacia abajo. Así que para poder utilizar nuestra función, tenemos que reescribir su nombre en la parte inferior. +Tú puedes preguntar por qué hemos escrito el nombre de la función en la parte inferior del archivo. Esto es porque Python lee el archivo y lo ejecuta de arriba a bajo. Así en orden para usar nuestra función, tenemos que re-escribirlo en la parte inferior. -Ejecutemos esto y veamos qué sucede: +Ejecuta ésto ahora y mira qué sucede: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hi there! How are you? -¡Eso fue fácil! Vamos a construir nuestra primera función con parámetros. Utilizaremos el ejemplo anterior - una función que dice 'Hi' a la persona que ejecuta el programa - con un nombre: +Nota: si ésto no funciona, ¡Tranquil@! La salida te ayudará a entender por qué: + +- Si te sale `NameError`, probablemente significa que escribiste algo mal, así que deberias comprobar si utilizaste el mismo nombre para crear la función con `def hi():` y al llamarla con `hi()`. +- Si te sale un `IndentationError`, comprueba que las líneas del `print` tienen el mismo espacio en blanco al comienzo de línea: python requiere que todo el código dentro de la función esté perfectamente alineado. +- Si no hay ninguna salida, comprueba que el último `hi()` *no esté* identado - si lo está, esa línea también será parte de la función, y nunca se ejecutará. + +Construyamos nuestra primera función con parámetros. Cambiaremos el ejemplo anterior - una función que dice 'hola' para la persona que lo ejecuta - con un nombre: -``` python - def hi(name): +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): ``` -Como puedes ver, ahora dimos a nuestra función un parámetro que llamamos `name`: +Como puedes ver, ahora le dimos a nuestra función un parámetro que llamamos `nombre`: -``` python - def hi(name): - if name == 'Ola': - print('Hi Ola!') - elif name == 'Sonja': - print('Hi Sonja!') - else: - print('Hi anonymous!') - - hi() -``` +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + if name == 'Ola': + print('Hi Ola!') + elif name == 'Sonja': + print('Hi Sonja!') + else: + print('Hi anonymous!') + +hi() +``` + +Recuerda: La función `print` está indentada con 4 espacios en la sentencia `if`. Esto es porque la función se ejecuta cuando la condición es conocida. Veamos cómo funciona ahora: -Como puedes notar, tuvimos que poner dos indentaciones antes de la función `print` porque `if` necesita saber lo que debería ocurrir cuando se cumple la condición. Vamos a ver cómo funciona: +{% filename %}{{ warning_icon }} command-line{% endfilename %} $ python3 python_intro.py Traceback (most recent call last): @@ -624,13 +914,17 @@ Como puedes notar, tuvimos que poner dos indentaciones antes de la función `pri TypeError: hi() missing 1 required positional argument: 'name' -Oops, un error. Por suerte, Python nos da un mensaje de error bastante útil. Nos dice que la función `hi()` (la que definimos) tiene un argumento requerido (llamado `name`) y que se nos olvidó pasarlo al llamar a la función. Vamos a arreglarlo en la parte inferior del archivo: +Oops, un error. Por suerte, Python nos da un útil y agradable mensaje de error. Este nos dice que la función `hi()` (que definimos) tiene un argumento requerido (llamado `nombre`) y que olvidamos pasarlo cuando llamamos a la función. Configuremos esto en la parte inferior del archivo: -``` python - hi("Ola") +{% filename %}python_intro.py{% endfilename %} + +```python +hi("Ola") ``` -y lo ejecutamos otra vez: +Y ejecutemos otra vez: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hi Ola! @@ -638,73 +932,93 @@ y lo ejecutamos otra vez: ¿Y si cambiamos el nombre? -``` python - hi("Sonja") -``` +{% filename %}python_intro.py{% endfilename %} -y lo corremos: +```python +hi("Sonja") +``` + +Y lo ejecutamos: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hi Sonja! -Ahora, ¿qué crees que pasará si escribes otro nombre allí? (No Ola o Sonja). Pruébalo y verás si tienes razón. Esto debería imprimir: +Ahora, ¿qué piensas que sucederá si escribes otro nombre allí? (No Ola o Sonja.) Inténtalo y comprueba si estás en lo correcto. Debería imprimir esto: + +{% filename %}command-line{% endfilename %} Hi anonymous! -Esto es increíble, ¿verdad? De esta forma no tienes que repetir todo cada vez que deseas cambiar el nombre de la persona a la que la función debería saludar. Y eso es exactamente el por qué necesitamos funciones - ¡para no repetir tu código! +Esto es sorprendente, ¿Verdad? De esta manera tú no tienes que repetir la función cada vez que cambies el nombre de la persona que está supuesta a recibir. Y eso es exactamente por qué necesitamos funciones - ¡tú nunca quieres repetir tú código! -Vamos a hacer algo más inteligente - hay más de dos nombres, y escribir una condición para cada uno sería difícil, ¿no? +Hacer algo más inteligente - hay más nombres que dos, y escribir una condición para cada uno sería difícil, ¿Verdad? Reemplaza el contenido de tu archivo con lo siguiente: -``` python - def hi(name): - print('Hi ' + name + '!') - - hi("Rachel") -``` +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + print('Hi ' + name + '!') + +hi("Rachel") +``` + +Llamarémos al código ahora: -Ahora vamos a llamar al código: +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hi Rachel! -¡Felicidades! Acabas de aprender cómo escribir funciones :) +¡Felicidades! ¡Ya aprendíste cómo escribir funciones! :) ## Bucles -Esta ya es la última parte. ¿Eso fue rápido, verdad? :) +> Para lectores en casa: este capítulo está cubierto en el vídeo [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0). -Como hemos mencionado, los programadores son perezosos, no les gusta repetir cosas. La programación intenta automatizar las cosas, así que no queremos saludar a cada persona por su nombre manualmente, ¿verdad? Es ahí donde los bucles se vuelven muy útiles. +Listo esta es la última parte. Eso fue rápido, ¿verdad? :) -¿Todavía recuerdas las listas? Hagamos una lista de las chicas: +Los programadores no les gusta repetir. Programar es todo acerca de automatizar cosas, así que no queremos recibir a cada persona por su nombre manualmente, ¿verdad? Allí es dónde los ciclos vienen a manejarse. -``` python - girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] -``` +¿Aún recuerdas las listas? Hagamos una lista de niñas: -Queremos saludar a todas ellas por su nombre. Tenemos la función `hi` que hace eso, así que vamos a usarla en un bucle: +{% filename %}python_intro.py{% endfilename %} -``` python - for name in girls: -``` +```python +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +``` -La sentencia for se comporta de manera similar a la sentencia if, el código que sigue a continuación debe estar indentado usando cuatro espacios. +Queremos recibir a todos ellos con sus nombres. Tenemos la función `hola` para hacerlo, así que usémosla en un ciclo: -Aquí está el código completo que estará en el archivo: +{% filename %}python_intro.py{% endfilename %} -``` python - def hi(name): - print('Hi ' + name + '!') - - girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] - for name in girls: - hi(name) - print('Next girl') -``` +```python +for name in girls: +``` + +La sentencia `for` se comporta parecido a una sentencia `if`; ambos códigos necesitan ser indentados por 4 espacios. + +Aquí está completo el código que estará en el archivo: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + print('Hi ' + name + '!') + +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +for name in girls: + hi(name) + print('Next girl') +``` -y cuando lo ejecutamos: +Y cuando lo ejecutemos: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hi Rachel! @@ -719,15 +1033,20 @@ y cuando lo ejecutamos: Next girl -Como puedes ver, todo lo que pones con una indentación dentro de una sentencia `for` será repetido para cada elemento de la lista `girls`. +Como puedes ver, todo lo que coloques dentro de una sentencia `for` con una indentación, será repetida para cada elemento de la lista `girls`. -También puedes usar el `for` en números usando la función `range`: +Tu puedes también usar `for` con números usando la función `range`: - for i in range(1, 6): - print(i) - +{% filename %}python_intro.py{% endfilename %} + +```python +for i in range(1, 6): + print(i) +``` + +El cuál imprimirá: -Lo que imprimirá: +{% filename %}command-line{% endfilename %} 1 2 @@ -738,14 +1057,14 @@ Lo que imprimirá: `range` es una función que crea una lista de números en serie (estos números son proporcionados por ti como parámetros). -Ten en cuenta que el segundo de estos dos números no será incluido en la lista que retornará Python (es decir, `range(1, 6)` cuenta desde 1 a 5, pero no incluye el número 6). +Nota que el segundo de estos números no está incluido en la lista que regresa Python (es decir, `range(1, 6)` cuenta desde 1 a 5, pero no incluye el número 6). Esto es porque "range" está medio-abierto, y por eso se incluye el primer valor, pero no el último. ## Resumen -Eso es todo. **¡Eres genial!** Esto no fue tan fácil realmente, así que deberías sentirte orgullosa de ti misma. ¡Estamos muy orgullosos de que hayas llegado hasta aquí! +Eso es todo. **¡Tú rockeas totalmente!** Esto fue un capítulo difícil, así que deberías sentirte orgullos@ de ti. ¡Estamos definitivamente encantados de que hayas llegado tan lejos! -Tal vez quieras hacer algo distinto por un momento - estirarte, caminar un poco, descansar tus ojos - antes de pasar al siguiente capítulo. :) +Para un tutorial oficial y completo de python visita https://docs.python.org/3/tutorial/. Este te dará un estudio completo de éste lenguaje. Gracias :) -![Cupcake][3] +Tu podrías querer un momento para algo - estirarte, caminar cerca, descansar tus ojos - antes de avanzar a un próximo capítulo. :) - [3]: images/cupcake.png +![Pastelillo](images/cupcake.png) diff --git a/es/python_introduction/images/cupcake.png b/es/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/es/python_introduction/images/cupcake.png and b/es/python_introduction/images/cupcake.png differ diff --git a/es/template_extending/README.md b/es/template_extending/README.md index a7fb7d7a133..7dc522a90ff 100755 --- a/es/template_extending/README.md +++ b/es/template_extending/README.md @@ -1,10 +1,10 @@ -# Extendiendo Plantillas +# Extendiendo plantillas -Otra cosa buena que Django tiene para tí es la **extensión de plantillas**. ¿Qué significa esto? Significa que puedes usar las mismas partes de tu HTML para diferentes páginas de tu sitio web. +Otra cosa buena que tiene Django es la **extensión de plantillas**. ¿Qué significa? Significa que puedes reutilizar partes del HTML para diferentes páginas del sitio web. -De esta forma no tienes que repetir el código en cada uno de los archivos cuando quieres usar una misma información o un mismo esquema. Y si quieres cambiar algo, no necesitas hacerlo en cada plantilla. +Las plantillas son útiles cuando quieres utilizar la misma información o el mismo diseño en más de un lugar. No tienes que repetirte a ti misma en cada archivo. Y si quieres cambiar algo, no tienes que hacerlo en cada plantilla, sólo en una! -## Creando una plantilla base +## Crea una plantilla base Una plantilla base es la plantilla más básica que extiendes en cada página de tu sitio web. @@ -17,106 +17,131 @@ Vamos a crear un archivo `base.html` en `blog/templates/blog/`: post_list.html -Luego ábrelo y copia todo lo que hay en `post_list.html` al archivo `base.html`, de la siguiente manera: +Ahora, ábrelo en el editor de código y copia todo el contenido de `post_list.html` en `base.html`, así: -```html - {% load staticfiles %} - - - Django Girls blog - - - - - - - - -
-
-
- {% for post in posts %} -
-
- {{ post.published_date }} -
-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

-
- {% endfor %} -
-
-
- - -``` - -Luego, en `base.html` reemplaza por completo tu `` (todo lo que haya entre `` and ``) con esto: +{% filename %}blog/templates/blog/base.html{% endfilename %} -``` html +```html +{% load static %} + + + Django Girls blog + + + + + +
- {% block content %} - {% endblock %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %}
+ +``` + +Luego, en `base.html` reemplaza por completo tu `` (todo lo que haya entre `` and ``) con esto: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ +``` + +{% raw %}Seguro que ya te has dado cuenta de que lo que hemos hecho ha sido cambiar todo lo que había entre `{% for post in posts %}` y `{% endfor %}` por {% endraw %} + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% block content %} +{% endblock %} ``` -Básicamente remplazamos todo entre `{% for post in posts %}{% endfor %}` con: +Pero ¿por qué? ¡Acabas de crear un bloque! Hemos usado la etiqueta de plantilla `{% block %}` para crear un área en la que se insertará HTML. Ese HTML vendrá de otra plantilla que extiende esta (`base.html`). Enseguida te enseñamos cómo se hace. + +Ahora guarda `base.html` y abre `blog/templates/blog/post_list.html` de nuevo en el editor. {% raw %}Quita todo lo que hay encima de `{% for post in posts %}` y por debajo de `{% endfor %}`. Cuando termines, el archivo tendrá este aspecto:{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} -``` html - {% block content %} - {% endblock %} +```html +{% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} ``` -¿Qué significa esto? Acabas de crear un `block`, una template tag que te permite insertar HTML en este bloque en otras plantillas que extiendan a `base.html`. Te mostraremos como hacer esto en un momento. +Queremos utilizar esto como parte de nuestra plantilla en los bloques de contenido. ¡Es hora de añadir etiquetas de bloque en este archivo! + +{% raw %}Tu etiqueta de bloque debe ser la misma que la etiqueta del archivo `base.html`. También querrás que incluya todo el código que va en los bloques de contenido. Para ello, pon todo entre `{% block content %}` y `{% endblock %}`. Algo como esto:{% endraw %} -Ahora guárdalo y abre tu archivo `blog/templates/blog/post_list.html` de nuevo. Elimina todo lo que no esté dentro del body y luego elimina también ``, de forma que tu archivo se verá asi: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} -``` html +```html +{% block content %} {% for post in posts %}
{{ post.published_date }}
-

{{ post.title }}

+

{{ post.title }}

{{ post.text|linebreaksbr }}

{% endfor %} +{% endblock %} ``` -Y ahora agrega esta línea al inicio del archivo: -``` - {% extends 'blog/base.html' %} -``` +Solo falta una cosa. Tenemos que conectar estas dos plantillas. ¡Esto es lo que significa extender plantillas! Para eso tenemos que añadir una etiqueta "extends" al comienzo del archivo. Así: -Significa que ahora estamos extendiendo de la plantilla `base.html` en `post_list.html`. Sólo nos falta una cosa: poner todo (excepto la línea que acabamos de agregar) entre `{% block content %}` y `{% endblock content %}`. Como esto: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} -``` html - {% extends 'blog/base.html' %} - - {% block content %} - {% for post in posts %} -
-
- {{ post.published_date }} -
-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

+```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }}
- {% endfor %} - {% endblock content %} +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} ``` -¡Eso es todo! Verifica que tu sitio web aún funcione apropiadamente :) +¡Y ya está! Guarda el fichero y comprueba que el sitio web sigue funcionando como antes. :) -> Si tienes un error `TemplateDoesNotExists` que diga que no hay un archivo `blog/base.html` y tienes `runserver` ejecutándose en la consola, intenta pararlo (presionando Ctrl+C - las teclas Control y C juntas) y reinicialo ejecutando el comando `python manage.py runserver`. +> Si te sale el error `TemplateDoesNotExist`, que significa que no hay ningún archivo `blog/base.html` y tienes `runserver` corriendo en la consola. Intenta pararlo, pulsando Ctrl+C (teclas Control y C a la vez) en la consola y reiniciarlo con el comando `python manage.py runserver`. \ No newline at end of file diff --git a/es/whats_next/README.md b/es/whats_next/README.md index 87742cd4c78..53a1d3cc887 100755 --- a/es/whats_next/README.md +++ b/es/whats_next/README.md @@ -1,40 +1,42 @@ -# ¿Qué sigue? +# ¿Y ahora qué? -¡Date muchas felicitaciones! **¡Eres increíble!**. ¡Estamos orgullosos! <3 +Date muchas felicitaciones. **¡Eres increíble!** ¡Estamos orgullosas! <3 ### ¿Qué hacer ahora? -Toma un descanso y relájate. Acabas de hacer algo realmente grande. +Toma un descanso y ¡relájate!. Acabas de hacer algo realmente grande. -Después de eso, asegúrate de: +Después de eso, asegúrate de seguir a Django Girls en [Facebook](http://facebook.com/djangogirls) o [Twitter](https://twitter.com/djangogirls) para estar al día. -* Seguir a Django Girls en [Facebook][1] o [Twitter][2] para estar al día +### ¿Me puedes recomendar recursos adicionales? - [1]: http://facebook.com/djangogirls - [2]: https://twitter.com/djangogirls +¡ Sí! Hay un *montón* de recursos en línea para el aprendizaje de todas las clases de habilidades en programación – puede ser algo intimidante donde ir, pero lo tenemos cubierto. Cualquiera que fueran tus intereses antes de que vinieras a Django Girls, y los intereses que hayas desarrollado a lo largo del tutorial, aquí hay algunos recursos gratuitos (o recursos con grandes componentes libres) que puedes utilizar para llegar hasta donde quieras. -### ¿Me puedes recomendar recursos adicionales? +#### Django + +- En nuestro libro [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org/) +- [El tutorial oficial de Django](https://docs.djangoproject.com/en/2.2/intro/tutorial01/) +- [Comienza a usar las lecciones en vídeo de Django](http://www.gettingstartedwithdjango.com/) + +#### HTML, CSS y JavaScript + +- [El curso de desarrollo web de Codeacademy](https://www.codecademy.com/learn/paths/web-development) +- [FreeCodeCamp](https://www.freecodecamp.org/) + +#### Python + +- [El curso de Python en Codeacademy](https://www.codecademy.com/learn/learn-python) +- [Curso de Python de Google](https://developers.google.com/edu/python/) +- [Learn Python The Hard Way book](http://learnpythonthehardway.org/book/) – Los primeros ejercicios son gratuitos +- [Nuevos tutoriales de Coder](http://newcoder.io/tutorials/) - esta es una variedad de ejemplos prácticos de cómo puedes usar Python +- [edX](https://www.edx.org/course?search_query=python) – puedes auditar la mayoría de los cursos gratis, pero si deseas un certificado o créditos para una calificación de educación superior, entonces eso costará dinero +- [La especialización Python en Coursera](https://www.coursera.org/specializations/python) – algunas videoconferencias pueden ser auditadas gratuitamente y puedes ganar un certificado de Coursera tomando estos cursos +- [Python for Everybody](https://www.py4e.com/) - una versión libre y abierta de la especialización de Python en Coursera + +#### Trabajar con datos + +- [Curso de ciencia de datos de Codecademy](https://www.codecademy.com/learn/paths/data-science) +- [edX](https://www.edx.org/course/?search_query=python&subject=Data%20Analysis%20%26%20Statistics) – puedes auditar la mayoría de los cursos gratis, pero si desea un certificado o créditos para una calificación de educación superior, entonces eso costará dinero +- [Dataquest](https://www.dataquest.io/) – las primeras 30 "misiones" son gratuitas -¡Sí! En primer lugar, sigue adelante y prueba nuestro libro llamado [Django Girls Tutorial: Extensiones][3]. - - [3]: http://djangogirls.gitbooks.io/django-girls-tutorial-extensions/ - -Más adelante, puedes intentar los recursos listados a continuación. ¡Son todos muy recomendables! - -- [Django's official tutorial][4] -- [New Coder tutorials][5] -- [Code Academy Python course][6] -- [Code Academy HTML & CSS course][7] -- [Django Carrots tutorial][8] -- [Learn Python The Hard Way book][9] -- [Getting Started With Django video lessons][10] -- [Two Scoops of Django: Best Practices for Django book][11] - - [4]: https://docs.djangoproject.com/en/1.8/intro/tutorial01/ - [5]: http://newcoder.io/tutorials/ - [6]: https://www.codecademy.com/en/tracks/python - [7]: https://www.codecademy.com/tracks/web - [8]: https://github.com/ggcarrots/django-carrots/ - [9]: http://learnpythonthehardway.org/book/ - [10]: http://gettingstartedwithdjango.com/ - [11]: https://twoscoopspress.org/products/two-scoops-of-django-1-6 +¡No podemos esperar para ver lo que construyes a continuación! \ No newline at end of file diff --git a/fa/GLOSSARY.md b/fa/GLOSSARY.md new file mode 100644 index 00000000000..c65a983e6a3 --- /dev/null +++ b/fa/GLOSSARY.md @@ -0,0 +1,3 @@ +# ویرایشگر کد + +ویرایشگر کد یک برنامه کاربردی است که به شما امکان می دهد کد خود را ذخیره کنید تا بتوانید بعدا به آن بازگردید. شما می توانید در [بخش ویرایشگر کد](./code_editor/README.md) یاد بگیرید که چطور یکی از آن‌ها را دانلود کنید \ No newline at end of file diff --git a/fa/README.md b/fa/README.md new file mode 100644 index 00000000000..4c69142bfbc --- /dev/null +++ b/fa/README.md @@ -0,0 +1,51 @@ +# جنگو برای دختران + +[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial) + +> این کار تحت مجوز Creative Commons Attribution-Share Alike 4.0 مجاز است. برای مشاهده یک نسخه از این مجوز، بهhttps://creativecommons.org/licenses/by-sa/4.0/ مراجعه کنید + +## خوش آمدید + +به دوره آموزشی دختران جنگو خوش آمدید! خوشحال هستیم که شما را اینحا می‌بینیم. :) در این آموزش، شما را به سفری به پشت صحنه تکنولوژی‌های وب خواهیم برد و نگاهی اجمالی می‌اندازیم به تمام بخش‌های بزرگ و کوچکی که کنار هم قرار می‌گیرند تا وب، آن طور که می‌شناسیمش، کار کند. + +مثل تمام کارهای ناشناخته دیگر، این کار نیز یک ماجراجویی خواهد بود. اما نگران نباشید، چرا که شهامت اینجا بودن را داشته‌اید، همه چیز خوب پیش خواهد رفت. :) + +## معرفی + +آیا تا به حال احساس کرده اید دنیا هر روز بیشتر و بیشتر پیرامون تکنولوژی می‌گذرد که شما (هنوز) با آن ارتباط برقرار نمی‌کنید؟ آیا شده به ساختن یک وبسایت فکر کنید ولی انگیزه کافی را برای شروع اش نداشته باشید؟ آیا تا به حال به این فکر کرده‌اید که دنیای نرم‌افزار برای آنکه شما وارد آن بشوید، بیش از حد پیچیده است؟ + +ما خبرهای خوبی برای شما داریم. برنامه نویسی آن قدر که به نظر می‌رسد سخت نیست و می‌خواهیم نشان دهیم که حتی میتواند جالب هم باشد. + +این آموزش شما را به طرز جادویی تبدیل به برنامه نویس نخواهد کرد. اگر بخواهید برنامه نویس خوبی شوید، باید ماه‌ها و یا حتی سال‌ها برایش وقت بگذارید. ولی ما می‌خواهیم نشان دهیم که برنامه نویسی یا ساختن وبسایت آنقدرها که به نظر می‌رسد پیچیده نیست. سعی ما این است که قدم به قدم و جز به جز جلو برویم، تا زیاد گیج نشوید. + +امیدواریم بتوانیم کاری کنیم که شما هم به اندازه ما از تکنولوژی خوشتان بیاید! + +## در این آموزش چه چیزی یاد خواهید گرفت؟ + +وقتی این برنامه آموزشی را تمام کنید، یک برنامه وب که کار می‌کند یعنی وبلاگ خودتان را خواهید داشت. به شما نشان خواهیم داد چه طور آن را روی اینترنت بگذارید تا بقیه کارتان را ببینند! + +کمابیش شبیه این خواهد شد: + +![تصویر 0.1](images/application.png) + +> اگر خودتان به تنهایی با این آموزش کار می‌کنید و مربی ندارید تا به شما کمک کند، در صورت بروز هر مشکلی ما یک سیستم چت برای شما داریم: [![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial). ما از مربی‌ها و شرکت کنندگان قبلی خود خواسته ایم تا هر چند وقت یکبار اینجا باشند و به بقیه کمک کنند! از پرسیدن سوال هایتان نترسید! + +خوب،[ بیایید از ابتدا شروع کنیم... ](./how_the_internet_works/README.md) + +## دنبال کردن آموزش در منزل + +فوق‌العاده خواهد بود که در یکی از کارگاه‌های دختران جنگو شرکت کنید، اما می‌دانیم که امکان شرکت همیشه فراهم نیست. به همین دلیل است که شما را تشویق می کنیم که در خانه از این آموزش استفاده کنید. برای خوانندگان در منزل، ما در حال تهیه ویدئوهایی هستیم که دنبال کردن آموزش به تنهایی را آسان‌‌تر می‌سازد. هنوز کامل نشده‌است، اما چیزهای بیشتر و بیشتری به زودی در کانال یوتیوب [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed) قرار خواهد گرفت. + +در هر فصل که قبلاً پوشش داده شده است، یک لینک وجود دارد که به ویدیو صحیح اشاره می‌کند. + +## مشارکت در توسعه + +این آموزش توسط [DjangoGirls](https://djangogirls.org/) نگهداری می‌شود. در صورتی که مشکلی در این آموزش می‌بینید یا می‌خواهید آن را بروز رسانی کنید [لطفاً دستورالعمل‌های مرتبط را انجام دهید](https://github.com/DjangoGirls/tutorial/blob/master/README.md). + +## آیا می‌خواهید به ما در ترجمه این دوره به زبان‌های دیگر، کمک کنید؟ + +در حال حاضر، ترجمه بر روی بستر crowdin.com نگهداری می‌شود: + +https://crowdin.com/project/django-girls-tutorial + +اگر زبان شما در [crowdin](https://crowdin.com/) لیست نشده است، [یک issue جدید](https://github.com/DjangoGirls/tutorial/issues/new) باز کنید و در مورد این زبان به ما اطلاع دهید تا ما بتوانیم آن را اضافه کنیم. \ No newline at end of file diff --git a/fa/SUMMARY.md b/fa/SUMMARY.md new file mode 100644 index 00000000000..e91eb48cbea --- /dev/null +++ b/fa/SUMMARY.md @@ -0,0 +1,35 @@ +# چکیده + +* [معرفی](README.md) +* [نصب و راه‌اندازی](installation/README.md) + * [خط فرمان](installation/README.md#command-line) + * [پایتون](installation/README.md#python) + * [ویرایشگر کد](installation/README.md#code-editor) + * [محیط مجازی](installation/README.md#virtualenv) + * [جنگو](installation/README.md#django) + * [گیت](installation/README.md#git) + * [GitHub](installation/README.md#github-account) + * [PythonAnywhere](installation/README.md#pythonanywhere-account) +* [نصب و راه اندازی (کروم بوک)](chromebook_setup/README.md) +* [اینترنت چگونه کار می‌کند](how_the_internet_works/README.md) +* [آشنایی با خط فرمان](intro_to_command_line/README.md) +* [نصب و راه اندازی پایتون](python_installation/README.md) +* [ویرایشگر کد](code_editor/README.md) +* [آشنایی با پایتون](python_introduction/README.md) +* [جنگو چیست?](django/README.md) +* [نصب و راه اندازی جنگو](django_installation/README.md) +* [اولین پروژه جنگو شما!](django_start_project/README.md) +* [مدل در جنگو](django_models/README.md) +* [پنل مدیریت در جنگو](django_admin/README.md) +* [فاز دیپلوی!](deploy/README.md) +* [URL ها در جنگو](django_urls/README.md) +* [ساخت view در جنگو!](django_views/README.md) +* [آشنایی با HTML](html/README.md) +* [ORM در جنگو](django_orm/README.md) +* [داده های پویا در templates](dynamic_data_in_templates/README.md) +* [templates در جنگو](django_templates/README.md) +* [CSS - آن را زیبا کنید](css/README.md) +* [توسعه template](template_extending/README.md) +* [برنامه خود را توسعه دهید](extend_your_application/README.md) +* [فرم در جنگو](django_forms/README.md) +* [گام بعدی چیست؟](whats_next/README.md) \ No newline at end of file diff --git a/fa/chromebook_setup/README.md b/fa/chromebook_setup/README.md new file mode 100644 index 00000000000..73d2075a168 --- /dev/null +++ b/fa/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# نصب Chromebook + +> **نکته** اگر الان در حال گذراندن [مراحل نصب](../installation/README.md) هستید، لازم نیست مجددا این مراحل را انجام دهید و می‌توانید مستقیماً به بخش [آشنایی با پایتون](../python_introduction/README.md) بروید. + +{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/fa/chromebook_setup/instructions.md b/fa/chromebook_setup/instructions.md new file mode 100644 index 00000000000..43acffe4657 --- /dev/null +++ b/fa/chromebook_setup/instructions.md @@ -0,0 +1,158 @@ +اگر از Chromebook استفاده نمی‌کنید می‌توانید [از این بخش ](http://tutorial.djangogirls.org/en/installation/#install-python) عبور کنید. اگر از آن استفاده می‌کنید تجربه نصب شما کمی متفاوت خواهد بود. شما می توانید بقیه دستورالعمل نصب را نادیده بگیرید. + +### IDE ابری (PaizaCloud Cloud IDE, AWS Cloud9 و Glitch.com) + +IDE ابری ابزاری است که به شما دسترسی به یک ویرایشگر کد و یک کامپیوتر در حال کار کردن روی اینترنت را می‌دهد که می‌توانید نصب، نوشتن و اجرای برنامه‌ها را در آن انجام دهید. در زمان این آموزش، IDE ابری به عنوان * دستگاه محلی شما * عمل خواهد کرد. شما همچنان مانند سایر همکلاسی‌ها که از macOS، اوبونتو یا ویندوز استفاده می‌کنند، دستورات را در ترمینال اجرا خواهید کرد اما ترمینال شما به کامپیوتری که IDE ابری برای شما آماده کرده متصل است. در اینحا دستورالعمل استفاده از IDE های ابری ( PaizaCloud Cloud IDE، AWS Cloud9 و Glitch.com) را خواهید دید. شما می‌توانید یکی از IDE های ابری را انتخاب کنید و دستورالعمل را دنبال کنید. + +#### IDE ابری PiazaCloud + +1. به [PaizaCloud Cloud IDE](https://paiza.cloud/) بروید +2. یک حساب کاربری بسازید +3. بر روی *New Server* کلیک کنید و گزینه Django app را انتخاب کنید +4. دکمه Terminal را (در سمت چپ صفحه) بزنید + +حالا شما باید صفحه ای با یک ستون کناری و کلیدهایی در سمت چپ ببینید. بر روی دکمه "Terminal" کلیک کنید تا پنجره ترمینال با پیغامی شبیه به این باز شود: + +{% filename %}Terminal{% endfilename %} + + $ + + +ترمینال در IDE ابری PiazaCloud برای دستورات شما آماده شده است. شما می‌توانید اندازه این پنجره را تغییر دهید تا کمی بزرگتر دیده شود. + +#### AWS Cloud9 + +در حال حاضر برای استفاده از Cloud 9 باید با اکانت AWS ثبت نام کنید و مشخصات کارت اعتباری را نیز وارد کنید. + +1. Cloud 9 را از [Chrome web store](https://chrome.google.com/webstore/detail/cloud9/nbdmccoknlfggadpfkmcpnamfnbkmkcp) نصب کنید +2. به [c9.io](https://c9.io) بروید و بر روی *Get started with AWS Cloud9* کلیک کنید +3. با یک حساب AWS ثبت نام کنید (به اطلاعات کارت اعتباری نیاز است اما می‌توانید به رایگان از آن استفاده کنید) +4. در داشبورد AWS عبارت *Cloud9* را در محل جستجو وارد کنید و کلید جستجو را بزنید +5. در داشبورد Cloud 9 بر روی *Create environment* کلیک کنید +6. نام آن را *django-girls* بگذارید +7. در هنگام انجام تنظیمات، در بخش "Environment Type" گزینه *Create a new instance for environment (EC2)* را و در بخش "Instance type" گزینه *t2.micro* را انتخاب کنید ("Free-tier eligible" را نشان خواهد داد). تنظیمات پیشفرض صرفه جویانه و خوب است و شما هم باقی تنظیمات پیشفرض را نگه دارید. +8. بر روی *Next step* کلیک کنید +9. بر روی *Create environment* کلیک کنید + +حالا باید صفحه‌ای با یک نوار کناری، یک صفحه اصلی بزرگ با مقداری نوشته و یک صفحه کوچک در پایین ببینید که شبیه به این خواهد بود: + +{% filename %}bash{% endfilename %} + + yourusername:~/workspace $ + + +این محدوده پایین، ترمینال شماست. شما می‌توانید از این ترمینال برای فرستادن دستورات به کامپیوتر Cloud 9 استفاده کنید. می‌توانید ابعاد این پنجره را تغییر دهید تا کمی بزرگتر دیده شود. + +#### IDE ابری Glitch.com + +1. به [Glitch.com](https://glitch.com/) بروید +2. یک حساب کاربری (https://glitch.com/signup) بسازید یا از حساب GitHub خود استفاده کنید. (راهنمای استفاده از حساب GitHubرا در زیر ببینید) +3. بر روی *New Project* کلیک کنید و گزینه *hello-webpage* را انتخاب کنید +4. بر روی گزینه کشویی Tools کلیک کنید (در سمت چپ و پایین صفحه)، سپس بر روی دکمه Terminal کلیک کنید تا یک کنسول خط فرمان باز شود: + +{% filename %}Terminal{% endfilename %} + + app@name-of-your-glitch-project:~ + + +هنگامی که از Glitch.com به عنوان ویرایشگر ابری خود استفاده می‌کنید، لازم نیست که یک محیط مجازی بسازید، به جای آن فایل‌های زیر را باید بسازید: + +{% 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 +``` + +وقتی این فایل‌ها ساخته شدند، به Terminal بروید و دستورات زیر را اجرا کنید تا اولین پروژه جنگو شما ساخته شود: + +{% filename %}Terminal{% endfilename %} + + django-admin.py startproject mysite . + refresh + + +برای دیدن جزییات مربوط به پیغام خطا، می‌توانید لاگ عیب‌یابی جنگو را در اپلیکیشن Glitch فعال کنید. به سادگی کد زیر را به انتهای فایل `mysite/settings.py` اضافه کنید. + +{% 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, + }, + }, +} +``` + +این کار یک فایل `debug.log` می‌سازد که جزییات عملیات جنگو و پیغام‌های خطای احتمالی، در آن است، به کمک این فایل عیب‌یابی وب‌سایت بسیار ساده‌تر می‌شود. + +اولین ریستارت پروژه Glitch‌ موفقیت‌آمیز نخواهد بود. (اگر بر روی منوی کشویی `Show` کلیک کنید و سپس `In a New Window` را بزنید، پیغام خطای `DisallowedHost` را دریافت خواهید کرد) در مورد این مرحله نگران نباشید، این آموزش این مشکل را به زودی و پس از به روزرسانی تنظیمات پروژه که در فایل `mysite/settings.py` است، حل خواهد کرد. + +### محیط مجازی + +یک محیط مجازی (Virtual Environment یا 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 + +دوره آموزشی جنگوگرلز شامل بخشی است به نام فاز دیپلوی یا Deployment، که شامل گرفتن و انتقال دادن کدهای وبسایت شما به یک کامپیوتر در دسترس عموم (به نام سرور) است تا سایرین هم بتوانند کار شما را ببینند. + +اگر این دوره آموزشی را بر روی Chromebook که خودش کامپیوتری بر روی اینترنت است (در مقابل لپ تاپ‌های معمولی که کامپیوتری محلی محسوب می‌شوند)، انجام می‌دهید این بخش کمی عجیب خواهد بود. با این‌حال، استفاده از Cloud 9 به عنوان یک محیط کاری برای کارهای در جریان و استفاده از Python Anywhere به عنوان یک فضای معرفی و نمایش پروژه هایی که در طول زمان کامل می‌شوند، مفید است. + +بنابراین یک حساب کاربری جدید در [www.pythonanywhere.com](https://www.pythonanywhere.com) بسازید. \ No newline at end of file diff --git a/fa/code_editor/README.md b/fa/code_editor/README.md new file mode 100644 index 00000000000..90c36a2806f --- /dev/null +++ b/fa/code_editor/README.md @@ -0,0 +1,11 @@ +# ویرایشگر کد + +> برای خوانندگان در خانه: این فصل در ویدئو [نصب پایتون و ویرایشگر کد](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s) توضیح داده شده است. + +به نوشتن اولین خط کدتان نزدیک می‌شوید، زمان مناسبی برای دانلود یک ویرایشگر کد است! + +> **نکته** اگر از Chromebook استفاده میکنید، این فصل را رد کنید و مطمئن شوید که دستورالعمل [نصب Chromebook](../chromebook_setup/README.md) را دنبال کنید. IDE ابری که شما انتخاب کرده‌اید (PaizaCloud Cloud IDE یا AWS Cloud9) شامل یک ویرایشگر کد هم هست و هنگامی که یک فایل را در IDE خودتان باز می‌کنید به صورت اتوماتیک از ویرایشگر استفاده می‌کنید. +> +> **نکته** ممکن است این بخش را قبل‌تر در بخش [نصب و راه‌اندازی](../installation/README.md) انجام داده باشید، در این صورت مستقیم به بخش بعد بروید! + +{% include "/code_editor/instructions.md" %} \ No newline at end of file diff --git a/fa/code_editor/instructions.md b/fa/code_editor/instructions.md new file mode 100644 index 00000000000..e6146e6516e --- /dev/null +++ b/fa/code_editor/instructions.md @@ -0,0 +1,37 @@ +ویرایشگرهای مختلف زیادی وجود دارد که این امر به سلیقه شخصی برمی‌گردد. اغلب برنامه‌نویسان پایتون از محیط‌های توسعه یکپارچه (IDE, Integrated Development Environments) بسیار قدرتمند مثل PyCharm استفاده می‌کنند. اما برای یک مبتدی احتمالا خیلی مناسب نیست. پیشنهادهای ما به همان اندازه قدرتمند، اما بسیار ساده‌تر هستند. + +ما موارد زیر را پیشنهاد می‌کنیم، اما می‌توانید از مربی خود، ترجیحش را بپرسید. راحت‌تر است از مربی کمک بگیرید. + +## Visual Studio Code + +Visual Studio Code یک ویرایشگر کد است که توسط مایکروسافت توسعه داده شده و برای ویندوز، لینوکس و macOS موجود است. این ویرایشگر قابلیت عیب یابی، کنترل Git از داخل نرم افزار، برجسته سازی دستورات، سیستم هوشمند کامل کردن دستورات، سیستم snippets (جلوگیری از نوشتن بخش‌های تکراری در کدها) و بازنویسی کدها است. + +[از اینجا دانلود کنید](https://code.visualstudio.com/) + +## Gedit + +Gedit یک نرم افزار آزاد و یک ویرایشگر رایگان است که برای تمام سیستم عامل‌ها موجود است. + +[از اینجا دانلود کنید](https://wiki.gnome.org/Apps/Gedit#Download) + +## Sublime Text + +Sublime Text یک ویرایشگر بسیار رایج است که یک دوره آزمایشی رایگان دارد و برای تمام سیستم عامل‌ها موجود است. + +[جهت دانلود کلیک نمایید](https://www.sublimetext.com/) + +## Atom + +Atom نیز یک ویرایشگر رایج دیگر است که نرم افزاری رایگان و آزاد است و برای ویندوز، لینوکس وmacOS موجود است. Atom توسط [GitHub](https://github.com/) توسعه داده شده است. + +[از اینجا دانلود کنید](https://atom.io/) + +## چرا ویرایشگر متن نصب می‌کنیم؟ + +ممکن است فکر کنید که چرا به جای استفاده از برنامه‌ای مثل Word یا Notepad، این نرم‌افزار خاص ویرایش کد را نصب می‌کنم. + +دلیل اول این است که کدها نیاز دارند که به صورت متن ساده (**plain text**) باشند و مشکل برنامه‌هایی مثل Word یا Textedit این است که متن ساده تولید نمی‌کنند، بلکه متنی غنی (با فونت و قالب‌بندی) می‌سازند و از قالب‌های سفارشی مثل [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format) استفاده می‌کنند. + +دلیل دوم این است که ویرایشگرهای متن به طور خاص برای ویرایش کد ساخته شده‌اند. بنابراین، امکاناتی مثل رنگ‌آمیزی کدها بر اساس معنایشان یا بستن خودکار نقل قول‌ها را دارند. + +همه این‌ها را بعداً در عمل خواهیم دید. به زودی، شما به ویرایشگر کد خود به عنوان یکی از ابزارهای محبوبتان نگاه خواهید کرد. :) diff --git a/fa/css/README.md b/fa/css/README.md new file mode 100644 index 00000000000..074ed7e7d6f --- /dev/null +++ b/fa/css/README.md @@ -0,0 +1,325 @@ +# CSS - زیبایش کن! + +بلاگ ما هنوز خیلی زشت است، نه؟ وقتش است که زیبایش کنیم. برای این کار از CSS استفاده می‌کنیم. + +## CSS چیست؟ + +CSS یا (Cascading Style Sheets) زبان مورد استفاده برای توصیف ظاهر و قالب‌بندی یک وب سایت نوشته شده در زبان نشانه گذاری، (مانند HTML) است. از آن به عنوان آرایش برای صفحه وب خود استفاده می‌کنیم. ؛) + +اما ما نمی‌خواهیم دوباره از ابتدا شروع کنیم، درست است؟ یک بار دیگر، ما از چیزی که برنامه‌نویسان در اینترنت به صورت رایگان منتشر کرده‌اند استفاده می‌کنیم. همانطور که می‌دانید اختراع دوباره چرخ جالب نیست. + +## با بوت‌ استرپ شروع کنیم! + +بوت استرپ یکی از محبوب‌ترین چارچوب‌های HTML و CSS برای توسعه وب سایت‌های زیبا است: https://getbootstrap.com/ + +توسط برنامه نویسانی که در توییتر کار می کردند نوشته شده بود. در حال حاضر توسط داوطلبانی از سراسر جهان توسعه یافته است! + +## نصب بوت استرپ + +برای نصب بوت استرپ فایل `.html` را در ویرایشگر متن باز کنید و به بخش `` خط‌های زیر را اضافه کنید: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +این کار هیچ فایلی به پروژه شما اضافه نمی‌کند. این کد به فایلی که در اینترنت وجود دارد اشاره می‌کند. بنابراین به پیش بروید وبسایت خود را باز کنید و صفحه را ریفرش کنید. بفرمایید! + +![تصویر 14.1](images/bootstrap1.png) + +ظاهری قشنگ‌تر از قبل! + +## فایل‌های ایستا در جنگو + +در نهایت نگاهی دقیق‌تر به فایل‌هایی بیاندازیم که به آن‌ها فایل ایستا یا ثابت **static files** می‌گوییم. فایل‌های ایستا شامل تمامی فایل‌های CSS و عکس‌ها می‌باشند. محتوای آن‌ها به متن درخواست بستگی ندارد و برای هر کاربر یکسان خواهد بود. + +### فایل‌های ایستا کجای جنگو قرار میگیرند + +جنگو به هرحال می‌داند که فایل‌های ثابت در اپلیکیشن پیش ساخته "admin" کجا قرار گرفته‌اند. حالا ما لازم داریم تا چند فایل ثابت را به اپلیکیشن `blog` خودمان اضافه کنیم. + +ما این کار را با ایجاد یک پوشه به نام `static` در داخل برنامه وبلاگ انجام می‌دهیم: + + djangogirls + ├── blog + │ ├── migrations + │ ├── static + │   └── templates + └── mysite + + +جنگو به طور خودکار هر پوشه‌ای با نام "static" را در پوشه اپلیکیشن‌های شما پیدا خواهد کرد. پس از آن قادر است از محتوای آن‌ها به عنوان فایل ایستا استفاده کند. + +## اولین فایل CSS شما! + +اکنون یک فایل CSS ایجاد کنیم تا سلیقه خود را به صفحه وب تان اضافه کنیم. یک پوشه جدید با نام `css` در داخل پوشه `static` بسازید. سپس در داخل این پوشه `css`، یک فایل جدید با نام `blog.css` ایجاد کنید. آماده شد؟ + + djangogirls + └─── blog + └─── static + └─── css + └─── blog.css + + +حالا وقت کمی CSS نوشتن است! فایل `blog/static/css/blog.css` را در ویرایشگر کد خود باز کنید. + +ما در اینجا، سفارشی سازی و یادگیری CSS را خیلی عمیق بررسی نخواهیم کرد. اگر بخواهید بیشتر در باره CSS بدانید، یک توصیه برای یک دوره رایگان، در پایین این صفحه وجود دارد. + +اما بیایید حداقل کمی به آن بپردازیم. شاید بتوانیم رنگ header هایمان را تغییر دهیم؟ برای درک رنگ‌ها، رایانه‌ها از کدهای ویژه استفاده می‌کنند. این کدها با `#` شروع می‌شوند و به ترتیب شامل 6 حرف (A-F) و اعداد (0-9) هستند. به عنان مثال، کد رنگ آبی `FF0000#` است. شما می‌توانید در آدرس http://www.colorpicker.com:/ کد رنگ بسیاری از رنگ‌ها را پیدا کنید. شما همچنین ممکن است از [رنگ‌های از پیش تعریف شده](http://www.w3schools.com/colors/colors_names.asp) از جمله `قرمز` و `سبز` استفاده کنید. + +در فایل ` blog/static/css/blog.css ` کد زیر را اضافه کنید: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +h1 a, h2 a { + color: #C25100; +} + +``` + +`h1 a` انتخابگر یا selector در یک فایل CSS است. به این معنی که ما درحال تنظیم کردن فرمت هر عنصر `a` هستیم که در داخل یک بخش `h1` باشد. `h2 a` نیز دقیقا مانند همین کار را در بخش `h2` انجام می‌دهد. بنابراین وقتی ما چیزی شبیه یک `

link

` داریم، فرمت `h1 a` اعمال خواهد شد. در این مورد، ما می‌خواهیم رنگ آن را به `#C25100` تغییر دهیم که رنگ نارنجی تیره است. یا اینکه می‌توانید رنگ مورد علاقه خودتان را بگذارید فقط مطمئن باشید با رنگ سفید زمینه، کنتراست کافی داشته باشد! + +در یک فایل CSS،ما فرمت‌ بخش‌های مختلف یک فایل HTML را مشخص می‌کنیم. اولین روش شناسایی هر عنصر یا element، نام عنصر است. ممکن است این عناصر را به عنوان تگ tag از بخش HTML بخاطر داشته باشید. عناصری مانند ` a `، ` h1 `، و `body` همه نمونه‌هایی از نام یک عنصر هستند. ما همچنین عناصر را با ویژگی‌هایی مانند `class` یا `id` نیز شناسایی می‌کنیم. class و id نام‌هایی هستند که شما خودتان به عناصر مختلف نسبت می‌دهید. class ها، گروه‌های عناصر را تعریف می‌کنند و id ها به یک عنصر خاص اشاره می‌کنند. برای مثال، می‌توانید عنصر زیر را با استفاده از نام تگ، یعنی ` a`، نام کلاس ` external_link ` یا به کمک آیدی `link_to_wiki_page ` شناسایی کنید: + +```html + +``` + +شما می‌توانید در این موارد بیشتر بخوانید [CSS Selectors at w3schools](http://www.w3schools.com/cssref/css_selectors.asp). + +ما همچنین باید به قالب HTML خودمان بگوییم که یک فایل CSS اضافه کرده‌ایم. فایل `blog/templates/blog/post_list.html` را در ویرایشگر کد باز کنید و خط زیر را به ابتدای آن اضافه کنید: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% load static %} +``` + +ما فقط فایل‌های ثابت یا static را در اینجا بارگیری می‌کنیم. :) بین برچسب `` و ``، پس از پیوند به فایل‌های بوت استرپ، این خط را اضافه کنید: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +مرورگر فایل‌ها را به ترتیب می‌خواند، بنابراین ما باید مطمئن شویم که این خط در جای مناسب قرار گرفته است. در غیر این صورت کد در فایل شما ممکن است توسط کد در فایل‌های بوت استرپ لغو شود. ما فقط به قالب HTML مان می‌گوییم که فایل CSS کجا قرار دارد. + +اکنون فایل شما باید مانند این باشد: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% load static %} + + + + Django Girls blog + + + + +
+

Django Girls Blog

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

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} + + +``` + +خب، حالا فایل را ذخیره کنید و صفحه را دوباره بارگذاری کنید! + +![تصویر 14.2](images/color2.png) + +کارت خوب بود! شاید بخواهیم کمی حاشیه سمت چپ صفحه وب مان را افزایش دهیم؟ بیایید این را امتحان کنیم! + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +body { padding-left: 15px; } +``` + +این کد را به فایل CSS خود اضافه کنید، و ببینید چگونه کار می‌کند! + +![تصویر 14.3](images/margin2.png) + +شاید ما بتوانیم فونت را در هدر صفحه‌مان سفارشی کنیم؟ این قطعه کد را در بخش `` فایل `blog/templates/blog/post_list.html` وارد کنید: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +همانند قبل ترتیب قرار دادن لینک‌ها را چک کنید و این خط را قبل پیوند به `blog/static/css/blog.css` قرار دهید. این خط، فونتی به نام *Lobster* را از مجموعه فونت‌های گوگل فراخوانی می‌کند (https://www.google.com/fonts). + +در فایل CSS به آدرس `blog/static/css/blog.css`، بخش تعریف عنصر ` h1 a ` را پیدا کنید (قطعه کدی که بین `{` و `}` قرار دارد). حالا خط `font-family: 'Lobster';` را بین آکولادها اضافه کنید و صفحه وب را دوباره بارگیری کنید: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +h1 a, h2 a { color: #C25100; font-family: 'Lobster'; } +``` + +![تصویر 14.3](images/font.png) + +عالی! + +همانطور که در بالا ذکر شد CSS دارای مفهوم کلاس است. کلاس‌ها به شما اجازه می‌دهند تا بخشی از کد HTML را نامگذاری کنید و تنها فرمت این قسمت از کد را تغییر بدهید، بدون اینکه به سایر قسمت‌ها آسیبی برسد. کلاس‌ها می‌توانند فوق‌العاده مفید باشند! شاید شما دو div دارید که کاری متفاوت انجام می دهند (مانند header و post). یک کلاس می‌تواند به شما کمک کند آن‌ها را متفاوت نگاه کنید. + +به همین ترتیب جلو بروید و برخی بخش‌های کد HTML را نام گذاری کنید. بخش `header` را که شامل header وب‌سایت شماست با کد زیر جابجا کنید: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +و اکنون کلاس `post` را به `article` اضافه کنید که حاوی یک پست وبلاگ است. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+``` + +ما اکنون بلوک‌های معرف را به انتخاب‌گرهای مختلف اضافه خواهیم کرد. انتخابگرهایی که با `.` آغاز می‌شوند مربوط به کلاس‌ها هستند. آموزش‌ها و توضیحات بسیار خوبی درباره CSS در اینترنت وجود دارد که می‌تواند به شما در درک کد زیر کمک کند. حالا این قطعه کد را در فایل `blog/static/css/blog.css` کپی کنید: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +.page-header { + 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 { + color: #ffffff; + font-size: 36pt; + text-decoration: none; +} + +h1, +h2, +h3, +h4 { + font-family: 'Lobster', cursive; +} + +.date { + color: #828282; +} + +.save { + float: right; +} + +.post-form textarea, +.post-form input { + width: 100%; +} + +.top-menu, +.top-menu:hover, +.top-menu:visited { + color: #ffffff; + float: right; + font-size: 26pt; + margin-right: 20px; +} + +.post { + margin-bottom: 70px; +} + +.post h2 a, +.post h2 a:visited { + color: #000000; +} + +.post > .date, +.post > .actions { + float: right; +} + +.btn-default, +.btn-default:visited { + color: #C25100; + background: none; + border-color: #C25100; +} + +.btn-default:hover { + color: #FFFFFF; + background-color: #C25100; +} +``` + +سپس کد HTML زیر را که نمایش پست‌ها با اسامی کلاس‌ها را نشان می‌دهد: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} +
+ +

{{ 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 %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
+``` + +این فایل‎‌ها را ذخیره کنید و وبسایت خود را دوباره بارگیری کنید. + +![تصویر 14.4](images/final.png) + +یووهو! به نظر عالی می‌آید، اینطور نیست؟ به کدی که اضافه کردیم نگاه کنید تا محلی که کلاس ها را در HTML اضافه و در CSS استفاده کرده ایم پیدا کنید. اگر بخواهید نوشته تاریخ ها را فیروزه ای رنگ کنید کجا را باید تغییر دهید؟ + +نگران نباشید کمی با این CSS کار کنید و سعی کنید برخی از چیزها را تغییر دهید. بازی با CSS می‌تواند به شما کمک کند که بفهمید هر بخش چگونه کار می‌کند. اگر چیزی را خراب کردید، نگران نباشید، همیشه می‌توانید این تغییرات را به حالت قبل برگردانید! + +ما اکیداً گذراندن دوره‌های آموزشی آنلاین "Basic HTML & HTML5" و "Basic CSS" را در [freeCodeCamp](https://learn.freecodecamp.org/) توصیه می‌کنیم. این دوره‌ها به شما کمک خواهد کرد تا همه چیزهایی که برای زیباتر کردن وبسایت خود با HTML و CSS لازم دارید یاد بگیرید. + +برای فصل بعدی آماده هستید؟! :) \ No newline at end of file diff --git a/fa/css/images/bootstrap1.png b/fa/css/images/bootstrap1.png new file mode 100644 index 00000000000..bd81cd14373 Binary files /dev/null and b/fa/css/images/bootstrap1.png differ diff --git a/fa/css/images/color2.png b/fa/css/images/color2.png new file mode 100644 index 00000000000..3f82e7d3922 Binary files /dev/null and b/fa/css/images/color2.png differ diff --git a/fa/css/images/final.png b/fa/css/images/final.png new file mode 100644 index 00000000000..067c83d36cc Binary files /dev/null and b/fa/css/images/final.png differ diff --git a/fa/css/images/font.png b/fa/css/images/font.png new file mode 100644 index 00000000000..310f9e85f18 Binary files /dev/null and b/fa/css/images/font.png differ diff --git a/fa/css/images/margin2.png b/fa/css/images/margin2.png new file mode 100644 index 00000000000..895828b688d Binary files /dev/null and b/fa/css/images/margin2.png differ diff --git a/fa/deploy/README.md b/fa/deploy/README.md new file mode 100644 index 00000000000..50e56b4341d --- /dev/null +++ b/fa/deploy/README.md @@ -0,0 +1,246 @@ +# مرحله منتشر کردن! + +> **توجه داشته باشید** که قسمت‌های پیش رو ممکن است کمی سخت به نظر برسد. نا امید نشوید و این بخش را تا آخر ادامه دهید، یکی از مهم‌ترین قسمت‌های توسعه وب سایت منتشرکردن یا Deploy می‌باشد. این فصل در وسط آموزش قرار گرفته است، بنابراین مربی شما می‌تواندبه شما در راه اندازی آنلاین وبسایتتان کمک کند. این به این معنی است که شما می‌توانید به تنهایی ادامه‌ی تمرین خود را به اتمام برسانید حتی اگر زمان کارگاه به پایان برسد. + +تا به اینجا وب سایت شما فقط در رایانه شما قابل مشاهده است. حالا شما یاد خواهید گرفت که چگونه آن را دیپلوی کنید! دیپلوی یعنی فرآیند انتشار پروژه شما در اینترنت، تا سایرین بتوانند در نهایت پروژه شما را ببینند. :) + +همانطور که یاد گرفتید، وب سایت باید بر یک سرور جای بگیرد. سرورهای زیادی در اینترنت وجود دارد، ما قصد داریم از [PythonAnywhere](https://www.pythonanywhere.com/) استفاده نماییم. PythonAnywhere برای پروژه‌های کوچک که بازدید‌کنندگان خیلی زیادی ندارند رایگان است بنابراین در حال حاضر برای شما مناسب است. + +سرویس خارجی دیگری که ما استفاده می‌کنیم [گیت هاب](https://www.github.com) است که سرویس میزبانی کد است. سرویس‌های دیگری نیز وجود دارد، اما تقریباً این روزها همه برنامه نویسان اکانت گیت هاب دارند و الان شما هم خواهید داشت! + +این سه مکان برای شما مهم خواهد بود. کامپیوتر محلی شما جایی است که شما در حال توسعه و تست هستید. هنگامی که شما تغییرات را اعمال کردید، یک نسخه از برنامه خود را در گیت هاب قرار می‌دهید. وب سایت شما در PythonAnywhere خواهد بود و شما آن را با یک کپی جدید از کدهای خود که از گیت هاب گرفته‌اید، به روز رسانی خواهید کرد. + +# گیت + +> **نکته** اگر بخش [نصب و راه‌اندازی](../installation/README.md) را انجام داده‌اید، نیازی نیست که دوباره این بخش را انجام دهید. می‌توانید از این بخش رد شده و ساختن مخزن گیت را شروع کنید. + +{% include "/deploy/install_git.md" %} + +## ایجاد مخزن گیت + +نرم افزار گیت تغییرات یک مجموعه فایل که در جایی به نام مخزن (به طور مخفف repo) وجود دارند را ردگیری می‌کند. بیایید یکی برای پروژه خودمان بسازیم. کنسول خود را باز کنید و این دستورات را در پوشه `djangogirls` اجرا کنید: + +> ** توجه ** قبل از شروع به کار موقعیت پوشه‌ای را که در آن هستید با دستور `pwd` (در سیستم عامل macOS / Linux) یا `cd` (در ویندوز) بفهمید. شما باید در پوشه `djangogirls` باشید. + +{% filename %}خط فرمان{% 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 + + +راه اندازی مخزن گیت کاری است که ما برای هر پرژه فقط یک بار انجام می‌دهیم (لازم نیست مجدداً نام کاربری و ایمیل را وارد کنید). + +گیت هاب تغییرات روی تمام فایل‌ها و پوشه های زیرمجموعه این پوشه را پیگیری می‌کند، اما برخی فایل‌هایی که می‌خواهیم آن‌ها را نادیده بگیریم نیز وجود دارند. ما این کار را با ایجاد یک فایل به نام `.gitignore` در پوشه پایه انجام می‌دهیم. ویرایشگر خود را باز کنید و یک فایل جدید با محتویات زیر ایجاد کنید: + +{% 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 + + +و آن را در پوشه "djangogirls" با نام `.gitignore` ذخیره کنید. + +> ** توجه** نقطه در ابتدای نام فایل مهم است! اگر مشکلی در ایجاد آن دارید (به عنوان مثال Mac شما دوست ندارد فایل هایی را بسازید که با نقطه شروع می‌شود)، پس از ویژگی save as استفاده کنید که به کمک آن می‌توانید این نوع فایل‌ها را ذخیره کنید. و مطمئن باشید که هیچ پسوندی مانند `.txt` یا `.py` در انتهای فایل نگذاشته باشید نام این فایل فقط باید `.gitignore` باشد تا توسط Git شناسایی شود. لینوکس و MacOS با فایل‌هایی که با `.` شروع شوند (مانند `.gitignore`) مانند یک فایل مخفی شده برخورد می‌کند و دستور `ls` به طور معمول آن‌ها را نشان نمی‌دهد. به جای آن از دستور `ls -a` برای دیدن فایل `.gitignore` استفاده کنید. +> +> **توجه** یکی از فایل‌هایی که در فایل `.gitignore` مشخص شده است فایل `db.sqlite3` است. این فایل پایگاه داده محلی شماست جایی که تمام اطلاعات مربوط به کاربر و پست‌های وبلاگ شما در آن ذخیره می‌شود. ما از روش استاندارد برنامه نویسی استفاده خواهیم کرد به این معنی که ما از پایگاه داده‌های متفاوتی برای توسعه بر روی کامپیوتر محلی و سپس وبسایت اصلی که روی PythonAnywhere هست استفاده خواهیم کرد. پایگاه داده بر روی PythonAnywhere می‌تواند SQLite باشد همانند آنچه بر روی کامپیوتر خود از آن استفاده می‌کنید اما معمولاً از پایگاه داده MySQL برای وبسایت اصلی استفاده می‌کنیم که می‌تواند تعداد بسیار زیاد بازدیدکننده از سایت را مدیریت کند. علاوه بر این حذف کردن فایل SQLite در کپی مربوط به GitHub به این معنی است که تمام پست‌های وبلاگی و superuser هایی که تا الان ساخته‌اید فقط روی کامپیوتر خودتان مورد استفاده خواهد بود و برای محیط اصلی وبسایت باید دوباره آن‌ها را بسازید. شما باید از پایگاه داده محلی خود به عنوان یک زمین بازی خوب استفاده کنید که در آن می‌توانید چیزهای مختلف را آزمایش کنید و نگرانی پاک کردن پست‌های اصلی از وبلاگ را نداشته باشید. + +ایده خوبی است که همیشه قبل از زدن دستور `git add` یا هر وقت که مطمئن نیستید چه چیزی تغییر کرده، دستور `git status` را بزنید. این کار کمک می‌کند که از هر نوع غافلگیری مانند اضافه کردن یا commit کردن فایل اشتباه، جلوگیری شود. دستور `git status` اطلاعاتی در مورد فایل‌های ردگیری نشده untracked، اصلاح شده modified، استیج شده staged و نیز درمورد وضعیت شاخه ای که در آن هستیم می‌دهد. خروجی باید شبیه به موارد زیر باشد: + +{% filename %}خط فرمان{% endfilename %} + + $ git status + On branch master + + 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) + + +و در نهایت ما تغییرات را ذخیره می‌کنیم. به کنسول خود بروید و این دستورات را اجرا کنید: + +{% filename %}خط فرمان{% 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 + + +## کدهای خود را به GitHub انتقال دهید + +به [GitHub.com](https://www.github.com) بروید و یک حساب کاربری رایگان برای خود بسازید. اگر این کار را در کارگاه برای اولین بار انجام می‌دهید حواستان باشد که رمز عبور خود را حفظ کنید یا به نر‌م‌افزار مدیریت رمز عبور خود بسپرید. + +حالا یک مخزن یا repository بسازید و نام آن را "my-first-blog" بگذارید. گزینه "initialize with a README" را علامت نخورده باقی بگذارید و هم چنین گزینه .gitignore را هم خالی بگذارید (ما بعداً آن را اضافه خواهیم کرد). هم چنین گزینه License را None بگذارید. + +![](images/new_github_repo.png) + +> **توجه** نام `my-first-blog` مهم است. شما می‌توانید اسم دیگری انتخاب کنید اما از این اسم زیاد استفاده خواهیم کرد و به یاد داشته باشید که اگر اسم دیگری گذاشتید هرجا لازم بود اسم انتخابی خود را استفاده کنید. احتمالاً راحت‌تر است که از همین اسم `my-first-blog` استفاده نمایید. + +در صفحه بعد شما URL مخزن خود را خواهید دید که در برخی دستورات بعدی از آن استفاده خواهیم کرد: + +![](images/github_get_repo_url_screenshot.png) + +حالا وقت آن است که مخزن Git روی کامپیوتر شما را به مخزن موجود در Github وصل کنیم. + +خط زیر را در کنسول خود تایپ کنید (`` را با نام کاربری و گذر واژه خود که در GitHub تعریف کرده اید عوض کنید. علامت‌های کوچکتر و بزرگتر را استفاده نکنید. URL باید دقیقاً همان آدرسی باشد که کمی قبل‌تر دیده‌اید): + +{% filename %}خط فرمان{% endfilename %} + + $ git remote add origin https://github.com//my-first-blog.git + $ git push -u origin master + + +وقتی شما فایلی را به GitHub می‌فرستید یا push می‌کنید نام کاربری و گذرواژه از شما پرسیده می‌شود (ممکن است در همان کنسول خط فرمان یا در یک پنجره جدید از شما پرسیده شود) پس از وارد کردن اطلاعات ورود، چیزی شبیه به این خواهید دید: + +{% filename %}خط فرمان{% endfilename %} + + 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/ola/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)، دوره آموزشی [Django Girls](https://github.com/DjangoGirls/tutorial) و بسیاری نرم‌افزارهای متن باز فوق العاده دیگر هم، کدهایشان را در GitHub قرار داده‌اند. :) + +# تنظیم کردن وبلاگ بر روی PythonAnywhere + +## یک حساب کاربری بر روی PythonAnywhere بسازید + +> **توجه** شما ممکن است کمی قبل‌تر و در مراحل نصب یک حساب کاربری در PythonAnywhere درست کرده باشید. اگر چنین است نیاز نیست که حساب کاربری دیگری بسازید. + +{% include "/deploy/signup_pythonanywhere.md" %} + +## وبسایت‌مان را بر روی PythonAnywhere تنظیم کنیم + +با کلیک کردن بر روی لوگو و انتخاب گزینه شروع یک کنسول "Bash" به [داشبورد PythonAnywhere ](https://www.pythonanywhere.com/) بروید. این محیط خط فرمان مخصوص PythonAnywhere است، شبیه آنچه در کامپیوتر خود دارید. + +![بخش 'New Console' در صفحه وبسایت PythonAnywhere با دکمه‌ای برای 'bash'](images/pythonanywhere_bash_console.png) + +> **توجه** PythonAnywhere بر مبنای لینوکس است، بنابراین اگر روی ویندوز کار می‌کنید این محیط خط فرمان با آنچه در ویندوز دارید کمی متفاوت است. + +منتشر کردن یک اپلیکیشن تحت وب بر روی PythonAnywhere شامل آوردن کدها از GitHub و تنظیم کردن PythonAnywhere برای تشخیص آن و اجرا کردنش به عنوان یک برنامه تحت وب است. روش‌های غیرخودکار برای این کار وجود دارد اما PythonAnywhere یک ابزار کمکی دارد که همه این کارها را برای شما انجام می‌دهد. اجازه بدهید اول از همه این ابزار را نصب کنیم: + +{% filename %}خط فرمان PythonAnywhere {% endfilename %} + + $ pip install --user pythonanywhere + + +این دستور باید چیزهایی شبیه به `Collecting pythonanywhere` بر روی صفحه نشان دهد و در انتها نیز این پیغام `Successfully installed (...) pythonanywhere- (...)` نمایش داده خواهد شد. + +حالا ما برنامه کمکی را اجرا می‌کنیم تا به طور اتوماتیک برنامه ما را از GitHub بخواند. خطوط زیر را در کنسول PythonAnywhere بنویسید (فراموش نکنید که نام کاربری GitHub را به جای `` بنویسید در نتیجه URL شما مانند URL اختصاصی شما در GitHub میشود): + +{% filename %}خط فرمان PythonAnywhere {% endfilename %} + + $ pa_autoconfigure_django.py --python=3.10 https://github.com//my-first-blog.git + + +همینطور که به اجراشدن آن نگاه می‌کنید می‌توانید بفهمید که چه کاری انجام می‌دهد: + +- دانلود کردن کد شما از GitHub +- ساختن یک محیط مجازی virtualenv بر روی PythonAnywhere شبیه آنچه که بر روی کامپیوتر خود داشتید +- به روزرسانی برخی از تنظیمات شما با تنظیمات مورد نیاز برای انتشار +- تنظیم کردن یک دیتابیس در PythonAnywhere با استفاده از دستور `manage.py migrate` +- تنظیم کردن فایل‌های ثابت شما (بعداً درمورد آن‌ها یاد خواهیم گرفت) +- و در نهایت تنظیم کردن PythonAnywhere برای ارائه اپلیکیشن شما از طریق API خودش + +در PythonAnywhere تمام این مراحل اتوماتیک انجام می‌شود اما برای سایر سرورها شما باید دقیقا تمام این اقدامات را انجام دهید. + +مهم‌ترین چیزی که اینجا باید به آن توجه کنید آن است که پایگاه داده شما در اینجا از چیزی که بر روی کامپیوتر خود دارید کاملا مستقل است در نتیجه ممکن است اینجا حساب کاربری ادمین یا پست‌های متفاوتی نسبت به کامپیوتر شخصی خود داشته باشید. در نتیجه همان طور که بر روی کامپیوتر خودمان انجام داده ایم باید یک کاربر admin با دستور `createsuperuser` بسازیم. PythonAnywhere به صورت اتوماتیک محیط مجازی یا virtulenv شما را فعال کرده است درنتیجه تنها چیزی که لازم دارید این است که خط زیر را اجرا کنید: + +{% filename %}خط فرمان Python Anywhere{% endfilename %} + + (ola.pythonanywhere.com) $ python manage.py createsuperuser + + +مشخصات کاربر ادمین را وارد کنید. می‌توانید این اطلاعات را شبیه اطلاعات ادمین که قبلاً در کامپیوتر خود زده‌اید در نظر بگیرید مگر اینکه بخواهید گذره واژه امن‌تری در PythonAnywhere در نظر بگیرید. + +حالا اگر بخواهید می‌‌توانید نگاهی به کدهای خود در PythonAnywhere بیندازید دستور `ls` را بزنید: + +{% filename %}خط فرمان PythonAnywhere{% 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.pytests.py static + templates views.py + + +علاوه بر این می‌توانید به صفحه File بروید و به کمک مرورگر فایل پیش‌ساخته که در PythonAnywhere قرار داده شده به فایل‌های خود نگاهی بیاندازید. از صفحه کنسول و به کمک کلید منو در گوشه بالا و سمت راست، می توانید به سایر صفحات PythonAnywhere بروید. وقتی شما در یک صفحه هستید، نزدیک به بالای صفحه، لینک‌هایی به سایر صفحات وجود دارد. + +## اکنون آنلاین هستید! + +وب‌سایت شما باید الان به طور عمومی در اینترنت منتشر شده باشد! از طریق صفحه "Web" در PythonAnywhere لینک به این صفحه را پیدا کنید. شما می‌توانید این صفحه را با هر کسی به اشتراک بگذارید. :) + +> **توجه** این یک تمرین ابتدایی است و ما در هنگام انتشار، برخی میانبرهایی را استفاده کرده‌ایم که از جنبه امنیت وبسایت، روش‌های ایده‌آلی نیستند. هرگاه تصمیم گرفتید که این پروژه یا پروژه دیگری را بسازید، باید به راهنمایی‌های امنیتی موجود در [چک لیست انتشار جنگو](https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/) نگاهی بیندازید. + +## نکات عیب‌یابی + +اگر شما با خطایی در هنگام اجرا کردن دستور `pa_autoconfigure_django.py` مواجه شدید ممکن است به دلایل زیر باشد: + +- فراموشی در ساخت توکن API در PythonAnywhere. +- اشتباه در URL مربوط به GitHub +- اگر خطایی با این مضمون *"Could not find your settings.py"* مشاهده کردید، احتمالاً تمام فایل‌های خود را به Git اضافه نکرده‌اید یا همه آن‌ها را (به کمک دستور push) به GitHub نفرستاده‌اید. به بخش Git در بالا نگاهی دوباره بیندازید +- اگر قبلاً حساب کاربری در PythonAnywhere داشته‌اید و خطای collectstatic دریافت می‌کنید احتمالاً نسخه‌های قدیمی‌تر SQLite (مثلاً 3.8.2) را در حساب کاربری خود دارید. در این موارد، یک حساب کاربری جدید بسازید و دستورات مربوط به PythonAnywhere را دوباره بزنید. + +اگر هنگام مراجعه به وبسایت خطایی مشاهده کردید اولین جا برای بررسی و عیب یابی نگاه کردن به بخش **error log** است. حتماً در صفحه ["Web"](https://www.pythonanywhere.com/web_app_setup/) در PythonAnywhere لینکی به این بخش پیدا خواهید کرد. نگاه کنید که آیا پیغام خطایی در این صفحه وجود دارد؛ آخرین پیغام‌ها در پایین‌ترین خط ها است. + +علاوه بر این دستورالعمل‌های عیب‌یابی عمومی‌تری هم در [صفحه راهنمای سایت PythonAnywhere](http://help.pythonanywhere.com/pages/DebuggingImportError) وجود دارد. + +و به یاد داشته باشید که مربی شما اینجاست تا به شما کمک کند! + +# وبسایت خود را بررسی کنید! + +صفحه اصلی سایت شما باید "It worked" را نشان دهد همانطور که بر روی کامپیوتر خودتان کار می‌کرد. سعی کنید ` /admin/ ` را به انتهای آدرس اینترنتی اضافه کنید و به سایت مدیریت برسید. با نام کاربری و گذرواژه خود وارد شوید خواهید دید که می‌توانید پست جدیدی ایجاد کنید. به یاد داشته باشید که پست‌هایی که در پایگاه داده کامپیوتر خود ایجاد کرده اید بر روی وبسایت آنلاین شما منتقل نشده است. + +وقتی چند پست جدید ایجاد کردید به تنظیمات بر روی کامپیوتر خود (local و نه تنظیمات روی PythonAnywhere) برگردید. از اینجا می‌توانید تنظیمات محلی را تغییر دهید. این یک روش رایج در توسعه وبسایت است؛ تغییرات را روی کامپیوتر خود اعمال کنید، آن‌ها را به GitHub بفرستید و سپس این تغییرات را از گیتهاب، بر روی وب سرور کپی کنید. این روش کمک می‌کند که بدون ایجاد خرابی در وبسایت آنلاین بتوان آن را به روز رسانی کرد. جالب نیست؟ + +یک *خسته نباشید* حسابی به خودتان بگویید! راه اندازی سرور یکی از مهارتی‌ترین بخش‌های توسعه وبسایت است و گاهی برای برخی افراد روزها زمان می‌برد تا بتوانند آن را راه اندازی کنند. اما شما توانستید سایت خود را بر روی اینترنت واقعی راه اندازی کنید! \ No newline at end of file diff --git a/fa/deploy/images/github_get_repo_url_screenshot.png b/fa/deploy/images/github_get_repo_url_screenshot.png new file mode 100644 index 00000000000..ee1560b1e85 Binary files /dev/null and b/fa/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/fa/deploy/images/new_github_repo.png b/fa/deploy/images/new_github_repo.png new file mode 100644 index 00000000000..d1f82e5d863 Binary files /dev/null and b/fa/deploy/images/new_github_repo.png differ diff --git a/fa/deploy/images/pythonanywhere_account.png b/fa/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/fa/deploy/images/pythonanywhere_account.png differ diff --git a/fa/deploy/images/pythonanywhere_bash_console.png b/fa/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..68eb2a030e1 Binary files /dev/null and b/fa/deploy/images/pythonanywhere_bash_console.png differ diff --git a/fa/deploy/images/pythonanywhere_beginner_account_button.png b/fa/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/fa/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/fa/deploy/images/pythonanywhere_create_api_token.png b/fa/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..abae45ae37a Binary files /dev/null and b/fa/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/fa/deploy/install_git.md b/fa/deploy/install_git.md new file mode 100644 index 00000000000..73a95657347 --- /dev/null +++ b/fa/deploy/install_git.md @@ -0,0 +1,52 @@ +گیت یک "سیستم کنترل نسخه" است که توسط بسیاری از برنامه‌نویسان مورد استفاده قرار می‌گیرد. این نرم‌افزار می‌تواند تغییرات روی فایل‌ها را در طول زمان دنبال کند بنابراین می‌توانید نسخه خاصی را بعداً بازیابی کنید. این قابلیت تقریباً شبیه ابزار "track changes" در برنامه‌های ویرایش متن (مانند Microsoft Word و LibreOffice Writer) است اما به مراتب از آن‌ها قویتر است. + +## نصب گیت + + + +برای نصب گیت می‌توانید آن را از [git-scm.com](https://git-scm.com/) دانلود کنید. همه جا میتوانید کلید next را بزنید به غیر از دو جا: جایی که در مورد ویرایشگر متن از شما می‌پرسد شما باید ویرایشگر Nano را انتخاب کنید و در مرحله‌ای که عنوان آن "Adjusting your PATH environment" است، گزینه "Use Git and optional Unix tools from the Windows Command Prompt" (گزینه آخر) را انتخاب کنید. در بقیه موارد، پیش فرض‌ها مناسب هستند. گزینه "Checkout Windows-style, commit Unix-style line endings" را انتخاب کنید. + +فراموش نکنید که بعد از اینکه نصب به پایان رسید command prompt یا PowerShell را از نو باز کنید. + + + +گیت را از [git-scm.com](https://git-scm.com/) دانلود کنید و دستورالعمل‌ها را دنبال کنید. + +> ** نکته **اگر شما از OS X نسخه 10.6، 10.7 یا 10.8 استفاده می‌کنید باید GIT را از اینجا نصب کنید: [ نصب Git برای OS X Snow Leopard ](https://sourceforge.net/projects/git-osx-installer/files/git-2.3.5-intel-universal-snow-leopard.dmg/download) + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo apt install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo dnf install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo zypper install git +``` + + \ No newline at end of file diff --git a/fa/deploy/signup_pythonanywhere.md b/fa/deploy/signup_pythonanywhere.md new file mode 100644 index 00000000000..919b24ce459 --- /dev/null +++ b/fa/deploy/signup_pythonanywhere.md @@ -0,0 +1,19 @@ +PythonAnywhere سرویسی است که برای اجرای کدهای نوشته شده با پایتون در سرورهای ابری استفاده می‌شود. ما از آن برای میزبانی سایت خود و قرار دادن آن بر روی اینترنت استفاده خواهیم کرد. + +بلاگی که در حال ساختن آن هستیم را بر روی PythonAnywhere قرار خواهیم داد. برای استفاده از سرویس PythonAnywhere میتوانید به صورت رایگان به عنوان تازه کار در آن ثبت نام کنید (ثبت نام به صورت تازه کار برای کار ما کفایت می کند. نیازی به ورود کارت اعتباری نیست). + +* [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +![صفحه ثبت نام PythonAnywhere دارای امکان ثبت نام رایگان برای کاربران تازه کار می باشد](../deploy/images/pythonanywhere_beginner_account_button.png) + +> **نکته:** هنگام انتخاب نام کاربری خود به این نکته توجه داشته باشید که آدرس بلاگ شما با نام کاربری شما به صورت `yourusername.pythonanywhere.com` مشخص خواهد شد. بنابراین علاوه بر استفاده از نام خود به عنوان نام کاربری، می‌توانید از یک اسم دلخواه برای بلاگ خود استفاده کنید. هچینین رمز عبور خود را به خاطر داشته باشید. + +## ایجاد API توکن PythonAnywhere + +این کار را فقط یکبار هنگام شروع انجام خواهید داد. پس از اینکه در PythonAnywhere ثبت نام کردید به داشبورد خود هدایت خواهید شد. در سمت راست بالای صفحه بر روی Account خود کلیک کنید: + +![لینک Account در سمت راست بالای صفحه](../deploy/images/pythonanywhere_account.png) + +سپس به تب "API token" رفته و "Create new API token" را بزنید. + +![تب API token در صفحه Account](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/fa/django/README.md b/fa/django/README.md new file mode 100644 index 00000000000..9870bd4f5a8 --- /dev/null +++ b/fa/django/README.md @@ -0,0 +1,27 @@ +# جنگو چیست؟ + +جنگو (*جَنگو*) یک فریم‌ورک تحت وب رایگان و متن بازopen source است که با زبان پایتون نوشته شده‌است. یک فریم ورک تحت وب، دارای مجموعه‌ای از ابزارهاست که به شما کمک می‌کنند تا یک وب سایت را سریع‌تر و راحت‌تر توسعه دهید. + +هنگامی که در حال ساخت یک وب سایت هستید، شما همیشه به مجموعه ای از اجزای مشابه نیاز دارید. به شرح زیر: یک روش برای کنترل کردن احراز هویت کاربر (ثبت نام ، ورود به حساب کاربری ، خروج از حساب کاربری) ، یک پنل مدیریت برای وب سایت خود ، فرم ها ، روشی برای آپلود فایل ها و غیره. + +خوشبختانه خیلی وقت پیش، افرادی متوجه این موضوع شدند که هنگام ساختن یک سایت جدید، توسعه دهندگان وب با مشکلات مشابهی روبرو می‌شوند، بنابراین آنها تیمی را تشکیل دادند که به راحتی اجزای کار را در اختیار شما قرار می‌دهد که شما بتوانید به راحتی از آنها استفاده کنید ودر نهایت فریم ورک‌ها را ساختند (جنگو یکی از آن هاست). + +فریم ورکها به این دلیل به وجود آمده اند که دیگر نیازی نباشد شما از اول چرخ را بسازید و به شما کمک می کند تا به راحتی سایت خود را بسازید. + +## چرا شما به یک فریم ورک نیاز دارید؟ + +برای درک بهتر چگونگی عملکرد جنگو لازم است نگاه دقیق‌تری به سرورها بیندازیم. اولین چیزی که سرور نیاز دارد بداند این است که شما می‌خواهید سرور برای شما یک وب پیج را ارائه کند. + +حالا یک صندوق پست (port) را تصور کنید که منتظر دریافت نامه‌ها (requests) است. این کار توسط وب سرور انجام خواهد گرفت. وب سرور نامه را خوانده و پاسخ مربوطه را به وب پیج می فرستد. اما هنگامی که شما می‌خواهید چیزی را ارسال کنید، به محتوا احتیاج دارید. و جنگو همانی است که به شما برای ایجاد محتوا کمک می‌کند. + +## زمانی که فردی از سرور شما یک وبسایت را درخواست می‌کند، چه اتفاقی می‌افتد؟ + +هنگامی که یک درخواست به وب سرور می آید، به جنگو انتقال داده می شود و جنگو تلاش می‌کند بفهمد که دقیقاً چه چیزی درخواست شده است. در ابتدا آدرس وب پیج را می‌گیرد و سعی می‌کند تشخیص دهد چه کاری باید انجام دهد. این بخش توسط **urlresolver** جنگو انجام می‌گیرد (آدرس وبسایت URL یا Uniform Resource Locator نامیده می‌شود به این دلیل *urlresolver* یا تجزیه کننده URL نام با مسمایی است). خیلی سیستم هوشمندی نیست فقط یک لیست از الگوها را می‌گیرد و سعی می‌کند درخواست را با یکی از این الگوها مطابقت دهد. جنگو الگوها را از بالا به پایین بررسی می‌کند و اگر الگویی مشابه درخواست پیدا کرد، آن درخواست را به تابع مرتبط با آن الگو (که * view * نامیده می‌شود) ارسال می‌کند. + +یک پستچی را با یک نامه تصور کنید. او در خیابان راه می‌رود و پلاک هر خانه را با پلاک نوشته شده روی نامه مقایسه می‌کند. اگر مطابقت داشته باشد، نامه را در آنجا می گذارد. این روش کار urlresolver است! + +در تابع * view*، تمام چیزهای جالب اتفاق می‌افتد: ما می‌توانیم به یک پایگاه داده نگاه کنیم تا اطلاعاتی را جستجو کنیم. شاید کاربر درخواست تغییر در داده را داشته باشد؟ مانند درخواست‌هایی که در یک نامه فرستاده می‌شوند: "لطفا شرح شغل من را تغییر دهید". تابع * view* می‌تواند بررسی کند که آیا شما مجاز به انجام این کار هستید، و سپس شرح شغل را برای شما به روز رسانی کرده و یک پیام را ارسال کند: "انجام شد!" سپس تابع *view * یک پاسخ ایجاد می‌کند و جنگو می‌تواند آن را به مرورگر وب کاربر ارسال کند. + +توضحیحات بالا کمی ساده شده‌اند اما شما نیازی ندارید که همه ریزه‌کاری‌های فنی را بدانید. یک درک کلی از فرآیند کافی است. + +پس به جای آن که بیش از این سراغ جزییات برویم می‌خواهیم با جنگو چیزی بسازیم و بخش‌های مهم آن را در این مسیر یاد بگیریم! \ No newline at end of file diff --git a/fa/django_admin/README.md b/fa/django_admin/README.md new file mode 100644 index 00000000000..49744baefaf --- /dev/null +++ b/fa/django_admin/README.md @@ -0,0 +1,57 @@ +# پنل مدیریت در جنگو + +برای اضافه کردن، ویرایش و حذف پست‌هایی که به تازگی مدلشان را درست کرده‌ایم، از جنگو ادمین یا پنل مدیریت جنگو استفاده خواهیم کرد. + +فایل `blog/admin.py` را در ویرایشگر کد باز کنید و محتوای آن را با خطوط زیر عوض کنید: + +{% filename %}blog/admin.py{% endfilename %} + +```python +from django.contrib import admin +from .models import Post + +admin.site.register(Post) +``` + +همانطور که می‌بینید، مدل Post را که در بخش قبل تعریف کرده بودیم فراخوانی کرده‌ایم. برای اینکه مدل ما در صفحه مدیریت نمایش داده شود، ما باید مدل را با دستور ` admin.site.register(Post)` ثبت کنیم. + +خوب، وقت آن است که به مدل Post نگاهی بیندازیم. به خاطر داشته باشید که دستور `python manage.py runserver` را در کنسول اجرا کنید تا وب سرور اجرا شود. به مرورگر خود بروید و آدرس http://127.0.0.1:8000/admin/ را تایپ کنید. شما یک صفحه لاگین را به شکل زیر می‌بینید: + +![صفحه لاگین](images/login_page2.png) + +برای ورود به سیستم، باید یک کاربر *superuser* ایجاد کنید - یک حساب کاربری که بر روی همه چیز در سایت کنترل داشته باشد. به محیط خط فرمان بازگردید و دستور `python manage.py createsuperuser` را تایپ کنید و Enter را فشار دهید. + +> به یاد داشته باشید، برای نوشتن دستورات جدید در حالی که وب سرور در حال اجرا است، یک پنجره ترمینال جدید را باز کرده و محیط مجازی خود را فعال کنید. ما در مورد نحوه نوشتن دستورات جدید در بخش **راه اندازی وب سرور** از فصل **اولین پروژه جنگو شما!** صحبت کردیم. + +{% filename %}macOS or Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py createsuperuser + + +{% 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. + + +به مرورگر خود برگردید و با نام کاربری که انتخاب کرده اید وارد شوید. شما باید داشبورد مدیریت جنگو را ببینید. + +![جنگو ادمین](images/django_admin3.png) + +به بخش Post بروید و کمی با آن کار کنید. پنج یا شش پست وبلاگی بسازید. نگران محتوای پست‌ها نباشید، این پست‌ها فقط به صورت محلی و برای شما نمایش داده خواهد شد. می‌توانید برای صرفه جویی در وقت از جایی مطالبی در آن کپی کنید. :) + +اطمینان حاصل کنید که حداقل برای دو یا سه پست (اما نه همه پست‌ها) تاریخ انتشار را تعیین کنید. بعداً مفید خواهد بود. + +![پنل مدیریت در جنگو](images/edit_post3.png) + +اگر می‌خواهید در مورد پنل مدیریت جنگو بیشتر بدانید باید مستندات جنگو را نگاه کنید: https://docs.djangoproject.com/en/2.2/ref/contrib/admin/ + +احتمالاً الان وقت مناسبی است تا قهوه یا چای بنوشید یا چیزی برای خوردن پیدا کنید تا دوباره سرحال شوید. شما اولین مدل جنگو را ایجاد کردید و شایسته یک استراحت کوتاه هستید! \ No newline at end of file diff --git a/fa/django_admin/images/django_admin3.png b/fa/django_admin/images/django_admin3.png new file mode 100644 index 00000000000..fb221bd18e1 Binary files /dev/null and b/fa/django_admin/images/django_admin3.png differ diff --git a/fa/django_admin/images/edit_post3.png b/fa/django_admin/images/edit_post3.png new file mode 100644 index 00000000000..57299b6f5af Binary files /dev/null and b/fa/django_admin/images/edit_post3.png differ diff --git a/fa/django_admin/images/login_page2.png b/fa/django_admin/images/login_page2.png new file mode 100644 index 00000000000..c16d1aa4289 Binary files /dev/null and b/fa/django_admin/images/login_page2.png differ diff --git a/fa/django_forms/README.md b/fa/django_forms/README.md new file mode 100644 index 00000000000..ef7ef374dec --- /dev/null +++ b/fa/django_forms/README.md @@ -0,0 +1,479 @@ +# فرم در جنگو + +آخرین چیزی که می‌خواهیم در وب سایت مان انجام دهیم ایجاد یک راه خوب برای اضافه کردن و ویرایش پست‌های وبلاگ است. `ادمین ` جنگو خوب است، اما سخت است که آن را زیبا یا سفارشی کنیم. با ` فرم‌ها ` ما کنترل کاملی بر روی صفحه خود داریم. تقریباً می‌توانیم هرکاری که بخواهیم انجام دهیم! + +ویژگی فرم‌ها در جنگو این است که ما می‌توانیم یکی را از ابتدا تعریف کنیم یا از `ModelForm`استفاده کنیم که نتیجه فرم را به صورت مدل ذخیره می‌کند. + +این دقیقا همان چیزی است که ما می‌خواهیم انجام دهیم: ما یک فرم را برای مدل ` Post` ایجاد خواهیم کرد. + +مانند هر بخش مهمی از جنگو، فرم‌ها فایل خود را دارند: ` forms.py`. + +ما باید یک فایل با این نام در پوشه ` blog` ایجاد کنیم. + + blog + └── forms.py + + +خوب، اجازه دهید آن را در ویرایشگر کد باز کنیم و خطوط زیر را تایپ کنیم: + +{% filename %}blog/forms.py{% endfilename %} + +```python +from django import forms + +from .models import Post + +class PostForm(forms.ModelForm): + + class Meta: + model = Post + fields = ('title', 'text',) +``` + +باید در ابتدا فرم‌های جنگو را فراخوانی کنیم (`from django import forms`) سپس مدل مربوط به `Post` را نیز فراخوانی کنیم(`from .models import Post`). + +` PostForm`، همانطور که احتمالاً حدس زده اید، نام فرم ما است. ما باید به جنگو بگوییم که این فرم یک نوع `ModelForm` است (بنابراین جنگو برای ما چند کار جادویی انجام خواهد داد) - `forms.ModelForm` مسئول انجام این کارها است. + +بعد از این، ما `class Meta` را داریم، جایی که به جنگو می‌گویم که کدام مدل باید برای ایجاد این فرم (`model = Post`) استفاده شود. + +در نهایت می‌توانیم بگوییم که کدام بخش‌ (بخش‌ها) باید در فرم ما باشد. در این سناریو ما تنها `title` و `text` را می‌خواهیم نشان دهیم - `author` باید فردی باشد که در حال حاضر وارد شده است (شما!) و `created_date` تاریخ ایجاد یک پست جدید است که باید به طور خودکار تنظیم شود، درست است؟ + +و همین! تمام مواردی که اکنون باید انجام دهیم، استفاده از فرم در یک *view* و نمایش آن در تمپلیت است. + +بنابراین یک بار دیگر یک لینک، یک URL، یک view و یک تمپلیت ایجاد خواهیم کرد. + +## لینک به یک صفحه با فرم + +قبل از آنکه لینک را اضافه کنیم، لازم است آیکونی را به عنوان دکمه برای این لینک اضافه کنیم. برای این دوره آموزشی فایل [file-earmark-plus.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/file-earmark-plus.svg) را دانلود کنید و آن را در پوشه `blog/templates/blog/icons/` ذخیره کنید + +> نکته: برای دانلود فایل SVG منو زمینه‌ای مربوط به آن را باز کنید (معمولاً به کمک راست کلیک بر روی آن) و بعد گزینه "Save link as" را انتخاب کنید. در پنجره‌ای که باز می‌شود آدرس محلی که می‌خواهید فایل را ذخیره کنید، مشخص کنید، به پوشه `djangogirls` که پروژه جنگو شما در آن است بروید و پوشه `blog/templates/blog/icons/` را پیدا کنید و فایل را در آن ذخیره کنید. + +وقت آن است که فایل `blog/templates/blog/base.html` را در ویرایشگر متن خود باز کنید. حالا می‌توانیم از فایل آیکون در تمپلیت base به شکل زیر استفاده کنیم. در عنصر `div` که در بخش `header` قرار دارد، لینکی قبل از عنصر `h1` اضافه خواهیم کرد: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + {% include './icons/file-earmark-plus.svg' %} + +``` + +توجه داشته باشید که ما می‌خواهیم نام ویو جدید را `post_new` بگذاریم. آیتم [SVG icon](https://icons.getbootstrap.com/icons/file-earmark-plus/) توسط [Bootstrap Icons](https://icons.getbootstrap.com/) ارائه می‌شود و علامتی مانند یک صفحه به همراه یک علامت به اضافه، نشان خواهد داد. ما از یک هدایت‌کننده جنگو یا Django template directive، به اسم `include` استفاده می‌کنیم. این هدایت‌کننده محتوای یک فایل را به تمپلیت جنگو تزریق می‌کند. مرورگر وب به خوبی می‌تواند این نوع از محتوا را بدون پردازش‌های اضافه، مدیریت کند. + +> شما می‌توانید تمام آیکون‌های بوتسترپ را از [اینجا](https://github.com/twbs/icons/releases/download/v1.11.3/bootstrap-icons-1.11.3.zip) دانلود کنید. فایل را از حالت زیپ خارج کنید و همه تصاویر را در پوشه‌ای به نام `icons` در داخل پوشه `blog/templates/blog/` قرار دهید. به این روش شما می‌توانید به آیکونی مانند `pencil-fill.svg` از طریق آدرس `blog/templates/blog/icons/pencil-fill.svg`، دسترسی داشته باشید + +بعد از اصلاح این خط، فایل شما باید به این شکل باشد: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% load static %} + + + + Django Girls blog + + + + + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ + +``` + +پس از ذخیره و بازخوانی صفحه http://127.0.0.1:8000 شما با یک خطای شناخته شده `NoReverseMatch` مواجه خواهید شد، درست است؟ بسیار عالی! + +## آدرس اینترنتی + +فایل `blog/urls.py` را باز کرده و کد زیر را به آن اضافه می‌کنیم: + +{% filename %}blog/urls.py{% endfilename %} + +```python +path('post/new/', views.post_new, name='post_new'), +``` + +و در نهایت کد ما بصورت زیر خواهد بود: + +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), + path('post/new/', views.post_new, name='post_new'), +] +``` + +از آنجایی که ویوی `post_new` را پیاده سازی نکرده ایم، هنگامی که سایت را ریفرش کنیم با خطای `AttributeError` مواجه خواهیم شد. پس باید ویوی مربوطه را نیز بسازیم: + +## ویو post_new + +زمان آن است که فایل `blog/views.py` را در ویرایشگر کد باز کنید و خطوط زیر را در ردیف `from` ها اضافه کنید: + +{% filename %}blog/views.py{% endfilename %} + +```python +from .forms import PostForm +``` + +و حالا *view* ما: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +برای ایجاد یک فرم جدید`Post`، ما باید`()PostForm` را فراخوانی کنیم و آن را به تمپلیت منتقل کنیم. ما به این *view* باز خواهیم گشت، اما در حال حاضر، بیایید به سرعت یک تمپلیت برای این فرم ایجاد کنیم. + +## تمپلیت + +لازم است یک فایل به نام `post_edit.html`در پوشه `blog/templates/blog`بسازیم و آن را در ویرایشگر کد بازکنیم. برای آنکه یک فرم کار کند به چند چیز نیاز داریم: + +* ما باید فرم را نمایش دهیم. مثلاً می‌توانیم این کار را با {% raw %}`{{ form.as_p }}`{% endraw %} انجام دهیم. +* خط بالا باید درون تگ فرم HTML پیچیده شود: `... `. +* ما به یک دکمه `ذخیره کردن` نیاز داریم. این کار را با یک دکمه HTML انجام می‌دهیم: ``. +* و در نهایت، درست بعد از باز شدن تگ `
` باید {% raw %}`{% csrf_token %}`{% endraw %} را اضافه کنیم. نوشتن این عبارت بسیار مهم است، زیرا فرم‌های شما را امن می‌کند! اگر شما این تکه را فراموش کنید، جنگو هنگام تلاش برای ذخیره کردن فرم پیغام خطا می‌دهد: + +![صفحه خطا CSRF](images/csrf2.png) + +خوب، بگذار ببینیم HTML در فایل `post_edit.html` چطور باید باشد: + +{% filename %}blog/templates/blog/post_edit.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} +

New post

+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} +``` + +حالا زمان به روزرسانی پروژه است! بله فرم شما نمایش داده می‌شود! + +![فرم جدید](images/new_form2.png) + +اما یک دقیقه صبر کنید وقتی چیزی را در فیلدهای `title` و `text` تایپ کنید و سعی کنید آن را ذخیره کنید، چه اتفاقی خواهد افتاد؟ + +هیچ چی! ما یک بار دیگر در همان صفحه هستیم و متن ما رفته است... و هیچ پست جدیدی اضافه نشده است. پس چه اتفاقی افتاد؟ + +جواب این است: هیچ چیز. ما باید در *view* خودمان کمی کارهای بیشتری انجام دهیم. + +## ذخیره فرم + +یکبار دیگر فایل `blog/views.py` را در ویرایشگر کد باز کنید. در حال حاضر آنچه که در ویو `post_new` داریم این هاست: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +هنگامی که فرم را ارسال می‌کنیم، ما به همان ویوی قبل باز می‌گردیم، اما این بار ما در `request` داده‌های بیشتری داریم، به ویژه در `request.POST` (نامگذاری request.POST هیچ ارتباطی با "پست" وبلاگ ندارد و به معنی آن است که ما در حال ارسال اطلاعات هستیم). به یاد می آورید که چگونه در فایل HTML، تعریف `
` دارای متغیر `method="POST"` بود؟ تمام فیلدهای فرم اکنون در `request.POST` قرار دارند. شما نباید عبارت `POST` را در اینجا به چیز دیگری تغییر دهید (تنها مقدار معتبر دیگر برای `method` مقدار `GET` است، اما الان وقت آن را نداریم تا تفاوت آن‌ها را توضیح دهیم). + +بنابراین در *view*، ما دو موقعیت جداگانه برای رسیدگی داریم: اول اینکه زمانی که ما برای اولین بار به صفحه می‌رویم و یک فرم خالی را می‌خواهیم، و دوم، وقتی با اطلاعات نوشته شده درون فرم، به *view* برمی‌گردیم. بنابراین ما نیاز به اضافه کردن یک شرط داریم (ما از `if`برای این منظور استفاده می‌کنیم): + +{% filename %}blog/views.py{% endfilename %} + +```python +if request.method == "POST": + [...] +else: + form = PostForm() +``` + +وقت آن است که نقاط `[...]` را پر کنید. اگر مقدار `method` برابر با `POST` باشد، ما می خواهیم که با اطلاعات درون فرم `PostForm` را بسازیم، درست است؟ ما این کار را به صورت زیر انجام خواهیم داد: + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(request.POST) +``` + +قدم بعدی این است که بررسی کنید که آیا فرم صحیح است (تمام فیلدهای لازم تنظیم شده و مقادیر نادرست وارد نشده است). ما این کار را با `form.is_valid()` انجام می‌دهیم. + +ما بررسی می کنیم که آیا فرم معتبر است و اگر چنین باشد، می توانیم آن را ذخیره کنیم! + +{% filename %}blog/views.py{% endfilename %} + +```python +if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() +``` + +اساساً، ما دو چیز در اینجا داریم: فرم را با `form.save` ذخیره می‌کنیم سپس یک نویسنده برای مطلب تعیین می‌کنیم (از آنجا که فیلد `author` در فرم موجود نبوده و داشتن نویسنده برای مطلب در `PostForm`الزامی است). `commit=False` بدین معنی است که ما نمی‌خواهیم مدل `Post` را ذخیره کنیم - ما می‌خواهیم ابتدا نویسنده را اضافه کنیم. در بیشتر موارد شما از `()form.save` بدون `commit=False` استفاده می‌کنید، اما در این مورد، ما باید آن را استفاده کنیم. `()post.save` تغییرات (اضافه کردن نویسنده) را اعمال می‌کند و یک پست جدید بلاگ ایجاد می‌شود! + +سرانجام، خوب بود اگر می‌توانستیم بلافاصله به صفحه جزییات پست جدید `post_detail` که هم اکنون ساخته‌ایم برویم، درست است؟ برای این کار ما نیاز به فراخوانی دیگری داریم: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import redirect +``` + +آن را در ابتدای فایل خود اضافه کنید. و اکنون می‌توان گفت، "به صفحه جزییات پست `post_detail` برای پست جدید برو": + +{% filename %}blog/views.py{% endfilename %} + +```python +return redirect('post_detail', pk=post.pk) +``` + +`post_detail` نام ویویی است که ما می‌خواهیم به آن برویم. به یاد دارید که این *view* نیاز به متغیر `pk` دارد؟ برای فرستادن آن به ویو، از `pk=post.pk` استفاده می‌کنیم، که در آن `post` جدیدترین پست وبلاگ است! + +خوب، ما خیلی صحبت کرده‌ایم، اما احتمالاً می‌خواهید ببینید که کل *view* چگونه به نظر می‌رسد، درست است؟ + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + if request.method == "POST": + form = PostForm(request.POST) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +بیایید ببینیم که آیا کار می‌کند. به صفحه http://127.0.0.1:8000/post/new/ بروید، یک `title` و یک `text` اضافه کنید و نتیجه را ببینید! پست جدید وبلاگ اضافه شده است و ما به صفحه `post_detail` هدایت می‌شویم! + +ممکن است متوجه شده باشید که قبل از ذخیره پست، تاریخ انتشار را تنظیم کرده‌ایم. بعدها، ما دکمه *publish button* را در بخش **Django Girls Tutorial: Extensions** معرفی می‌کنیم. + +این عالیه! + +> همانطور که اخیراً رابط کاربری ادمین جنگجو را استفاده کردیم، سیستم در حال حاضر فکر می‌کند ما هنوز در سیستم لاگین هستیم. چند موقعیت وجود دارد که می تواند منجر به خروج ما از رابط کاربری مدیریت شود (بسته شدن مرورگر، راه اندازی مجدد دیتابیس و غیره). اگر در هنگام ایجاد یک پست متوجه شدید که خطایی در رابطه با عدم وجود یک کاربر ایجاد شده است، به صفحه مدیریت http://127.0.0.1:8000/admin بروید و دوباره وارد شوید. این مسأله به طور موقت حل خواهد شد. یک تکلیف اضافه برای خانه که بعد از بخش اصلی آموزش، انتظار شما را می‌کشد رفع مشکلات امنیتی وبسایت در بخش **Homework: add security to your website!** است. + +![خطا ورود به سیستم](images/post_create_error.png) + +## اعتبارسنجی فرم + +حالا به شما نشان می‌دهیم که فرم‌ها در جنگو چقدر جالب هستند. یک پست وبلاگ باید فیلدهای `title` و `text` را داشته باشد. در مدل `Post` ما نگفتیم که این فیلدها (به غیر از `published_date`) الزامی نیستند، بنابراین، جنگو به طور پیش فرض آن‌ها را الزامی می‌داند. + +سعی کنید فرم را بدون `title` و `text` ذخیره کنید. حدس بزنید چه اتفاقی خواهد افتاد! + +![اعتبارسنجی فرم](images/form_validation2.png) + +جنگو مواظب است که تمام فیلدهای موجود در فرم ما صحیح پر شده باشند. فوق‌العاده نیست؟ + +## ويرايش فرم + +حالا ما می‌دانیم که چگونه یک پست جدید اضافه کنیم. اما اگر بخواهیم یک فرم موجود را ویرایش کنیم، چه؟ این کار بسیار شبیه آنچه ما انجام داده‌یم است. بگذارید برخی از چیزهای مهم را سریع بسازیم. (اگر چیزی را درک نمی‌کنید، باید از مربی خود بپرسید یا در فصل‌های قبلی نگاه کنید، زیرا ما قبلاً همه این مراحل را پوشش دادیم.) + +ابتدا، اجازه دهید که آیکونی که نمایش دهنده دکمه اصلاح است را ذخیره کنیم. فایل [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` اضافه کنید: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + +``` + +قالب فوق شبیه به این خواهد شد: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} + +{% endblock %} +``` + +فایل `blog/urls.py` را باز کنید و خط زیر را به آن اضافه کنید: + +{% filename %}blog/urls.py{% endfilename %} + +```python + path('post//edit/', views.post_edit, name='post_edit'), +``` + +ما از این تمپلیت `blog/templates/blog/post_edit.html` مجدداً استفاده خواهیم کرد پس تنها قطعه باقی مانده *view* است. + +فایل `blog/views.py` را باز کنید و خط زیر را به انتهای این فایل اضافه کنید: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_edit(request, pk): + post = get_object_or_404(Post, pk=pk) + if request.method == "POST": + form = PostForm(request.POST, instance=post) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm(instance=post) + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +این ویو شبیه ویوی `post_new` ماست، درست است؟ اما نه دقیقاً. در ابتدا ما یک پارامتر `pk` اضافی از `urls` ارسال کرده‌ایم. سپس مدل `Post` را که می‌خواهیم اصلاح کنیم با دستور `get_object_or_404(Post, pk=pk)` می‌گیریم و بعد از آن یک فرم می‌سازیم و این فرم را به صورت `instance`ارسال می‌کنیم، هر دو این کارها وقتی اتفاق می‌افتد که فرم را ذخیره می‌کنیم… + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(request.POST, instance=post) +``` + +… و هنگامی که یک فرم را به این صورت برای تغییر دادن باز می‌کنیم: + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(instance=post) +``` + +بسیار خوب، حالا بیایید امتحان کنیم که آیا کار می‌کند! به صفحه `post_detail` بروید. باید یک کلید edit در گوشه سمت راست بالا باشد: + +![کلید Edit](images/edit_button2.png) + +وقتی بر روی آن کلیک کنید یک فرم که با اطلاعات پست وبلاگی ما پر شده است نشان داده می‌شود: + +![فرم Edit](images/edit_form2.png) + +به راحتی محتوای پست را تغییر دهید و آن را ذخیره کنید! + +تبریک! برنامه شما کامل و کامل‌تر می‌شود! + +اگر اطلاعات بیشتری در مورد فرم‌ها در جنگو لازم دارید باید مستندات مربوط به آن را در این آدرس بخوانید: https://docs.djangoproject.com/en/2.2/topics/forms/ + +## امنیت + +ساختن یک پست جدید فقط با یک کلیک، بسیار فوق العاده است! اما همین الان هرکسی که از صفحه شما بازدید می‌کند می‌تواند به راحتی یک پست جدید بسازد و این احتمالاً چیزی نیست که شما بخواهید. حالا بیایید کاری کنیم که این دکمه فقط برای شما نشان داده شود و کس دیگری آن را نبیند. + +فایل `blog/templates/blog/base.html` را در ویرایشگر کد باز کنید بخش `div` با نام `header` و تگ a موجود در آن را پیدا کنید. باید چیزی شبیه به این باشد: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + {% include './icons/file-earmark-plus.svg' %} + +``` + +حالا ما می‌خواهیم یک تگ `{% if %}` دیگر به این اضافه کنیم که باعث خواهد شد این لینک فقط برای کاربری نشان داده شود که به عنوان ادمین وارد شده باشد که در حال حاضر فقط شما هستید! تگ `` را به شکل زیر تغییر دهید: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% if user.is_authenticated %} + + {% include './icons/file-earmark-plus.svg' %} + +{% endif %} +``` + +تگ `{% if %}` باعث خواهد شد که لینک فقط در صورتی به مرورگر ارسال شود که کاربر درخواست کننده صفحه، با حساب کاربری ادمین وارد شده باشد. این کار به طور کامل ساختن پست جدید را محافظت نمی‌کند اما قدم اولیه‌ی خوبی است. مباحث بیشتری از امنیت را در بخش‌های اضافه آموزش پوشش خواهیم داد. + +کلید edit را که به صفحه جزییات یک پست اضافه کردیم به یاد دارید؟ حالا همین کار را برای آن صفحه نیز می‌خواهیم انجام دهیم تا دیگران قادر به تغییر محتوای یک پست نباشند. + +فایل `blog/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 %} +``` + +از آنجا که احتمالاً هنوز به عنوان ادمین در سیستم لاگین کرده‌اید، اگر صفحه را دوباره بازخوانی کنید، تغییر خاصی را نمی‌بینید. صفحه را در یک مرورگر دیگر یا یک پنجره ناشناس incognito window (در Windows Edge به آن "InPrivate" می‌گویند) بارگذاری کنید. خواهید دید که لینک و آیکون اصلاح پست، نمایش داده نمی‌شود! + +## یک چیز دیگر: زمان دیپلوی است! + +بیایید ببینیم آیا همه این تغییرات در PythonAnywhere کار می‌کند. وقت یک دیپلوی کردن دیگر است! + +* ابتدا کد جدید را کامیت کنید و آن را به GitHub بفرستید: + +{% filename %}خط فرمان{% endfilename %} + + $ git status + $ git add . + $ git status + $ git commit -m "Added views to create/edit blog post inside the site." + $ git push + + +* سپس در کنسول [PythonAnywhere Bash console](https://www.pythonanywhere.com/consoles/) تایپ کنید: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(یادتان باشد که `` را با زیر دامنه اصلی خود در PythonAnywhere عوض کنید البته بدون آکولادها.) + +* در نهایت به صفحه ["Web" page](https://www.pythonanywhere.com/web_app_setup/) بروید (از کلید منو در بالا و سمت راست کنسول استفاده کنید) و کلید **Reload** را بزنید. آدرس وبلاگ خودتان https://subdomain.pythonanywhere.com را باز کنید تا تغییرات را ببینید. + +به نتیجه رسید! تبریک! :) \ No newline at end of file diff --git a/fa/django_forms/images/csrf2.png b/fa/django_forms/images/csrf2.png new file mode 100644 index 00000000000..ee946324f92 Binary files /dev/null and b/fa/django_forms/images/csrf2.png differ diff --git a/fa/django_forms/images/drafts.png b/fa/django_forms/images/drafts.png new file mode 100644 index 00000000000..1d62f8866f4 Binary files /dev/null and b/fa/django_forms/images/drafts.png differ diff --git a/fa/django_forms/images/edit_button2.png b/fa/django_forms/images/edit_button2.png new file mode 100644 index 00000000000..804674f0965 Binary files /dev/null and b/fa/django_forms/images/edit_button2.png differ diff --git a/fa/django_forms/images/edit_form2.png b/fa/django_forms/images/edit_form2.png new file mode 100644 index 00000000000..3d4e525d5d0 Binary files /dev/null and b/fa/django_forms/images/edit_form2.png differ diff --git a/fa/django_forms/images/form_validation2.png b/fa/django_forms/images/form_validation2.png new file mode 100644 index 00000000000..6e333af3077 Binary files /dev/null and b/fa/django_forms/images/form_validation2.png differ diff --git a/fa/django_forms/images/new_form2.png b/fa/django_forms/images/new_form2.png new file mode 100644 index 00000000000..8f2a1088070 Binary files /dev/null and b/fa/django_forms/images/new_form2.png differ diff --git a/fa/django_forms/images/post_create_error.png b/fa/django_forms/images/post_create_error.png new file mode 100644 index 00000000000..d140e8e2419 Binary files /dev/null and b/fa/django_forms/images/post_create_error.png differ diff --git a/fa/django_installation/README.md b/fa/django_installation/README.md new file mode 100644 index 00000000000..dc3cccdfa7d --- /dev/null +++ b/fa/django_installation/README.md @@ -0,0 +1,7 @@ +# نصب و راه اندازی جنگو + +> **نکته** اگر از Chromebook استفاده می‌کنید، این فصل را رد کنید و مطمئن شوید که دستورالعمل [ تنظیمات Chromebook](../chromebook_setup/README.md) را دنبال کنید. +> +> **نکته** اگر مراحل [نصب و راه‌اندازی](../installation/README.md) را انجام داده‌اید یعنی این بخش انجام شده است، می‌توانید مستقیم به بخش بعد بروید! + +{% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/fa/django_installation/instructions.md b/fa/django_installation/instructions.md new file mode 100644 index 00000000000..f35dfc76d3f --- /dev/null +++ b/fa/django_installation/instructions.md @@ -0,0 +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 متعلق به Markus Zapke-Gründemann و همکاران می‌باشد. + +## محیط مجازی + +قبل از اینکه ما جنگو را نصب کنیم، ابزاری بسیار پراستفاده به شما می‌دهیم تا با نصب آن محیط برنامه نویسی خود را بر روی کامپیوترتان تمیز و مرتب نگه دارید. می‌توانید برای ادامه کار از این مرحله صرف نظر کنید اما استفاده از آن بسیار توصیه می‌شود. شروع کار با تنظیمات مناسب جلوی بسیاری از مشکلات در آینده را می‌گیرد! + +بنابراین، اجازه دهید یک ** محیط مجازی ** یا virtual environment بسازیم (همچنین به آن * virtualenv* هم گفته می‌شود). محیط مجازی، تنظیمات پایتون/جنگو را برای هر پروژه و جدا از دیگر پروژه‌ها، قرنطینه و حفظ خواهد کرد. یعنی هر تغییری که در تنظیمات یک وبسایت انجام می‌دهید، بر روی دیگر وبسایت‌هایی که در حال توسعه آن‌ها هستید تاثیر نخواهد گذاشت. تمیز و مرتب، اینطور نیست؟ + +آنچه شما باید انجام دهید این است که یک پوشه را پیدا کنید که در آن می‌خواهید ` محیط مجازی` را ایجاد کنید. برای مثال، پوشه home. در ویندوز، چیزی شبیه `C:\Users\Name` است (که در آن `Name` نام کاربری شما است که با آن وارد ویندوز شده‌اید). + +> **نکته: ** در ویندوز اطمینان حاصل کنید که نام این پوشه حاوی کاراکترهای خاص یا دارای اعراب نیست؛ اگر نام کاربری شما دارای کاراکترهای خاص است، از یک پوشه دیگر استفاده کنید، به عنوان مثال `C:\djangogirls`. + +برای این آموزش ما از یک پوشه جدید `djangogirls` در پوشه اصلی شما استفاده خواهیم کرد: + +{% filename %}خط فرمان{% endfilename %} + + $ mkdir djangogirls + $ cd djangogirls + + +ما یک محیط مجازی به نام `myvenv` خواهیم ساخت. فرمان کلی در این قالب خواهد بود: + +{% filename %}خط فرمان{% endfilename %} + + $ python3 -m venv myvenv + + + + +برای ایجاد یک `محیط مجازی` جدید، باید کنسول خط فرمان را باز کنید و دستور <`python -m venv myvenv` را اجرا کنید. شبیه این خواهد شد: + +{% filename %}خط فرمان{% endfilename %} + + C:\Users\Name\djangogirls> python -m venv myvenv + + +در اینجا `myvenv` نام `محیط مجازی` شماست. می‌توانید هر نام دیگری انتخاب کنید اما از حروف کوچک استفاده کنید و از اسپیس، اعراب گذاری و کاراکترهای خاص استفاده نکنید. همچنین بهتر است اسم کوتاهی انتخاب کنید چون بعدتر ارجاعات زیادی به آن خواهید داشت! + + + + + +می‌توانیم با دستور `python3 -m venv myvenv` هم در لینوکس و هم در macOS `محیط مجازی` بسازیم. شبیه این خواهد بود: + +{% filename %}خط فرمان{% endfilename %} + + $ python3 -m venv myvenv + + +نام `محیط مجازی` شما، `myvenv` است. می‌توانید هر نام دیگری انتخاب کنید اما از حروف کوچک استفاده کنید و از اسپیس استفاده نکنید. همچنین بهتر است اسم کوتاهی انتخاب کنید چون بعدتر ارجاعات زیادی به آن خواهید داشت! + +> **نکته: ** در بعضی نسخه‌های دبیان/اوبونتو ممکن است چنین پیغام خطایی دریافت کنید: +> +> {% filename %}خط فرمان{% 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 %}خط فرمان{% endfilename %} +> +> $ sudo apt install python3-venv +> +> +> **نکته: ** در بعضی نسخه‌های دبیان/اوبونتو ساختن محیط مجازی با این دستور ممکن است باعث چنین خطایی بشود: +> +> {% filename %}خط فرمان{% endfilename %} +> +> Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 +> +> +> برای حل این مشکل، از دستور `virtualenv` استفاده کنید. +> +> {% filename %}خط فرمان{% endfilename %} +> +> $ sudo apt install python-virtualenv +> $ virtualenv --python=python{{ book.py_version }} myvenv +> +> +> **نکته: ** اگر چنین خطایی گرفتید +> +> {% filename %}خط فرمان{% endfilename %} +> +> E: Unable to locate package python3-venv +> +> +> در عوض از این دستور استفاده کنید: +> +> {% filename %}خط فرمان{% endfilename %} +> +> sudo apt install python{{ book.py_version }}-venv +> + + + +## کار کردن با محیط مجازی + +دستور بالا یک پوشه به نام `myvenv` می‌سازد (یا هر نام دیگری که شما گذاشته باشید) که شامل محیط مجازی ماست (درواقع مجموعه‌ای از پوشه‌ها و فایل‌ها). + + + +محیط مجازی خود را با اجرای دستور زیر فعال کنید: + +{% filename %}خط فرمان{% endfilename %} + + C:\Users\Name\djangogirls> myvenv\Scripts\activate + + +> **نکته: ** در ویندوز 10 و در هنگام استفاده از Windows PowerShell ممکن است با این خطا مواجه شوید `execution of scripts is disabled on this system`. در این شرایط یک بار دیگر Windows PowerShell را با گزینه "Run as Administrator" اجرا کنید. سپس دستورات زیر را قبل از فعال کردن محیط مجازی خود، اجرا کنید: +> +> {% filename %}خط فرمان{% 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 +> + + + +> **نکته:** برای کاربران ویرایشگر VS Code که درون خود یک ترمینال خط فرمان منطبق بر PowerShell ویندوز دارد، اگر بخواهید از این ترمینال استفاده کنید باید این دستور را برای فعال کردن محیط مجازی خود بزنید: +> +> $ . myvenv\Scripts\activate.ps1 +> +> +> مزیت آن این است که لازم نیست بین پنجره ویرایشگر کد و پنجره خط فرمان جابجا شوید + + + + + +محیط مجازی خود را با اجرای دستور زیر فعال کنید: + +{% filename %}خط فرمان{% endfilename %} + + $ source myvenv/bin/activate + + +به یاد داشته باشید که `myvenv` را با نامی که برای `محیط مجازی` خود انتخاب کرده‌اید عوض کنید! + +> **نکته: ** گاهی اوقات ممکن است دستور `source` در دسترس نباشد. در این مواقع دستور زیر را امتحان کنید: +> +> {% filename %}خط فرمان{% endfilename %} +> +> $ . myvenv/bin/activate +> + + + +هنگامی که پیشوند `(myvenv)` در کنسول خط فرمان اضافه شود به معنی آن است که `محیط مجازی` شما فعال شده است. + +وقتی درون یک محیط مجازی کار می‌کنید کلمه `python` به صورت اتوماتیک به نسخه صحیح پایتون ارجاع می‌دهد در نتیجه می‌توانید به جای `python3` از `python` استفاده کنید. + +بسیار خوب، ما همه نیازمندی‌ها را داریم حالا می‌توانیم جنگو را نصب کنیم! + +## نصب جنگو {#django} + +حالا که `محیط مجازی` شما فعال شده است می‌توانید جنگو را نصب کنید. + +قبل از آن باید مطمئن شویم که آخرین نسخه `pip` که برای نصب جنگو استفاده می‌شود را داریم: + +{% filename %}خط فرمان{% endfilename %} + + (myvenv) ~$ python -m pip install --upgrade pip + + +### نصب پکیج‌ها و پیش‌نیازهایشان + +یک فایل پیش‌نیازها شامل لیستی از پکیج‌های وابسته است که باید به کمک `pip install` نصب شوند: + +در ابتدا یک فایل `requirements.txt` در پوشه `djangogirls/` بسازید. معمولاً می‌توانید از خود ویرایشگر کد که قبل‌تر نصب کرده‌اید هم برای ساختن فایل جدید استفاده کنید. یک فایل جدید در ویرایشگر کد بسازید و سپس به نام `requirements.txt`در پوشه `djangogirls/` ذخیره‌اش کنید. پوشه شما شبیه این خواهد بود: + + djangogirls + ├── myvenv + │ └── ... + └───requirements.txt + + +در فایل `djangogirls/requirements.txt` باید خط زیر را اضافه کنید: + +{% filename %}djangogirls/requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +حالا دستور `pip install -r requirements.txt` را اجرا کنید تا جنگو نصب شود. + +{% filename %}خط فرمان{% endfilename %} + + (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.1MB) + Installing collected packages: Django + Successfully installed Django-{{ book.django_version }} + + + + +> اگر در هنگام اجرای دستور pip در ویندوز خطایی دریافت کردید لطفاً کنترل کنید که در مسیر نام پوشه‌ها هیچ پوشه‌ای اسپیس، اعراب گذاری یا کارکتر خاص در نام خود نداشته باشد (مثلا مانند این `C:\Users\User Name\djangogirls`). اگر چنین است لطفاً از مسیری استفاده کنید که در آن اسپیس به کار نرفته باشد (مثلا چنین مسیری `C:\djangogirls`). یک محیط مجازی در پوشه جدید درست کنید سپس محیط مجازی قبلی را پاک کنید و دستور بالا را دوباره اجرا کنید. (جابجا کردن پوشه مربوط به محیط مجازی ایده خوبی نیست و باعث می‌شود محیط مجازی کار نکند. محیط مجازی با آدرس مطلق کار می‌کند) + + + + + +> ممکن است کنسول خط فرمان شما بعد از اجرای دستور فوق ثابت و بی‌حرکت شود. اگر چنین اتفاقی افتاد به جای دستور بالا از خط زیر استفاده کنید: +> +> {% filename %}خط فرمان{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> + + + + + +> اگر هنگام اجرای دستور pip بر روی اوبونتو نسخه 12.04 پیغام خطا گرفتید از دستور `python -m pip install -U --force-reinstall pip` برای اصلاح پکیج pip در محیط مجازی استفاده کنید. + + + +عالی! بالاخره در نهایت آماده شدید تا یک برنامه جنگو بسازید! \ No newline at end of file diff --git a/fa/django_models/README.md b/fa/django_models/README.md new file mode 100644 index 00000000000..6804dde9f87 --- /dev/null +++ b/fa/django_models/README.md @@ -0,0 +1,203 @@ +# مدل در جنگو + +آنچه الان می‌خواهیم بسازیم چیزی است که تمام پست‌های ما در وبلاگ را ذخیره می‌کند. اما برای اینکه بتوانیم این کار را بکنیم باید کمی در مورد مفهوم `شیء` صحبت کنیم. + +## اشیاء + +مفهومی در برنامه نویسی وجود دارد که به آن `برنامه‌نویسی شیء‌گرا` گفته می‌شود. به این معنی که به جای آنکه همه چیز را در ردیف‌هایی طولانی از دستورات بنویسیم می‌توانیم مدل هایی درست کنیم و تعریف کنیم که این مدل ها چگونه با هم ارتباط داشته باشند. + +یک شیء چیست؟ یک شیء مجموعه‌ای از خصوصیات و اعمال است. ممکن است کمی عجیب باشد اما برای شما مثالی خواهیم زد. + +اگر بخواهیم مدلی برای یک گربه بسازیم یک شیء به نام `Cat` میسازیم که دارای خصوصیاتی است مانند `رنگ`، `سن`، `حالت` (مثلاً خوب، بد یا خواب‌آلود) و `مالک` (که می‌تواند اشاره به یک شیء `Person` یا در در مورد گربه‌های ولگرد، بدون اشاره به فردی خاص، خالی بماند). + +یک شیء از نوع `Cat` دارای فعالیتی‌هایی مانند: `خُرخُر کردن`، `خراشیدن` و یا `غذا خوردن` است. (برخی مواقع به گربه، `غذای گربه` می‌‌دهیم که می‌تواند یک شیء جداگانه باشد که خصوصیت `مزه` داشته باشد). + + Cat + -------- + color + age + mood + owner + purr() + scratch() + feed(cat_food) + + + CatFood + -------- + taste + + +بنابراین ایده اصلی آن است که چیزهای واقعی در کدها با خصوصیات (که به آن `object properties` می‌گوییم) و اعمال (که به آن `methods` می‌گوییم) تعریف شوند. + +ما می‌خواهیم یک وبلاگ درست کنیم، درست است؟ چگونه یک مدل برای پست‌های وبلاگی بسازیم؟ + +باید به این سوال پاسخ دهیم که: یک پست وبلاگی چیست؟ چه خصوصیاتی دارد؟ + +خب، پست وبلاگی ما قطعاً به مقداری متن و یک عنوان نیاز دارد، درست است؟ بسیار خوب خواهد بود که بدانیم چه کسی مطلب را نوشته است، پس به نویسنده هم احتیاج داریم. سرانجام می‌خواهیم بدانیم که این مطلب در چه تاریخی نوشته و منتشر شده است. + + Post + -------- + title + text + author + created_date + published_date + + +چه کارهایی با یک پست وبلاگی می‌توان انجام داد؟ بسیار جالب خواهد بود که `متدهایی` داشته باشیم که بتواند یک پست را منتشر کند. چطور است؟ + +بنابراین به یک متد انتشار یا `publish` نیاز داریم. + +حالا که می‌دانیم دقیقاً به چه چیزی احتیاج داریم بیایید مدل سازی در جنگو را شروع کنیم! + +## مدل در جنگو + +حالا که می‌دانیم شیء چیست، می‌توانیم یک مدل جنگویی برای پست‌های وبلاگ‌مان بسازیم. + +یک مدل در جنگو نوعی شیء ویژه است که در `پایگاه داده` یا database ذخیره می‌شود. یک پایگاه داده مجموعه‌ای از اطلاعات است. جایی است که در آن اطلاعات مربوط به کاربرها، پست‌های وبلاگی و غیره را نگهداری می‌کنیم. ما از پایگاه داده SQLite برای ذخیره اطلاعات استفاده می‌کنیم. این پایگاه داده، پایگاه داده پیشفرض در جنگو است و الان برای ما کافی است. + +شما می‌توانید یک مدل را در پایگاه داده، چیزی شبیه به یک صفحه گسترده با ستون‌ها (فیلدها) و ردیف‌ها(داده‌ها) تصور کنید. + +### ساختن یک اپلیکیشن + +برای آنکه همه چیز مرتب باشد ما یک برنامه مجزا (اپلیکیشن) در پروژه خود خواهیم ساخت. خوب است که همه چیز از ابتدا مرتب باشد. برای ساخت یک برنامه جدید باید دستور زیر را در خط فرمان اجرا کنیم (در پوشه `djangogirls` و جایی که فایل `manage.py` وجود دارد): + +{% filename %}macOS or Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py startapp blog + + +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + + +خواهید دید که یک پوشه جدید به نام `blog` ساخته شده و شامل تعدادی فایل است. پوشه‌ها و فایل‌ها در پروژه ما باید شبیه به این باشد: + + djangogirls + ├── blog + │   ├── admin.py + │   ├── apps.py + │   ├── __init__.py + │   ├── migrations + │   │   └── __init__.py + │   ├── models.py + │   ├── tests.py + │   └── views.py + ├── db.sqlite3 + ├── manage.py + ├── mysite + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + + + +بعد از ساختن این برنامه، باید به جنگو بگوییم تا از آن استفاده کند. این کار را در فایل `mysite/settings.py` انجام می‌دهیم -- این فایل را در ویرایشگر کد باز کنید. باید `INSTALLED_APPS` را پیدا کنیم و دقیقاً بالای علامت `[` در انتهای این بخش، خطی شامل `'blog.apps.BlogConfig',` را اضافه کنیم. پس در نهایت شبیه این خواهد بود: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog.apps.BlogConfig', +] +``` + +### ساختن مدل برای پست وبلاگ + +در فایل `blog/models.py` ما تمام اشیائی را که به آن `مدل Model` می‌گوییم تعریف می‌کنیم. اینجا فضایی است که پست‌های وبلاگی را تعریف می‌کنیم. + +فایل `blog/models.py` را در ویرایشگر کد باز کنید، تمام محتویات آن را پاک کنید و کد‌های زیر را در آن بنویسید: + +{% filename %}blog/models.py{% endfilename %} + +```python +from django.conf import settings +from django.db import models +from django.utils import timezone + + +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) + + def publish(self): + self.published_date = timezone.now() + self.save() + + def __str__(self): + return self.title +``` + +> مطمئن بشوید که در هر طرف `str` دوبار از کاراکتر `_` استفاده کنید. از این قرارداد زیاد در پایتون استفاده می‌شود که به آن "dunder" هم می‌گویند که مخفف "double-underscore" است. + +عجیب به نظر می‌رسد؟ نگران نباشید ما درباره عملکرد این خط ها توضیح خواهیم داد! + +تمام خطوطی که با `from` یا `import` شروع می‌شوند خطوطی هستند که محتوایی را از یک فایل دیگر به این فایل اضافه می‌کنند. پس به جای آنکه یک محتوای یکسان را در هر فایل تکرار کنیم، می‌توانیم از این الگو استفاده کنیم `from ... import ... `. + +`class Post(models.Model):` – این خط مدل ما را تعریف می‌کند (که یک `شیء` یا object است). + +- `class` کلید واژه‌ای است که نشان می‌دهد در حال تعریف کردن یک شیء هستیم. +- `Post` نام مدل ما است. می‌توانیم به آن نام متفاوتی بدهیم (اما نباید از کاراکترهای خاص و اسپیس استفاده کنیم). همیشه نام یک کلاس را با حروف بزرگ شروع کنید. +- `models.Model` به این معنی است که Post یک مدل جنگویی است، بنابراین جنگو می‌داند که این مدل باید در پایگاه داده ذخیره شود. + +حالا ویژگی‌هایی که در مورد آن‌ها صحبت کردیم را اضافه می‌کنیم: `title`، `text`، `created_date`، `published_date` و `author`. برای این کار باید ویژگی‌های هرکدام از این‌ها را مشخص کنیم (آیا متن است؟ یا عدد؟ یا تاریخ؟ یا ارتباطی با یک شیء دیگر دارد، مثلا کاربر؟) + +- `models.CharField` – این عبارت مشخص می‌کند که ویژگی مورد نظر از جنس متن با تعداد کاراکتر محدود است. +- `models.TextField` – این عبارت برای اختصاص دادن متن با تعداد کاراکتر نامحدود است. به نظر برای متن پست‌های وبلاگی مناسب است، درست است؟ +- `models.DateTimeField` – مشخص کننده تاریخ و زمان است. +- `models.ForeignKey` – نشان دهنده ارتباط به یک مدل دیگر است. + +ما همه قطعات کد را توضیح نخواهیم داد برای آنکه زمان بسیار زیادی می‌گیرد. اگر بخواهید اطلاعات بیشتری در مورد فیلدهای یک مدل‌ و انواع آن بدانید باید نگاهی به مستندات جنگو بیندازید (https://docs.djangoproject.com/en/2.2/ref/models/fields/#field-types). + +منظور از `def publish(self):` چیست؟ این دقیقاً متد یا عملیات `publish` (انتشار یک پست وبلاگی) است که قبل‌تر در مورد آن صحبت کردیم. عبارت `def` نشان دهنده آن است که یک تابع یا متد تعریف شده‌ است و `publish` نام این تابع است. شما می‌توانید نام این تابع را به دلخواه عوض کنید. برای نامگذاری متدها، معمولاً از حروف کوچک و خط زیرین (underscore) به جای کاراکتر فاصله (space) استفاده می‌کنیم. برای مثال، تابعی که برای محاسبه قیمت متوسط لازم داریم به این صورت نامگذاری می‌شود `calculate_average_price`. + +توابع معمولاً یک مقدار را باز می‌گردانند که با `return` تعریف می‌شود. نمونه‌ای از این بازگرداندن در تابع `__str__` وجود دارد. در این سناریو وقتی ما تابع `__str__()` را فراخوانی می‌کنیم یک نوشته (با فرمت **string**) که حاوی عنوان پست وبلاگی است دریافت می‌کنیم. + +همچنین توجه داشته باشید که هر دو تابع `def publish(self):` و `def __str__(self):` به کمک فاصله‌گذاری ابتدای خط، درون کلاس تعریف شده‌اند. چون پایتون به فاصله‌ها حساس است نیاز داریم که میزان فاصله ابتدا خط برای متدها درست تعریف شوند تا متد، درون کلاس قرار داشته باشد. در غیر اینصورت متدها عضوی از کلاس نخواهند بود، و ممکن است رفتار غیرمنتظره‌ای ببینید. + +اگر هنوز چیزی در مورد مدل‌ها برای شما مبهم است حتماً از مربی خود بپرسید! می‌دانیم که یادگرفتن مفاهیم اشیاء و توابع به طور همزمان، پیچیده است. ولی حداقل الان کمی برای شما واضح‌تر شده است! + +### ساختن جدول برای مدل‌ها در پایگاه داده‌ها + +آخرین مرحله این است که مدل جدیدی که ساخته‌ایم را به پایگاه داده اضافه کنیم. ابتدا باید جنگو را از تغییراتی که در مدل‌ها ایجاد کرده‌ایم آگاه کنیم. (این تغییرات همین کارهایی است که انجام داده‌ایم!) به کنسول خط فرمان بروید و تایپ کنید `python manage.py makemigrations blog`. چیزی شبیه این خواهید دید: + +{% filename %}خط فرمان{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py makemigrations blog + Migrations for 'blog': + blog/migrations/0001_initial.py: + + - Create model Post + + +**نکته: **به یاد داشته باشید که فایل‌هایی که تغییر داده‌اید را ذخیره کنید وگرنه ممکن است کامپیوتر نسخه قبلی فایل را در نظر بگیرد و پیغام خطا نشان بدهد. + +جنگو یک فایل مهاجرت یا migration برای ما درست می‌کند که ما باید آن را به پایگاه داده ارسال کنیم. عبارت `python manage.py migrate blog` را اجرا کنید و خروجی باید شبیه به این باشد: + +{% filename %}خط فرمان{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py migrate blog + Operations to perform: + Apply all migrations: blog + Running migrations: + Applying blog.0001_initial... OK + + +هورا! مدل Post ما اکنون در پایگاه داده قرار گرفته است! جالب خواهد بود که نگاهی به آن بیندازیم! پس به سراغ بخش بعدی بروید تا ببینید Post ها به چه صورتی درآمده‌اند! \ No newline at end of file diff --git a/fa/django_orm/README.md b/fa/django_orm/README.md new file mode 100644 index 00000000000..653a5e0371f --- /dev/null +++ b/fa/django_orm/README.md @@ -0,0 +1,221 @@ +# ORM و QuerySets در جنگو + +در این فصل شما نحوه اتصال جنگو به پایگاه داده و روش ذخیره اطلاعات در آن را یاد خواهید گرفت. بگذارید شروع کنیم! + +## QuerySet چیست؟ + +به صورت خلاصه، کوئری‌ست لیستی از تعدادی شیء مربوط به یک مدل خاص است. کوئری‌ست به شما این امکان را می‌دهد که داده‌ها را از پایگاه داده بخوانید، فیلتر کنید یا آن‌ها را مرتب کنید. + +ساده‌ترین راه فهمیدن آن، مثال است. پس شروع می‌کنیم.آماده‌اید؟ + +## کنسول خط فرمان جنگو + +کنسول‌های لوکال خود را باز کرده (نه در PythonAnywhere) و این دستور را تایپ کنید: + +{% filename %}خط فرمان{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py shell + + + +باید پاسخی مانند زیر دریافت کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +(InteractiveConsole) +>>> +``` + +شما در حال حاضر در کنسول تعاملی جنگو هستید. این محل کاملاً شبیه به محیط تعاملی پایتون می‌باشد با این تفاوت که چند ویژگی جادویی جنگو را در بر دارد. :) شما می‌توانید تمامی دستورات پایتون را در اینجا استفاده کنید. + +### تمام اشیاء + +در ابتدا تمامی پست ها را نمایش می دهیم. با دستور زیر می توان این کار را انجام داد: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> Post.objects.all() +Traceback (most recent call last): + File "", line 1, in +NameError: name 'Post' is not defined +``` + +اوه اوه! به خطا خوردیم. این خطا به این معنی است که هیچ پستی وجود ندارد. درست است! فراموش کردیم که پست ها را import کنیم! + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> from blog.models import Post +``` + +مدل `Post` را از `blog.models` فراخوانی می‌کنیم. حالا دوباره تمامی پست‌ها را نمایش می‌دهیم: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> Post.objects.all() +, ]> +``` + +لیستی از پست‌هایی که قبلا ایجاد کرده بودیم درست شد! ما این پست‌ها را با استفاده از صفحه مدیریت جنگو ایجاد کرده‌بودیم. اما حالا می‌خواهیم پست جدیدی با استفاده از پایتون درست کنیم. چطور این کار را انجام می‌دهیم؟ + +### ساختن شیء + +به صورت زیر می‌توان یک شیء جدید از نوع Post در پایگاه داده ایجاد کرد: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') +``` + +اما ما در اینجا یک عنصر گم شده داریم: `نویسنده`. نیاز هست که یک نمونه از مدل `User` را به عنوان نویسنده برای ساخت شیء جدید تعریف کنیم. نحوه انجام کار به صورت زیر می باشد. + +بیایید اول مدل User را فراخوانی کنیم: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> from django.contrib.auth.models import User +``` + +چه کاربرانی در پایگاه داده داریم؟ این را امتحان کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> User.objects.all() +]> +``` + +این همان کاربر اصلی یا superuser است که کمی قبل‌تر ساخته‌ایم! حالا بیایید نمونه ای از روی کاربر اصلی بسازیم (این خط را مطابق نام کاربر اصلی که قبلاً وارد کرده‌اید تغییر دهید): + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> me = User.objects.get(username='ola') +``` + +همان طور که می‌بینید ما یک `کاربر` را به کمک دستور `get` و با ارجاع دادن مقدار 'ola' به متغیر `username` فراخوانی کردیم. خیلی دقیق! + +الان ما می‌توانیم پست خود را ایجاد کنیم: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') + +``` + +هورا! می‌خواهید امتحان کنیم که آیا درست کار می‌کند؟ + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> Post.objects.all() +, , ]> +``` + +بنابراین یک پست دیگر در لیست خواهیم داشت! + +### اضافه کردن پست های بیشتر + +حالا برای تفریح هم که شده می‌توانید پست‌های بیشتری بسازید تا با نحوه کارکرد آن بهتر آشنا شوید. دو یا سه پست دیگربسازید و سپس به مرحله بعد بروید. + +### فیلتر کردن اشیاء + +بخش مهمی از QuerySet، توانایی فیلتر کردن آن است. در اینجا می‌خواهیم تمام پست‌هایی که کاربر ola ساخته است را پیدا کنیم. در اینجا از عبارت `filter` به جای `all` در `Post.objects.all()` استفاده می‌کنیم. در پرانتز ما شرطی (شرایطی) که لازم است وجود داشته باشد تا شیء مورد نظر به QuerySet اضافه شود را بیان می‌کنیم. در اینجا، شرط ما این است که `author` برابر با `me` باشد. نحوه نوشتن آن در جنگو به این صورت است `author=me`. الان یک کد به صورت زیر داریم: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> Post.objects.filter(author=me) +, , , ]> +``` + +یا شاید ما بخواهیم تمام پست‌هایی که در فیلد `title` کلمه 'title' را داشته باشند پیدا کنیم؟ + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> Post.objects.filter(title__contains='title') +, ]> +``` + +> **نکته** دقت کنید که ۲تا کاراکتر underscore ( `ـ`) در میان `title` و `contains` وجود دارد. ORM جنگو از این قانون استفاده می‌کند تا عملیات یا فیلتر مورد نظر را ("contains") از نام فیلد ("title") جدا کند. اگر فقط از یک underscore استفاده کنید خطایی مانند این دریافت خواهید کرد "FieldError: Cannot resolve keyword title_contains". + +همچنین می‌توانید لیستی از تمام پست‌های منتشر شده دریافت کنید. ما این کار را با فیلتر کردن همه پست‌هایی که برای آن‌ها `published_date` تعیین کرده بودیم انجام می‌دهیم: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) + +``` + +متاسفانه پست هایی که از طریق کنسول پایتون اضافه کرده‌ایم هنوز منتشر نشده‌اند. اما می‌توانیم این وضعیت را تغییر دهیم! ابتدا یک نسخه از پست‌هایی که می‌خواهیم منتشر کنیم تهیه می‌کنیم: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> post = Post.objects.get(title="Sample title") +``` + +و حالا با متد `publish` آن را منتشر می کنیم: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> post.publish() +``` + +الان دوباره سعی کنید لیستی از پست‌های منتشر شده را نمایش دهید (دکمه جهت بالا در کیبورد را ۳ بار زده و `enter` کنید): + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +]> +``` + +### مرتب‌سازی اشیاء (Ordering objects) + +QuerySet ها همچنین به شما اجازه می‌دهند لیستی از اشیاء را مرتب کنید. بیایید آن‌ها را بر اساس `created_date`، مرتب کنیم: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> Post.objects.order_by('created_date') +, , , ]> +``` + +همچنین با اضافه کردن `-` در ابتدای دستور می‌توانیم اشیاء را به صورت معکوس مرتب کنیم: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> Post.objects.order_by('-created_date') +, , , ]> +``` + +### کوئری‌های پیچیده از طریق زنجیره توابع + +همانطور که دیدید برخی از توابع در `Post.objects`، یک کوئری ست باز می‌گردانند. همان تابع می‌تواند مجدداً بر روی یک کوئری ست اعمال شود و کوئری ست دیگری برگرداند. بنابراین، شما می‌توانید تاثیر آن‌ها را به صورت **زنجیره‌ای** با هم ترکیب کنید: + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> +``` + +این روش واقعاً قدرتمند است و به شما اجازه می‌دهد کوئری‌های پیچیده‌ای بسازید. + +موفق شدیم! شما الان برای قسمت بعدی آماده هستید. برای بستن پوسته (shell) دستور زیر را تایپ کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> exit() +``` \ No newline at end of file diff --git a/fa/django_start_project/README.md b/fa/django_start_project/README.md new file mode 100644 index 00000000000..f6185426cf0 --- /dev/null +++ b/fa/django_start_project/README.md @@ -0,0 +1,260 @@ +# اولین پروژه جنگو شما! + +> قسمت‌هایی از این بخش بر اساس دوره آموزشی Geek Girls Carrots بنا شده است (https://github.com/ggcarrots/django-carrots). +> +> قسمت‌هایی هم بر اساس دوره آموزشی [django-marcador tutorial](http://django-marcador.keimlink.de/) تحت مجوز بین المللی Creative Commons Attribution-ShareAlike 4.0 تهیه شده است. امتیاز دوره آموزشی django-marcador متعلق به Markus Zapke-Gründemann و همکاران است. + +قصد داریم یک وبلاگ کوچک بسازیم! + +در قدم اول یک پروژه جدید جنگو میسازیم. در واقع ساختن یک پروژه جنگو شامل اجرا کردن دستوراتی است که توسط جنگو آماده شده و با اجرای آن، بدنه اصلی پروژه ساخته می‌شود. این بدنه، شامل تعدادی پوشه و فایل است که ما بعداً از آن ها استفاده خواهیم کرد. + +نام برخی از این فایل‌ها و پوشه‌ها برای جنگو بسیار مهم است. شما نباید نام فایل‌‌هایی که الان می‌خواهیم بسازیم را تغییر دهید. همچنین تغییر پوشه‌های آنها هم ایده خوبی نیست. جنگو باید در یک ساختار مشخص مورد استفاده قرار گیرد تا بتواند موارد مهم را پیدا کند. + +> به یاد داشته باشید که همه دستورات را در محیط مجازی (virtualenv) اجرا کنید. اگر پیشوند `(myvenv)` را در کنسول خط فرمان نمی‌بینید، باید محیط مجازی را فعال کنید. فعال کردن محیط مجازی را در قسمت **کارکردن با محیط مجازی** از بخش **نصب جنگو** توضیح داده‌ایم. در ویندوز با تایپ `myvenv\Scripts\activate` و در لینوکس یا مک با نوشتن `source myvenv/bin/activate` می‌توانید محیط مجازی را فعال کنید. + + + +در کنسول لینوکس یا مک باید دستورات زیر را اجرا کنید. **فراموش نکنید که `علامت نقطه` را در آخر عبارت بگذارید!** + +{% filename %}خط فرمان{% endfilename %} + + (myvenv) ~/djangogirls$ django-admin startproject mysite . + + +> علامت `.` مهم است برای اینکه به سیستم می‌گوید که جنگو را در همین پوشه جاری نصب کند (علامت `.` به پوشه ای که در حال حاضر در آن هستیم اشاره میکند). +> +> **نکته** وقتی دستور بالا را می‌نویسید به یاد داشته باشید که فقط بخشی را می‌نویسید که با `django-admin` شروع می‌شود. بخش `(myvenv) ~/djangogirls$` نشان می‌دهد که شما باید دستورات ورودی را در مقابل آن بنویسید. + + + + + +در ویندوز باید دستور زیر را اجرا کنید. **(فراموش نکنید که `علامت نقطه` را در انتها بگذارید)**: + +{% filename %}خط فرمان{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . + + +> علامت `.` مهم است برای اینکه به سیستم می‌گوید که جنگو را در همین پوشه جاری نصب کند (علامت `.` به پوشه ای که در حال حاضر در آن هستیم اشاره میکند). +> +> **نکته** وقتی دستور بالا را می‌نویسید به یاد داشته باشید که فقط بخشی را می‌نویسید که با `django-admin.exe` شروع می‌شود. بخش `(myvenv) C:\Users\Name\djangogirls>` نشان می‌دهد که شما باید دستورات ورودی را در مقابل آن بنویسید. + + + +`django-admin.py` دستوری است که پوشه‌ها و فایل‌ها را برای شما می‌سازد. الان باید ساختار پوشه‌ها و فایل‌های شما شبیه به این باشد: + + djangogirls + ├── manage.py + ├── mysite + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + + +> **نکته**: در ساختار پوشه‌ها، شما پوشه `myvenv` را هم که قبلاً ساخته ایم خواهید دید. + +`manage.py` دستوری است که به مدیریت سایت کمک می‌کند. به کمک این دستور (و برخی چیزهای دیگر) و بدون نصب نرم افزارهای دیگر می‌توانیم یک وب سرور بر روی کامپیوتر خود راه اندازی کنیم. + +فایل `settings.py` حاوی تنظیمات وبسایت شما است. + +یادتان می‌آید در مورد حامل نامه و این موضوع که: کجا را باید نگاه کند تا بتواند نامه را به مقصد برساند‌، صحبت کردیم؟ فایل `urls.py` شامل الگوهایی است که توسط `urlresolver` استفاده می‌شوند. + +اجازه بدهید الان از سایر فایل‌ها چشم‌پوشی کنیم چون آن‌ها را تغییر نخواهیم داد. تنها چیزی که باید مواظب آن باشید این است که آن‌ها را اشتباهی پاک نکنید! + +## تغییر تنظیمات + +می‌خواهیم کمی تغییرات در فایل `mysite/settings.py` ایجاد کنیم. این فایل را در ویرایشگر کد، که پیش از این نصب کرده اید باز کنید. + +**نکته**: به یاد داشته باشید که فایل `settings.py`، یک فایل معمولی مانند بقیه فایل‌ها است. شما می‌توانید این فایل را به کمک ویرایشگر کد با استفاده از منو "file -> open"، باز کنید. از این طریق یک پنجره معمولی باز می‌شود که می‌توانید به کمک آن فایل `settings.py` را پیدا کنید و آن را انتخاب کنید. به جای این کار، می‌توانید در بین پوشه‌ها، پوشه djangogirls را پیدا کنید بر روی آن راست کلیک کنید. سپس نام ویرایشگر کد خود را از لیست به نمایش درآمده انتخاب کنید. انتخاب ویرایشگر مهم است چرا که ممکن است نرم افزارهای دیگر هم فایل را باز کنند ولی اجازه ویرایش کردن به شما ندهند. + +خیلی خوب خواهد بود که زمان درست را در وبسایت خود داشته باشیم. به [لیست منطقه های زمانی ویکیپدیا](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) بروید و محدوده زمانی مناسب را برای خود انتخاب کنید (TZ) (مثلاً `Asia/Tehran`). + +در فایل `settings.py` خطی را که حاوی `TIME_ZONE` است پیدا کنید و آن را اصلاح کنید تا منطقه زمانی شما را نشان دهد. مثلاً: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +TIME_ZONE = 'Asia/Tehran' +``` + +یک شناسه زبان شامل دو بخش است یکی زبان، مثلاً `en` برای انگلیسی و `fa` برای فارسی، و دیگری کد کشور، مثلاً `de` برای آلمان و `ir` برای ایران. اگر انگلیسی زبان اصلی شما نیست می‌توانید این شناسه را تغییر دهید تا پیغام‌های جنگو به زبان خودتان برای شما نمایش داده شود. بنابراین شما ترجمه دکمه "Cancel" را به زبانی که در اینجا معرفی کرده اید خواهید دید. [جنگو به زبان‌های زیادی ترجمه شده و قابل استفاده است](https://docs.djangoproject.com/en/2.2/ref/settings/#language-code). + +اگر زبان دیگری را می‌خواهید شناسه زبان را در خط زیر تغییر دهید: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +LANGUAGE_CODE = 'de-ch' +``` + +علاوه بر این نیاز داریم تا آدرس فایل‌های ثابت یا ایستا را نیز اضافه کنیم. (بعداً به طور کامل در این دوره آموزشی به فایل‌های ثابت و CSS خواهیم پرداخت.) به *انتهای* فایل بروید و دقیقاً زیر ورودی `STATIC_URL`، یک خط جدید با عنوان `STATIC_ROOT` اضافه کنید: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +STATIC_URL = '/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'] +``` + +> **نکته**: اگر از کروم بوک استفاده می‌کنید، این خط را هم به انتهای فایل settings.py اضافه کنید: `MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'` +> +> اگر از cloud9 استفاده می‌کنید `.amazonaws.com` را به `ALLOWED_HOSTS` اضافه کنید +> +> اگر شما پروژه خود را بر روی `Glitch.com` میزبانی می‌کنید، اجازه دهید که از کلید مخفی جنگو یا Djanog secret key پروژه شما که باید محرمانه بماند محافظت کنیم (در غیر اینصورت هر کس که پروژه شما را بررسی کند آن را خواهد دید): +> +> - در ابتدا، یک کلید مخفی شانسی می‌سازیم. ترمینال Glitch را دوباره باز کنید و دستورات زیر را تایپ کنید: +> +> {% filename %}خط فرمان{% endfilename %} +> +> ```bash +> python -c 'from django.core.management.utils import get_random_secret_key; \ +> print(get_random_secret_key())' +> ``` +> +> این کار باعث خواهد شد که یک رشته اتفاقی از کاراکترها و حروف ساخته شود، چیزی که به عنوان یک کلید مخفی برای پروژه جنگو شما کاملاً مناسب است. ما این کلید را در فایل `.env` در Glitch اضافه می‌کنیم، این فایل درصورتی توسط Glitch به ما نشان داده می‌شود که ما صاحب پروژه باشیم. +> +> - فایلی به نام `.env` در پوشه اصلی پروژه بسازید و کدهای زیر را در آن قرار دهید: +> +> {% filename %}.env{% endfilename %} +> +> ```bash +> # Here, inside the single quotes, you can cut and paste the random key generated above +> SECRET='3!0k#7ds5mp^-x$lqs2%le6v97h#@xopab&oj5y7d=hxe511jl' +> ``` +> +> - سپس فایل settings پروژه جنگو را با تغییرات زیر به روز رسانی کنید تا کلید مخفی به آن اضافه شود: +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> 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': BASE_DIR / 'db.sqlite3', + } +} +``` + +برای ساختن یک پایگاه داده برای وبسایتمان، دستور زیر را در کنسول خط فرمان اجرا می‌کنیم: `python manage.py migrate` (هنگام اجرای این دستور باید در پوشه `djangogirls` باشیم جایی که فایل `manage.py` قرار دارد). اگر همه چیز خوب پیش برود باید چیزی شبیه به این را ببینیم: + +{% filename %}خط فرمان{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py migrate + Operations to perform: + Apply all migrations: auth, admin, 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 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 sessions.0001_initial... OK + + +تمام شد! وقت آن است که وب سرور را اجرا کنیم و ببینیم آیا وبسایت ما کار می‌کند! + +## فعال کردن وب سرور + +شما باید در پوشه‌ای باشید که فایل `manage.py` در آن قرار دارد. (در پوشه `djangogirls`). در کنسول خط فرمان، وب سرور را به کمک این دستور فعال می‌کنیم `python manage.py runserver`: + +{% filename %}خط فرمان{% 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 %} + + $ refresh + + + +اگر در ویندوز کار می‌کنید و با خطای `UnicodeDecodeError` مواجه شدید، از دستور زیر استفاده کنید: + +{% filename %}خط فرمان{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + + +حالا زمان آن است که چک کنید وبسایت کار می‌کند یا نه. مرورگر خود را باز کنید (فایرفاکس، کروم، سافاری، اینترنت اکسپلورر یا هر چیز دیگر) و آدرس زیر را وارد کنید: + +{% filename %}browser{% endfilename %} + + http://127.0.0.1:8000/ + + +اگر از Chromebook و Cloud9 استفاده می‌کنید، در پنجره pop-up که در گوشه ی بالا، سمت راست پنجره ی خط فرمان، که در حال اجرای وب سرور است، باز شده است، بر روی آدرس URL ظاهر شده کلیک کنید. این آدرس چیزی شبیه به این است: + +{% filename %}browser{% endfilename %} + + https://.vfs.cloud9.us-west-2.amazonaws.com + + +یا در Glitch: + + https://name-of-your-glitch-project.glitch.me + + +تبریک! شما اولین وبسایت خود را ساخته اید و با یک وب سرور آن را فعال کرده اید! فوق العاده نیست؟ + +![Install worked!](images/install_worked.png) + +توجه داشته باشید که یک کنسول خط فرمان در هر لحظه فقط یک کار را می‌تواند انجام دهد و کنسول خط فرمان که شما قبل‌تر باز کرده‌اید در حال اجرای وب سرور است. تا زمانی که وب سرور در حال اجراست و منتظر است تا درخواستی به آن برسد می‌توان چیزی تایپ کرد ولی هیچ دستور جدیدی را نمی‌توان اجرا کرد. + +> نحوه عملکرد وب سرور را در بخش **اینترنت چگونه کار می‌کند** دوره کرده ایم. + +برای اینکه در زمان فعال بودن وب سرور، دستورات بیشتری را در کنسول خط فرمان تایپ کنید باید یک کنسول جدید باز کنید و محیط مجازی خود را فعال کنید. برای آنکه روش باز کردن یک کنسول جدید را مرور کنید می‌توانید به بخش [آشنایی با خط فرمان](../intro_to_command_line/README.md) نگاهی بیندازید. برای قطع فعالیت وب سرور، به همان کنسولی بروید که وب سرور در آن فعال است و کلید CTRL و C را با هم بزنید (در ویندوز ممکن است لازم باشد کلید CTRL را با کلید Break بزنید). + +برای قدم بعدی آماده هستید؟ حالا وقت آن است که کمی محتوا بسازیم! \ No newline at end of file diff --git a/fa/django_start_project/images/install_worked.png b/fa/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..4354c634ddb Binary files /dev/null and b/fa/django_start_project/images/install_worked.png differ diff --git a/fa/django_templates/README.md b/fa/django_templates/README.md new file mode 100644 index 00000000000..06eefa0c9d7 --- /dev/null +++ b/fa/django_templates/README.md @@ -0,0 +1,108 @@ +# templates در جنگو + +وقت آن است که داده‌ها را در وبسایت نمایش دهیم. جنگو چندین **template tag** مفید در اختیار ما قرار می‌دهد. + +## template tag چیست؟ + +میدانیم که در کدهای HTML نمی‌توانیم از کد های پایتون استفاده کنیم،به این دلیل که مرورگر نمی‌تواند کد پایتون را درک کند. مرورگرها فقط HTML را می‌فهمند. همینطور می‌دانیم که HTML ایستا است، در حالی که پایتون بسیار پویاتر است. + +** template tags در جنگو ** ما را قادر می‌سازد تا اشیا پایتونی را به HTML انتقال دهیم، بنابراین شما می‌توانید با سرعت بیشتری وبسایت‌های پویا توسعه دهید. چه خوب! + +## نمایش دادن قالب لیست پست‌های وبلاگ + +در بخش قبلی، ما لیستی از پست‌ها را در قالب متغیر `posts` به template دادیم. حالا آن را به وسیله HTML نمایش می‌دهیم. + +برای چاپ یک متغیر در template های جنگو، نام متغیر را درون دو جفت آکولاد قرار می دهیم. مانند کد زیر: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{{ posts }} +``` + +این مورد را در قالب `blog/templates/blog/post_list.html` امتحان کنید. آن را در ویرایشگر کد باز کنید، و هر چیزی از دومین `
` تا سومین `
` را با `{{ posts }}` جایگزین کنید. فایل را ذخیره کنید، و صفحه را برای دیدن نتیجه refresh کنید: + +![تصویر 13.1](images/step1.png) + +همینطوری که مشاهده می‌کنید، تمام چیزی که به دست آورده‌ایم این است: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +, ]> +``` + +این به معنای آن است که جنگو این متغیر را به عنوان لیستی از اشیا در نظر می‌گیرد. آیا از بخش **معرفی پایتون** بخاطر دارید که چگونه می‌توانیم لیست‌ها را نمایش دهیم؟ بله، با حلقه for ! در یک template جنگو شما این کار را به صورت زیر انجام خواهید داد: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} + {{ post }} +{% endfor %} +``` + +این کار را در template خود امتحان کنید. + +![تصویر 13.2](images/step2.png) + +کار میکند! اما ما میخواهیم تا پست ها مانند پست های ایستایی که پیش از این در بخش **معرفی HTML** ساختیم، نمایش داده شود. میتوانید HTML و template tag را با هم استفاده کنید. قسمت `body` به صورت زیر خواهد بود: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+

Django Girls Blog

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

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` + +{% raw %} هر چیزی که بین `{% for %}` و `{% endfor %}` قرار می‌دهید، برای هر شی در لیست تکرار می‌شود. صفحه خود را refresh کنید: {% endraw %} + +![تصویر 13.3](images/step3.png) + +آیا توجه کردید که این بار از نشانه گذاری متفاوتی استفاده کردیم؟ (`{{ post.title }}` یا `{{ post.text }}`)؟ ما در حال دسترسی به داده‌های موجود در هر فیلد تعریف شده در مدل `Post` هستیم. همچنین، `|linebreaksbr` متن پست‌ها را از فیلتری رد می‌کند که line-break ها را به پاراگراف تبدیل می‌کند. + +## یک مورد دیگر + +خوب است اگر بدانیم وب سایت شما روی اینترنت عمومی نیز به درستی کار می‌کند یا نه، درست است؟ بیایید تا دوباره انتشار آن را روی PythonAnywhere امتحان کنیم. خلاصه‌ای از مراحل در زیر آورده شده‌ است… + +* ابتدا کد خود را روی گیتهاب push کنید + +{% filename %}command-line{% endfilename %} + + $ git status + [...] + $ git add . + $ git status + [...] + $ git commit -m "Modified templates to display posts from database." + [...] + $ git push + + +* سپس دوباره به [PythonAnywhere](https://www.pythonanywhere.com/consoles/) وارد شوید و به **Bash console** خود بروید ( یا یک کنسول خط فرمان جدید باز کنید)، و دستورات زیر را اجرا کنید: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd .pythonanywhere.com + $ git pull + [...] + + +(به خاطر داشته باشید `` را با زیردامنه PythonAnywhere خود جایگزین کنید، بدون علامت های <>) + +* سرانجام، به برگه ["Web" page](https://www.pythonanywhere.com/web_app_setup/) بروید و **Reload** را انتخاب کنید. (برای رسیدن به سایر صفحات در PythonAnywhere از دکمه منو در سمت بالا و راست صفحه استفاده کنید.) به روز رسانی شما باید در آدرس https://subdomain.pythonanywhere.com موجود باشد در مرورگر خود آن را امتحان کنید! اگر پست‌های وبلاگی شما در PythonAnywhere با پست‌های شما در سرور فعال روی کامپیوترتان یکی نیست، نگران نباشید همه چیز مرتب است. پایگاه داده موجود روی کامپیوتر شما و PythonAnywhere، برخلاف سایر فایل‌های شما، با یکدیگر یکسان سازی نمی‌شوند و یکی نیستند. + +تبریک! حالا سعی کنید که یک پست جدید از طریق پنل مدیریت جنگو (به یاد دارید که published_date را اضافه کردیم) اضافه کنید مطمئن شوید که در بخش مدیریت جنگو در وبسایت PythonAnywhere باشید، https://subdomain.pythonanywhere.com/admin. سپس صفحه خود را دوباره بارگزاری کنید و ببینید آیا پست جدید به آن اضافه شده است. + +جذاب نیست؟ به شما افتخار می‌کنیم! کمی از کامپیوتر خود دور شوید، لازم است کمی استراحت کنید. :) + +![تصویر 13.4](images/donut.png) \ No newline at end of file diff --git a/fa/django_templates/images/donut.png b/fa/django_templates/images/donut.png new file mode 100644 index 00000000000..f31cebdc8a3 Binary files /dev/null and b/fa/django_templates/images/donut.png differ diff --git a/fa/django_templates/images/step1.png b/fa/django_templates/images/step1.png new file mode 100644 index 00000000000..cbf6420360a Binary files /dev/null and b/fa/django_templates/images/step1.png differ diff --git a/fa/django_templates/images/step2.png b/fa/django_templates/images/step2.png new file mode 100644 index 00000000000..fd6269c837c Binary files /dev/null and b/fa/django_templates/images/step2.png differ diff --git a/fa/django_templates/images/step3.png b/fa/django_templates/images/step3.png new file mode 100644 index 00000000000..b471fdd4d7b Binary files /dev/null and b/fa/django_templates/images/step3.png differ diff --git a/fa/django_urls/README.md b/fa/django_urls/README.md new file mode 100644 index 00000000000..164462a0938 --- /dev/null +++ b/fa/django_urls/README.md @@ -0,0 +1,103 @@ +# URL ها در جنگو + +ما در آستانه ساخت اولین صفحه وب هستیم: یک صفحه برای وبلاگ شما! ولی قبل از آن بیایید کمی در مورد آدرس دهی در جنگو یادبگیریم. + +## URL چیست؟ + +یک URL یک آدرس اینترنتی است. شما هربار که وبسایتی را بازدید می‌کنید می‌توانید آدرس آن را ببینید، این آدرس، در address bar یا پنجره آدرس مرورگر دیده می‌شود. (بله! `127.0.0.1:8000` یک آدرس (URL) است! و `https://djangogirls.org` هم یک آدرس (URL) است.) + +![URL](images/url.png) + +هر صفحه‌ای در اینترنت آدرس خود را لازم دارد. به این روش برنامه ما متوجه می‌شود که چه چیزی را باید به کاربری که یک آدرس را باز می‌کند نشان بدهد. در جنگو ما از چیزی به نام `URLconf` استفاده می‌کنیم (URL configuration). URLconf مجموعه‌ای از الگوها است که جنگو به کمک آن می‌تواند متوجه شود که آدرس درخواست شده باید به کدام ویو، ارجاع داده شود. + +## آدرس ها در جنگو چطور کار می‌کنند؟ + +حالا فایل `mysite/urls.py` را در ویرایشگر کد خود باز کنید و ببینید چگونه است: + +{% filename %}mysite/urls.py{% endfilename %} + +```python +"""mysite URL Configuration + +[...] +""" +from django.contrib import admin +from django.urls import path + +urlpatterns = [ + path('admin/', admin.site.urls), +] +``` + +همانطور که می‌بینید، اینجا جنگو چیزهایی برای ما گذاشته است. + +به خطوط بین نقل قول سه تایی (`'''` یا `"""`) docstrings یا توضیحات سند گفته می‌شود. شما می‌توانید این توضیحات را در بالای فایل، کلاس یا تابع بنویسید و عملکرد آن را شرح دهید. این خطوط توسط پایتون اجرا نمی‌شوند. + +همچنین، آدرس بخش مدیریت که در بخش قبل دیده اید، اینجا وجود دارد: + +{% filename %}mysite/urls.py{% endfilename %} + +```python + path('admin/', admin.site.urls), +``` + +معنی این خط این است که هر آدرسی که با `admin/` شروع شود، جنگو *view* مربوط به آن را پیدا خواهد کرد. در این مورد خاص، ما تعداد زیادی آدرس را اضافه کرده‌ایم که همه آن‌ها در این فایل نیامده‌اند - این شکل از خلاصه کردن آدرس‌ها خوانایی وتمیزی کدها را افزایش می‌دهد. + +## اولین آدرس جنگویی شما! + +زمان آن است که اولین آدرس خود را بسازید! ما می‌خواهیم که 'http://127.0.0.1:8000/' صفحه اصلی وبلاگ ما باشد که در آن لیستی از پست‌ها نمایش داده شود. + +همچنین می‌خواهیم که فایل `mysite/urls.py` را تمیز نگه داریم، در نتیجه آدرس‌ها را از اپلیکیشن `blog` ، در فایل اصلی آدرس‌ها `mysite/urls.py` فراخوانی می‌کنیم. + +به پیش برویم و خطی را اضافه کنیم که `blog.urls` را بارگذاری می‌کند. همچنین لازم است که خط `from django.urls…` را عوض کنید چرا که ما اینجا از تابع `include` استفاده می‌کنیم، بنابراین لازم است که شما دستور import را به این خط اضافه کنید. + +فایل `mysite/urls.py` شما باید چیزی شبیه به این شده باشد: + +{% filename %}mysite/urls.py{% endfilename %} + +```python +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('blog.urls')), +] +``` + +حالا جنگو هر درخواستی که به آدرس 'http://127.0.0.1:8000/' ارسال شود را به `blog.urls` ارسال می‌کند و دستورالعمل‌های بعدی را در آنجا جستجو می‌کند. + +## blog.urls + +در پوشه `blog` یک فایل خالی به نام `urls.py` بسازید و آن را در ویرایشگر کد باز کنید. بسیار خوب! این دو خط را به آن اضافه کنید: + +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views +``` + +در اینجا ما تابع جنگویی `path` و تمام `view` ها از اپلیکیشن `blog` را بارگذاری کرده‌ایم (هرچند که هنوز هیچ view نداریم ولی تا چند دقیقه دیگر سراغ آن خواهیم رفت!) + +بعد از این می‌توانیم اولین الگو آدرس را اضافه کنیم: + +{% filename %}blog/urls.py{% endfilename %} + +```python +urlpatterns = [ + path('', views.post_list, name='post_list'), +] +``` + +همانطور که می‌بینید ما یک `view` به نام `post_list` را به آدرس پایه وبلاگ نسبت داده‌ایم. این الگوی URL، شامل یک رشته خالی از کاراکتر است و سیستم بررسی آدرس جنگو نام دامنه را (مثلاً http://127.0.0.1:8000/) که پیشوندی برای همه آدرس‌ها است، در نظر نمی‌گیرد. این الگو به جنگو می‌گوید که اگر کسی آدرس 'http://127.0.0.1:8000/' را وارد کرد باید به `views.post_list` بروی. + +قسمت آخر، `name='post_list'`، نام آدرس است که برای تعیین هویت یک view استفاده می‌شود. این نام می‌تواند کاملاً شبیه نام view باشد یا نام کاملاً متفاوتی داشته باشد. ما بعداً از آدرس‌های نامگذاری شده در پروژه استفاده خواهیم کرد بنابراین مهم است که برای هر آدرسی نام، تعریف شود. علاوه بر این تلاش خواهیم کرد که نام آدرس‌ها، منحصر به فرد و برای به خاطر سپردن، ساده باشد. + +اگر الان تلاش کنید تا به آدرس http://127.0.0.1:8000/ بروید احتمالاً با پیغام خطای موجود نبودن صفحه مواجه خواهید شد. این پیغام به خاطر این است که سرور (یادتان هست که تایپ می‌کردیم `runserver`؟) فعال نیست. به کنسول سرور نگاه کنید تا ببینید دلیل آن چیست. + +![خطا](images/error1.png) + +کنسول سرور یک پیعام خطا نشان می‌دهد ولی نگران نباشید، ابزار سودمندی است: این پیغام خطا می‌گوید که **no attribute 'post_list'**. این نام همان *view* است که جنگو تلاش می‌کند آن را پیدا و اجرا کند، اما ما هنوز آن را نساخته‌ایم. در این مرحله `/admin/` شما هم کار نمی‌کند. نگران نباشید، سراغ آن هم خواهیم رفت. اگر پیغام خطای دیگری دریافت کردید یک بار وب سرور را قطع و مجدداً فعال کنید. برای این کار، در پنجره کنسولی که وب سرور در آن در حال اجرا است، با زدن کلیدهای Ctrl+C (کلید Control و کلید C با هم)، وب سرور را متوقف کنید. در ویندوز ممکن است لازم باشد کلیدهای Ctrl+Break را بزنید. سپس لازم است که وب سرور را مجدداً با دستور `python manage.py runserver` راه اندازی کنید. + +> اگر می‌خواهید بیشتر در مورد URLconfs جنگو بدانید، به مستندات رسمی آن نگاهی بیندازید: https://docs.djangoproject.com/en/2.2/topics/http/urls/ \ No newline at end of file diff --git a/fa/django_urls/images/error1.png b/fa/django_urls/images/error1.png new file mode 100644 index 00000000000..50618fca3fe Binary files /dev/null and b/fa/django_urls/images/error1.png differ diff --git a/fa/django_urls/images/url.png b/fa/django_urls/images/url.png new file mode 100644 index 00000000000..c22441e930e Binary files /dev/null and b/fa/django_urls/images/url.png differ diff --git a/fa/django_views/README.md b/fa/django_views/README.md new file mode 100644 index 00000000000..7a51ba2acf9 --- /dev/null +++ b/fa/django_views/README.md @@ -0,0 +1,44 @@ +# ساخت view در جنگو! + +وقتشه که از شر باگی که تو فصل قبلی ایجاد کردیم راحت بشیم :) + +یک *view* یا نما بخشی از برنامه است که "منطق" برنامه در آن قرار می‌گیرد. این مولفه اطلاعات مورد نیاز را از `model` هایی که قبلا ایجاد کرده‌اید می گیرد و به `template` ارسال می‌کند. ما در بخش بعد یک قالب یا template خواهیم ساخت. View ها صرفاً توابع پایتونی هستند که کمی پیچیده‌تر از توابعی هستند که در بخش **آشنایی با پایتون** نوشتیم. + +ویوها در فایل `views.py` قرار دارند. ما *ویوهای* مورد نظرمان را در فایل `blog/views.py` اضافه خواهیم کرد. + +## blog/views.py + +خب، بیایید این فایل را در ویرایشگر کد باز کنیم و ببینیم چه چیزی در آن هست: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render + +# Create your views here. +``` + +هنوز چیز زیادی در آن نیست. + +به یاد داشته باشید که خط هایی که با `#` شروع می‌شوند کامنت یا توضیحات هستند - به این معنی که این خط ها توسط پایتون اجرا نمی‌شوند. + +حالا بیایید همانند توصیه‌ای که در خود فایل شده است یک *view* بسازیم. این ویو بسیار خلاصه را زیر کامنت موجود در فایل اضافه کنید: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` + +همانطور که می‌بینید ما یک تابع ساختیم ( دستور `def` تابع `post_list` را که یک آرگومان به نام `request` می‌گیرد صدا می‌زند و در نهایت به کمک یک تابع دیگر به نام `render` قالب `blog/post_list.html` را باز می‌گرداند (`return`)). + +فایل را ذخیره کنید و در مرورگر خود آدرس http://127.0.0.1:8000/ را بزنید و ببینید چه چیزی دیده می‌شود. + +باز هم خطا! ببینید چه اتفاقی افتاده است: + +![خطا](images/error.png) + +حداقل می‌توان دید که سرور در حال کار است اما هنوز، همه چیز کامل نیست، درست است؟ نگران نباشید این فقط یک صفحه خطاست، لازم نیست بترسید! دقیقاً شبیه خطاهای موجود در کنسول، این خطاها هم کاملاً مفید هستند. شما می‌توانید ببینید که با خطای *TemplateDoesNotExist* یعنی قالب وجود ندارد، مواجه شده اید. خب بگذارید این خطا را درست کنیم و در بخش بعد یک قالب یا template بسازیم! + +> با خواندن مستندات رسمی جنگو اطلاعات بیشتری در مورد ویوها یاد خواهید گرفت: https://docs.djangoproject.com/en/2.2/topics/http/views/ \ No newline at end of file diff --git a/fa/django_views/images/error.png b/fa/django_views/images/error.png new file mode 100644 index 00000000000..1530c879cb5 Binary files /dev/null and b/fa/django_views/images/error.png differ diff --git a/fa/dynamic_data_in_templates/README.md b/fa/dynamic_data_in_templates/README.md new file mode 100644 index 00000000000..32450f053a8 --- /dev/null +++ b/fa/dynamic_data_in_templates/README.md @@ -0,0 +1,84 @@ +# داده‌های پویا در template ها + +ما قطعات مختلفی داریم: مدل `Post` که در فایل `models.py` تعریف شده است، `post_list` که در فایل `views.py` تعریف شده و یک template که ساخته‌ایم. ولی واقعاً چطور پست‌های وبلاگمان را در قالب HTML نشان می‌دهیم؟ چون این کاری است که می‌خواهیم انجام دهیم؛ گرفتن محتوا (مدل‌هایی که در پایگاه داده ذخیره شده اند) و نشان دادن آن در قالب مورد نظر خودمان، درست است؟ + +این دقیقاً همان چیزی است که *view*ها برای آن طراحی شده اند: وصل کردن مدل ها و قالب‌ها. در *ویو* `post_list` ما نیاز داریم که مدل مورد نظر را بگیریم و آن را به تمپلیت مناسب آن ارجاع دهیم. ما در *ویو* تصمیم می‌گیریم که چه چیزی (model) در تمپلیت نشان داده شود. + +بسیار خوب، چطور به این هدف برسیم؟ + +لازم است که فایل`blog/views.py` را در ویرایشگر کد باز کنیم. تا اینجا *ویو* `post_list` شبیه به این است: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render + +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` + +به یاد دارید که در مورد اضافه کردن کدهای نوشته شده در فایل‌های مختلف صحبت کردیم؟ حالا وقت آن است که مدلی را که در فایل `models.py` نوشتیم به این فایل اضافه کنیم. ما خط `from .models import Post` را به این صورت اضافه می‌کنیم: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from .models import Post +``` + +نقطه قبل از `models` به معنی *پوشه جاری* یا *اپلیکیشن جاری* است. هر دو فایل `views.py` و `models.py` در یک پوشه قرار دارند. پس به این معنی است که ما می‌توانیم از `.` به همراه نام فایل (بدون پسوند `.py`) استفاده کنیم. سپس نام مدل را فراخوانی می‌کنیم (`Post`). + +قدم بعدی چیست؟ برای اینکه پست‌های وبلاگی واقعی که قبلاً ساخته ایم را فراخوانی کنیم به چیزی نیاز داریم که به آن `کوئری ست` یا `QuerySet` می‌گوییم. + +## QuerySet + +شما باید با نحوه کار کوئری ست‌ها آشنا باشید. ما در [بخش ORM جنگو](../django_orm/README.md) در مورد آن‌ها صحبت کرده ایم. + +حالا ما پست‌هایی را می‌خواهیم که بر اساس `تاریخ انتشار` یا published_date، مرتب شده اند، درست است؟ این کار را هم در بخش کوئری ست انجام داده ایم! + +{% filename %}blog/views.py{% endfilename %} + +```python +Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +``` + +حالا فایل `blog/views.py` را در ویرایشگر کد باز کنید و این تکه کد را به تابع `def post_list(request)` اضافه کنید. فراموش نکنید که خط `from django.utils import timezone` را هم به بالای فایل اضافه کنید: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from django.utils import timezone +from .models import Post + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {}) +``` + +برای نمایش QuerySet در لیست ارسال های بلاگ، دو کار باقی مانده است که باید انجام شود: + +1. فرستادن کوئری ست `posts` به تمپلیت با تغییر تابع `render`. الان این کار را انجام می‌دهیم. +2. اصلاح تمپلیت برای نمایش دادن کوئری ست `posts`. این کار را در بخش‌های بعد انجام خواهیم داد. + +توجه داشته باشید که ما یک *متغیر* برای کوئری ست مان درست کردیم: `posts`. آن را به عنوان نام کوئری ست در نظر بگیرید. از این به بعد ما به کمک همین نام به این کوئری ست مراجعه می‌کنیم. + +در تابع `render` ما یک پارامتر `request` داریم (درخواستی است که کاربر از طریق اینترنت برای ما ارسال کرده است) و یک پارامتر دیگر که نام فایل template است (`'blog/post_list.html'`). آخرین پارامتر ما، `{}`، محلی است که می‌توانیم چیزهایی را برای استفاده در template در آن قرار دهیم. باید برای این چیزها اسم تعریف کنیم (مثلاً همین متغیر `'posts'`). :) باید به این صورت برای فایل تمپلیت ارسال شوند: `{'posts': posts}`. توجه کنید که بخش سمت چپ علامت `:` از نوع رشته یا string است و لازم است که با علامت نقل قول `''` محصور شود. + +در نتیجه فایل `blog/views.py` ما شبیه به این خواهد شد: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from django.utils import timezone +from .models import Post + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {'posts': posts}) +``` + +همین! وقت آن است که به فایل template برگردیم و این کوئری ست را نمایش دهیم! + +دوست دارید در مورد کوئری ست‌ها بیشتر بدانید؟ به اینجا نگاهی بیندازید: https://docs.djangoproject.com/en/2.2/ref/models/querysets/ \ No newline at end of file diff --git a/fa/extend_your_application/README.md b/fa/extend_your_application/README.md new file mode 100644 index 00000000000..eb64c918205 --- /dev/null +++ b/fa/extend_your_application/README.md @@ -0,0 +1,214 @@ +{% set warning_icon = '' %} + +# برنامه خود را توسعه دهید + +ما تقریباً تمام مراحل مختلف ضروری برای ساختن وبسایتمان را کامل کرده‌ایم: می‌دانیم که چطور مدل، URL، ویو و تمپلیت بنویسیم. علاوه بر این می‌دانیم که چطور وبسایتمان را زیباتر کنیم. + +زمان تمرین است! + +اولین چیزی که در وبلاگمان لازم داریم صفحه‌ای است که یک پست را نشان دهد، درست است؟ + +ما یک مدل `Post` داریم پس لازم نیست چیزی به فایل `models.py` اضافه کنیم. + +## ساختن لینک به جزییات پست در تمپلیت + +ما با اضافه کردن یک لینک به فایل `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.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +{% raw %} ما می‌خواهیم در لیست پست ها، یک لینک از عنوان پست وبلاگی به جزییات پست داشته باشیم. عبارت `

{{ post.title }}

` را تغییر دهید تا به صفحه جزییات پست لینک شود: {% endraw %} + +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} + +```html +

{{ post.title }}

+``` + +{% raw %} زمان آن است که عبارت رازآلود `{% url 'post_detail' pk=post.pk %}` را توضیح دهیم. همانطور که ممکن است حدس زده باشید این علامت `{% %}` به معنی آن است که ما از سیستم template tag جنگو استفاده می‌کنیم. این بار ما از یک tag استفاده خواهیم کرد که برایمان یک URL بسازد!{% endraw %} + +بخش `post_detail` به معنی آن است که جنگو انتظار دارد یک آدرس به نام post_detail، در فایل `blog/urls.py` وجود داشته باشد + +حالا معنی `pk=post.pk` چیست؟ `pk` مخفف primary key (کلید اصلی) است که یک نام منحصر به فرد برای هر ردیف از داده‌ها در پایگاه داده می‌باشد. هر مدل جنگو یک فیلد به عنوان کلید اصلی دارد، و سوای اینکه چه نام دیگری داشته باشد، همواره به عنوان pk قابل ارجاع است. چون ما در مدل `Post` کلید اصلی نساخته بودیم، جنگو یکی برای ما ساخته است (به طور پیشفرض فیلدی که نام آن "id" است، عددی را در خود ذخیره می‌کند که با هر دیتای جدید یکی به آن اضافه می‌شود مثلاً 1، 2، 3 ) و برای هر پست جدید در وبلاگ یکی به آن اضافه می‌کند. ما با نوشتن `post.pk` به کلید اصلی دسترسی پیدا می‌کنیم، همانطور که به فیلدهای دیگر (مانند `title` و `author`) در آبژکت `Post`، دسترسی داشته‌ایم. + +حالا وقتی به آدرس http://127.0.0.1:8000/ می‌رویم با خظا مواجه می‌شویم (همانطور که انتظار داشتیم، چرا که ما هنوز برای `post_detail` ، یک آدرس یا یک *view* نساخته ایم). چیزی شبیه به این: + +![خطا NoReverseMatch](images/no_reverse_match2.png) + +## ساختن آدرس برای جزییات یک پست وبلاگ + +بیایید یک URL برای *ویو* `post_detail` در فایل `urls.py` بسازیم! + +ما می‌خواهیم جزییات اولین پست ما در این **URL** دیده شود: http://127.0.0.1:8000/post/1/ + +بیایید یک آدرس در فایل `blog/urls.py` بسازیم تا جنگو را به *view* با نام `post_detail` هدایت کند که جزییات کامل یک پست وبلاگ را نشان می‌دهد. فایل `blog/urls.py`را در ویرایشگر کد باز کنید و خط `path('post//', views.post_detail, name='post_detail'),` را اضافه کنید، چیزی شبیه به این می‌شود: + +{% filename %}{{ warning_icon }} blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), +] +``` + +بخش `post//` یک الگوی URL را معرفی می‌کند که برای شما توضیح خواهیم داد: + +- `post/` نشان می‌دهد که آدرس باید با کلمه **post** شروع شده باشد و در ادامه آن یک **/** وجود داشته باشد. تا اینجا همه چیز خوب است. +- `` این بخش ممکن است کمی گیج کننده باشد، این عبارت به این معنی است که جنگو انتظار دارد که یک عدد صحیح دریافت کند و مقدار آن را به یک متغیر به نام `pk` نسبت خواهد داد. +- `/` - درنهایت ما به یک **/** در انتهای آدرس نیاز داریم. + +یعنی اگر شما آدرس `http://127.0.0.1:8000/post/5/` را در مرورگر خود وارد کنید جنگو متوجه خواهد شد که شما به دنبال یک *view* به نام `post_detail` هستید و مقدار متغیر `pk` را برابر `5` قرار می‌دهد و این اطلاعات را به *view* مورد نظر ارسال می‌کند. + +بسیار عالی، ما یک الگوی آدرس جدید به فایل `blog/urls.py` اضافه کردیم! حالا صفحه http://127.0.0.1:8000/ را دوباره بارگزاری کنید، بووم! سرور دوباره متوقف شده است. به کنسول نگاهی بیندازید، یک پیغام خطای دیگر دیده می‌شود! + +![AttributeError](images/attribute_error2.png) + +یادتان هست که مرحله بعدی چیست؟ اضافه کردن ویو! + +## اضافه کردن ویو جزییات یک پست + +این بار *view* ما یک پارامتر اضافه دریافت کرده است، `pk`. *ویو* ما باید بتواند آن را دریافت کند، درست است؟ پس ما تابع خودمان را به این صورت تعریف می‌کنیم `def post_detail(request, pk):`. باید توجه داشته باشید که این پارامتر باید دقیقاً همان نامی را داشته باشد که ما در `urls` تعریف کرده‌ایم (`pk`). همچنین توجه کنید که حذف این متغیر، غلط است و باعث ایجاد خطا خواهد شد. + +حالا ما می‌خواهیم فقط و فقط یک پست وبلاگی را داشته باشیم. برای اینکار از کوئری ست به شکل زیر استفاده می‌کنیم: + +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} + +```python +Post.objects.get(pk=pk) +``` + +اما این کد یک مشکل دارد. اگر هیچ `Post` با `کلید اصلی` (`pk`) وجود نداشته باشد، یک خطای زشت دریافت خواهیم کرد! + +![خطا DoesNotExist](images/does_not_exist2.png) + +چنین چیزی را نمی‌خواهیم! اما خوشبختانه جنگو چیزی دارد که می‌تواند این مشکل را حل کند: `get_object_or_404`. در صورتی که هیچ `Post` با `pk` داده شده وجود نداشته باشد، یک صفحه خطای زیباتر یعنی صفحه `Page Not Found 404` را نشان خواهد داد. + +![صفحه پیدا نشد](images/404_2.png) + +خبر خوب اینکه شما می‌توانید صفحه `Page not found` اختصاصی برای خودتان را با سلیقه خودتان بسازید. اما این الان موضوع خیلی مهمی نیست بنابراین ما از آن رد خواهیم شد. + +وقت آن است که یک *ویو* به فایل `views.py` اضافه کنیم! + +در فایل `blog/urls.py` ما یک الگوی آدرس به نام `post_detail` ساختیم که به یک ویو با نام `views.post_detail` ارجاع داشت. این به این معنی است که جنگو انتظار دارد که یک تابع با نام `post_detail` در فایل `blog/views.py` وجود داشته باشد. + +زمان آن است که فایل `blog/views.py` را در ویرایشگر کد باز کنید و خطوط زیر را در ردیف `from` ها اضافه کنید: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render, get_object_or_404 +``` + +و در انتهای فایل، *ویو* خودمان را اضافه خواهیم کرد: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) +``` + +بله، حالا وقت بارگذاری مجدد صفحه است: http://127.0.0.1:8000/ + +![Post list view](images/post_list2.png) + +کار می‌کند! ولی وقتی روی لینک مربوط به عنوان یک پست کلیک کنید چه اتفاقی می‌افتد؟ + +![خطا TemplateDoesNotExist](images/template_does_not_exist2.png) + +وای نه! یک خطای دیگر! اما حالا ما می‌دانیم که چطور با این خطا برخورد کنیم، درست است؟ ما باید یک تمپلیت اضافه کنیم! + +## ساختن یک تمپلیت برای جزییات پست وبلاگی + +در پوشه `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.text|linebreaksbr }}

+
+{% endblock %} +``` + +یک بار دیگر ما فایل `base.html` را اضافه کرده‌ایم. ما می‌خواهیم در بلوک `content` ، جزییات یک پست منتشر شده (اگر چنین پستی وجود داشت) شامل عنوان و متن را نشان دهیم. اما باید در مورد چند موضوع مهم صحبت کنیم، خب؟ + +{% raw %}`{% if ... %} ... {% endif %}` یک تمپلیت تگ است که وقتی می‌خواهیم چیزی را چک کنیم از آن استفاده می‌کنیم. (عبارت `if ... else ...` را از بخش **آشنایی با پایتون** به یاد دارید؟) در این سناریو ما می‌خواهیم بررسی کنیم آیا بخش `published_date` مربوط به یک پست خالی نیست.{% endraw %} + +بسیار خوب، ما می‌توانیم صفحه وبلاگمان را دوباره بارگذاری کنیم و ببینیم آیا خطا `TemplateDoesNotExist` از بین رفته است یا نه. + +![صفحه جزییات پست](images/post_detail2.png) + +واو! بالاخره کار کرد! + +# زمان دیپلوی! + +خوب خواهد بود اگر ببینیم وبسایت شما هنوز روی PythonAnywhere کار میکند یا نه؟پس بیایید یک بار دیگر آن را منتشر کنیم. + +{% filename %}خط فرمان{% endfilename %} + + $ 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 + + +سپس در کنسول [PythonAnywhere Bash console](https://www.pythonanywhere.com/consoles/) تایپ کنید: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(یادتان باشد که `` را با زیر دامنه اصلی خود در PythonAnywhere عوض کنید البته بدون آکولادها.) + +## به روزرسانی فایل‌های ایستا در سرور + +سرورهایی مانند PythonAnywhere دوست دارند که با فایل‌های ایستا (مانند فایل‌های CSS) به گونه‌ای متفاوت از فایل‌های پایتون برخورد کنند، چرا که می‌توانند آن ها را بهینه کنند و سرعت لود شدن آن‌ها را افزایش دهند. در نتیجه هرگاه که ما تغییری در فایل‌های CSS می‌دهیم ، باید دستوری اضافه بر روی آن اجرا کنیم تا به سرور بگوییم که این فایل‌ها تغییر کرده اند. این دستور `collectstatic` نام دارد. + +ابتدا با فعال کردن محیط مجازی شروع کنیم اگر از قبل هنوز فعال نیست (PythonAnywhere از دستوری به نام `workon` برای این کار استفاده می‌کند این دستور دقیقاً شبیه `source myenv/bin/activate` است که شما بر روی کامپیوتر خودتان اجرا می‌کنید): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ workon .pythonanywhere.com + (ola.pythonanywhere.com)$ python manage.py collectstatic + [...] + + +دستور `manage.py collectstatic` تقریباً شبیه دستور `manage.py migrate` است. ما تغییراتی در کدها می‌دهیم و به جنگو می‌گوییم این تغییرات را *apply* (اعمال) کند، چه در فایل‌های ایستا در سرور باشد چه در پایگاه داده. + +به هرحال، الان ما آماده هستیم، به سراغ ["Web" page](https://www.pythonanywhere.com/web_app_setup/) بروید (از طریق دکمه menu در گوشه بالا و سمت راست کنسول) و دکمه **Reload** را بزنید و سپس به صفحه https://subdomain.pythonanywhere.com نگاه کنید تا نتیجه را ببینید. + +به نتیجه رسید! تبریک! :) \ No newline at end of file diff --git a/fa/extend_your_application/images/404_2.png b/fa/extend_your_application/images/404_2.png new file mode 100644 index 00000000000..0a6fdf3234e Binary files /dev/null and b/fa/extend_your_application/images/404_2.png differ diff --git a/fa/extend_your_application/images/attribute_error2.png b/fa/extend_your_application/images/attribute_error2.png new file mode 100644 index 00000000000..4b8262476d9 Binary files /dev/null and b/fa/extend_your_application/images/attribute_error2.png differ diff --git a/fa/extend_your_application/images/does_not_exist2.png b/fa/extend_your_application/images/does_not_exist2.png new file mode 100644 index 00000000000..e7015f2c80d Binary files /dev/null and b/fa/extend_your_application/images/does_not_exist2.png differ diff --git a/fa/extend_your_application/images/no_reverse_match2.png b/fa/extend_your_application/images/no_reverse_match2.png new file mode 100644 index 00000000000..aba1c9c8980 Binary files /dev/null and b/fa/extend_your_application/images/no_reverse_match2.png differ diff --git a/fa/extend_your_application/images/post_detail2.png b/fa/extend_your_application/images/post_detail2.png new file mode 100644 index 00000000000..b40c92efb8c Binary files /dev/null and b/fa/extend_your_application/images/post_detail2.png differ diff --git a/fa/extend_your_application/images/post_list2.png b/fa/extend_your_application/images/post_list2.png new file mode 100644 index 00000000000..dd0a0d67a6f Binary files /dev/null and b/fa/extend_your_application/images/post_list2.png differ diff --git a/fa/extend_your_application/images/template_does_not_exist2.png b/fa/extend_your_application/images/template_does_not_exist2.png new file mode 100644 index 00000000000..c856abeda31 Binary files /dev/null and b/fa/extend_your_application/images/template_does_not_exist2.png differ diff --git a/fa/how_the_internet_works/README.md b/fa/how_the_internet_works/README.md new file mode 100644 index 00000000000..92ce549d377 --- /dev/null +++ b/fa/how_the_internet_works/README.md @@ -0,0 +1,47 @@ +# اینترنت چگونه کار می‌کند + +> برای خوانندگان در خانه: این فصل در ویدئو [نصب پایتون و کد ویرایشگر](https://www.youtube.com/watch?v=oM9yAA09wdc) توضیح داده شده است. +> +> این فصل "اینترنت چگونه کار می‌کند" از سخنرانی جسیکا مک کلر (http://web.mit.edu/jesstess/www/) الهام گرفته شده است. + +قطعاً شما هر روز از اینترنت استفاده می‌کنید. اما آیا می‌دانید در واقع وقتی شما آدرسی مثل https://djangogirls.org را در مرورگر خود تایپ می‌کنید، چه اتفاقی می‌افتد؟ + +اولین چیزی که باید بدانید این است که یک وب سایت از مجموعه‌ای از فایل‌ها تشکیل شده است که روی یک هارد دیسک ذخیره شده اند ـ دقیقاً مانند فیلم‌ها، آهنگ‌ها و تصاویر شما. با این وجود، وب سایت ها یک ویژگی منحصر به فرد دارند: کدهای کامپیوتری به نام HTML. + +اگر با برنامه نویسی آشنایی ندارید، ممکن است درک HTML در ابتدا سخت باشد، ولی مرورگر های شما (مثل گوگل کروم، سافاری، فایرفاکس و...) عاشق آن هستند. مرورگرها طراحی شده اند تا این کدها را درک کنند، دستورات آنها را دنبال کنند و فایل‌هایی را که وب سایت شما از آن تشکیل شده است، دقیقاً آنطور که می‌خواهید، نمایش دهند. + +مانند هر فایل دیگری، ما نیاز داریم تا فایل‌های HTML را نیز جایی بر روی هارد دیسک ذخیره کنیم. برای اینترنت، ما از کامپیوترهای مخصوص و قوی به نام *servers* استفاده می‌کنیم. این کامپیوترها صفحه نمایش، کیبورد یا موس ندارند برای آنکه وظیفه اصلی آن‌ها ذخیره اطلاعات و ارائه آن‌ها است. برای همین به آن‌ها *سرور* می‌گویند برای آنکه آن‌ها داده‌ها را *ارائه* می‌کنند (serve یعنی ارائه کردن). + +خب، ولی شما می‌خواهید بدانید که اینترنت چطور کار می‌کند، درست است؟ + +تصویری برای شما کشیده ایم! چیزی شبیه به این: + +![تصویر 1.1](images/internet_1.png) + +کمی به هم ریخته است، درست است؟ در واقع این شبکه‌ای از ماشین‌های به هم متصل شده است (همانطور که در بالا اشاره شد *سرورها* هستند). صدها و هزاران دستگاه! کیلومترها سیم و کابل دور دنیا! شما می‌توانید وبسایت نقشه کابل‌های زیردریایی (http://submarinecablemap.com) را ببینید تا با پیچیدگی شبکه آشنا شوید. این تصویری از این وبسایت است: + +![تصویر 1.2](images/internet_3.png) + +جذاب است، اینطور نیست؟ اما کشیدن یک سیم مستقیم بین هر دستگاه متصل شده به اینترنت با دیگر دستگاه‌ها ممکن نیست. بنابراین برای رسیدن به یک دستگاه (مثلاً دستگاهی که https://djangogirls.org روی آن ذخیره شده) نیاز است تا ما درخواستی (request) را از طریق دستگاه‌های بسیار زیادی ارسال کنیم. + +شبیه به این: + +![تصویر 1.3](images/internet_2.png) + +تصور کنید که وقتی شما https://djangogirls.org را تایپ می‌کنید، نامه‌ای فرستاده اید به این مضمون: "دختران جنگو عزیز، من می‌خواهم وب سایت djangogirls.org را ببینم. لطفاً آن را برای من بفرستید!" + +نامه شما به نزدیکترین اداره پست فرستاده می‌شود. بعد به اداره پست دیگری می‌رود که کمی بیشتر به مقصد نزدیک است و همینطور پیش می‌رود تا به مقصد نهایی برسد. تنها ویژگی این سیستم این است که اگر نامه های بسیاری به یک مقصد بفرستید (*data packets*) آن‌ها می‌توانند از مسیرهایی کاملاً متفاوت (*routers*) به مقصد برسند. این موضوع بستگی به این دارد که نامه ها در هر اداره پست چطور تقسیم شوند. + +![تصویر 1.4](images/internet_4.png) + +این روش کار است - شما پیغامی میفرستید و منتظر پاسخ می‌مانید. به جای قلم و کاغذ شما از بایت‌های داده استفاده می‌کنید اما منطق کار یکسان است! + +به جای آدرس یا نام خیابان، شهر و کدپستی، ما از آدرس IP استفاده می‌کنیم. کامپیوتر شما ابتدا از DNS (Domain Name System) می‌خواهد که djangogirls.org را به IP address تبدیل کند. این سیستم شبیه دفترچه تلفن‌های قدیمی است که شما می‌توانستید دنبال نام یک نفر بگردید و آدرس و شماره تلفن وی را پیدا کنید. + +وقتی شما نامه‌ای می‌فرستید نیاز است که ویژگی های مشخصی داشته باشد تا قابل ارسال باشد: آدرس، تمبر و غیره. علاوه بر این از زبانی استفاده می‌کنید که گیرنده آن را متوجه شود، درست است؟ عین همین اتفاق برای *data packet* هایی می‌افتد که شما برای دیدن یک وبسایت ارسال می‌کنید. ما از پروتکلی به نام HTTP (Hypertext Transfer Protocol) استفاده می‌کنیم. + +بنابراین به طور اصولی، وقتی شما وبسایتی دارید، نیاز است تا یک *سرور* داشته باشید که وبسایت بر روی آن قرار داشته باشد. وقتی که *سرور* یک *ریکوئست* (یک درخواست به صورت یک نامه) را دریافت می‌کند، وبسایت شما را در پاسخ به آن نامه ارسال می‌کند (در یک نامه جداگانه). + +از آنجاییکه این دوره آموزشی جنگو است، ممکن است شما بپرسید جنگو چه کاری را انجام می‌دهد. وقتی شما پاسخ هر درخواست را می‌فرستید، معمولاً نمی‌خواهید یک پاسخ یکسان را برای همه بفرستید. بسیار بهتر خواهد بود اگر هر نامه‌ای شخصی و ویژه هر فرد فرستنده، پاسخ داده شود، درست است؟ جنگو به شما کمک می‌کند تا این نامه‌های شخصی و جالب را بسازید. :) + +صحبت بس است - وقت ساختن است! \ No newline at end of file diff --git a/fa/how_the_internet_works/images/internet_1.png b/fa/how_the_internet_works/images/internet_1.png new file mode 100644 index 00000000000..e289eac2b23 Binary files /dev/null and b/fa/how_the_internet_works/images/internet_1.png differ diff --git a/fa/how_the_internet_works/images/internet_2.png b/fa/how_the_internet_works/images/internet_2.png new file mode 100644 index 00000000000..e8cf8b77999 Binary files /dev/null and b/fa/how_the_internet_works/images/internet_2.png differ diff --git a/fa/how_the_internet_works/images/internet_3.png b/fa/how_the_internet_works/images/internet_3.png new file mode 100644 index 00000000000..6f5d95dec80 Binary files /dev/null and b/fa/how_the_internet_works/images/internet_3.png differ diff --git a/fa/how_the_internet_works/images/internet_4.png b/fa/how_the_internet_works/images/internet_4.png new file mode 100644 index 00000000000..d4748ac48ef Binary files /dev/null and b/fa/how_the_internet_works/images/internet_4.png differ diff --git a/fa/html/README.md b/fa/html/README.md new file mode 100644 index 00000000000..8dc4c605f52 --- /dev/null +++ b/fa/html/README.md @@ -0,0 +1,227 @@ +# آشنایی با HTML + +ممکن است بپرسید تمپلیت چیست؟ + +تمپلیت (به معنی قالب) فایلی است که می‌توانیم بارها از آن استفاده کنیم و اطلاعات مختلفی را به کمک آن و در یک فرمت ثابت ارائه کنیم. مثلاً شما می‌توانید از یک تمپلیت کمک بگیرید و یک نامه بنویسید چرا که با اینکه هر نامه‌ای پیغام و آدرس متفاوتی دارد، اما از فرمت مشابهی استفاده می‌کند. + +یک تمپلیت جنگو توسط زبانی به نام HTML تعریف می‌شود (همان HTML که در بخش اول، **اینترنت چگونه کار می‌کند**، به آن اشاره کرده بودیم). + +## HTML چیست؟ + +HTML نوعی از کد است که توسط مرورگر وب، مانند کروم و فایرفاکس یا سافاری، تفسیر و اجرا می‌شود تا یک صفحه وب را نشان دهد. + +HTML مخفف عبارت "HyperText Markup Language" است. **HyperText** به این معنی است که نوعی از نوشته است که هایپرلینک بین صفحات را پشتیبانی می‌کند. **Markup** یعنی ما یک متن را برمی‌داریم و آن را علامت گذاری می‌کنیم تا به سیستم دیگری (مثلاً در اینجا مرورگر وب) بگوییم چطور آن را تفسیر کند. کدهای HTML با **tag** ها ساخته شده اند که هرکدام با `>` آغاز و با `<` پایان می‌یابند. این تگ‌ها **المان‌های** نشانه گذاری هستند. + +## اولین تمپلیت شما! + +ساختن یک تمپلیت یعنی ساختن یک فایل تمپلیت. هرچیزی، یک فایل است، درست است؟ احتمالاً تا الان این موضوع را متوجه شده اید. + +تمپلیت‌ها در دایرکتوری `blog/templates/blog` ذخیره می‌شوند. بنابراین اول یک دایرکتوری به نام `templates` در دایرکتوری وبلاگ بسازید. سپس دایرکتوری دیگری به نام `blog` در داخل آن بسازید: + + blog + └───templates + └───blog + + +(ممکن است فکر کنید که چرا دوتا دایرکتوری به نام `blog` لازم داریم. همانطور که بعدتر خواهیم دید این یک سیستم نامگذاری کارآمد برای وقتی است که اوضاع پیچیده‌تر می‌شود.) + +حالا یک فایل `post_list.html` (که فعلاً خالی باشد) در دایرکتوری بسازید `blog/templates/blog`. + +نگاه کنید که الان وبسایت شما چه شکلی شده است: http://127.0.0.1:8000/ + +> اگر هنوز پیغام خطا `TemplateDoesNotExist` را می‌بینید، یک بار سرور را قطع و بعد دوباره فعال کنید. به خط فرمان بروید سرور را با زدن Ctrl+C (کلید کنترل و کلید 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/ + +![تصویر 11.2](images/step3.png) + +کار می‌کند! خوب شد! :) + +* خط `` یک تگ HTML نیست. این عبارت فقط نوع فایل را مشخص می‌کند. در اینجا این عبارت به مرورگر اعلام می‌کند که نوع فایل [HTML5](https://html.spec.whatwg.org/#the-doctype) است. همیشه شروع هر نوع فایل HTML5 با همین عبارت شروع می‌شود. +* `` پایه‌ای‌ترین تگ و معمولاً اولین تگ در ابتدای صفحه است و تگ `` معمولاً در انتهای صفحه می‌آید. همانطور که می‌بینید، تمام محتوای وبسایت بین تگ `` در ابتدا و تگ `` در انتها قرار می‌گیرند +* تگ `

` برای پاراگراف‌ها به کار می‌رود و تگ `

` پایان هر پاراگراف را مشخص می‌کند + +## Head and body + +هر صفحه HTML همچنین به دو بخش اصلی تقسیم می‌شود: **head** و **body**. + +* **head** عنصری است که شامل اطلاعاتی در مورد هر فایل می‌شود که در صفحه نشان داده نمی‌شوند. + +* **body** عنصری است که شامل هر چیزی است که در صفحه وبسایت نمایش داده می‌شوند. + +ما از `` استفاده می‌کنیم تا در مورد تنظیمات فایل به مرورگر اطلاعاتی بدهیم و `` نشان می‌دهد که چه چیزی واقعاً در صفحه وجود دارد. + +برای مثال شما می‌توانید تگ عنوان یا title را به شکل زیر در ``، قرار دهید: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + + Ola's blog + + +

Hi there!

+

It works!

+ + +``` + +این فایل‎ را ذخیره کنید و وبسایت خود را دوباره بارگذاری کنید. + +![تصویر 11.3](images/step4.png) + +توجه کنید که چگونه مرورگر متوجه شد که "Ola's blog" عنوان صفحه شماست؟ مرورگر عبارت `Ola's blog` را تفسیر کرده و آن را به عنوان نام صفحه، در نوار نام صفحه مرورگر قرار داده است (البته عنوان در جاهای دیگری مانند bookmark کردن هم استفاده می‌شود). + +احتمالاً تا الان توجه کرده‌اید که هر تگ شروع به همراه یک *تگ پایان* و علامت `/` می‌آید و عوامل در آن نیز *nested* می‌شوند (یعنی شما نمی‌توانید یک تگ را ببندید مگر آنکه تمام تگ‌های درون آن را بسته باشید). + +شبیه گذاشتن چیزها در جعبه است. شما یک جعبه بزرگ دارید، ``؛ درون آن یک جعبه دیگر ``، و این همینطور ادامه دارد تا به کوچکترین جعبه برسد: `

`. + +شما باید از این قوانین *بستن تگ‌ها* و نیز *nesting*، پیروی کنید. اگر این قوانین رعایت نشوند مرورگر ممکن است نتواند فایل شما را درست تفسیر کند و صفحه HTML درست نمایش داده نخواهد شد. + +## تنظیم کردن تمپلیت + +الان می‌توانید کمی تفریح کنید و تلاش کنید تا تمپلیت خود را تنظیم کنید! در اینجا تعدادی تگ مفید معرفی شده: + +* `

heading

` یک تیتر برای عنوان‌های مهم +* `

sub-heading

` یک تیتر برای عنوان‌های کم اهمیت‌تر +* `

sub-sub-heading

` یک زیر عنوان که تا `
` درجه اهمیت آن کمتر می‌شود +* `

پاراگراف

پاراگرافی از نوشته‌ها` +* `تاکید` بر نوشته شما تاکید می‌کند +* `تاکید` تاکید بیشتر روی متن +* `
` به خط بعد می‌رود (شما نمی‌توانید چیزی درون تگ br بگذارید و علاوه بر این br، تگِ پایانی ندارد) +* `لینک` یک لینک می‌سازد +* `
  • آیتم اول
  • آیتم دوم
` یک لیست، دقیقاً مانند همین لیست درست می‌کند! +* `
` یک بخش جدید در صفحه تعریف می‌کند +* `` مجموعه‌ای از لینک‌های دسترسی را تعریف می‌کند +* `
`محتوای مستقل و فارق از محیط را مشخص می‌کند +* `
` یک بخش را در فایل مشخص می‌کند +* `
` بخش سربرگ یک صفحه را مشخص می‌کند +* `
` بخش محتوای اصلی صفحه را مشخص می‌کند +* `` محتوای جانبی نسبت به جایی که در آن قرار گرفته را مشخص می‌کند (مانند منوی کناری) +* `
` بخش پاورقی یک سند را مشخص می‌کند +* `` بک زمان (یا تاریخ و زمان) را مشخص می‌کند + +اینجا نمونه‌ای از یک تمپلیت کامل داریم. آن را در فایل `blog/templates/blog/post_list.html` کپی کنید: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + + Django Girls blog + + +
+

Django Girls Blog

+
+ +
+ +

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.

+
+ +
+ +

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.

+
+ + +``` + +ما اینجا یک بخش `header` و دو بخش 0>article ایجاد کردیم. + +* بخش `header` شامل عنوان مقاله وبلاگ ماست - یک عنوان و یک لینک +* دو عنصر `article` شامل پست‌های وبلاگ ما به همراه تاریخ انتشار در یک عنصر `time`، یک عنصر`h2` با عنوان مقاله که قابل کلیک کردن است و عنصر `p` (paragraph) که برای متن مقاله استفاده شده است. + +چنین نتیجه ای به ما می‌دهد: + +![تصویر 11.4](images/step6.png) + +واای! ولی تا اینجا تمپلیت ما دقیقاً **اطلاعات یکسانی** را نمایش می‌دهد درحالیکه قبل‌تر در مورد این صحبت کردیم که تمپلیت به ما اجازه می‌دهد **اطلاعات متفاوتی** را در **قالب یکسان** نمایش دهیم. + +آن چیزی که واقعاً می‌خواهیم این است که پست‌های واقعی که در جنگو ادمین اضافه کرده‌ایم را نمایش دهد و این همان چیزی است که در ادامه سراغ آن خواهیم رفت. + +## فقط یک چیز دیگر: دیپلوی! + +خیلی خوب خواهد بود که همه اینها را به صورت آنلاین بر روی اینترنت ببینیم، درست است؟ پس بیایید یک بار دیگر به کمک PythonAnywhere وبسایت را منتشر کنیم: + +### کامیت کنید و کد را بر روی گیتهاب پوش کنید + +اول از همه ببینیم کدام فایل ها را به نسبت آخرین انتشار، تغییر داده ایم (این دستور را بر روی کامپیوتر خود اجرا کنید و نه در PythonAnywhere): + +{% filename %}خط فرمان{% endfilename %} + + $ git status + + +مطمئن باشید که در دایرکتوری `djangogirls` هستید و به `گیت` اجازه دهید تمام تغییرات ایجاد شده در این دایرکتوری را در نظر بگیرد: + +{% filename %}خط فرمان{% endfilename %} + + $ git add . + + +قبل از آنکه همه فایل‌ها را آپلود کنیم بگذارید ببینیم که `گیت` چه فایل‌هایی را آپلود خواهد کرد (تمام فایل‌هایی که `گیت` آپلود خواهد کرد الان سبز رنگ دیده می‌شوند): + +{% filename %}خط فرمان{% endfilename %} + + $ git status + + +حالا وقت آن است که بگوییم تمام این تغییرات را در سابقه خودش ذخیره کند. الان می‌خواهیم یک "commit message" یا پیغام کامیت تعریف کنیم که تغییرات ما را توضیح می‌دهد. هرچیزی که دلتان بخواهد می‌توانید تایپ کنید، اما بهتر است توضیحاتی را بنویسید که بعداً متوجه شوید در این مرحله چه تغییراتی داده‌اید. + +{% filename %}خط فرمان{% endfilename %} + + $ git commit -m "Changed the HTML for the site." + + +> **نکته** مطمئن باشید که از علامت نقل قول دوتایی در اطراف پیغام مربوط به کامیت استفاده کنید. + +وقتی این کار را انجام دادیم تغییرات را در گیتهاب آپلود (push) می‌کنیم: + +{% filename %}خط فرمان{% endfilename %} + + $ git push + + +### فایل‌های جدیدتان را بر روی PythonAnywhere ببرید و صفحه وبسایت را دوباره بارگذاری کنید + +* سپس دوباره به صفحه **Bash console** خود در [PythonAnywhere](https://www.pythonanywhere.com/consoles/) بروید (یا یک کنسول خط فرمان جدید باز کنید) و دستورات زیر را اجرا کنید: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +یادتان باشد که `` را با زیر دامنه اصلی خود در PythonAnywhere عوض کنید البته بدون آکولادها. نام زیردامنه شما معمولاً همان نام کاربری شما در PythonAnywhere است اما در مواردی ممکن است کمی متفاوت باشد (مثلاً اگر نام کاربری شما دارای حروف بزرگ باشد). اگر این دستور کار نکرد از `ls` (لیست کردن فایل‌ها) استفاده کنید تا زیردامنه خود را پیدا کنید و سپس با دستور `cd` به آن دایرکتوری بروید. + +حالا منتظر شوید تا فایل‌های شما دانلود شوند. اگر می‌خواهید بدانید که فایل‌ها رسیده اند یا نه به صفحه **"Files"** بروید و کدهای خود بر روی PythonAnywhere را ببینید (شما میتوانید به بقیه فایل‌های خود در PythonAnywhere، از طریق کلید منو در کنسول دسترسی پیدا کنید). + +* سرانجام به صفحه ["Web"](https://www.pythonanywhere.com/web_app_setup/) بروید و **Reload** را بزنید. + +تغییرات شما آنلاین شده اند! صفحه وبسایت خود را در مرورگرتان دوباره بارگذاری کنید. تغییرات دیده خواهند شد. :) \ No newline at end of file diff --git a/fa/html/images/step1.png b/fa/html/images/step1.png new file mode 100644 index 00000000000..eb474aaeddd Binary files /dev/null and b/fa/html/images/step1.png differ diff --git a/fa/html/images/step3.png b/fa/html/images/step3.png new file mode 100644 index 00000000000..47ede3f9993 Binary files /dev/null and b/fa/html/images/step3.png differ diff --git a/fa/html/images/step4.png b/fa/html/images/step4.png new file mode 100644 index 00000000000..0e6b48ec4a5 Binary files /dev/null and b/fa/html/images/step4.png differ diff --git a/fa/html/images/step6.png b/fa/html/images/step6.png new file mode 100644 index 00000000000..f044389de53 Binary files /dev/null and b/fa/html/images/step6.png differ diff --git a/fa/images/application.png b/fa/images/application.png new file mode 100644 index 00000000000..79071fe8d1b Binary files /dev/null and b/fa/images/application.png differ diff --git a/fa/installation/README.md b/fa/installation/README.md new file mode 100644 index 00000000000..d5fde0951c5 --- /dev/null +++ b/fa/installation/README.md @@ -0,0 +1,69 @@ +# اگر این آموزش را در خانه دنبال می‌کنید + +اگر این آموزش را در خانه دنبال می‌کنید و نه در یکی از [رویدادهای دختران جنگو](https://djangogirls.org/events/)، می‌توانید به طور کامل از این بخش بگذرید و به بخش [اینترنت چگونه کار می‌کند](../how_the_internet_works/README.md) بروید. + +به دلیل اینکه ما نصب کردن هر چیزی را که دراین سری آموزشی نیاز است، در محل مورد نیاز بیان می‌کنیم. این صفحه تنها برای بیان همه دستورات نصب در یک مکان، اضافه شده است (که برای برخی کارگاه‌ها مفید است). شما می‌توانید هرچیزی که در این بخش آمده است را نصب کنید. اما اگر ترجیح می‌دهید پیش از نصب چند ابزار و نرم افزار روی کامپیوترتان، در مورد آن‌ها یاد بگیرید، از این بخش عبور کنید. ما نحوه‌ی نصب هر چیزی را، زمانی که به آن نیاز داشتید، توضیح می‌دهیم. + +موفق باشید! + +# اگر در یک کارگاه شرکت کرده‌اید + +اگر در یکی از [رویدادهای جنگو برای دختران](https://djangogirls.org/events/) شرکت کرده اید: + +* ممکن است کارگاه شما یک "جلسه نصب پیش‌نیازها" قبل از رویداد اصلی داشته باشد. اگر در جلسه نصب پیش‌نیازها هستید، این بخش مخصوص شماست! برای نصب هرچیزی که در این رویداد نیاز دارید، دستورالعمل‌های این بخش را دنبال کنید، و در صورت نیاز از مربی‌ها کمک بگیرید. سپس در کارگاه اصلی، می‌توانید از دستورالعمل‌های نصب که در آموزش اصلی با آنها مواجه می‌شوید، عبور کنید. +* ممکن است برگزار کنندگان کارگاه، از شما بخواهند تا سعی کنید همه چیز را قبل از شروع کارگاه روی کامپیوترتان نصب کنید. اگر از شما این درخواست را داشته اند، این بخش برای شماست! به بهترین نحو دستورالعمل های این بخش را دنبال کنید. اگر نتوانستید چیزی را نصب کنید، در کارگاه اصلی، زمانی که به دستورالعمل‌های نصب آن بخش در آموزش اصلی می‌رسید، می‌توانید از مربی‌ها کمک بگیرید. +* اگر کارگاه شما فاقد جلسه نصب پیش نیازها بود (یا شما نتوانستید در آن شرکت کنید)، و اگر برگزارکنندگان از شما نخواستند که همه چیز را پیش از شروع رویداد نصب کنید، از این بخش عبور کنید و مستقیم به بخش [ اینترنت چگونه کار می‌کند](../how_the_internet_works/README.md) بروید. شما هر چیزی را که به آن نیاز دارید، در طول آموزش اصلی نصب خواهید کرد. + +# نصب پیش‌نیازها + +در این آموزش شما یک وبلاگ خواهید ساخت. برای انجام این کار، در خلال روند آموزش، به شما نحوه‌ی نصب نرم‌افزارهای مختلف روی کامپیوترتان و نحوه‌ی راه اندازی چند حساب اینترنتی گفته خواهد شد. این بخش شامل تمام مراحل نصب و دستورالعمل‌های ثبت نام است (که برای بعضی از کارگاه‌ها مفید است). + + {% include "/chromebook_setup/instructions.md" %} + + + +# معرفی کوتاه کنسول خط فرمان {#command-line} + +بسیاری از مراحل زیر به "کنسول"، "ترمینال"، "پنجره دستورات" یا "خط فرمان" اشاره می‌کنند ـ همه آنها یک معنا دارند: یک پنجره روی کامپیوتر شما که می‌توانید دستوراتی را در آن وارد کنید. زمانی که به آموزش اصلی رسیدید، در مورد خط فرمان بیشتر می‌آموزید. فعلاً، اصلی‌ترین موردی که باید بدانید نحوه باز کردن یک پنجره خط فرمان و شکل ظاهری آن است: +{% include "/intro_to_command_line/open_instructions.md" %} + +# نصب پایتون {#python} + +{% include "/python_installation/instructions.md" %} + +# نصب یک ویرایشگر متنی {#code-editor} + +{% include "/code_editor/instructions.md" %} + +# نصب محیط مجازی و نصب جنگو {#virtualenv} + +{% include "/django_installation/instructions.md" %} + +# نصب گیت {#git} + +{% include "/deploy/install_git.md" %} + +# ساخت حساب کاربری GitHub {#github-account} + +به [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) + +* [معرفی پایتون](../python_introduction/README.md) + +* [جنگو چیست؟](../django/README.md) + +# از کارگاه لذت ببرید! + +زمانی که کارگاه را شروع کردید، می‌توانید مستقیماً به بخش [اولین پروژه جنگو شما](../django_start_project/README.md) بروید، چون قبلاً مطالب بخش‌های پیش از آن را مرور کرده اید. diff --git a/fa/intro_to_command_line/README.md b/fa/intro_to_command_line/README.md new file mode 100644 index 00000000000..331bb60fb29 --- /dev/null +++ b/fa/intro_to_command_line/README.md @@ -0,0 +1,441 @@ +# آشنایی با خط فرمان + +> برای خوانندگان در خانه: این فصل در ویدئو [دوست جدید شما: Command Line](https://www.youtube.com/watch?v=jvZLWhkzX-8) توضیح داده شده است. + +هیجان انگیز است! شما تا چند دقیقه دیگر اولین خط کد خود را خواهید نوشت! :) + +**بگذارید شما را به اولین دوست جدیدتان معرفی کنیم: خط فرمان!** + +این مراحل به شما یاد می‌دهد که چطور از این پنجره سیاهی استفاده کنید که همه هکرها از آن استفاده می‌کنند. ممکن است در ابتدا کمی ترسناک به نظر بیاید ولی این فقط یک علامت است که نشان می‌دهد سیستم منتظر فرمان‌های شماست. + +> **نکته** توجه داشته باشید که در این دوره آموزشی ما بارها از دایرکتوری یا پوشه صحبت کرده ایم هر دو این مفاهیم یکی هستند. + +## خط فرمان چیست؟ + +این پنجره که معمولاً **command line** یا **صفحه خط فرمان** گفته می‌شود یک نرم افزار مبتنی بر متن است که برای مشاهده، مدیریت و تغییر فایل‌ها از آن استفاده می‌شود. شباهت زیادی به ویندوز اکسپلورر یا فایندر در مک دارد با این تفاوت که اینترفیس گرافیکی ندارد. نام های دیگر خط فرمان این‌ها هستند: *cmd*, *CLI*, *prompt*, *console* ، *terminal*. + +## اینترفیس خط فرمان را باز کنید + +برای اینکه کمی تجربه کنیم باید ابتدا اینترفیس خط فرمان را باز کنید. + +{% include "/intro_to_command_line/open_instructions.md" %} + +## Prompt + +شما صفحه‌ای سیاه یا سفید خواهید دید که منتظر دستورات شماست. + + + +اگر بر روی مک یا لینوکس کار می‌کنید، ممکن است یک علامت `$` ببینید: + +{% filename %}خط فرمان{% endfilename %} + + $ + + + + + + +بر روی ویندوز، احتمالاً علامت `>` را خواهید دید: + +{% filename %}خط فرمان{% endfilename %} + + > + + +به بخش لینوکس در بالا نگاه کنید، چیزی که در آنجا می‌بینید بسیار شبیه چیزی است که در وبسایت PythonAnywhere و در ادامه این دوره آموزشی خواهید دید. + + + +هر دستور با یک پیشوند `$` یا `>` و یک اسپیس نشان داده شده‌اند، ولی شما نباید آن‌ها را تایپ کنید کامپیوتر آن را قبل از هر دستور شما گذاشته است. :) + +> یک نکته کوچک: ممکن است در کامپیوتر شما چیزهایی شبیه به `C:\Users\ola>` یا `Olas-MacBook-Air:~ ola$` قبل از علامت پرامت باشد که کاملاً طبیعی است. + +به بخشی که از ابتدای خط تا علامت `$` یا `>` را شامل می‌شود *command line prompt* یا به طور خلاصه *prompt* گفته می‌شود (prompt به معنی تشویق کردن و برانگیختن است). این علامت شما را تشویق می‌کند تا جلوی آن چیزی بنویسید. + +در این دوره آموزشی وقتی که از شما می‌خواهیم که دستوری را بنویسید، معمولاً در سمت چپ آن `$` یا `>` را گذاشته‌ایم. این تکه را در نظر نگیرید و فقط دستور را که بلافاصله بعد از پرامت قرار دارد تایپ کنید. + +## اولین دستور شما (وای!) + +بیایید با تایپ این دستور شروع کنیم: + + + +{% filename %}خط فرمان{% endfilename %} + + $ whoami + + + + + + +{% filename %}خط فرمان{% endfilename %} + + > whoami + + + + +و سپس کلید `enter` را بزنید. نتیجه این خواهد بود: + +{% filename %}خط فرمان{% endfilename %} + + $ whoami + olasitarska + + +همانطور که می‌بینید کامپیوتر نام کاربری شما را نشان می‌دهد. جالب نیست؟ :) + +> برای امتحان کردن هر دستور آن را کپی نکیند. با تایپ کردن بهتر یاد خواهید گرفت! + +## اصول اولیه + +هر سیستم عامل، مجموعه دستورات کمی متفاوت برای خط فرمان، با دیگر سیستم عامل‌ها دارد، بنابراین مطمئن شوید که دستورالعمل‌های سیستم عامل خود را دنبال می‌کنید. حالا این را امتحان کنیم، آماده اید؟ + +### دایرکتوری جاری + +بسیار خوب است که بفهمیم در کدام دایرکتوری هستیم. این دستور را تایپ کنید و کلید `enter` را بزنید: + + + +{% filename %}خط فرمان{% endfilename %} + + $ pwd + /Users/olasitarska + + +> نکته: 'pwd' مخفف 'print working directory' به معنی 'دایرکتوری در حال اجرا را چاپ کن' است. + + + + + +{% filename %}خط فرمان{% endfilename %} + + > cd + C:\Users\olasitarska + + +> نکته: 'cd' مخفف 'change directory' به معنی 'دایرکتوری را عوض کن'. در نرم افزار PowerShell در ویندوز شما می‌توانید مانند لینوکس یا مک از دستور pwd استفاده کنید. + + + +احتمالاً چیزی شبیه به این را بر روی کامپیوتر خود دیده اید. وقتی پنچره خط فرمان را باز می‌کنید معمولاً در دایرکتوری home اکانت کاربری خود هستید. + +* * * + +### چیزهای بیشتر در مورد یک فرمان + +بسیاری از فرمان‌هایی که شما می‌توانید در پرامت فرمان تایپ کنید یک راهنمای داخلی دارند که می‌توانید آن را ببینید و بخوانید! مثلاٌ برای آنکه در مورد فرمان دایرکتوری جاری بیشتر بدانید: + + + +macOS و لینوکس یک فرمان `man` دارند که در مورد فرمان‌ها کمک زیادی می‌کند. دستور `man pwd` را امتحان کنید و ببینید که چه می‌شود. یا دستور `man` را قبل از فرمان‌های دیگر قرار دهید تا راهنمای داخلی آن‌ها را ببینید. خروجی فرمان `man` صفحه بندی شده است. با کمک کلید اسپیس به صفحه بعد بروید و با زدن `q` از راهنما خارج شوید. + + + + + +اضافه کردن یک پسوند `/?` به اکثر فرمان‌ها باعث می‌شود که صفحه راهنما نشان داده شود. لازم است صفحه را به سمت بالا اسکرول کنید تا تمام آن را ببینید. `cd /?` را امتحان کنید. + + + +### لیست کردن فایل‌ها و دایرکتوری‌ها + +چی توش هست؟ خوبه که بفهمیم. نگاه کنید: + + + +{% filename %}خط فرمان{% endfilename %} + + $ ls + Applications + Desktop + Downloads + Music + ... + + + + + + +{% filename %}خط فرمان{% endfilename %} + + > dir + Directory of C:\Users\olasitarska + 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 شما می‌توانید مانند لینوکس یا macOS از دستور 'ls' استفاده کنید. + +* * * + +### تغییر دایرکتوری جاری + +حالا به دایرکتوری Desktop کامپیوترمان برویم: + + + +{% filename %}خط فرمان{% endfilename %} + + $ cd Desktop + + + + + + +{% filename %}خط فرمان{% endfilename %} + + $ cd Desktop + + +توجه داشته باشید که ممکن است دایرکتوری Desktop به زبان کاربری تعیین شده در لینوکس شما ترجمه شود. اگر چنین اتفاقی افتاد لازم است که شما `Desktop` را با نام ترجمه شده عوض کنید؛ مثلاً برای زبان آلمانی با `Schreibtisch` عوض کنید. + + + + + +{% filename %}خط فرمان{% endfilename %} + + > cd Desktop + + + + +بررسی کنید که آیا واقعاً دایرکتوری جاری عوض شد: + + + +{% filename %}خط فرمان{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}خط فرمان{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + + +بله درست شد! + +> نکته حرفه‌ای: اگر شما تایپ کنید `cd D` و بعد کلید `tab` را بر روی کیبورد بزنید، خط فرمان ادامه فرمان شما را تایپ خواهد کرد بنابراین سریعتر می‌توانید حرکت کنید. اگر دایرکتوری هایی که با "D" شروع می‌شوند بیشتر از یکی باشند، با دوبار زدن کلید `tab` لیستی از آن‌ها را خواهید دید. + +* * * + +### ساختن دایرکتوری + +چطور است که یک دایرکتوری آزمایشی بر روی دسکتاپ بسازیم؟ به این روش می‌توانید انجام دهید: + + + +{% filename %}خط فرمان{% endfilename %} + + $ mkdir practice + + + + + + +{% filename %}خط فرمان{% endfilename %} + + > mkdir practice + + + + +این دستور کوچک یک دایرکتوری به نام `practice` بر روی دسکتاپ شما خواهد ساخت. شما می‌توانید با اجرا کردن دستور `ls` یا `dir` بررسی کنید که آیا این دایرکتوری روی Desktop هست یا نه! آن را امتحان کنید. :) + +> نکته حرفه‌ای: اگر دوست ندارید یک دستور را بارها و بارها تایپ کنید، کلید `up arrow` یا جهت بالا و `down arrow` یا جهت پایین را بر روی کیبورد بزنید تا فرمان‌هایی که اخیراً زده اید را ببینید. + +* * * + +### تمرین! + +یک چالش کوچک برای شما: در این دایرکتوری `practice` که اخیراٌ ساخته اید، یک دایرکتوری به نام `test` بسازید. (از دستور `cd` و `mkdir` استفاده کنید.) + +#### راه حل: + + + +{% filename %}خط فرمان{% endfilename %} + + $ cd practice + $ mkdir test + $ ls + test + + + + + + +{% filename %}خط فرمان{% endfilename %} + + > cd practice + > mkdir test + > dir + 05/08/2020 07:28 PM test + + + + +تبریک! :) + +* * * + +### پاک‌سازی + +نمی‌خواهیم همه جا را شلوغ کنیم، پس بیایید همه چیزهایی که ساخته ایم را پاک کنیم. + +اول از همه باید به Desktop برویم: + + + +{% filename %}خط فرمان{% endfilename %} + + $ cd .. + + + + + + +{% filename %}خط فرمان{% endfilename %} + + > cd .. + + + + +استفاده کردن از `..` به همراه دستور `cd` باعث خواهد شد که به دایرکتوری parent بروید (parent دایرکتوری است که دایرکتوری جاری درون آن قرار دارد). + +بررسی کنید که کجا هستید: + + + +{% filename %}خط فرمان{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}خط فرمان{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + + +حالا وقت پاک کردن دایرکتوری `practice` است: + +> **توجه**: پاک کردن فایل‌ها با `del` یا `rmdir` یا `rm` غیر قابل بازگشت است به این معنی که *فایل‌های پاک شده برای همیشه از بین می‌روند*! بنابراین هنگام کار با این دستورها بسیار احتیاط کنید. + + + +{% filename %}خط فرمان{% endfilename %} + + $ rm -r practice + + + + + + +{% filename %}خط فرمان{% endfilename %} + + > rmdir /S practice + practice, Are you sure ? Y + + + + +انجام شد! برای اینکه مطمئن شوید پاک شده است آن را چک کنید: + + + +{% filename %}خط فرمان{% endfilename %} + + $ ls + + + + + + +{% filename %}خط فرمان{% endfilename %} + + > dir + + + + +### خروج + +برای الان کافی است! شما می‌توانید به راحتی خط فرمان را ببندید. بیایید به روش هکرها انجامش دهیم، باشه؟ :) + + + +{% filename %}خط فرمان{% endfilename %} + + $ exit + + + + + + +{% filename %}خط فرمان{% endfilename %} + + > exit + + + + +با حال بود، نه؟ :) + +## چکیده + +اینجا چکیده‌ای از دستورات مهم آورده شده: + +| دستورات (Windows) | دستورات (Mac OS / Linux) | توضیحات | مثال | +| ----------------- | ------------------------ | --------------------------- | -------------------------------------------------- | +| exit | exit | بستن پنجره خط فرمان | **exit** | +| cd | cd | تغییر دایرکتوری | **cd test** | +| cd | pwd | نشان دادن دایرکتوری جاری | **cd** (Windows) or **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** | +| rmdir (or del) | rm | حذف کردن یک فایل | **del c:\test\test.txt** | +| rmdir /S | rm -r | حذف کردن یک دایرکتوری | **rm -r testdirectory** | +| [CMD] /? | man [CMD] | دیدن راهنمای یک دستور | **cd /?** (Windows) or **man cd** (Mac OS / Linux) | + +این‌ها تعداد بسیار کمی از دستوراتی هستند که می‌توانید در خط فرمان اجرا کنید، اما امروز چیزی بیشتر از این‌ها لازم ندارید. + +اگر علاقمند هستید، وبسایت [ss64.com](http://ss64.com) مرجع کاملی از انواع فرمان‌ها برای سیستم عامل‌های مختلف دارد. + +## آماده هستید؟ + +حالا در پایتون شیرجه بزنیم! \ No newline at end of file diff --git a/fa/intro_to_command_line/open_instructions.md b/fa/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..de4c44b8456 --- /dev/null +++ b/fa/intro_to_command_line/open_instructions.md @@ -0,0 +1,29 @@ + + + +بسته به نسخه ویندوز و نیز نوع کیبورد شما، یکی از موارد زیر برای شما یک command window یا خط فرمان باز خواهد کرد (شاید باید کمی امتحان کنید ولی لازم نیست تمام این پیشنهادات را آزمایش کنید): + +- به منوی استارت یا screen بروید و عبارت "Command Prompt" را در بخش جستجو وارد کنید. +- این مسیر را دنبال کنید Start menu → Windows System → Command Prompt. +- این مسیر را دنبال کنید Start menu → All Programs → Accessories → Command Prompt. +- به بخش Start بروید و موس را روی صفحه تکان دهید و به گوشه پایین سمت چپ بروید و بر روی فلش به سمت پایین که ظاهر می‌شود کلید کنید (در یک سیستم تاچ اسکرین باید از پایین اسکرین را لمس کنید و دست خود را بالا بکشید). صفحه App ها باید باز شود. بر روی Command Prompt در بخش Windows System کلیک کنید. +- کلید مخصوص Windows را بر روی کیبورد نگه دارید و دکمه "X" را بزنید. "Command Prompt" را از پنجره‌ای که باز می‌شود انتخاب کنید. +- کلید Windows را نگه دارید و دکمه "R" را بزنید تا پنجره "Run" بازشود. تایپ کنید "cmd" و کلید OK را بزنید. + +![در پنجره "Run" بنویسید "cmd"](../python_installation/images/windows-plus-r.png) + +بعداً در این دوره آموزشی احتیاج دارید که دو پنجره خط فرمان به طور همزمان باز داشته باشید. با این حال در برخی نسخه‌های ویندوز، اگر یک پنجره خط فرمان باز داشته باشید و از همان روش برای باز کردن یک پنجره خط فرمان دیگری استفاده کنید به جای باز شدن پنجره جدید، همان قبلی دوباره نشان داده می‌شود. حالا روی کامپیوتر خود امتحان کنید و ببینید چه اتفاقی می‌افتد! اگر فقط یک پنجره خط فرمان دریافت کردید، یک روش دیگر از این لیست بالا را امتحان کنید. حداقل یکی از این‌ها باید یک پنجره جدید خط فرمان بازکند. + + + + + +به اینجا بروید Launchpad → Other → Terminal. + + + + + +احتمالاً Applications → Accessories → Terminal یا Applications → System → Terminal است که بستگی به سیستم کامپیوتر شما دارد. اگر در این آدرس‌ها پیدا نکردید سعی کنید با جستجو در گوگل جای آن را پیدا کنید. :) + + diff --git a/fa/python_installation/README.md b/fa/python_installation/README.md new file mode 100644 index 00000000000..53720da3016 --- /dev/null +++ b/fa/python_installation/README.md @@ -0,0 +1,15 @@ +# بیایید پایتون را شروع کنیم + +بالاخره به اینجا رسیدیم! + +اما در ابتدا بگذارید که به شما بگوییم پایتون چیست. پایتون یک زبان برنامه نویسی بسیار رایج است که می‌تواند برای ساخت وبسایت، بازی‌ها، نرم افزارهای علمی، گرافیک و بسیاری امور دیگر استفاده شود. + +پایتون به اواخر دهه 1980 باز می‌گردد و هدف اصلی آن این بود که زبانی طراحی شود که خواندن آن برای افراد هم راحت باشد (و نه اینکه صرفاً ماشین‌ها راحت باشند!). به خاطر همین است که خواندن آن نسبت به بقیه زبان‌ها ساده تر است، اما نگران نباشید، پایتون واقعاً قدرتمند است! + +# نصب و راه اندازی پایتون + +> **نکته** اگر از Chromebook استفاده می‌کنید، از این بخش رد شوید و دستورالعمل‌های بخش [نصب Chromebook](../chromebook_setup/README.md) را پیگیری کنید. +> +> **نکته** اگر مراحل [نصب و راه‌اندازی](../installation/README.md) را طی کرده‌اید، نیازی به انجام دوباره آن نیست. شما می‌توانید به بخش بعد بروید! + +{% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/fa/python_installation/images/add_python_to_windows_path.png b/fa/python_installation/images/add_python_to_windows_path.png new file mode 100644 index 00000000000..3266efb6177 Binary files /dev/null and b/fa/python_installation/images/add_python_to_windows_path.png differ diff --git a/fa/python_installation/images/python-installation-options.png b/fa/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..a0a6c65d81d Binary files /dev/null and b/fa/python_installation/images/python-installation-options.png differ diff --git a/fa/python_installation/images/windows-plus-r.png b/fa/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/fa/python_installation/images/windows-plus-r.png differ diff --git a/fa/python_installation/instructions.md b/fa/python_installation/instructions.md new file mode 100644 index 00000000000..40f621ebbb0 --- /dev/null +++ b/fa/python_installation/instructions.md @@ -0,0 +1,117 @@ +> برای خوانندگان در خانه: این فصل در ویدئو [نصب پایتون و ویرایشگر کد](https://www.youtube.com/watch?v=pVTaqzKZCdA) توضیح داده شده است. +> +> این قسمت بر اساس دوره آموزشی Geek Girls Carrots نوشته شده است.(https://github.com/ggcarrots/django-carrots) + +جنگو با پایتون نوشته شده است. برای انجام هر کاری در جنگو، به زبان پایتون احتیاج داریم. بیایید با نصب پایتون شروع کنیم! ما می‌خواهیم شما آخرین نسخه پایتون 3 را نصب کنید، بنابراین اگر هرنسخه قدیمی تری دارید باید آن را به روزرسانی کنید. اگر پایتون نسخه {{ book.py_min_version }} یا بالاتر دارید، خوب است. + +حتی اگر بر روی کامپیوتر شما Anaconda نصب شده است، لطفاً پایتون معمولی را به روش زیر نصب کنید. + + + +ابتدا چک کنید که کامپیوتر شما دارای ویندوز 32-bit است یا 64-bit، در ردیف "System type" در صفحه System Info می‌توانید این را متوجه شوید. برای پیدا کردن این صفحه یکی از کارهای زیر را انجام دهید: + +* دکمه Windows و دکمه Pause/Break را همزمان روی کیبورد فشار دهید +* Control Panel را از منو ویندوز باز کنید، سپس به System & Security بروید و بعد از آن به System بروید +* دکمه Windows را فشار دهید، سپس مسیر Settings > System > About را دنبال کنید +* منوی Start ویندوز را برای یافتن "System Information" جستجو کنید. برای این کار بر روی منوی Start کلیک کنید یا کلید Windows را بزنید، سپس شروع به تایپ کردن `System Information` کنید. این کار باعث خواهد شد پیشنهادهای مختلف در هنگام تایپ کردن به شما نشان داده شود. شما می‌توانید گزینه System Information‌ را به محض ظاهر شدن، انتخاب کنید. + +می‌توانید پایتون برای ویندوز را از وبسایت https://www.python.org/downloads/windows/ دانلود کنید. بر روی لینک "Latest Python 3 Release - Python x.x.x" کلیک کنید. اگر کامپیوتر شما نسخه **64-bit** ویندوز را اجرا می‌کند، **Windows x86-64 executable installer** را دانلود کنید. در غیر اینصورت، **Windows x86 executable installer** را دانلود کنید. پس از دانلود کردن اینستالر، باید آن را اجرا کنید (بر روی آن دوبار کلیک کنید) و دستورالعمل‌ها را دنبال کنید. + +نکته قابل توجه: در هنگام نصب پنجره‌ای را خواهید دید به نام "Setup". مطمئن شوید که گزینه "Add Python {{ book.py_version }} to PATH" یا "Add Python to your environment variables"را انتخاب کرده‌اید و سپس بر روی "Install Now" که اینجا می‌بینید، کلیک کنید (اگر نسخه‌‌های دیگری را نصب کنید ممکن است کمی با این متفاوت باشد): + +![فراموش نکنید که پایتون را به Path اضافه کنید](../python_installation/images/python-installation-options.png) + +وقتی که نصب کامل شد، یک پنجره خواهید دید که شما را به یک لینک برای آموزش بیشتر در مورد پایتون و نیز در مورد نسخه‌ای که نصب کرده‌اید ارجاع می‌دهد. این پنجره را کنسل کنید و یا ببندید - شما در همین دوره آموزشی بیشتر در مورد پایتون یاد خواهید گرفت! + +نکته: اگر از نسخه‌های قدیمی‌تر ویندوز استفاده می‌کنید (7، Vista یا نسخه‌های قدیمی‌تر) و نصب پایتون نسخه {{ book.py_version }} با خطا مواجه شد، تمام آپدیت‌های ویندوز را نصب کنید و دوباره برای نصب پایتون تلاش کنید. اگر همچنان با خطا مواجه شدید، سعی کنید پایتون نسخه {{ book.py_min_release }} را از [Python.org](https://www.python.org/downloads/windows/) نصب کنید. + +> جنگو {{ book.django_version }} به پایتون {{ book.py_min_version }} یا بالاتر نیاز دارد که ویندوز XP یا نسخه‌های قدیمی‌تر را پشتیبانی نمی‌کند. + + + + + +> **نکته** قبل از نصب پایتون بر روی macOS، باید مطمئن شوید که تنظیمات Mac‌، اجازه نصب پکیج‌هایی را که در App Store‌ نیستند، می‌دهد. به System Preferences بروید (در پوشه Applications است)، بر روی "Security & Privacy," کلیک کنید و به تب "General" بروید. اگر "Allow apps downloaded from:" بر روی "Mac App Store" تنظیم شده بود آن را به گزینه "Mac App Store and identified developers" تغییر دهید. + +شما باید به آدرس https://www.python.org/downloads/ بروید و آخرین نسخه پایتون را دانلود کنید: + +* فایل *macOS installer* را دانلود کنید، +* بر روی *python-{{ book.py_release }}-macos11.pkg* دوبار کلیک کنید تا نصب‌کننده نرم‌افزار فعال شود. + + + + + +احتمال زیادی دارد که شما بر روی کامپیوترتان پایتون داشته باشید. برای چک کردن آنکه آیا پایتون دارید (یا اینکه نسخه آن چیست)، یک کنسول باز کنید و دستورات زیر را تایپ کنید: + +{% filename %}خط فرمان{% endfilename %} + + $ python3 --version + Python {{ book.py_release }} + + +اگر نسخه نصب شده دیگری از پایتون دارید حداقل {{ book.py_min_version }} (یا مثلاً {{ book.py_min_release }})، نیازی به به‌‌روزرسانی ندارید. اگر پایتون نصب شده ندارید یا نسخه دیگری را می‌خواهید، اول باید به کمک دستورات زیر، کنترل کنید که از کدام توزیع لینوکس استفاده می‌کنید: + +{% filename %}خط فرمان{% endfilename %} + + $ grep '^NAME=' /etc/os-release + + +سپس بسته به نتیجه، یکی از روش‌های نصب زیر را به کار ببرید. + + + + + +این دستور را در کنسول تایپ کنید: + +{% filename %}خط فرمان{% endfilename %} + + $ sudo apt install python3 + + + + + + +این دستور را در کنسول تایپ کنید: + +{% filename %}خط فرمان{% endfilename %} + + $ sudo dnf install python3 + + +اگر بر روی نسخه‌های قدیمی Fedora کار می‌کنید ممکن است پیغام خطایی بگیرید که `dnf` پیدا نشد. در این مورد، باید به جای آن از `yum` استفاده کنید. + + + + + +این دستور را در کنسول تایپ کنید: + +{% filename %}خط فرمان{% endfilename %} + + $ sudo zypper install python3 + + + + +برای بررسی موفقیت‌آمیز بودن نصب، یک خط فرمان باز کنید و دستور `python3 + +

{% filename %}خط فرمان{% endfilename %}

+ +
$ python3 --version
+Python {{ book.py_release }}
+`
+ +نسخه نمایش داده شده ممکن است با {{ book.py_release }} متفاوت باشد اما باید آن چیزی باشد که در موقع نصب انتخاب کرده‌اید. + +**نکته:** اگر بر روی ویندوز کار می‌کنید و خطای `python3` wasn't found را گرفتید، از دستور `python` (بدون `3`) استفاده کنید و ببنید آیا ممکن است که نسخه پایتون {{ book.py_min_version }} یا بالاتر باشد. اگر این کار هم موثر نبود، یک خط فرمان جدید بازکنید و دوباره تلاش کنید؛ اگر خط فرمان شما از قبل از نصب پایتون باز مانده باشد ممکن است چنین خطایی دریافت کنید. + +* * * + +اگر جایی تردید داشتید یا مشکل دیگری بوجود آمد که نمی‌دانستید چه باید بکنید، لطفاً از مربی خود کمک بگیرید! گاهی وقت‌ها اوضاع به خوبی پیش نمی‌رود و بهتر است از فرد باتجربه‌تری کمک بگیرید. \ No newline at end of file diff --git a/fa/python_introduction/README.md b/fa/python_introduction/README.md new file mode 100644 index 00000000000..acd4182febf --- /dev/null +++ b/fa/python_introduction/README.md @@ -0,0 +1,1071 @@ +{% set warning_icon = '' %} + +# آشنایی با پایتون + +> قسمت‌هایی از این بخش بر اساس دوره آموزشی Geek Girls Carrots طراحی شده است (https://github.com/ggcarrots/django-carrots). + +حالا بیایید کمی کد بنویسیم! + +## خط فرمان پایتون + +> > برای کسانی که در خانه مطالعه می‌کنند این بخش در ویدئو [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U) توضیح داده شده است. + +برای آنکه با پایتون کار کنیم باید یک کنسول *خط فرمان* روی کامپیوتر خود باز کنید. احتمالا بلد هستید که چطور این کار را بکنید، در بخش [آشنایی با خط فرمان](../intro_to_command_line/README.md) آن را یاد گرفته‌اید. + +زمانی که آماده بودید، دستورالعمل‌های زیر را دنبال کنید. + +ما می‌خواهیم یک کنسول پایتون باز کنیم، پس در کنسول خط فرمان ویندوز `python` و در ترمینال لینوکس/ مک `python3` را تایپ کنید و `enter` بزنید. + +{% filename %}خط فرمان{% endfilename %} + + $ python3 + Python {{ book.py_release }} (...) + Type "help", "copyright", "credits" or "license" for more information. + >>> + + +## اولین دستور پایتونی شما! + +پس از اجرای دستور Python، خط فرمان به `>>>` تغییر می‌کند. این تغییر برای ما به معنای آن است که در حال حاضر فقط می‌توانیم از دستورات زبان پایتون استفاده کنیم. شما نیازی به تایپ `>>>` ندارید - خط فرمان پایتون این کار را برایتان میکند. + +اگر هر زمان قصد خروج از خط فرمان پابتون را داشتید `exit()` را تایپ کنید یا از `Ctrl + Z` در ویندوز و `Ctrl + D` در مک/لینوکس استفاده کنید. پس از خروج `>>>` را دیگر نمی‌بینید. + +ما الان نمی‌خواهیم از خط فرمان پایتون خارج شویم. ما می‌خواهیم چیزهای بیشتری در مورد آن یاد بگیریم. بیایید با کمی ریاضیات شروع کنیم، مانند `2 + 3`3 و زدن `enter`. + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> 2 + 3 +5 +``` + +خوبه! دیدید که جواب چگونه ظاهر شد؟ پایتون ریاضیات را می‌فهمد! می‌توانید دستور دیگری مثل این را امتحان کنید: + +- `4 * 5` +- `5 - 1` +- `40 / 2` + +برای اجرای محاسبات نمایی، مانند ۲ به توان ۳، تایپ میکنیم: {% filename %}خط فرمان{% endfilename %} + +```python +>>> 2 ** 3 +8 +``` + +کمی با دستورات مختلف محاسباتی تفریح کنید و دوباره آموزش را ادامه دهید. :) + +همانطور که می‌بینید، پایتون محاسبه‌گر بسیار خوبی است. آیا به این فکر می‌کنید که چه کارهای دیگری می‌شود انجام داد… + +## رشته‌های متنی + +چطور است با اسم شما شروع کنیم؟ نام خود را بین علامت نقل قول به صورت زیر بنویسید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> "Ola" +'Ola' +``` + +شما همین الان اولین رشته متنی خود را ساختید! رشته متنی دنباله‌ای از کاراکترها است که می‌توان آن‌ها را توسط کامپیوتر پردازش کرد. رشته متنی همواره باید با یک علامت شروع، و با همان پایان یابد. این علامت ممکن است نقل قول تکی یا آپاستروف (`'`) یا نقل قول دوتایی (`"`) باشد (در پایتون بین این دو فرقی نیست) این علامت ها به پایتون میگویند که حاوی یک رشته متنی هستند. + +رشته ها می‌توانند به همدیگر الحاق شوند. دستور زیر را امتحان کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> "Hi there " + "Ola" +'Hi there Ola' +``` + +همچنین میتوانید یک رشته را در یک عدد ضرب کنید، رشته به تعداد آن عدد تکرار می‌شود: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` + +اگر نیاز داشتید تا یک علامت آپاستروف داخل رشته بیاورید، دو راه دارید. + +استفاده از علامت نقل قول دوتایی: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> "Runnin' down the hill" +"Runnin' down the hill" +``` + +یا استفاده از یک بک اسلش (`\`) پیش از علامت آپاستروف: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> 'Runnin\' down the hill' +"Runnin' down the hill" +``` + +خوب است، نه؟ برای دیدن نام خود با حروف بزرگ، تایپ کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> "Ola".upper() +'OLA' +``` + +شما همین الان از **متد** `upper` روی رشته متنی استفاده کردید! یک متد (مانند `upper()`) دنباله‌ای از دستورات پایتونی است. زمانی که متد را صدا بزنید، آن دستورات روی یک شی ورودی (`"Ola"`) اعمال می‌شود. + +آیا می‌خواهید تعداد حروف نام خود را بدانید؟ یک **تابع** برای این کار هم هست! + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> len("Ola") +3 +``` + +به این فکر می‌کنید که چرا گاهی تابع را با یک `.` در انتهای یک رشته صدا می‌کنیم (مانند `"Ola".upper()`) و گاهی ابتدا یک تابع را صدا می‌زنیم و رشته را جلوی نام تابع داخل پرانتز می‌گذاریم؟ در بعضی موارد، توابع به اشیا تعلق دارند، مانند `upper()` ، که فقط میتواند روی رشته‌های متنی اعمال شود. در این موارد، تابع را یک **method** می‌نامیم. در موارد دیگر، توابع به چیزی تعلق ندارند و می‌توان آنها را روی انواع مختلفی از اشیا استفاده کرد، درست مانند `len()`. به همین دلیل است که `"Ola"` را به عنوان یک پارامتر ورودی به تابع `len` می‌دهیم. + +### چکیده + +بسیار خب، صحبت راجع به رشته‌ها کافی است. تا اینجا شما موارد زیر را یاد گرفته‌اید: + +- **خط فرمان** - تایپ دستورات (کد) و دیدن نتایج در خط فرمان پایتون +- ** اعداد و رشته‌های متنی** - در پایتون اعداد برای محاسبات ریاضی و رشته‌ها به عنوان اشیا متنی استفاده می‌شوند +- **عملگرها** مانند `+` و `*`، برای ساخت یک مقدار جدید، چند مقدار را با هم ترکیب می‌کنند +- **توابع**- مانند `upper()` و `len()`، که بر روی اشیا، اعمالی را انجام می‌دهند. + +موارد گفته شده، مبانی تمام زبان‌های برنامه‌نویسی است که ممکن است بعدا بیاموزید. برای کارهای سخت‌تر آماده هستید؟ حتماً آماده‌اید! + +## خطاها + +بیایید چیز جدیدی را امتحان کنیم. می‌توانیم طول یک عدد را همانطور که طول نام خودمان را پیدا می‌کنیم، به دست آوریم؟ تایپ کنید`len(304023)` و `enter` را بزنید: + +{% filename %}{{ warning_icon }} خط فرمان{% endfilename %} + +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` + +اولین خطا را دریافت کردیم! به وسیله آیکن {{ warning_icon }} به شما اعلام می‌کنیم کدی که قرار است اجرا کنید، مطابق انتظار شما اجرا نخواهد شد. اشتباه کردن (حتی اشتباهات عمدی) بخش مهمی از یادگیری است! + +خطای دریافتی می‌گوید اشیا نوع "int" (اعداد طبیعی)، صفت "طول" ندارند. خب پس حالا چه کاری می‌توانیم بکنیم؟ می‌توانیم عددمان را به عنوان یک رشته متنی بنویسیم؟ رشته‌های متنی دارای طول هستند، درست است؟ + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> len(str(304023)) +6 +``` + +کار کرد! ما از تابع `str` داخل تابع `len` استفاده کردیم. `str()` هرچیزی را به رشته متنی تبدیل می کند. + +- تابع `str` ورودی‌اش را به **strings** تبدیل می‌کند +- تابع `int` ورودی‌اش را به **integers** تبدیل می‌کند + +> توجه: ما می‌توانیم اعداد را به متن تبدیل کنیم، اما همیشه نمی‌توان متن را به عدد تبدیل کرد - مثلا خروجی `int('hello')` چه چیزی می‌تواند باشد؟ + +## متغیرها + +یکی از مفاهیم مهم در برنامه‌نویسی، مفهوم متغیرها است. متغیر نامی است برای یک مقدار که بعدا بتوانید برای ارجاع به آن مقدار، از نام متغیر استفاده کنید. برنامه‌نویس‌ها از این متغیرها برای ذخیره داده، و بالا بردن خوانایی کد استفاده می‌کنند تا مجبور نباشند همه‌چیز را در ذهن نگه‌دارند. + +بیایید یک متغیر جدید به نام `name` بسازیم: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> name = "sara" +``` + +تایپ می‌کنیم name مساوی sara. + +همانطور که توجه کردید، برنامه شما مانند دفعات قبل خروجی نداد. پس از کجا بدانیم متغیر واقعا وجود دارد؟ نام متغیر `name` را وارد کنید و `enter` بزنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> name +'sara' +``` + +بلههههه! اولین متغیر شما!‌ :) همواره می‌توانید چیزی را که متغیر به آن ارجاع می‌دهد، تغییر دهید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> name = "Mahsa" +>>> name +'Mahsa' +``` + +می‌توانید از آن در توابع نیز استفاده کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> len(name) +5 +``` + +عالی است، نه؟ متغیرها می‌توانند هرچیزی باشند- مثل اعداد! این یکی را امتحان کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` + +ولی اگر نام اشتباه را استفاده کنیم چه می‌شود؟ می‌توانید حدس بزنید چه اتفاقی می‌افتد؟ بیایید امتحان کنیم! + +{% filename %}{{ warning_icon }} خط-فرمان{% endfilename %} + +```python +>>> city = "Tehran" +>>> ctiy +Traceback (most recent call last): + File "", line 1, in +NameError: name 'ctiy' is not defined +``` + +یک خطا! همانطور که می‌بینید، پایتون دارای انواع مختلفی از خطاها است و این یکی خطا **NameError** نام دارد. اگر سعی کنید از متغیری که هنوز تعریف نشده استفاده کنید، پایتون این خطا را به شما می‌دهد. اگر بعداً به این خطا برخورد کردید، کد خود را برای اشتباه تایپی در نام متغیرها چک کنید. + +کمی این موارد را امتحان کنید تا ببینید چه کارهایی می‌توانید با آن انجام دهید! + +## تابع print + +این را امتحان کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> name = 'Mahsa' +>>> name +'Mahsa' +>>> print(name) +Mahsa +``` + +زمانی که فقط `name` را تایپ می‌کنید، مفسر پایتون با *ارائه‌ای* از رشته متنی داخل متغیر 'name' پاسخ می‌دهد، که این پاسخ دنباله کاراکترهای M-a-h-s-a درون علامت نقل قول است. وقتی که `print(name)` را اجرا می‌کنید، پایتون محتوای متغیر را در صفحه نمایش نشان می‌دهد، البته بدون علامت‌های نقل قول که مرتب‌تر است. + +بعداً خواهیم دید که `print()` زمانی که می‌خواهیم از داخل توابع چیزی را نمایش دهیم، یا زمانی که می‌خواهیم چندین خط از متن را نمایش دهیم، نیز مفید است. + +## لیست‌ها + +پایتون علاوه بر رشته ها و اعداد، انواع مختلفی از اشیا را دارد. و الان نوعی از اشیا را معرفی می‌کنیم که **list** نام دارند. لیست‌ها دقیقا همان چیزی هستند که فکرش را می‌کنید: یک نوع شی که خودش لیستی از اشیای دیگر است. :) + +حالا یک لیست بسازید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> [] +[] +``` + +بله، این لیست خالی است. آنقدر مفید نیست، درست است؟ بیایید یک لیست از اعداد بخت آزمایی بسازیم. ما نمی‌خواهیم یک عدد تکراری را انتخاب کنیم، پس اعداد بخت آزمایی را داخل یک متغیر می‌گذاریم: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> lottery = [3, 42, 12, 19, 30, 59] +``` + +بسیار خب، ما یک لیست داریم! چه کاری می‌توانیم با آن انجام دهیم؟ بیایید ببینیم چه تعداد عدد بخت آزمایی درون لیست داریم. هیچ ایده‌ای درمورد این که از چه تابعی باید استفاده کنیم، دارید؟ از قبل این را می‌دانید! + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> len(lottery) +6 +``` + +بله! تابع `len()` می‌تواند تعداد اشیای درون لیست را بدهد. بسیار مفید، درست است؟ حالا بیایید لیستمان را مرتب کنیم: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> lottery.sort() +``` + +این یکی هیچ خروجی نداد، بلکه فقط ترتیب قرارگرفتن اعداد در لیست را تغییر داد. بیایید دوباره لیست را چاپ کنیم و ببینیم چه اتفاقی افتاده: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> print(lottery) +[3, 12, 19, 30, 42, 59] +``` + +همانطور که می‌بینید، اعداد درون لیست از کمترین مقدار به بیشترین مقدار مرتب شده‌اند. تبریک! + +شاید بخواهیم ترتیب اعداد را برعکس کنیم. بیایید انجامش دهیم! + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> lottery.reverse() +>>> print(lottery) +[59, 42, 30, 19, 12, 3] +``` + +اگر می‌خواهید چیزی به لیست خود اضافه کنید، می‌توانید این دستور را تایپ کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> lottery.append(199) +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +``` + +اگر می‌خواهید فقط عدد اول را نمایش دهید، می‌توانید این کار با استفاده از **indexes** انجام دهید. ایندکس شماره‌ای است که نشان دهنده محل قرار گرفتن یک آیتم در لیست است. برنامه‌نویس‌ها ترجیح می‌دهند شمردن را از 0 شروع کنند. پس شماره اولین شی در لیست 0 است، بعدی 1 است و الی آخر. دستور زیر را امتحان کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> print(lottery[0]) +59 +>>> print(lottery[1]) +42 +``` + +همانطور که می‌بینید، می‌توانید به اشیاء مختلف موجود در لیست به کمک نام لیست و ایندکس آن شیء که درون یک براکت آمده باشد، دسترسی پیدا کنید. + +برای حذف چیزی از داخل لیست، باید همانطور که در بالا یاد گرفتیم، از **ایندکس** و متد `pop()` استفاده کنید. بیایید یک مثال را امتحان کنیم و چیزی را که قبلا یاد گرفتیم، بهبود دهیم؛ ما اولین عدد لیست را حذف خواهیم کرد. + +{% 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] +``` + +مانند یک افسون عمل کرد! + +برای تفریح بیشتر، باقی ایندکس ها را نیز امتحان کنید:6 ،7، 1000، -1، -6، یا -1000. ببینید می‌توانید نتیجه را پیش از اجرای دستور، پیش بینی کنید؟ نتایج برای شما معنایی دارند؟ + +می توانید لیستی از متدهای مربوط به لیست‌ها را در این بخش از مستندات پایتون پیدا کنید: https://docs.python.org/3/tutorial/datastructures.html + +## دیکشنری‌ها + +> برای خوانندگان داخل خانه: این قسمت در ویدئوهای بخش [Python Basics: Dictionaries](https://www.youtube.com/watch?v=ZX1CVvZLE6c) پوشش داده شده است. + +دیکشنری شبیه به لیست است، ولی برای دسترسی به مقادیر باید از کلیدها به جای ایندکس‌های عددی استفاده کنید. یک کلید می‌تواند رشته متنی و یا عدد باشد. دستور زبان تعریف یک دیکشنری خالی این است: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> {} +{} +``` + +خروجی نشان می‌دهد که یک دیکشنری خالی ساخته‌اید. هورررااا! + +حالا سعی کنید که دستور زیر را بنویسید (سعی کنید اطلاعات خود را نیز جایگزین کنید): + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> participant = {'name': 'Mahsa', 'country': 'Iran', 'favorite_numbers': [7, 42, 92]} +``` + +با این دستور، یک متغیر به نام `participant` شامل سه جفت کلید-مقدار ساخته‌اید: + +- کلید `name` به مقدار `Mahsa` (یک شی `string` ) اشاره می‌کند +- کلید `country` به `'Iran'` (یک `string` دیگر) اشاره می‌کند +- و کلید `favorite_numbers` به `[7, 42, 92]` اشاره می‌کند (یک `لیست` با سه عدد داخل آن). + +می‌توانید محتوای هر کلید را طبق دستور زیر به تنهایی چک کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> print(participant['name']) +Mahsa +``` + +ببینید، دیکشنری مشابه یک لیست است. ولی نیازی نیست که ایندکس ها را بخاطر بیاورید - فقط کافی است نام کلید را بدانید. + +اگر مقدار کلیدی را که وجود ندارد از پایتون درخواست کنیم چه اتفاقی می‌افتد؟ می‌توانید حدس بزنید؟ بیایید امتحان کنیم و ببینیم! + +{% filename %}{{ warning_icon }} خط فرمان{% endfilename %} + +```python +>>> participant['age'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'age' +``` + +ببینید، یک خطای دیگر! این یکی **KeyError** است. پایتون به شما کمک می‌کند و می‌گوید که کلید `'age'` در دیکشنری وجود ندارد. + +چه زمانی از لیست و چه زمانی از دیکشنری باید استفاده کرد؟ نکته خوبی است. قبل از دیدن خط بعد به پاسخ فکر کنید. + +- یک دنباله ترتیبی از آیتم ها نیاز دارید؟ لیست را انتخاب کنید. +- آیا نیاز است کلیدها و مقادیر را به همدیگر ارتباط دهید، که بعدا بتوانید به صورت کارآمد مقادیر را بوسیله کلیدها جستجو کنید؟ از یک دیکشنری استفاده کنید. + +دیکشنری‌ها، مانند لیست‌ها *تغییر پذیر* هستند، به معنای آن که می‌توان آن‌ها را پس از ساخت، تغییر داد. می‌توانید پس از ساختن دیکشنری، جفت کلید-مقدار جدید به آن اضافه کنید، مانند زیر: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> participant['favorite_language'] = 'Python' +``` + +استفاده از متد `len()` روی دیکشنری، مانند لیست‌ها، تعداد جفت‌های کلید-مقدار را برمی‌گرداند. دستور زیر را تایپ کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> len(participant) +4 +``` + +امیدواریم تا اینجا همه چیز برایتان روشن باشد. :) آماده تفریح بیشتر با دیکشنری‌ها هستید؟ ادامه آموزش را بخوانید تا با چیزهای شگفت انگیز روبرو شوید. + +می‌توانید از متد `pop()` برای حذف یک آیتم از دیکشنری استفاده کنید. برای مثال، اگر می‌خواهید مدخل مربوط به کلید `'favorite_numbers'` را حذف کنید، دستور زیر را تایپ کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> participant.pop('favorite_numbers') +[7, 42, 92] +>>> participant +{'country': 'Iran', 'favorite_language': 'Python', 'name': 'Mahsa'} +``` + +همانطور که در خروجی مشاهده می‌کنید، کلید مقدار متناظر با 'favorite_numbers' حذف شده است. + +به همین شکل، می‌توانید مقدار مربوط به یک کلید موجود در دیکشنری را تغییر دهید. این را تایپ کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> participant['country'] = 'Germany' +>>> participant +{'country': 'Germany', 'favorite_language': 'Python', 'name': 'Mahsa'} +``` + +همانطور که می‌توانید ببینید مقدار کلید `'country'` از `'Iran'` به `'Germany'` تغییر پیدا کرده‌است. :) هیجان انگیز نیست؟ هورا! همین الان یک مورد شگفت انگیز دیگر یاد گرفتید. + +### چکیده + +بسیار عالی! الان چیزهای زیادی راجع به برنامه‌نویسی می‌دانید. در همین قسمت آخر شما موارد زیر را آموختید: + +- **خطاها** - اگر پایتون دستوری را متوجه نشود و خطایی را نشان دهد، حالا شما می‌دانید چطور آن خطا را بخوانید و درک کنید +- **متغیرها** - نام‌هایی برای اشیا هستند که شما را قادر می‌سازد راحت تر کد بزنید و کد شما را خواناتر می‌کند +- **لیست‌ها** - لیستی از اشیا که در یک ترتیب خاص ذخیره شده‌اند +- **دیکشنری‌ها** - اشیایی که به عنوان جفت‌های کلید-مقدار ذخیره شده‌اند + +برای بخش بعدی هیجان زده‌اید؟ :) + +## مقایسه اشیا + +> برای خوانندگان داخل خانه: این قسمت در ویدئو های بخش [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4) پوشش داده شده است. + +بخش بزرگی از برنامه‌نویسی شامل مقایسه اشیا است. مقایسه چه چیزهایی از همه راحت‌تر است؟ اعداد! بیایید نحوه کارکرد آن را ببینیم: + +{% filename %}خط فرمان{% 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 +``` + +ما به پایتون تعدادی عدد برای مقایسه کردن داده‌ایم. همانطور که می‌بینید، پایتون نه تنها می‌تواند اعداد را مقایسه کند بلکه می‌تواند عبارت‌های ریاضی مانند `2 * 2` و متدهایی همچون `len([4, 5])` که نتیجه `2` را می‌دهد نیز با هم مقایسه کند. جالب است، نه؟ + +آیا به این فکر کرده‌اید که چرا دو علامت مساوی `==` کنار هم برای چک کردن تساوی اعداد گذاشته‌ایم؟ ما از یک علامت مساوی `=` برای انتساب مقادیر به متغیرها استفاده می‌کنیم. اگر می‌خواهید مساوی بودن دو شی با همدیگر را چک کنید، همیشه و **همیشه** باید از دو علامت مساوی `==` استفاده کنید. همچنین می‌توانیم مساوی نبودن اشیا را تعیین کنیم. برای این منظور، از علامت `=!`، همانطور که در مثال بالا نشان داده شده است، استفاده می‌کنیم. + +دو تمرین دیگر با پایتون انجام بدهید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` + +ما `>` و `<` را دیدیم، ولی `>=` و `<=` چه معنایی دارد؟ آنها را به این صورت بخوانید: + +- x `>` y یعنی‌: x بزرگتر از y است +- x `<` y یعنی: x کوچکتر از y است +- x `<=` y یعنی: x کوچکتر یا مساوی y است +- x `>=` y یعنی: x بزرگتر یا مساوی y است + +بسیارعالی! می‌خواهید بیشتر با آن کار کنید؟ این را امتحان کنید: + +{% filename %}خط فرمان{% endfilename %} + +```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 ارزیابی شود + +آیا عبارت " مقایسه سیب با پرتقال" را شنیده‌اید؟ بیایید نسخه پایتونی آن را امتحان کنیم: + +{% filename %}{{ warning_icon }} خط فرمان {% endfilename %} + +```python +>>> 1 > 'django' +Traceback (most recent call last): + File "", line 1, in +TypeError: '>' not supported between instances of 'int' and 'str' +``` + +همانطور که در عبارت بالا می‌بینید، پایتون قادر نیست یک رشته (`str`) و یک عدد (`int`) را با هم مقایسه کند. درعوض، یک **TypeError** نشان می‌دهد و به ما می‌گوید که دو نوع نمی‌توانند با یکدیگر مقایسه شوند. + +## Boolean + +در حقیقت شما با نوع جدیدی از اشیا در پایتون آشنا شدید. به نام **Boolean** بولیَن. + +فقط دو نوع شی بولین وجود دارد: + +- True - درست +- False - نادرست + +برای اینکه پایتون این نوع را بشناسد، باید همیشه آن را به صورت 'True' بنویسید (حرف اول بزرگ، و باقی حروف کوچک). **true, TRUE, و tRUE را نخواهد شناخت - فقط Trueدرست است.** ( برای False هم همینطور.) + +بولین ها می توانند به صورت متغیر باشند، اینجا را ببینید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> a = True +>>> a +True +``` + +می‌توانید به این صورت نیز انجامش دهید: + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> a = 2 > 5 +>>> a +False +``` + +با اجرای دستورات زیر، با بولین ها تفریح و تمرین کنید: + +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 =! 2` + +تبریک! بولین‌ها یکی از جالب ترین ویژگی‌های برنامه‌نویسی هستند، و شما همین الان یاد گرفتید چطور از آن‌ها استفاده کنید! + +# ذخیره کنید! + +> برای خوانندگان داخل خانه: این قسمت در ویدئو های بخش [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk) پوشش داده شده است. + +تا اینجا ما تمام کدهای پایتون خود را در مفسر خط فرمان نوشته‌ایم، که ما را محدود به ورود یک خط از کد در یک زمان می‌کرد. برنامه‌های نرمال در فایل ذخیره می‌شوند و به وسیله **مفسر** یا **کامپایلر** زبان برنامه‌نویسی اجرا می‌شوند. تا اینجا ما برنامه‌هایمان به صورت - هربار، یک خط - در **مفسر** پایتون اجرا کردیم. برای تمرین‌های بعدی به بیش از یک خط کد نیاز خواهیم داشت، پس ما نیاز داریم تا سریعاً: + +- از مفسر پایتون خارج شویم +- ویرایشگر متنی دلخواه خود را نصب کنیم +- چندخط کد در فایل جدید پایتون ذخیره کنیم +- آن را اجرا کنیم! + +برای خروج از مفسر پایتونی که در حال استفاده از آن هستیم، تابع `exit()` را تایپ کنید + +{% filename %}خط فرمان{% endfilename %} + +```python +>>> exit() +``` + +این عمل شما را به خط فرمان بازمی‌گرداند. + +پیش از این، ما یک ویرایشگر متنی از بخش [ویرایشگر متن](../code_editor/README.md) انتخاب کردیم. حالا باید ویرایشگر را باز کنیم و چند خط کد در یک فایل جدید بنویسیم (یا اگر از یک کروم بوک استفاده می کنید، یک فایل جدید روی cloud IDE بسازید و فایل را باز کنید): + +{% filename %}editor{% endfilename %} + +```python +print('Hello, Django girls!') +``` + +به وضوح، حالا شما یک توسعه دهنده پایتون کاربلد هستید، پس کمی از کدهایی که امروز یاد گرفتید را بنویسید. + +حالا باید فایل را ذخیره کنیم و یک نام توصیفی به آن بدهیم. بیایید فایل را **python_intro.py** نامگذاری کنیم و آن را روی صفحه دسکتاپ ذخیره کنیم. می‌توانیم به فایل هر نامی که می‌خواهیم بدهیم، ولی پایان یافتن فایل با **.py** مهم است. پسوند **.py** به سیستم عامل می‌گوید که این یک **فایل اجرایی پایتون** است و پایتون می تواند آن را اجرا کند. + +> **توجه** شما باید به یکی از جالب‌ترین ویژگی‌های ویرایشگر کد دقت کنید: رنگ‌ها! در کنسول پایتون، همه چیز به یک رنگ بود، حالا شما می‌توانید ببینید که تابع `print` رنگ متفاوتی با رشته متنی دارد. به این ویژگی "برجسته سازی دستوری " می‌گویند، که ویژگی بسیار مفیدی برای کد زدن است. رنگ چیزها شما را راهنمایی می‌کند، مانند رشته متنی بسته نشده یا غلط دیکته ای در کلمات کلیدی (مانند `def` در یک تابع که در ادامه خواهیم دید). این یکی از دلایلی است که از ویرایشگر کد استفاده می‌کنیم. :) + +وقتی فایل را ذخیره کردیم وقت آن است که آن را اجرا کنیم! ار مهارت‌هایی که در بخش خط فرمان گفتیم استفاده کنید، از ترمینال برای **تغییر دایرکتوری** به دسکتاپ استفاده کنید. + + + +بر روی Mac، فرمان‌ها شبیه به این خواهد بود: + +{% filename %}خط فرمان{% endfilename %} + + $ cd ~/Desktop + + + + + + +بر روی لینوکس شبیه به این است: + +{% filename %}خط فرمان{% endfilename %} + + $ cd ~/Desktop + + +(به یاد داشته باشید که ممکن است کلمه "Desktop" به زبان منتخب شما ترجمه شده باشد.) + + + + + +در خط فرمان ویندوز، شبیه به این است: + +{% filename %}خط فرمان{% endfilename %} + + > cd %HomePath%\Desktop + + + + + + +بر روی پاورشل ویندوز، شبیه به این است: + +{% filename %}خط فرمان{% endfilename %} + + > cd $Home\Desktop + + + + +اگر گیر کردید تقاضای راهنمایی کنید. مربی‌ها برای همین کار در کنار شما هستند! + +حالا از پایتون استفاده کنید تا کدهای موجود در فایل را اجرا کنید: + +{% filename %}خط فرمان{% endfilename %} + + $ python3 python_intro.py + Hello, Django girls! + + +نکته: در ویندوز 'pyhton3' یک دستور محسوب نمیشود. به جای آن از 'python' برای اجرای فایل استفاده کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +> python python_intro.py +``` + +بسیار خب! شما اولین برنامه پایتون خود را که در یک فایل ذخیره شده بود اجرا کردید. فوق العاده نیستید؟ + +حالا شما می‌توانید به سراغ یکی از ابزارهای ضروری برنامه نویسی بروید: + +## If … elif … else + +بسیاری از کدها تنها زمانی باید اجرا شوند که شروط داده شده درست باشند. به همین دلیل پایتون چیزی به نام دستور شرطی - **دستور if** دارد. + +کد خود را در فایل **python_intro.py** با این جایگزین کنید: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 3 > 2: +``` + +اگر ما این را ذخیره و اجرا کنیم، خطایی مانند زیر را مشاهده می‌کنیم: + +{% filename %}{{ warning_icon }} خط-فرمان{% endfilename %} + + $ python3 python_intro.py + File "python_intro.py", line 2 + ^ + SyntaxError: unexpected EOF while parsing + + +پایتون انتظار دارد که ما مشخص کنیم اگر شرط `3 > 2` درست باشد چه دستوری باید اجرا شود (یا به صورت صحیح‌تر شرط `True` باشد). بیایید کاری کنیم که در صورت درست بودن شرط، پایتون در خروجی بنویسد: “It works!”. کد را در فایل **python_intro.py** به این تغییر دهید: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 3 > 2: + print('It works!') +``` + +به تورفتگی خط بعدی کد به اندازه 4 اسپیس دقت کردید؟ به این تورفتگی ها نیاز داریم تا پایتون بداند در صورت درست بودن شرط کدام دستورات را اجرا کند. می توانید از یک اسپیس استفاده کنید، ولی تقریبا همه برنامه‌نویسان پایتون برای تمیزی و خوانایی کد از 4 اسپیس استفاده می کنند. همچنین می‌توانید ویرایشگر کد خود را طوری تنظیم کنید تا یک tab به عنوان 4 اسپیس محسوب شود. زمانی که انتخاب خود را تعیین کردید، آن را تغییر ندهید! اگر تورفتگی را با 4 اسپیس انجام می‌دهید، تمام تورفتگی های بعدی را با 4 اسپیس انجام دهید، درغیر این صورت به مشکل برمی‌خورید. + +فایل را ذخیره کنید و بار دیگر اجرا کنید: + +{% filename %}خط فرمان{% endfilename %} + +```python +$ python3 python_intro.py +It works! +``` + +توجه: یادتان باشد که در ویندوز 'python3' به عنوان یک دستور شناخته نمی‌شود. از الان به بعد 'python3' را با 'python' برای اجرای فایل ها جایگزین کنید. + +### چه می‌شود اگر یک شرط True نباشد؟ + +در مثال قبلی، کد تنها زمانی اجرا می‌شد که شرط‌ها درست بودند. ولی پایتون دستورات `elif` و `else` هم دارد: + +{% filename %}python_intro.py{% endfilename %} + +```python +if 5 > 2: + print('5 is indeed greater than 2') +else: + print('5 is not greater than 2') +``` + +وقتی آن را اجرا کنید، خروجی زیر را نمایش می‌دهد: + +{% filename %}خط فرمان{% endfilename %} + + $ python3 python_intro.py + 5 is indeed greater than 2 + + +اگر 2 عدد بزرگتری از 5 بود، دستور دوم اجرا می‌شد. بیایید نحوه کار `elif` را ببینیم: + +{% filename %}python_intro.py{% endfilename %} + +```python +name = 'Sonja' +if name == 'Ola': + print('Hey Ola!') +elif name == 'Sonja': + print('Hey Sonja!') +else: + print('Hey anonymous!') +``` + +و اجرا کنید: + +{% filename %}خط فرمان{% endfilename %} + + $ python3 python_intro.py + Hey Sonja! + + +دیدید چه اتفاقی افتاد؟ `elif` شما را قادر میسازد تا شرط های بیشتری اضافه کنید تا اگر شروط قبلی درست نبودند، شروط جدید ارزیابی شوند. + +میتوانید هر تعداد `elif` که خواستید پس از `if` اولیه اضافه کنید، به عنوان مثال: + +{% filename %}python_intro.py{% endfilename %} + +```python +volume = 57 +if volume < 20: + print("It's kinda quiet.") +elif 20 <= volume < 40: + print("It's nice for background music") +elif 40 <= volume < 60: + print("Perfect, I can hear all the details") +elif 60 <= volume < 80: + print("Nice for parties") +elif 80 <= volume < 100: + print("A bit loud!") +else: + print("My ears are hurting! :(") +``` + +پایتون تمام شرط ها را به ترتیب ارزیابی می‌کند و چاپ می‌کند: + +{% filename %}خط فرمان{% endfilename %} + + $ python3 python_intro.py + Perfect, I can hear all the details + + +## کامنت‌ها + +کامنت‌ها خطوطی هستند که با `#` شروع می‌شوند. می‌توانید بعد از `#` هر توضیحاتی راجع به کد بنویسید و پایتون آن را نادیده می‌گیرد. کامنت‌ها می‌توانند کد شما را برای دیگران خواناتر کنند. + +بیایید ببینیم چطور دیده می‌شود: + +{% 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!") +``` + +نیازی نیست برای هر خط کد کامنت بنویسید، ولی برای توضیح اینکه چرا کد شما کاری را انجام می‌دهد یا برای داشتن یک خلاصه، زمانی که کد کار پیچیده‌ای را انجام می‌دهد، مفید اند. + +### چکیده + +در تمرین های اخیر شما موارد زیر را یاد گرفتید: + +- **مقایسه اشیا** - در پایتون می‌توانید اشیا را به وسیله `>` و `>=` و `==` و `<=` و `<` و عملگرهای `and` و `or` مقایسه کنید +- **بولین‌ها** - نوعی از اشیا که می‌تواند فقط دو مقدار معتبر بگیرد: `True` یا `False` +- ** ذخیره فایل‌ها** - ذخیره کردن کدها در فایل تا بتوانید برنامه‌های بزرگتری را اجرا کنید. +- **if … elif … else** - دستوراتی که شما را قادر می‌سازد کدها را زمانی اجرا کنید که شروط مشخصی درست باشند. +- **کامنت‌ها** - خطوطی که پایتون آن‌ها را به عنوان کد اجرا نمی‌کند، و به شما اجازه می‌دهد تا کد خود را مستند سازی کنید + +زمان آخرین بخش از این فصل رسیده است! + +## تابع خودتان را بنویسید! + +> برای خوانندگان داخل خانه: این قسمت در ویدئو های بخش [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0) پوشش داده شده است. + +توابعی مانند `len()` را که می‌توانید در پایتون اجرا کنید، به خاطر دارید؟ بسیار خوب - شما الان یاد می‌گیرید که چطور تابع خود را بنویسید! + +یک تابع دنباله‌ای از دستورات است که پایتون باید اجرا کند. همه توابع در پایتون با کلمه کلیدی `def` شروع می شوند، نام می‌گیرند و می‌توانند پارامترهای ورودی داشته باشند. بیایید امتحانش کنیم. کد داخل فایل **python_intro.py** را با این جایگزین کنید: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(): + print('Hi there!') + print('How are you?') + +hi() +``` + +خب، اولین تابع ما آماده است! + +شاید فکر می‌کنید که چرا نام تابع را در انتهای فایل نوشته‌ایم. وقتی که ما عبارت `def hi():` و خطوط تو رفته زیر آن را می‌نویسیم، دستورالعمل‌هایی را که باید توسط تابع `hi()` اجرا شوند مشخص می‌کنیم. پایتون این دستورالعمل‌ها را می‌خواند و به یاد می‌آورد اما آن را اجرا نمی‌کند. برای آنکه به پایتون بگوییم که این تابع را اجرا کند، باید تابع را فراخوانی کنیم یا آن را با عبارت `hi()` صدا بزنیم. پایتون فایل را می‌خواند و آن را از بالا به پایین اجرا می‌کند، بنابراین ما باید قبل از صدا زدن آن، عملکرد تابع را در فایل تعریف کرده باشیم. + +بیایید این را اجرا کنیم و ببینیم چه اتفاقی می‌افتد: + +{% filename %}خط فرمان{% endfilename %} + + $ python3 python_intro.py + Hi there! + How are you? + + +توجه: اگر درست کار نکرد، نترسید! خروجی به شما کمک می کند دلیل آن را بفهمید: + +- اگر یک خطای `NameError` دریافت کردید، احتمالا چیزی را اشتباه تایپ کرده‌اید، پس چک کنید که از نام یکسانی موقع ساختن تابع با `def hi():` و صدا کردن آن با `hi()` استفاده کرده‌باشید. +- اگر یک خطای `IndentationError` دریافت کردید، چک کنید که هر دو دستور `print` تورفتگی یکسانی دارند: پایتون می‌خواهد که تمام کدهای داخل تابع به درستی قرار بگیرند و هم راستا باشند. +- اگر اصلا چیزی چاپ نشده، چک کنید که آخرین `hi()` تورفته *نباشد* - اگر تورفتگی داشته‌باشد، بخشی از کد تابع می‌شود و هرگز اجرا نمی‌شود. + +بیایید اولین تابع خود را با پارامتر ورودی بسازیم. ما مثال قبلی را تغییر می‌دهیم - تابعی که به فرد اجرا کننده آن سلام می‌کند - با نام خود فرد: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): +``` + +همانطور که می‌بینید، ما الان به تابع یک پارامتر به نام `name` دادیم: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + if name == 'Ola': + print('Hi Ola!') + elif name == 'Sonja': + print('Hi Sonja!') + else: + print('Hi anonymous!') + +hi() +``` + +به خاطر داشته باشید: تابع `print` با 4 اسپیس داخل دستور `if` تورفتگی دارد. بخاطر آنکه تابع زمانی اجرا می‌شود که شرط درست باشد. بیایید نحوه کار آن را ببینیم: + +{% filename %}{{ warning_icon }} خط-فرمان{% 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' + + +آخ، خطا. خوشبختانه، پایتون یک پیام خطای مفید به ما می‌دهد. به ما می‌گوید که تابع `hi()` (همانی که تعریف کردیم) یک پارامتر ورودی دارد (به نام `name`) و ما فراموش کردیم زمان صدا کردن تابع آن را وارد کنیم. بیایید آن را در انتهای فایل درست کنیم: + +{% filename %}python_intro.py{% endfilename %} + +```python +hi("Ola") +``` + +و دوباره اجرا کنیم: + +{% filename %}خط فرمان{% endfilename %} + + $ python3 python_intro.py + Hi Ola! + + +و اگر نام را تغییر دهیم چه می‌شود؟ + +{% filename %}python_intro.py{% endfilename %} + +```python +hi("Sonja") +``` + +و اجرا کنیم: + +{% filename %}خط فرمان{% endfilename %} + + $ python3 python_intro.py + Hi Sonja! + + +فکر میکنید اگر نام دیگری را بنویسید چه اتفاقی می‌افتد؟(بغیر از Ola یا Sonja). امتحان کنید و ببینید که درست فکر می کردید یا نه. باید این را نمایش دهد: + +{% filename %}خط فرمان{% endfilename %} + + Hi anonymous! + + +عالی است.نه؟ با این روش، نیاز نیست برای هر تغییر نامی که تابع به آن سلام میکند، کار تکراری انجام دهید. ما دقیقا توابع را برای همین نیاز داریم - شما نمی‌خواهید تا هر دفعه کد خود را تکرار کنید! + +بیایید کار هوشمندانه‌تری انجام دهیم - بیشتر از 2 اسم داریم، و نوشتن یک شرط برای هر کدام سخت است. درست است؟ محتوای فایل خود را با فایل زیر جایگذاری کنید: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + print('Hi ' + name + '!') + +hi("Rachel") +``` + +حالا بیایید تا کد را صدا بزنیم: + +{% filename %}خط فرمان{% endfilename %} + + $ python3 python_intro.py + Hi Rachel! + + +تبریک! شما همین الان نحوه نوشتن توابع را یاد گرفتید! :) + +## حلقه‌های تکرار + +> برای خوانندگان داخل خانه: این قسمت در ویدئو های بخش [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0) پوشش داده شده است. + +این آخرین بخش است. سریع تمام شد درست است؟ :) + +برنامه‌نویس‌ها دوست ندارند کار تکراری انجام دهند. برنامه‌نویسی برای اتوماتیک کردن کارها است، پس ما نمی‌خواهیم به طور غیر اتوماتیک به هر فرد سلام کنیم، درست است؟ این همان جایی است که حلقه‌های تکرار - Loop - به کار می‌آیند. + +هنوز لیست‌ها را به خاطر دارید؟ بیایید یک لیست از دختران بسازیم: + +{% filename %}python_intro.py{% endfilename %} + +```python +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +``` + +ما می‌خواهیم به همه آنها با ذکر نامشان سلام کنیم. برای این کار تابع `hi` را داریم، بیایید در یک حلقه از آن استفاده کنیم: + +{% filename %}python_intro.py{% endfilename %} + +```python +for name in girls: +``` + +عبارت `for` کمی شبیه به عبارت `if` رفتار می‌کند؛ کد زیر هر دو باید به اندازه 4 اسپیس تو رفتگی داشته باشد. + +اینجا کد کاملی را که باید در فایل باشد، داریم: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + print('Hi ' + name + '!') + +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +for name in girls: + hi(name) + print('Next girl') +``` + +و وقتی آن را اجرا کنیم: + +{% filename %}خط فرمان{% endfilename %} + + $ python3 python_intro.py + Hi Rachel! + Next girl + Hi Monica! + Next girl + Hi Phoebe! + Next girl + Hi Ola! + Next girl + Hi You! + Next girl + + +همانطور که می‌بینید، هر چیزی که درون یک عبارت `for` با تورفتگی قرار دهید، برای هر المان لیست `girls` تکرار می‌شود. + +همچنین می‌توانید از `for` با استفاده تابع `range` روی اعداد نیز استفاده کنید: + +{% filename %}python_intro.py{% endfilename %} + +```python +for i in range(1, 6): + print(i) +``` + +که چاپ می کند: + +{% filename %}خط فرمان{% endfilename %} + + 1 + 2 + 3 + 4 + 5 + + +`range` تابعی است که لیستی از اعداد متوالی را می‌سازد (ابتدا و انتهای بازه توسط شما به عنوان پارامتر به تابع داده می شود). + +توجه کنید که کران بالای بازه -دومین پارامتر- در لیست ساخته‌شده توسط پایتون نمی‌آید (به این معناست که `range(1, 6)` از 1 تا 5 می‌شمارد، اما شامل 6 نمی‌شود). به دلیل این که "range" نیمه‌باز است، و منظور این است که شامل عدد ابتدای بازه می‌شود ولی عدد انتهایی را شامل نمی‌شود. + +## چکیده + +همین بود. **شما فوق‌العاده هستید!** این بخش دارای ریزه کاری هایی بود و شما باید به خودتان افتخار کنید. ما هم قطعاً به شما افتخار می‌کنیم که تا اینجا پیش آمده اید! + +برای دیدن آموزش رسمی و کامل پایتون آدرس https://docs.python.org/3/tutorial/ را ببینید. این آموزش به شما دید کامل‌تر و درست‌تری نسبت به این زبان می‌دهد. موفق باشید! :) + +شاید بخواهید قبل از رفتن به مرحله بعد، کارهای دیگری بکنید، کمی کش قوس بیایید، قدم بزنید و به چشم های خود استراحتی بدهید. :) + +![Cupcake](images/cupcake.png) \ No newline at end of file diff --git a/fa/python_introduction/images/cupcake.png b/fa/python_introduction/images/cupcake.png new file mode 100644 index 00000000000..8c1820adee8 Binary files /dev/null and b/fa/python_introduction/images/cupcake.png differ diff --git a/fa/template_extending/README.md b/fa/template_extending/README.md new file mode 100644 index 00000000000..a2aa76589ec --- /dev/null +++ b/fa/template_extending/README.md @@ -0,0 +1,151 @@ +# توسعه template + +چیز دیگری که جنگو برای شما دارد **توسعه template** است. معنای آن چیست؟ به این معنی است که شما می‌توانید بخش‌هایی از یک کد HTML را در چندین صفحه مختلف از وب سایت خود استفاده کنید. + +زمانی که قصد دارید از اطلاعات یا ترکیب بندی خاصی چندین بار استفاده کنید، template ها به کمک شما خواهند آمد. نیازی نیست که یک کار تکراری را برای همه فایل ها انجام دهید. و اگر قصد داشتید چیزی را تغییر دهید، لازم نیست آن تغییر را در تک تک template ها اعمال کنید. فقط یکبار کافی است! + +## ساخت یک template پایه + +یک template پایه، اساسی ترین template است که شما آن را در هر صفحه وب سایت خود توسعه می‌دهید. + +اجازه دهید تا یک فایل `base.html` در مسیر `blog/templates/blog/` بسازیم: + + blog + └───templates + └───blog + base.html + post_list.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.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
+ + +``` + +سپس در فایل `base.html`, همه محتویات تگ `` (همه چیز بین `` و ``) را با کد زیر عوض کنید: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ +``` + +{% raw %} ممکن است توجه کرده باشید که این عمل هر چیزی بین `{% for post in posts %}` و `{% endfor %}` را با کد زیر عوض کرده است: {% endraw %} + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% block content %} +{% endblock %} +``` + +ولی چرا؟ شما همین الان یک `block` ساختید! شما از تمپلیت تگ `{% block %}` برای ساخت یک ناحیه استفاده کردید، که کد HTML در آن قرار می‌گیرد. زمانی که تمپلیت `base.html` را در فایل تمپلیت دیگری گسترش می‌دهیم، کدهای HTML مذکور را داخل تگ block می‌نویسیم. ما نحوه انجام کار را همین الان به شما نشان خواهیم داد. + +فایل `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.text|linebreaksbr }}

+
+{% endfor %} +``` + +ما می‌خواهیم از این بخش template برای تمام بلاک‌های محتوا استفاده کنیم. زمان اضافه کردن تگ‌های block به این فایل رسیده‌است! + +{% raw %} شما می‌خواهید که تگ block با تگ‌های فایل `base.html` هماهنگ باشد. هم چنین می‌خواهید تا این تگ تمام کدهای متعلق به بلاک محتوا را شامل شود. برای انجام این کار، همه چیز را بین `{% block content %}` و `{% endblock %}` قرار دهید. به این صورت:{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% block content %} + {% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +تنها یک کار باقی مانده. ما باید این دو template را به یکدیگر متصل کنیم. هدفمان از گسترش template همین است! با اضافه کردن تگ extends در ابتدای فایل، این کار را انجام می‌دهیم. مانند زیر: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +همین است! فایل را ذخیره کنید، و چک کنید که آیا وب‌سایت شما هنوز به درستی کار می‌کند. :) + +> اگر خطای`TemplateDoesNotExist` را دریافت کردید، به معنای آن است که فایل `blog/base.html` وجود ندارد و دستور `runserver` در کنسول خط فرمان در حال اجرا است. سعی کنید دستور را متوقف کنید (با زدن Ctrl+C - کلید Control و کلید C به صورت همزمان) و وب سرور را دوباره با دستور `python manage.py runserver` راه اندازی کنید. \ No newline at end of file diff --git a/fa/whats_next/README.md b/fa/whats_next/README.md new file mode 100644 index 00000000000..9a14d147f2a --- /dev/null +++ b/fa/whats_next/README.md @@ -0,0 +1,43 @@ +# گام بعدی چیست؟ + +تبریک به شما! **شما فوق العاده هستید**. به شما افتخار می‌کنیم! <3 + +### حالا چه باید کرد؟ + +یک نفس راحت بکش. همین حالا هم یک کار واقعاٌ بزرگ انجام دادی. + +بعد از این مطمئن شو که جنگو گرلز را در [فیسبوک](http://facebook.com/djangogirls) یا [توییتر](https://twitter.com/djangogirls) دنبال میکنی تا در جریان تازه‌ترین‌ها باشی. + +### آیا می‌توانید منابع دیگری معرفی کنید؟ + +بله! حجم *بسیار زیادی* منابع آنلاین برای یادگرفتن هر نوع مهارت برنامه نویسی وجود دارد - این می‌تواند به راحتی باعث سردرگمی بشود اما ما از شما حمایت می‌کنیم. هرچیزی که باعث شد که شما به جنگو گرلز بیایید و یا هرچیزی که در طول دوره آموزش برایتان جالب بوده، ما منابعی کاملاً رایگان (یا با بخش‌هایی رایگان) برای آن‌ها معرفی می‌کنیم که شما می‌توانید به هر شکلی که بخواهید از آنها استفاده کنید. + +#### جنگو + +- کتاب دیگر ما، [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org/) +- [دوره آموزشی رسمی جنگو](https://docs.djangoproject.com/en/2.2/intro/tutorial01/) +- [شروع کردن جنگو با درس‌های ویدئویی](http://www.gettingstartedwithdjango.com/) +- [Django for Everybody Specialization](https://www.coursera.org/specializations/django)، برخی ویدئوها به رایگان قابل استفاده است و می‌توانید بعد از گذراندن این دوره‌ها مدرک Coursera بگیرید + +#### HTML, CSS and JavaScript + +- [دوره توسعه وبسایت Codecademy](https://www.codecademy.com/learn/paths/web-development) +- [freeCodeCamp](https://www.freecodecamp.org/) + +#### پایتون + +- [دوره پایتون Codecademy](https://www.codecademy.com/learn/learn-python) +- [دوره پایتون گوگل](https://developers.google.com/edu/python/) +- [کتاب Learn Python The Hard Way](http://learnpythonthehardway.org/book/) - تمرین‌های ابتدایی رایگان است +- [دوره آموزشی New Coder](http://newcoder.io/tutorials/) - مجموعه‌ای از تمرین ‌های کاربردی است که نشان می‌دهد چطور از پایتون می‌توان استفاده کرد +- [edX](https://www.edx.org/course?search_query=python) - بسیاری از دوره‌ها را می‌توانید رایگان استفاده کنید، ولی اگر مدرک یا تأییدیه بخواهید باید هزینه بپردازید +- [Coursera's Python specialization](https://www.coursera.org/specializations/python) - برخی از دوره‌ها رایگان هستند و با گذراندن آنها می‌توانید مدرک دوره را بگیرید +- [Python for Everybody](https://www.py4e.com/) - یک دوره آزاد و رایگان بر اساس Coursera Python for Everybody + +#### کار کردن با داده‌ها + +- [دوره علم داده 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/) - سی "مأموریت" اول رایگان هستند + +نمی‌توانیم صبر کنیم تا ببینیم چه چیزی درست می‌کنید! \ No newline at end of file diff --git a/fr/GLOSSARY.md b/fr/GLOSSARY.md index 17c69c4d382..48cb7aaa0d3 100644 --- a/fr/GLOSSARY.md +++ b/fr/GLOSSARY.md @@ -1,3 +1,3 @@ # Éditeur de texte -L'éditeur de texte est une application qui permet d'écrire et d'enregistrer du code que vous pourrez ré-utiliser plus tard. Vous pouvez apprendre comment s'en procurer un grâce au chapitre [Éditeur de Texte](./code_editor/README.md) +L'éditeur de texte est une application qui permet d'écrire et enregistrer du code que vous pourrez ré-utiliser plus tard. Vous pouvez apprendre comment s'en procurer un grâce au chapitre [Éditeur de Texte](./code_editor/README.md) \ No newline at end of file diff --git a/fr/README.md b/fr/README.md index f45ef9780cd..5ba91076d15 100755 --- a/fr/README.md +++ b/fr/README.md @@ -1,52 +1,51 @@ # Tutoriel de 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) +[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial) -> Cette œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution-ShareAlike 4.0 International. Pour obtenir une copie de cette licence, visitez https://creativecommons.org/licenses/by-sa/4.0/ +> Cette œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution — ShareAlike 4.0 International. Pour consulter une copie de cette licence, visitez https://creativecommons.org/licenses/by-sa/4.0/deed.fr -## Translation +## Bienvenue -This tutorial has been translated from English to French by a group of awesome volunteers. Special thanks for help go to Lucie Daeye, Georges Dubus, Emmanuelle Delescolle, Leila, MadCath, Mélanie Chauvel and Sebastien Barbier. <3 <3 +Bienvenue dans le tutoriel Django Girls ! Nous sommes heureux de vous voir ici. :) Dans ce tutoriel, nous allons vous emmener dans un voyage sous le capot des technologies web, en vous offrant un aperçu de tous les pièces et les morceaux qui doivent être assemblés pour que le web fonctionne tel que nous le connaissons. + +Comme avec toutes les choses inconnues, cela va être une aventure, mais pas de soucis, puisque vous avez déjà eu le courage d'arriver ici, vous allez y arriver. :) ## Introduction -Avez-vous déjà eu l'impression que la technologie prend une place de plus en plus importante, mais que vous êtes en quelque sorte laissée à la traine ? Avez-vous déjà été curieuse de comment créer un site web, sans jamais avoir le courage de vous plonger dedans ? Vous êtes-vous déjà dit que le monde du logiciel est trop compliqué pour savoir ne serait-ce que par où l'attaquer ? +Avez-vous déjà eu l'impression que le monde est de plus en plus rempli de technologies avec lesquelles vous n'êtes pas (encore) familière ? Avez-vous déjà été curieuse de comment créer un site web, sans jamais avoir le courage de vous plonger dedans ? Vous êtes-vous déjà dit que le monde de l'informatique est trop compliqué, ne serait-ce que pour savoir par où commencer ? Hé bien, bonne nouvelle ! Programmer n'est pas aussi dur que ça en a l'air, et nous sommes là pour vous montrer à quel point ça peut être amusant. -Ce tutoriel ne va pas vous transformer en programmeuse du jour au lendemain. Devenir vraiment bonne peut prendre des mois, voire même des années d'apprentissage et de pratique. Mais nous voulons vous montrer que programmer ou créer des sites web n'est pas aussi compliqué que ça en ait l'air. Nous allons essayer de vous expliquer différents morceaux afin de rendre la technologie moins intimidante. +Ce tutoriel ne vous transformera pas magiquement en programmeuse. Si vous voulez devenir bonne, cela peut prendre des mois, voire même des années d'apprentissage et de pratique. Mais nous voulons vous montrer que programmer ou créer des sites web n'est pas aussi compliqué que ça en a l'air. Nous allons essayer de vous expliquer différents morceaux afin de rendre la technologie moins intimidante. Nous espérons arriver à vous faire aimer la technologie autant que nous l'aimons ! ## Qu'apprendrez-vous au cours de ce tutoriel ? -À la fin de ce tutoriel, vous aurez une application toute simple et pleinement fonctionnelle : votre propre blog. Nous allons vous montrer comment le mettre en ligne afin de pouvoir montrer le résultat à d'autres personnes ! +Une fois que vous aurez terminé le tutoriel, vous aurez une petite application web : votre propre blog. Nous allons vous montrer comment le mettre en ligne, ainsi votre travail sera visible par d'autres ! Ça devrait ressembler plus ou moins à ça : -![Figure 0.1][2] +![Figure 0.1](images/application.png) - [2]: images/application.png +> Si vous travaillez avec le tutoriel de votre côté et n'avez pas un coach qui vous aiderait en cas de problème, nous avons un système de discussion instantanée pour vous : [![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial). Nous avons demandé aux coachs et participant·e·s des précédentes éditions de passer de temps en temps pour aider les autres avec le tutoriel. N'ayez pas peur et allez poser vos questions ! -> Si vous travaillez sur ce tutoriel dans votre coin et que vous n'avez pas de coach pour vous aider, venez sur le chat : [![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) en cas de problème. Nous avons demandé aux coachs et participant·e·s des précédentes éditions de passer de temps en temps pour aider les autres avec le tutoriel. N'aillez pas peur et allez poser vos questions ! +OK, [commençons par le commencement…](./how_the_internet_works/README.md) -Alors, [commençons par le commencement...][3] +## Suivre le tutoriel chez soi - [3]: how_the_internet_works/README.md +Il est formidable de participer à un atelier Django Girls, mais nous comprenons qu'il n'est pas toujours facile d'en trouver un. C'est pourquoi nous vous encourageons à essayer de suivre ce tutoriel chez vous. Pour les lectrices à la maison, nous sommes actuellement en train de préparer des vidéos afin qu'il vous soit plus facile de suivre le tutoriel de votre côté. C'est encore un travail en cours, mais la chaine YouTube [Le code convient aux filles](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed) couvre de plus en plus de choses. -## À propos et contributions +Dans chaque chapitre couvert se trouve un lien pointant vers la vidéo correspondante. -Ce tutoriel est maintenu par [DjangoGirls][4]. Si vous rencontrez des erreurs ou souhaitez simplement suggérer une amélioration du tutoriel, il est important de respecter [les règles de contribution][5]. +## À propos et contributions - [4]: https://djangogirls.org/ - [5]: https://github.com/DjangoGirls/tutorial/blob/master/README.md +Ce tutoriel est maintenu par [DjangoGirls](https://djangogirls.org/). Si vous rencontrez des erreurs ou souhaitez simplement suggérer une amélioration du tutoriel, il est important de respecter [les règles de contribution](https://github.com/DjangoGirls/tutorial/blob/master/README.md). -## Voulez-vous nous aider à traduire le tutoriel dans d'autres langues ? +## Vous voulez nous aider à traduire le tutoriel dans d'autres langues ? -Pour l'instant, les traductions sont stockées sur la plate-forme crowdin.com dans : +Actuellement, les traductions sont faites sur la plateforme crowdin.com : https://crowdin.com/project/django-girls-tutorial -Si votre langue n'est pas sur crowdin, veuillez [ouvrir un ticket][6] avec la langue, pour que nous puissions l'ajouter. - - [6]: https://github.com/DjangoGirls/tutorial/issues/new +Si votre langue n'est pas listée sur [crowdin](https://crowdin.com/), merci [d'ouvrir un ticket](https://github.com/DjangoGirls/tutorial/issues/new) pour nous en informer afin que nous la rajoutions. \ No newline at end of file diff --git a/fr/SUMMARY.md b/fr/SUMMARY.md index 4eabc020e6f..e0cd7739510 100755 --- a/fr/SUMMARY.md +++ b/fr/SUMMARY.md @@ -1,26 +1,35 @@ # Résumé -* [Introduction](README.md) -* [Installation](installation/README.md) -* [Comment fonctionne l'Internet ?](how_the_internet_works/README.md) -* [Introduction à l'interface en ligne de commande](intro_to_command_line/README.md) -* [Installation de Python](python_installation/README.md) -* [L'éditeur de texte](code_editor/README.md) -* [Introduction à Python](python_introduction/README.md) -* [Qu'est-ce que Django?](django/README.md) -* [Installation de Django](django_installation/README.md) -* [Votre premier projet Django !](django_start_project/README.md) -* [Les modèles dans Django](django_models/README.md) -* [Django admin](django_admin/README.md) -* [Déployer !](deploy/README.md) -* [Les urls Django](django_urls/README.md) -* [Créons nos vues Django!](django_views/README.md) -* [Introduction au HTML](html/README.md) -* [Django ORM (Querysets)](django_orm/README.md) -* [Données dynamiques dans les templates](dynamic_data_in_templates/README.md) -* [Templates Django](django_templates/README.md) -* [CSS - Rendez votre site joli](css/README.md) -* [Héritage de template](template_extending/README.md) -* [Finaliser votre application](extend_your_application/README.md) -* [Formulaires Django](django_forms/README.md) -* [La suite ?](whats_next/README.md) \ No newline at end of file +* [Introduction](README.md) +* [Installation](installation/README.md) + * [Ligne de commande](installation/README.md#command-line) + * [Python](installation/README.md#python) + * [Éditeur de code](installation/README.md#code-editor) + * [Environnement virtuel](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) +* [Installation (chromebook)](chromebook_setup/README.md) +* [Comment marche l'Internet](how_the_internet_works/README.md) +* [Introduction à l'interface en ligne de commande](intro_to_command_line/README.md) +* [Installation de Python](python_installation/README.md) +* [L'éditeur de texte](code_editor/README.md) +* [Introduction à Python](python_introduction/README.md) +* [Qu'est-ce que Django ?](django/README.md) +* [Installation de Django](django_installation/README.md) +* [Votre premier projet Django !](django_start_project/README.md) +* [Les modèles dans Django](django_models/README.md) +* [Django admin](django_admin/README.md) +* [Déployer !](deploy/README.md) +* [Les URL de Django](django_urls/README.md) +* [Vues Django – c'est l'heure de créer !](django_views/README.md) +* [Introduction au HTML](html/README.md) +* [Django ORM (Querysets)](django_orm/README.md) +* [Données dynamiques dans les templates](dynamic_data_in_templates/README.md) +* [Templates Django](django_templates/README.md) +* [CSS – donnez du style](css/README.md) +* [Héritage de template](template_extending/README.md) +* [Finaliser votre application](extend_your_application/README.md) +* [Formulaires Django](django_forms/README.md) +* [Et maintenant ?](whats_next/README.md) \ No newline at end of file diff --git a/fr/chromebook_setup/README.md b/fr/chromebook_setup/README.md new file mode 100644 index 00000000000..98cda3e1c66 --- /dev/null +++ b/fr/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# Installation de Chromebook + +> **Note** Si vous avez déjà passé les [étapes d’installation](../installation/README.md), il n'est pas nécessaire de les répéter - vous pouvez vous rendre directement à [Introduction à Python](../python_introduction/README.md). + +{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/fr/chromebook_setup/instructions.md b/fr/chromebook_setup/instructions.md new file mode 100644 index 00000000000..62ef8ea2dc0 --- /dev/null +++ b/fr/chromebook_setup/instructions.md @@ -0,0 +1,158 @@ +Vous pouvez [passer cette section](http://tutorial.djangogirls.org/en/installation/#install-python) si vous n'utilisez pas un Chromebook. Sinon, votre installation sera un peu différente. Vous pouvez ignorer le reste des instructions d'installation. + +### Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com) + +Cloud 9 est un outil qui vous propose un éditeur de code et un accès à un ordinateur, fonctionnant sur Internet, sur lequel vous pouvez installer, écrire et exécuter des logiciels. Pour la durée du tutoriel, Cloud IDE agira comme votre *machine locale*. Vous lancerez toujours des commandes dans un terminal exactement comme vos camarades sous macOS, Ubuntu ou Windows, mais votre terminal sera connecté à un ordinateur distant que Cloud IDE aura configuré pour vous. Voici les instructions pour Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com). Vous pouvez choisir l'un des cloud IDE et suivre les instructions du cloud IDE. + +#### PaizaCloud Cloud IDE + +1. Allez sur [PaizaCloud Cloud IDE](https://paiza.cloud/) +2. Créez un compte +3. Cliquez sur *Nouveau Serveur* et choisissez l'application Django +4. Cliquez sur le bouton Terminal (sur le côté gauche de la fenêtre) + +Maintenant vous devriez voir une interface avec une barre latérale et des boutons à gauche. Cliquez sur le bouton « Terminal » pour ouvrir la fenêtre de terminal. Vous devriez voir le résultat suivant : + +{% filename %}Terminal{% endfilename %} + + $ + + +Le terminal de PaizaCloud Cloud IDE attend vos instructions. Vous pouvez redimensionner ou maximiser la fenêtre pour la rendre un peu plus grand. + +#### AWS Cloud9 + +Cloud 9 requiert actuellement que vous vous connectiez avec AWS et que vous renseigniez votre carte de crédit. + +1. Installez Cloud 9 depuis le [Chrome Web Store](https://chrome.google.com/webstore/detail/cloud9/nbdmccoknlfggadpfkmcpnamfnbkmkcp) +2. Allez à [c9.io](https://c9.io) et cliquez sur *Mise en route avec AWS Cloud9* +3. Créez un compte AWS (requiert votre carte de crédit, mais il existe un forfait gratuit) +4. Dans le tableau de bord AWS, entrez *Cloud9* dans la barre de recherche et cliquez dessus +5. Dans le tableau de bord Cloud 9, cliquez sur *Créer un environnement* +6. Appelez-le *django-girls* +7. Lors de la configuration des paramètres, sélectionnez *Créer une nouvelle instance pour l'environnement (EC2)* pour "Type d'environnement" et le "Type d'instance" *t2.micro* (il devrait être indiqué comme disponible gratuitement). Le paramètre d'économie par défaut suffira. Vous pouvez garder les autres paramètres par défaut. +8. Cliquez sur *Étape suivante* +9. Cliquez sur *Créer un environnement* + +Maintenant, vous pouvez voir une interface avec une barre latérale, une grande fenêtre principale avec du texte et une petite fenêtre en bas qui ressemble à quelque chose comme ceci: + +{% filename %}bash{% endfilename %} + + nomutilisateur:~/workspace $ + + +Cette fenêtre en bas est votre terminal. Vous pouvez l'utiliser pour donner des instructions à l'ordinateur Cloud9. Vous pouvez changer la taille de la fenêtre et l'agrandir un peu. + +#### Glitch.com Cloud IDE + +1. Allez sur [Glitch.com](https://glitch.com/) +2. Créez un compte (https://glitch.com/signup) ou utilisez votre compte GitHub si vous en avez un. (Voir les instructions GitHub ci-dessous.) +3. Cliquez sur *New Project* et choisissez *hello-webpage* +4. Cliquez sur la liste déroulante Outils (en bas à gauche de la fenêtre), puis sur le bouton Terminal pour ouvrir l'onglet terminal qui contiendra une invite comme celle-ci : + +{% filename %}Terminal{% endfilename %} + + app@nom-de-votre-projet-glitch:~ + + +Lorsque vous utilisez Glitch.com comme environnement de développement Cloud (IDE), vous n'avez pas besoin de créer un environnement virtuel. À la place, créez manuellement les fichiers suivants : + +{% 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 +``` + +Une fois ces fichiers créés, allez dans le Terminal et exécutez les commandes suivantes pour créer votre premier projet Django : + +{% filename %}Terminal{% endfilename %} + + django-admin.py startproject mysite . + refresh + + +Afin de voir les messages d'erreur détaillés, vous pouvez activer les journaux de débogage Django pour votre application Glitch. Ajoutez simplement ce qui suit à la fin du fichier `mysite/settings.py`. + +{% 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, + }, + }, +} +``` + +Cela va créer un fichier `debug.log` détaillant les opérations Django et tous les messages d'erreur qui pourraient apparaître, ce qui rendra la correction beaucoup plus facile si votre site Web ne fonctionne pas. + +Le redémarrage initial du projet Glitch devrait échouer. (Si vous cliquez sur le bouton en haut de la liste déroulante `Show` puis cliquez sur `In a New Window`, vous recevrez un message d'erreur `DisallowedHost` (accès non autorisé).) Ne vous inquiétez pas à ce stade, le tutoriel corrigera cela dès que vous aurez mis à jour les paramètres Django de votre projet dans le fichier `mysite/settings.py` . + +### Environnement virtuel + +Un environnement virtuel (également appelé un virtualenv) est comme une boîte noire dans laquelle nous pouvons insérer du code informatique utile à un projet sur lequel nous travaillons. Nous les utilisons pour conserver séparément les différents morceaux de code que nous voulons dans nos différents projets afin que les choses ne se mélangent entre les projets. + +Lancer : + +{% filename %}Cloud 9{% endfilename %} + + mkdir djangogirls + cd djangogirls + python3 -m venv myvenv + source myvenv/bin/activate + pip install django~={{ book.django_version }} + + +(Notez que sur la dernière ligne, nous utilisons un tilde suivi d'un signe égal : `~=`). + +### GitHub + +Créez un compte [GitHub](https://github.com). + +### PythonAnywhere + +Le tutoriel Django Girls comprend une section sur ce qui est appelé le Déploiement, un processus qui permet de déplacer le code de votre application web vers un ordinateur public (appelé serveur) pour que d'autres personnes puissent voir votre travail. + +Cette partie est un peu étrange quand on fait le tutoriel sur un Chromebook puisque nous utilisons déjà un ordinateur qui est visible sur Internet (par opposition, par exemple, à un ordinateur portable). Cependant, c'est toujours utile, car nous devons penser à notre espace de travail Cloud 9 comme un endroit pour notre travail "en cours" et Python Anywhere comme un endroit pour publier notre projet à mesure qu'il devient plus complet. + +Donc, inscrivez-vous pour un nouveau compte Python Anywhere sur [www.pythonanywhere.com](https://www.pythonanywhere.com). \ No newline at end of file diff --git a/fr/code_editor/README.md b/fr/code_editor/README.md index b149081182d..b3e64c1cad6 100755 --- a/fr/code_editor/README.md +++ b/fr/code_editor/README.md @@ -1,7 +1,11 @@ -# L'éditeur de texte +# L'éditeur de code -Vous allez bientôt écrire vos premières lignes de code : Il vous faut tout d'abord télécharger un éditeur de texte ! +> Pour les lectrices autodidactes, ce chapitre est traité dans la vidéo [Installer Python & Éditeur de code](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s). -> **Note** : Vous l'avez peut-être déjà fait dans le chapitre d'installation. Si c'est le cas, passez directement au prochain chapitre! +Vous êtes sur le point d'écrire vos premières lignes de code, il est donc temps de télécharger un éditeur de code. + +> **Note** Si vous utilisez un Chromebook, ignorez ce chapitre mais assurez-vous de suivre les instructions dans [configuration pour Chromebook](../chromebook_setup/README.md). Le cloud IDE que vous avez choisi (PaizaCloud Cloud IDE ou AWS Cloud9) inclut un éditeur de code, et lorsque vous ouvrez un fichier dans votre IDE dans le menu fichier, vous utiliserez automatiquement l’éditeur. +> +> **Note** Vous l'avez probablement déjà fait au chapitre [Installation](../installation/README.md). Si c'est le cas, vous pouvez passer directement au prochain chapitre ! {% include "/code_editor/instructions.md" %} \ No newline at end of file diff --git a/fr/code_editor/instructions.md b/fr/code_editor/instructions.md index d5649f6293b..288a4a15aeb 100644 --- a/fr/code_editor/instructions.md +++ b/fr/code_editor/instructions.md @@ -1,6 +1,12 @@ -Choisir un éditeur de texte parmi tous ceux qui sont disponibles est surtout une histoire de goûts personnels. La plupart des programmeurs·ses Python utilisent des IDE (Environnements de développement intégrés) complexes mais très puissants, comme Pycharm par exemple. Ce n'est pas forcément le meilleur choix pour débuter : ceux que nous vous recommandons sont tout aussi puissants, mais beaucoup plus simples à utiliser. +Choisir un éditeur de texte parmi tous ceux qui sont disponibles est surtout une histoire de goûts personnels. La plupart des programmeurs·ses Python utilisent des IDE (Environnements de Développement Intégrés) complexes mais très puissants, comme PyCharm par exemple. Ce n'est pas forcément le meilleur choix pour débuter : ceux que nous vous recommandons sont tout aussi puissants, mais beaucoup plus simples à utiliser. -Vous pouvez choisir l'un des éditeurs de la liste ci-dessous, mais n'hésitez pas à demander à votre coach l'éditeur qu'il·elle préfère. +Nos suggestions sont listées ci-dessous, mais n'hésitez pas à demander à vos coachs quelles sont leurs préférences - il sera plus facile d'obtenir de l'aide de leur part. + +## Visual Studio Code + +Visual Studio Code est éditeur de texte développé par Microsoft pour Windows, Linux et macOS. Il inclut le support du déboggage, l'utilisation de Git intégrée, le surlignage syntaxique, l'autocompletion intelligente du code, les snippets et la refactoring du code. + +[Télécharger](https://code.visualstudio.com/) ## Gedit @@ -8,24 +14,24 @@ Gedit est un éditeur libre et gratuit disponible pour tout les systèmes d'expl [Télécharger](https://wiki.gnome.org/Apps/Gedit#Download) -## Sublime Text 3 +## Sublime Text -Sublime text est un éditeur très populaire : il est disponible gratuitement sous forme de version d'évaluation pour tout les systèmes d'exploitation. Il est facile à installer et à utiliser. +Sublime Text est un éditeur très populaire avec une période d'évaluation gratuite et il est disponible pour tous les systèmes d'exploitation. -[Télécharger](https://www.sublimetext.com/3) +[Télécharger](https://www.sublimetext.com/) ## Atom -Atom est un éditeur très récent créé par [GitHub](https://github.com/). Disponible pour tout les systèmes d'exploitation, il est libre, gratuit, facile à installer et à utiliser. +Atom est un autre éditeur populaire. Il est gratuit, ouvert et disponible pour Windows, macOS et Linux. Atom est développé par [GitHub](https://github.com/). [Télécharger](https://atom.io/) ## Pourquoi installer un éditeur de texte? -Vous vous demandez sûrement pourquoi nous vous faisons installer un éditeur spécialement créé pour écrire du code. Pourquoi ne pourrions nous pas simplement utiliser un éditeur de texte comme Word ou Notepad ? +Vous devez vous demander pourquoi on installe un éditeur de texte spécial plutôt que d'utiliser Word ou Notepad plus simplement. -La première raison est que votre code doit être écrit en **texte brut**. Le problème avec les applications comme Word ou Textedit, c'est qu'elles ne produisent pas du texte brut mais du texte enrichi (avec des polices et de la mise en page), basé sur un standard comme [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format). +La première raison est que le code doit être en format **texte brute**, et le problème est que les éditeurs comme Word et Textedit ne produisent pas réellement du texte brute, mais du texte enrichi (avec des polices et de la mise en forme), en utilisant des formats personnalisés comme [ RTF (Rich Text Format) ](https://en.wikipedia.org/wiki/Rich_Text_Format). -La seconde raison est que les éditeurs de texte dédiés à la programmation contiennent de nombreuses fonctions très utiles. Ils peuvent colorer le texte en fonction du sens de celui-ci (coloration syntaxique) ou ajouter automatiquement un guillemet fermant à chaque fois que vous ouvrez un guillemet. +La seconde raison est que les éditeurs de code sont conçus spécialement pour l'édition de code. Ils fournissent donc des fonctionnalités très utiles comme la coloration du code en fonction du sens de celui ou automatiquement ajouter un guillemet fermant à chaque que vous ouvrez un guillemet. -Vous allez bientôt vous rendre compte à quel point un logiciel dédié à la programmation peut être pratique ! Prenez un peu de temps pour trouver l'éditeur qui vous convient, car il deviendra rapidement l'un de vos outils préférés :) +Nous verrons tout cela en pratique plus tard. Bientôt votre bon vieux éditeur de code deviendra l'un de vos outils favoris. :) diff --git a/fr/css/README.md b/fr/css/README.md index 31e3302fa4b..8e5c0ad8aa8 100755 --- a/fr/css/README.md +++ b/fr/css/README.md @@ -4,141 +4,144 @@ Soyons honnêtes : notre blog est plutôt moche, non ? Un peu de CSS devrait nou ## Qu'est-ce que le CSS ? -Les feuilles de style, ou Cascading Style Sheets (CSS), sont un langage informatique utilisé pour décrire l'apparence et le formatage d'un document écrit en langage markup (ex : HTML). Pour faire simple : des produits cosmétiques pour pages web ;) +Les feuilles de style (CSS : Cascading Style Sheets) sont un langage utilisé pour décrire l'apparence et la disposition d'un site écrit en langage de balisage (comme HTML). Considérez-le comme le maquillage de notre page web. ;) -Je suppose que vous n'avez pas particulièrement envie de partir de rien et de devoir tout construire vous-même. Pour éviter cela, nous allons une nouvelle fois utiliser différentes ressources créées et mises à disposition gratuitement sur Internet par d'autres développeurs·ses. Réinventer à chaque fois la roue n'est pas vraiment fun, en plus, c'est absolument inutile. +Mais on ne souhaite pas repartir de zéro. Une fois de plus, nous utiliserons quelque chose que les programmeurs ont publié gratuitement sur Internet. Réinventer la roue n'est pas amusant, n'est-ce pas ? ## Utilisons Bootstrap ! -Bootsrap est l'un des frameworks HTML et CSS les plus populaires. Il est utilisé pour créer de très beaux sites web : https://getbootstrap.com/ +Bootstrap est l'un des frameworks HTML/CSS les plus populaires pour développer de beaux sites web : https://getbootstrap.com/ -Il a été créé par d'anciens programmeurs·ses de chez Twitter et est maintenant développé par des bénévoles aux quatre coins du monde. +Il a été créé par d'anciens développeurs de Twitter. Il est maintenant développé par des bénévoles aux quatre coins du monde ! ## Installer Bootstrap -Pour installer Bootstrap, vous avez besoin d'ajouter ceci dans le `` de votre fichier `.html` (`blog/templates/blog/post_list.html`) : +Pour installer Bootstrap, ouvrez votre fichier `.html` dans l'éditeur de code et ajoutez cela à la section `` : + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - - + ``` -En faisant ceci, vous n'ajoutez aucun nouveau fichier à votre projet : vous reliez simplement des fichiers hébergés sur Internet à votre projet. Essayez maintenant de rafraichir votre page. Et voilà ! - -![Figure 14.1][1] +Cela n'ajoute pas de fichier à votre projet, mais crée seulement un lien vers des fichiers existant sur internet. Allez-y, ouvrez votre site web et rafraichissez la page. Et voilà ! - [1]: images/bootstrap1.png +![Figure 14.1](images/bootstrap1.png) C'est déjà un peu mieux ! ## Les fichiers statiques dans Django -Enfin, allons jeter un coup d'œil à ces **fichiers statiques** dont nous n'arrêtons pas de vous parler. Votre CSS et vos images sont des fichiers statiques et non dynamiques. Cela signifie que leur contenu ne dépend pas du contexte de la requête et qu'il sera donc identique pour chaque utilisateur. +Enfin, allons jeter un coup d'œil à ces **fichiers statiques** dont nous n'arrêtons pas de vous parler. Les fichiers statiques correspondent à tous vos CSS et vos images. Leur contenu ne dépend pas du contexte de la requête et sera le même pour tous les utilisateurs. ### Où ranger les fichiers statiques dans Django ? -Comme vous l'avez probablement remarqué lorsque nous avons exécuté la commande `collectstatic` sur le serveur, Django sait déjà où trouver les fichiers statiques pour la partie "admin". Maintenant, il ne nous reste plus qu'à ajouter les fichiers statiques liés à notre app `blog`. +Django sait déjà où trouver les fichiers statiques pour l'application "admin" intégrée. Maintenant, nous devons ajouter quelques fichiers statiques pour notre propre application, `blog`. -Pour cela, nous allons créer un dossier appelé `static` à l'intérieur de notre blog app : +Pour cela, nous allons créer un dossier appelé `static` à l'intérieur de notre appli blog : djangogirls ├── blog │ ├── migrations - │ └── static + │ ├── static + │   └── templates └── mysite + +Django va rechercher automatiquement tous les dossiers dits "statiques" à l'intérieur de vos dossiers d'appli. Ensuite, il sera en mesure d'utiliser leur contenu sous forme de fichiers statiques. -Django est capable de détecter automatiquement tout les dossiers appelés "static" dans l'arborescence de votre app. Il sera ainsi capable d'utiliser les fichiers présents à l'intérieur de ces dossiers comme des fichiers statiques. +## Votre premier fichier CSS ! -## Votre première CSS ! - -Nous allons créer un fichier CSS afin de personnaliser notre page web. Créez un nouveau dossier appelé `css` à l'intérieur de votre dossier `static`. Ensuite, créez un nouveau fichier appelé `blog.css` à l'intérieur du dossier `css`. Vous êtes prête ? +Nous allons maintenant créer un fichier CSS afin de personnaliser votre page. Créez un nouveau dossier appelé `css` à l'intérieur de votre dossier `static`. Ensuite, créez un nouveau fichier appelé `blog.css` à l'intérieur du dossier `css`. Vous êtes prêt ? djangogirls └─── blog └─── static └─── css └─── blog.css + +Et c'est parti pour un peu de CSS ! Ouvrez le fichier `blog/static/css/blog.css` dans votre éditeur de texte. -Et c'est parti pour un peu de CSS ! Ouvrez le fichier `static/css/blog.css` dans votre éditeur de texte. - -Nous n'allons pas trop nous attarder sur les CSS aujourd'hui. Nous vous invitons, une fois rentrée chez vous, à vous plonger dans d'autres tutoriels de CSS. Vous verrez, c'est assez simple à comprendre ! Vous pouvez par exemple consulter le cours [Codeacademy HTML & CSS course][2] qui est une excellente ressource et qui vous permettra d'en apprendre plus sur la personnalisation de site web à l'aide de CSS. +Nous n'irons pas trop loin dans la personnalisation et l'apprentissage du CSS ici. Il y a à la fin de cette page une recommandation pour un cours CSS gratuit si vous souhaitez en savoir plus. - [2]: https://www.codecademy.com/tracks/web +Que pourrions-nous faire rapidement ? Pourquoi ne pas changer la couleur de notre en-tête ? Pour indiquer la couleur que nous souhaitons utiliser, nous devons utiliser un code particulier. Ce code commence par un `#` suivi de 6 lettres (A-F) et chiffres (0-9). Par exemple, le code pour du bleu est `#0000FF`. Afin de trouver le code associé à la couleur de votre choix, vous pouvez consulter le site http://www.colorpicker.com/. Vous pouvez aussi utiliser des [couleurs prédéfinies](http://www.w3schools.com/colors/colors_names.asp), comme `red` ou `green`. -Que pourrions-nous faire rapidement ? Pourquoi ne pas changer la couleur de notre entête ? Pour indiquer la couleur que nous souhaitons utiliser, nous devons utiliser un code particulier. Ces codes commencent par `#` et sont suivis de 6 lettres (A-F) et chiffres (0-9). Afin de trouver le code associé à la couleur de votre choix, vous pouvez consulter le site http://www.colorpicker.com/. Vous pouvez aussi utiliser des [couleurs prédéfinies][3], comme `red` ou `green`. +Dans votre fichier `blog/static/css/blog.css`, ajoutez le code suivant : - [3]: http://www.w3schools.com/cssref/css_colornames.asp - -Ajoutez le code suivant dans votre fichier `blog/static/css/blog.css` : +{% filename %}blog/static/css/blog.css{% endfilename %} ```css -h1 a { - color: #FCA205; +h1 a, h2 a { + color: #C25100; } -``` -`h1 a` est un sélecteur CSS. Cela signifie que nous appliquons ce style pour chaque élément `a` présent à l'intérieur d'un élément `h1` (ce qui est le cas de `

link

`). Dans notre exemple précédent, nous indiquions notre souhait de changer la couleur du texte en `#FCA205`, c'est à dire en orange. Bien évidemment, vous êtes libre de choisir n'importe quelle couleur ! +``` + +`h1 a` est un sélecteur CSS. Cela signifie que nous allons appliquer nos styles à tout élément `a` qui se trouve dans un élément `h1` ; le sélecteur `h2 a` fait la même chose pour les éléments `h2`. Donc lorsque nous avons quelque chose comme `

lien

`, le style `h1 a` est appliqué. Dans notre cas, nous indiquons de changer sa couleur en `#C25100`, c'est à dire en orange foncé. Ou vous pouvez mettre votre propre couleur ici, mais assurez-vous qu’il contraste bien avec le fond blanc ! -Un fichier CSS permet de déterminer le style des éléments présents dans un fichier HTML. Les différents éléments sont identifiés par leur nom (`a`, `h1`, `body`), l’attribut `class` ou l’attribut `id`. Class et id sont des noms que vous choisissez vous-même. Les classes définissent des groupes d'éléments tandis que les ids désignent des éléments précis. Par exemple, l'élément suivant peut être identifié par CSS à la fois par son nom `a`, sa classe `external_link`, ou son identifiant `link_to_wiki_page` : +Un fichier CSS permet de déterminer le style des éléments présents dans un fichier HTML. La première façon pour identifier des éléments, c'est avec leur nom d'élément. Vous vous en souviendrez car ces noms proviennent des balises HTML. Exemple : `a`, `h1` et `body` sont tous des noms d'élément. Vous pouvez aussi identifier les éléments par leur attribut `class` ou `id`. La classe et l'identifiant sont des noms que vous choisissez vous-même. Les classes définissent des groupes d'éléments tandis que les identifiants pointent un élément spécifique. Par exemple, l'élément suivant peut être identifié par CSS à la fois par son nom `a`, sa classe `external_link`, ou son identifiant unique (id) `link_to_wiki_page` : ```html ``` -Nous vous conseillons d'en apprendre un peu plus sur les sélecteurs CSS sur [w3schools][4]. +Apprenez-en plus à propos des [Sélecteurs CSS sur W3Schools](http://www.w3schools.com/cssref/css_selectors.asp). - [4]: http://www.w3schools.com/cssref/css_selectors.asp +Nous devons aussi dire à notre modèle HTML que nous avons utilisé un peu de CSS. Ouvrez le fichier `blog/templates/blog/post_list.html` dans l'éditeur de code et ajoutez cette ligne au tout début : -Afin que nos modifications fonctionnent, nous devons aussi signaler à notre template HTML que nous utilisons des CSS. Ouvrez le fichier `blog/templates/blog/post_list.html` et ajoutez cette ligne au tout début de celui-ci : +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} ``` -Hop, nous chargeons les fichiers statiques :). Pour l'ajout de code suivant, gardez en tête que le navigateur lit vos fichiers dans l'ordre dans lequel ils lui sont donnés : en le plaçant à l'endroit que nous vous indiquons, vous allez pouvoir remplacer du code provenant des fichiers Boostrap par le vôtre. Donc, entre le `` et le `` et après les liens vers les fichiers CSS de Boostrap, ajoutez ceci : +On vient tout juste de charger les fichiers statiques :). Entre les balises `` et ``, après les liens vers les fichiers CSS de Bootstrap, ajoutez cette ligne : + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html ``` -Nous venons simplement de dire à notre template où nous avons rangé notre fichier CSS. +Le navigateur lit les fichiers dans l'ordre où ils sont donnés, donc nous devons nous assurer que c'est dans le bon endroit. Dans le cas contraire, le code dans notre fichier peut être écrasé par le code des fichiers Bootstrap. Nous venons simplement de dire à notre template où trouver notre fichier CSS. Maintenant, votre fichier doit ressembler à ceci : +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html -{% load staticfiles %} +{% load static %} + Django Girls blog - - + - + {% for post in posts %} -
-

published: {{ post.published_date }}

-

{{ post.title }}

+
+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} ``` -Ok, on sauvegarde et on rafraichit la page ! +Ok, on sauvegarde et on rafraîchit la page ! -![Figure 14.2][5] +![Figure 14.2](images/color2.png) - [5]: images/color2.png +Bravo ! Peut-être que nous pourrions aérer un peu notre page web en augmentant la marge du côté gauche ? Essayons pour voir ! -Bravo ! Peut-être que nous pourrions un peu aérer notre page web en augmentant la marge du côté gauche ? Essayons pour voir ! +{% filename %}blog/static/css/blog.css{% endfilename %} ```css body { @@ -146,80 +149,90 @@ body { } ``` -Ajoutez ceci à votre fichier CSS, sauvegardez-le et voyons le résultat ! +Ajoutez ceci à votre CSS, enregistrez le fichier et regarder comment cela fonctionne ! -![Figure 14.3][6] +![Figure 14.3](images/margin2.png) - [6]: images/margin2.png +Et si nous changions aussi la police de caractères de notre entête ? Collez ceci dans le `` de votre fichier `blog/templates/blog/post_list.html` : -Et si nous changions aussi la police de caractères de notre entête ? Collez ceci dans la partie `` de votre fichier `blog/templates/blog/post_list.html` : +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - + ``` -Cette ligne nous permet d'importer la police de caractères *Lobster* depuis Google Fonts (https://www.google.com/fonts). +Comme précédemment, vérifiez l'ordre et placez le avant `blog/static/css/blog.css`. Cette ligne importera une police appelée *Lobster* à partir de Google Fonts (https://www.google.com/fonts). -Maintenant, ajoutons `font-family: 'Lobster';` à l'intérieur du bloc déclaratif `h1 a` dans le fichier CSS `blog/static/css/blog.css`. Le bloc déclaratif est le code situé à l'intérieur des accolades `{` et `}`. N'oubliez pas ensuite de rafraichir la page. +Retrouvez le bloc de règles `h1 a` (délimité par les accolades `{` `}`) dans le fichier css `blog/static/css/blog.css`. Ajoutez maintenant la ligne `font-family; 'Lobster',` dans les accolades et rafraîchissez la page : + +{% filename %}blog/static/css/blog.css{% endfilename %} ```css -h1 a { - color: #FCA205; +h1 a, h2 a { + color: #C25100; font-family: 'Lobster'; } ``` -![Figure 14.3][7] - - [7]: images/font.png +![Figure 14.3](images/font.png) Super ! -Comme nous l'avions mentionné précédemment, il existe une notion de classe dans CSS. En gros, cela vous permet de donner un nom à un morceau de code HTML auquel vous souhaitez appliquer un style particulier sans que cela ne concerne le reste du code. C'est particulièrement pratique lorsque vous avez deux divs qui font quelque chose de différent (par exemple, votre entête et votre post) et que vous ne voulez pas qu'ils soient identiques. +Comme mentionné ci-dessus, CSS a un concept de classe. Ce concept vous permet de nommer une partie de code HTML et d'y appliquer des styles, uniquement pour cette partie, sans affecter le reste. Cela peut être très utile ! Peut-être que vous avez deux divs qui sont en train de faire quelque chose de différent (comme votre en-tête et votre contenu). Une classe peut vous aider à leur donner un aspect différent. -Allons donner des noms à certaines parties de notre code html. Ajouter la classe `page-header` à votre `div` qui contient votre entête. Votre fichier doit ressembler maintenant à ceci : +Vous pouvez maintenant nommer certaines parties du code HTML. Remplacez l'élément `header` qui contient votre en-tête avec ce qui suit : + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - - ``` + +``` + +Maintenant, ajoutez la classe `post` à votre `article` contenant votre blog post. -Maintenant, ajoutez la classe `post` à votre `div` contenant votre blog post. +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -
-

published: {{ post.published_date }}

-

{{ post.title }}

+
+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ ``` -Nous allons maintenant ajouter des blocs déclaratifs à différents sélecteurs. Les sélecteurs qui commencent par `.` sont reliés aux classes. Le net regorge de bons tutoriels sur CSS qui vous permettront de comprendre le code que nous allons rajouter à notre fichier. Pour l'instant, copier-coller le code qui suit dans votre fichier `blog/static/css/blog.css` : +Nous allons maintenant ajouter des blocs de règles aux différents sélecteurs. Les sélecteurs qui commencent par `.` désignent des classes. De nombreux tutoriels et explications sur le CSS existent sur le Web, cela pourra vous aider qui à comprendre le code suivant. Pour le moment, copiez et collez-le dans votre fichier `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; } @@ -227,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; @@ -242,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-default, +.btn-default:visited { + color: #C25100; + background: none; + border-color: #C25100; +} + +.btn-default:hover { + color: #FFFFFF; + background-color: #C25100; +} ``` -Nous allons maintenant nous intéresser au code concernant les posts. Il va falloir remplacer le code suivant : +Nous allons maintenant nous intéresser au code concernant les posts. Il va falloir remplacer le code le code suivant : + +{% 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 %} ``` -Ce code se trouve dans le fichier `blog/templates/blog/post_list.html`. Il doit être remplacé par le code suivant : +se trouvant dans le fichier `blog/templates/blog/post_list.html` par : + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -
+
-
+
{% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %}
-
+
``` -Sauvegardez les fichiers modifiés et rafraichissez votre site web. - -![Figure 14.4][8] +Sauvegardez les fichiers modifiés et rafraîchissez votre page. - [8]: images/final.png +![Figure 14.4](images/final.png) -Woohoo ! C'est pas mal, non ? Le code que nous avons collé n'est pas bien compliqué à comprendre et vous devriez pouvoir en saisir l'essentiel rien qu'en le lisant (ce n'est pas grave si ce n'est pas le cas ! ). +Woohoo ! Ça a l'air génial, non ? Intéressez-vous au code que nous venons juste de coller pour trouver quelles règles CSS sont appliquées aux sélecteurs HTML que nous avons nommés précédemment. Où feriez-vous le changement si l'on souhaite mettre la date en turquoise ? -N'ayez pas peur et jouez un peu avec la CSS : essayez par exemple d'en changer des morceaux. Vous avez cassé quelque chose ? Pas de problème : vous pouvez toujours annuler vos modifications ! +N'ayez pas peur de bricoler un peu le CSS et essayer de changer certaines choses. Jouer avec le CSS peut vous aider à comprendre comment et qui agit sur quoi. Si vous cassez quelque chose, ne vous inquiétez pas – vous pouvez toujours faire marche arrière ! -Voilà pour la partie CSS. Nous vous encourageons vivement à suivre le tutoriel gratuit de [Code Academy][2] : considérez ce tutoriel comme un petit travail à faire une fois rentrée chez vous. Vous connaitrez ainsi tout ce qu'il y a à savoir pour rendre son site bien plus joli ! +Nous vous recommandons chaudement de suivre les cours en ligne "Basic HTML & HTML5" et "Basic CSS" sur [freeCodeCamp](https://learn.freecodecamp.org/). Ils vous aideront à en apprendre plus sur le sujet et à créer de magnifiques sites web avec HTML et CSS. -Prête pour le chapitre suivant ? :) +Prêt pour le chapitre suivant ? :) \ No newline at end of file diff --git a/fr/css/images/bootstrap1.png b/fr/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/fr/css/images/bootstrap1.png and b/fr/css/images/bootstrap1.png differ diff --git a/fr/css/images/color2.png b/fr/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/fr/css/images/color2.png and b/fr/css/images/color2.png differ diff --git a/fr/css/images/final.png b/fr/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/fr/css/images/final.png and b/fr/css/images/final.png differ diff --git a/fr/css/images/font.png b/fr/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/fr/css/images/font.png and b/fr/css/images/font.png differ diff --git a/fr/css/images/margin2.png b/fr/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/fr/css/images/margin2.png and b/fr/css/images/margin2.png differ diff --git a/fr/deploy/README.md b/fr/deploy/README.md index 6626e3996b4..aec1afdd53d 100755 --- a/fr/deploy/README.md +++ b/fr/deploy/README.md @@ -1,26 +1,18 @@ -# Déployer ! +# Déployer! > **Note** Le chapitre suivant peut-être un peu difficile à comprendre. Accrochez-vous et allez jusqu'au bout : le déploiement fait partie intégrale du processus de développement d'un site internet. Ce chapitre a été placé au milieu du tutoriel afin de permettre à votre coach de vous aider dans cette étape un peu compliquée qu'est la mise en ligne de votre site. Si jamais vous manquez de temps à la fin de la journée, ne vous inquiétez pas ! Une fois ce chapitre terminé, vous serez en mesure de finir le tutoriel chez vous :) -Jusqu'à présent, votre site web n'était seulement disponible que sur votre ordinateur. Maintenant, vous allez apprendre à le déployer ! Déployer signifie mettre en ligne votre site pour que d'autres personnes puissent enfin voir votre app :). +Jusqu'à maintenant, votre site web est uniquement disponible sur votre ordinateur. Maintenant, vous allez apprendre à déployer! Déployer signifie mettre en ligne votre site pour que d'autres personnes puissent enfin voir votre app. :) -Comme vous l'avez appris, un site web a besoin d'être installé sur un serveur. Il existe de très nombreux fournisseurs de serveurs sur Internet. Nous allons en utiliser un qui dispose d'un système de déploiement relativement simple : [PythonAnywhere][1]. PythonAnywhere est gratuit pour les petites applications qui n'ont pas beaucoup de visiteurs : cela correspond parfaitement à ce dont nous avons besoin pour le moment. +Comme vous l'avez appris, un site web a besoin d'être installé sur un serveur. Il existe de nombreux fournisseurs de serveurs disponibles sur Internet, nous utiliserons [PythonAnywhere](https://www.pythonanywhere.com/). PythonAnywhere est gratuit pour les petites applications qui n'ont pas trop de visiteurs, donc ce sera certainement suffisant pour vous maintenant. - [1]: https://pythonanywhere.com/ +Nous allons aussi utiliser les services [GitHub](https://www.github.com), ce qui nous permettra d'héberger notre code en ligne. Il existe d'autres entreprises qui proposent des services similaires. Cependant, presque tous⋅tes les développeurs·ses possèdent aujourd'hui un compte Github et, dans quelques instants, vous aussi ! -Nous allons aussi utiliser les services [GitHub][2], ce qui nous permettra d'héberger notre code en ligne. Il existe d'autres entreprises qui proposent des services similaires. Cependant, presque tous⋅tes les développeurs·ses possèdent aujourd'hui un compte Github et, dans quelques instants, vous aussi ! - - [2]: https://www.github.com - -Github va nous servir d'intermédiaire pour envoyer et récupérer notre code sur PythonAnywhere. +Ces trois endroits sont importants pour vous. Votre ordinateur local est l'endroit où vous faites de développement et de test. Lorsque vous êtes heureux avec le résultat, vous sauvegarderez une copie de votre programme sur GitHub. Votre site sera sur PythonAnywhere et vous le mettrez à jour en y mettant une copie de votre nouveau code sur GitHub. # Git -Git est un "gestionnaire de version" utilisé par de nombreux·ses développeurs·ses. Ce logiciel permet de garder une trace des modifications apportées à chaque fichier afin que vous puissiez facilement revenir en arrière ou à une version spécifique. Cette fonction est similaire au "suivi des modifications" de Microsoft Word, mais en beaucoup plus puissant. - -## Installer Git - -> **Note** Si vous avez suivi la partie "installation" du tutoriel, vous n'avez pas besoin d'installer Git à nouveau. Vous pouvez passer directement à la prochaine section et commencer à créer votre dépôt Git. +> **Note** Si vous avez déjà effectué [l'installation](../installation/README.md), il n'est pas nécessaire de la refaire : vous pouvez passer à la partie suivante et commencer à créer votre dépôt Git {% include "/deploy/install_git.md" %} @@ -30,262 +22,229 @@ Git conserve toutes les modifications apportées à un ensemble de fichiers dans > **Note** : n'oubliez pas de vérifier dans quel répertoire vous vous trouvez avant d'initialiser votre dépôt. Pour cela tapez la commande `pwd` (OSX/Linux) ou `cd` (Windows). Vous devriez vous trouver dans le dossier `djangogirls`. - $ git init - Initialise un dépôt Git vide à l'emplacement ~/djangogirls/.git/ - $ git config --global user.name "Votre nom" - $ git config --global user.email you@exemple.com - - -L'initialisation d'un dépôt git ne se fait qu'une fois par projet. De même, vous n'aurez plus jamais à ré-entrer votre nom d'utilisateur ou votre email. +{% filename %}command-line{% endfilename %} -Git va surveiller et conserver les modifications concernant l'ensemble des fichiers et dossiers présents dans ce répertoire, à l'exception de certains fichiers que nous aimerions exclure. Pour cela, nous allons créer un fichier appelé `.gitignore` dans le répertoire principal du projet. Ouvrez votre éditeur et créez un nouveau fichier en copiant le contenu suivant : - -``` -*.pyc -__pycache__ -myvenv -db.sqlite3 -/static -.DS_Store -``` - -Enregistrez ce fichier `.gitignore` dans votre répertoire principal "djangogirls". - -> **Attention**: le point au début du nom du fichier est important ! Vous pouvez parfois rencontrer des difficultés à créer ce fichier. Par exemple, Mac ne vous laisse pas enregistrer un fichier qui commence par un point dans Finder. Pour contourner ce problème, utilisez la fonction "enregistrer sous" de votre éditeur : ça marche à tous les coups! - -> **Note** L'un des fichiers spécifiés dans `.gitignore` est `db.sqlite3`. Ce fichier est votre base de donnée locale, où tous vos posts de blog sont stockés. Ce fichier n'est pas ajouté à la base de données parce que votre site internet sur PythonAnywhere utilise une base de donnée différente. Cette base de donnée peut être en SQLite, comme celle créée localement sur votre ordinateur mais en général, une base de données appelée MySQL est utilisée parce qu'elle peut gérer beaucoup plus de visiteurs qu'une base de données SQLite. Dans tous les cas, ignorer votre base de donneés SQLite pour la copie sur GitHub signifie que tous les posts que vous avez créé jusqu'à maintenant vont rester sur votre machine locale et ne seront accessible que depuis cette machine. Vous allez devoir les ajouter à nouveau sur votre site internet en production. Considérez votre base de données locale comme une aire de jeu où vous pouvez essayer des choses différentes sans vous souciez de supprimer un de vos vrais post de blog. - -Avant de taper la commande `git add` ou lorsque vous ne vous souvenez plus des changements que vous avez effectué dans votre projet, pensez à taper la commande `git status`. Cela permet surtout d'éviter les mauvaises surprises, comme l'ajout ou l'envoi d'un mauvais fichier. La commande `git status` permet d'obtenir des informations sur tous les fichiers non-suivis/modifiés/mis-à-jour, l'état de la branche, et bien plus encore. Voici ce qui se passe lorsque vous tapez cette commande : + $ git init + Initialized empty Git repository in ~/djangogirls/.git/ + $ git config --global user.name "Your Name" + $ git config --global user.email you@example.com + + +L'initialisation d'un dépôt git ne doit être faite qu'une seule fois par projet (et vous n'avez plus jamais besoin de re-saisir le nom d'utilisateur et adresse email). + +Git va surveiller les modifications faites à tous les fichiers et dossiers présents dans ce répertoire, mais il y a certains fichiers que nous voudrions qu'il ignore. Pour cela, nous allons créer un fichier appelé `.gitignore` dans le répertoire principal du projet. Ouvrez votre éditeur et créez un nouveau fichier en copiant le contenu suivant : + +{% filename %}.gitignore{% endfilename %} + + # Python + *.pyc + *~ + __pycache__ + + # Env + .env + myvenv/ + venv/ + + # Base de donnée + db.sqlite3 + + # Dossier "static" à la racine du projet + /static/ + + # macOS + ._* + .DS_Store + .fseventsd + .Spotlight-V100 + + # Windows + Thumbs.db* + ehthumbs*.db + [Dd]esktop.ini + $RECYCLE.BIN/ + + # Visual Studio + .vscode/ + .history/ + *.code-workspace + + Text + XPath: /pre[2]/code + + + +Enregistrez ce fichier sous le nom `.gitignore` dans votre répertoire principal "djangogirls". + +> **Attention** : le point au début du nom du fichier est important ! Si vous avez des difficultés à le faire (les Macs n'aiment pas que vous créiez des fichiers commençant par un point dans le Finder, par exemple), utilisez la fonction "Enregistrer sous" dans votre éditeur; ça marche toujours. N'ajoutez pas `.txt`, `.py`, ou d'autres extensions à la fin du nom. Git va reconnaitre le fichier seulement s'il porte le nom `.gitignore`. Linux et MacOS considèrent les fichiers commençant par `.` (comme `.gitignore`) comme étant cachés et la commande `ls` normale ne va pas montrer ces fichiers. Il faut utiliser `ls -a` pour voir le fichier `.gitignore`. +> +> **Remarque** un de fichiers que vous avez spécifié dans votre fichier `.gitignore` est `db.sqlite3`. Ce fichier est votre base de données locale, où tous les utilisateurs et les articles que vous avez créés sont stockés. Suivant les bonnes pratiques du développement web, nous allons utiliser des bases de données distinctes pour votre site de test local et votre site Web en ligne sur PythonAnywhere. La base de données sur PythonAnywhere pourrait être du type SQLite, comme votre version locale. Normalement on lui préfèrerait une base de données du type MySQL, car capable de gérer un plus grand nombre de visiteurs. Quoi qu’il en soit, le fait que votre base de données SQLite soit ignorée lors de l'archivage sur GitHub implique que tous les messages et le superutilisateurs que vous avez créé jusqu'à présent ne seront disponibles que localement. Vous devrez les créer de nouveau en production. Vous devriez penser à votre base de données locale comme un terrain de jeux où vous pouvez tester différentes choses et ne pas avoir peur de supprimer vos messages réels sur votre blog. + +C'est une bonne idée d'utiliser la commande `git status` avant `git add` ou dès que vous n'êtes plus sûr de ce qui a changé dans le projet. Cela vous évitera des surprises comme ajouter ou envoyer un mauvais fichier. La commande `git status` permet d'obtenir des informations sur tous les fichiers non-suivis/modifiés/ajoutés, l'état de la branche, et bien plus encore. La commande devrait renvoyer ceci: + +{% filename %}command-line{% endfilename %} $ git status On branch master - - Initial commit - + + 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) + +Et pour finir, nous allons enregistrer nos modifications. Tapez ces commandes dans votre terminal: -Pour le moment, nous n'avons fait que regarder l'état de notre branche. Pour enregistrer nos changements, nous allons devoir taper les commandes suivantes : +{% filename %}command-line{% endfilename %} - $ git add --all . + $ 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 - + ## Publier votre code sur GitHub -Allez sur [GitHub.com][2] et inscrivez-vous gratuitement (si vous possédez déjà un compte, c'est très bien!) +Allez sur [GitHub.com](https://www.github.com) et créez-vous un nouveau compte gratuitement. (Si vous l'avez déjà fait lors de la préparation pour l’atelier, c’est très bien !) N’oubliez pas de mémoriser votre mot de passe (ajoutez-le à votre gestionnaire de mot de passe, si vous en utilisez un). -Ensuite, créez un nouveau dépôt en lui donnant le nom "my-first-blog". Pensez à laisser les options par défaut. Dans notre cas, il n'est pas nécessaire de cocher la case "initialise with a README". Vous pouvez aussi laisser l'option .gitignore vide car nous avons déjà créé ce fichier précédemment. Enfin, comme nous n'avons pas besoin d'une licence pour notre application, laissez le champ License à None. +Ensuite, créez un nouveau dépôt en lui donnant le nom "mon-nouveau-blog". Laissez la case "initialisation avec README" décochée, laissez l'option .gitignore vide (nous l'avons fait manuellement) et laissez la Licence en tant que Aucune. -![][3] +![](images/new_github_repo.png) - [3]: images/new_github_repo.png +> **Note** : dans le cadre de ce tutoriel, le nom `mon-nouveau-blog` est très important. Cependant, vous êtes libre de le changer mais, attention : à chaque fois que ce nom apparaîtra dans le tutoriel, vous allez devoir le remplacer par le nom que vous avez choisi. Il est probablement plus simple de garder le nom `mon-nouveau-blog`. -> **Note** : dans le cadre de ce tutoriel, le nom `my-first-blog` est très important. Cependant, vous êtes libre de le changer mais, attention : à chaque fois que ce nom apparaitra dans le tutoriel, vous allez devoir le substituer avec le nom que vous avez choisi. Il est probablement plus simple de garder le nom `my-first-blog` pour cette fois. +Dans l'image suivante, vous verrez le URL de votre dépôt, que vous utiliserez dans certaines commandes qui suivent (ex. pour cloner le dépôt) : -La page suivante vous donne l'URL qui va vous permettre de cloner votre dépôt. Choisissez la version « HTTPS » et copiez l'URL car nous allons rapidement en avoir besoin : +![](images/github_get_repo_url_screenshot.png) -![][4] +Nous avons maintenant besoin de relier nos deux dépôts ("hook" en anglais) : celui sur notre ordinateur et celui sur GitHub. - [4]: images/github_get_repo_url_screenshot.png +Tapez les instructions suivantes dans votre console (remplacez `` avec le nom d'utilisateur de votre compte GitHub et sans les chevrons. Le URL doit correspondre exactement à l'URL que vous venez de voir) : -Nous avons maintenant besoin de relier nos deux dépôts : celui sur notre ordinateur et celui sur GitHub. On utilise l'expression "hook" en anglais pour cette décrire cette étape. +{% filename %}command-line{% endfilename %} -Tapez les instructions suivantes dans votre console (remplacez `` avec le nom d'utilisateur de votre compte GitHub et sans les chevrons) : - - $ git remote add origin https://github.com//my-first-blog.git + $ git remote add origin https://github.com//my-first-blog.git $ git push -u origin master + +Lorsque vous "poussez" sur GitHub, votre nom d’utilisateur ainsi que le mot de passe vous seront demandés (que ce soit dans la fenêtre de ligne de commande ou dans une fenêtre pop-up). Après avoir entré les informations d’identification, vous devriez voir quelque chose comme ceci : -Entrez votre nom d'utilisateur et mot de passe Github. Vous devriez voir quelque chose comme ceci : +{% filename %}command-line{% endfilename %} - Username for 'https://github.com': votre-nom - Password for 'https://votre-nom@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/votre-nom/my-first-blog.git + To https://github.com/ola/my-first-blog.git + * [new branch] master -> master Branch master set up to track remote branch master from origin. + + - - -Votre code est maintenant sur GitHub. Allez jeter un coup d’œil ! Votre code est maintenant au même endroit que d'autres projets super cool : [Django][5], [le tutoriel Django Girls][6] et les nombreux autres projets libres qui sont hébergés sur GitHub :) - - [5]: https://github.com/django/django - [6]: https://github.com/DjangoGirls/tutorial +Votre code est maintenant sur GitHub. Allez jeter un coup d’œil ! Votre code est maintenant au même endroit que d'autres projets super cool : [Django](https://github.com/django/django), [le tutoriel Django Girls](https://github.com/DjangoGirls/tutorial) et les nombreux autres projets libres qui sont hébergés sur GitHub. :) # Mettre votre blog en ligne avec PythonAnywhere +## Créez votre compte utilisateur sur PythonAnywhere + > **Note** Vous avez peut être déjà créé un compte PythonAnyWhere au cours de la phase d'installation - si c'est le cas, inutile de le refaire. {% include "/deploy/signup_pythonanywhere.md" %} -## Récupérer votre code sur PythonAnywhere - -Une fois enregistré sur PythonAnywhere, vous serez automatiquement redirigée sur votre écran d'accueil où se trouve la liste des consoles. Cliquez sur le lien "Bash" dans la partie "start a new console". C'est la version PythonAnywhere des consoles que vous avez sur votre ordinateur. - -> **Note** : PythonAnywhere utilise Linux. Si vous êtes sous Windows, la console sera un peu différente de celle de votre ordinateur. - -Importons notre code depuis Github vers PythonAnywhere en créant un "clone" de notre dépôt. Tapez la commande suivante dans la console de PythonAnywhere (n'oubliez pas d'utiliser votre nom d'utilisateur Github à la place de ``): - - $ git clone https://github.com//my-first-blog.git - +## Configurer votre site sur PythonAnywhere -Cette commande va permettre d'effectuer une copie de votre code vers PythonAnywhere. La commande `tree my-first-blog` permet d'afficher un aperçu de ce qui se trouve maintenant sur votre serveur : +Allez sur le [Panneau de Contrôle de PythonAnywhere](https://www.pythonanywhere.com/) en cliquant sur le logo, et choisissez l'option de démarrer un terminal "Bash". C'est comme votre terminal à vous, mais chez PythonAnywhere. - $ 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 +![La section "nouveau terminal" sur l'interface web de PythonAnywhere, avec un bouton pour "bash"](images/pythonanywhere_bash_console.png) +> **Note** : PythonAnywhere utilise Linux. Si vous êtes sous Windows, la console sera un peu différente de celle de votre ordinateur. -### Créer un virtualenv sur PythonAnywhere - -Tout comme sur votre ordinateur, vous allez devoir créer un environnement virtuel et installer Django sur PythonAnywhere. L'opération est identique, à une différence près pour les utilisatrices de Windows : il s'agit ici d'une console Linux. Pas de panique, c'est très simple ! Ouvrez la console Bash de PythonAnywhere et tapez les commandes suivantes : - - $ 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~=1.10.0 - Collecting django - [...] - Successfully installed django-1.10 - - -> **Note** : L'étape `pip install` peut prendre quelques minutes. Patience, patience ! Cependant, si cela prend plus de 5 minutes, c'est que quelque chose ne va pas. N'hésitez pas à solliciter votre coach. - - - - - -### Créer une base de données sur PythonAnywhere - -Tout comme l'environnement virtuel, la base de données n'est pas partagée entre le serveur et votre ordinateur. Cela signifie, entre autre, que vous n'aurez plus forcément les mêmes utilisateurs ni les mêmes posts sur votre ordinateur et sur PythonAnywhere. - -Pour créer une base de données sur PythonAnywhere, nous allons taper les mêmes commandes que sur notre ordinateur: d'abord `migrate`, puis `createsuperuser`: - - (mvenv) $ python manage.py migrate - Operations to perform: - [...] - Applying sessions.0001_initial... OK - - - (mvenv) $ python manage.py createsuperuser - - -## Faire de votre blog une application web - -Maintenant, notre code est sur PythonAnywhere, notre virtualenv est prêt, les fichiers statiques sont recueillis et la base de données est initialisée. Nous sommes prêts à le publier comme une application web ! - -Retourner sur la page d'accueil de PythonAnywhere en cliquant sur le logo en haut à gauche. Ensuite, cliquez sur l'onglet **Web** et **Add a new web app**. - -Après avoir confirmé votre nom de domaine, choisissez **manual configuration** dans la boite de dialogue (NB : ne choisissez *pas* l'option "Django"). Enfin, choisissez **Python 3.4** et cliquez sur "next" pour fermer l'assistant de configuration. +Pour déployer une application sur PythonAnywhere, vous devez y télécharger votre code depuis GitHub, puis configurer PythonAnywhere pour qu'il la reconnaisse et commence à la faire tourner en tant qu'application web. Cela peut se faire de façon manuelle, mais PythonAnywhere fourni un outil qui va tout faire pour vous. Commençons par l'installer: -> **Note** : Faites bien attention à sélectionner l'option configuration manuelle ("Manual configuration") et non l'option "Django". N'oubliez pas une chose : vous êtes bien trop cool pour prendre l'option Django qui est fourni par défaut ;-) +{% filename %}PythonAnywhere command-line{% endfilename %} -### Configurer le virtualenv + $ pip install --user pythonanywhere + -Une fois l'assistant fermé, vous serez automatiquement conduite sur la page de configuration dédiée à votre application web. Dès que vous aurez besoin de modifier quelque chose concernant votre appli, c'est là que vous devrez aller. +Vous devriez voir quelque chose comme `Collecting pythonanywhere`, et au bout d'un moment une dernière ligne disant `Successfully installed (...) pythonanywhere-(...)`. -![][7] +Maintenant, nous exécutez l'assistant pour configurer automatiquement votre application à partir de GitHub. Tapez ce qui suit dans la console sur PythonAnywhere (n'oubliez pas d'utiliser votre nom d'utilisateur GitHub à la place de ``, afin que l'URL corresponde à celle du clone de GitHub) : - [7]: images/pythonanywhere_web_tab_virtualenv.png +{% filename %}PythonAnywhere command-line{% endfilename %} -Dans la section "Virtualenv", cliquez sur le texte en rouge qui indique "Enter the path to a virtualenv" (entrer le chemin d'accès de votre environnement virtuel), et entrez ceci : `/home//my-first-blog/myvenv/`. Cliquez sur la boite bleue avec la case à cocher pour sauvegarder le chemin d’accès. + $ pa_autoconfigure_django.py --python=3.10 https://github.com//my-first-blog.git + -> **Note** : N'oubliez pas de mettre votre nom d'utilisateur. Ne vous inquiétez pas : si vous faites une erreur, PythonAnywhere vous le signalera. +En regardant la commande s'exécuter, vous devriez voir ce qui ce passe: -### Configurer le fichier WSGI +- Téléchargement de votre code depuis GitHub +- Création d'un virtualenv chez PythonAnywhere, comme celui sur votre propre ordinateur +- Mise à jour de votre fichier de paramètres avec des paramètres de déploiement +- Mise en place d’une base de données sur PythonAnywhere en utilisant la commande `manage.py migrate` +- Mise en place de vos fichiers statiques (nous verrons ce que c'est plus tard) +- Et configuration de PythonAnywhere pour servir votre application web via son API -Django utilise le protocole "WSGI" qui est un stantard pour servir des sites web qui utilisent Python. Ce protocole est supporté par PythonAnywhere. Afin que PythonAnywhere détecte notre blog Django, nous allons éditer le fichier de configuration WSGI. +Sur PythonAnywhere toutes ces étapes sont automatisées, mais ce sont les mêmes étapes que vous auriez à faire avec n'importe quel autre fournisseur de serveurs. -Dans l'onglet web, vous allez trouver une section code : cliquez sur le lien "WSGI configuration file" : votre fichier de configuration devrait s’intituler `/var/www/_pythonanywhere_com_wsgi.py`. Une fois que vous avez cliqué dessus, vous serez automatiquement redirigée dans un éditeur de texte. +La principale chose à remarquer maintenant est que votre base de donnée sur PythonAnywhere est complètement séparée de votre base de données sur votre propre ordinateur. Cela veut dire qu'elle peut contenir des messages différents et avoir des comptes administrateurs différents. Et donc, exactement comme on l'avait fait sur votre ordinateur, on doit initialiser le compte administrateur avec `createsuperuser`. PythonAnywhere a initialisé votre virtualenv pour vous automatiquement, donc la seule chose que vous avez à faire est d'exécuter: -Supprimer le contenu du fichier et le remplacer par ce qui suit : +{% filename %}PythonAnywhere command-line{% endfilename %} -```python -import os -import sys + (ola.pythonanywhere.com) $ python manage.py createsuperuser + -path = '/home//my-first-blog' # use your own username here -if path not in sys.path: - sys.path.append(path) +Entrez les informations pour votre compte administrateur. Mieux vaut utiliser les mêmes que sur votre ordinateur pour éviter toute confusion, sauf si vous voulez utiliser un mot de passe plus sécurisé sur PythonAnywhere. -os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' +Maintenant, si vous voulez, vous pouvez aussi jeter un œil à votre code sur PythonAnywhere en utilisant la commande `ls`: -from django.core.wsgi import get_wsgi_application -from django.contrib.staticfiles.handlers import StaticFilesHandler -application = StaticFilesHandler(get_wsgi_application()) -``` +{% filename %}PythonAnywhere command-line{% endfilename %} -> **Note** : N'oubliez pas de remplacer `` par votre nom d'utilisateur -> **Note** : A la ligne 3, on s'assure que PythonAnywhere saura trouver notre application. Il est très important que ce chemin d'accès soit correct, et plus particulièrement qu'il n'y ait pas d'espaces en plus. Dans le cas contraire "ImportError" s'affichera dans le log d'erreur. + (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 + -Le but de ce fichier est de permettre à PythonAnywhere de savoir où votre application web se situe et de connaître le nom des fichiers de configuration de Django. +Vous pouvez également accéder à la page "Fichiers" et naviguer à l'aide du navigateur de fichiers PythonAnywhere intégré. (Depuis la page Console, vous pouvez visiter d'autres pages PythonAnywhere en cliquant sur le bouton Menu en haut à droite. Une fois que vous vous trouvez dans une de ces pages, les liens vers les autres pages se trouve en haut.) -`StaticFilesHandler` sert à gérer notre CSS. Cette étape est réalisée automatiquement en exécutant la commande `runserver`. Nous aborderons un peu plus en détails les fichiers statiques quand nous éditerons le CSS de notre site. +## Vous êtes désormais sur Internet ! -Cliquez sur **Save** puis, retournez dans l'onglet **Web**. +Votre site devrait maintenant être accessible sur Internet ! Cliquez sur l'onglet "Web" dans PythonAnywhere pour y obtenir un lien. Vous pouvez partagez ce lien avec qui vous voulez. :) -Et voilà, c'est fini ! Vous n'avez plus qu'à cliquer sur le gros bouton vert **Reload** et vous devriez voir votre application en ligne. Le lien vers votre site est situé en haut de l'onglet web de PythonAnywhere. +> **Note** Ce tutoriel est conçu pour les débutants, et pendant le déploiement on a pris quelques raccourcis qui, d'un point de vue de la sécurité, ne sont pas idéaux. Quand vous voudrez aller plus loin dans ce projet, ou commencer un nouveau projet, vous devriez consulter la [Checklist de déploiement pour Django](https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/) pour obtenir des conseils sur comment sécuriser votre site. ## Conseils en cas de bug -Si vous constatez une erreur lorsque vous essayez de visiter votre site web, les **logs d'erreurs** devraient vous permettre de comprendre ce qui ne marche pas. Vous trouverez un lien vers ces fichiers dans l'onglet [Web][8] de PythonAnywhere. Regardez s’il y a des messages d’erreurs ; les plus récents seront en bas du fichier. Les bugs les plus fréquents que vous pouvez rencontrer sont les suivants: - - [8]: https://www.pythonanywhere.com/web_app_setup/ - -* Oublier une étape lors du passage dans la console. Vous devriez avoir fait toutes les étapes suivantes : créer un environnement virtuel, l'activer, installer Django, lancer la commande "collectstatic" et enfin créer la base de données. +Si vous constatez une erreur en exécutant le script `pa_autoconfigure_django.py`, voici quelques causes courantes : -* Se tromper dans le chemin d'accès à l'environnement virtuel : si c'est le cas, vous trouverez un petit message d'erreur en rouge dans l'onglet "web", section virtualenv. +- Oubli de créer votre "jeton API" pour PythonAnywhere. +- Faire une erreur dans votre URL GitHub +- Si vous voyez un message d’erreur indiquant *« Could not find your settings.py »*, vous avez probablement oublié d'ajouter tous vos fichiers sur Git, et/ou vous ne les avez pas envoyé à GitHub. Regardez à nouveau la section Git ci-dessus +- Si vous avez précédemment créé un compte PythonAnywhere et avez rencontré une erreur avec collectstatic, vous avez probablement une version antérieure de SQLite (par ex : 3.8.2) sur votre compte. Dans ce cas, créez un nouveau compte et essayez les commandes présentes dans la section PythonAnywhere ci-dessus. -* Se tromper lors de la création du fichier de configuration WSGI : pensez à vérifier si le chemin d'accès que vous avez entré est bien celui de "my-first-blog"? +Si vous constatez une erreur lorsque vous essayez de visiter votre site web, les **logs d'erreurs** devraient vous permettre de comprendre ce qui ne marche pas. Vous trouverez un lien vers les logs dans la page [Web](https://www.pythonanywhere.com/web_app_setup/) de PythonAnywhere. Regardez s’il y a des messages d’erreurs ; les plus récents seront en bas du fichier. -* Se tromper de version de Python : votre environnement virtuel et votre application web doivent toutes les deux être sous Python 3.4. - -* Il y a quelques [astuces générales de débogage sur le wiki PythonAnywhere][9]. - - [9]: https://www.pythonanywhere.com/wiki/DebuggingImportError +Vous pourrez aussi trouver des astuces pour le débogage sur le site d'aide de[PythonAnywhere](http://help.pythonanywhere.com/pages/DebuggingImportError). Et n'oubliez pas, votre coach est là pour vous aider ! -# Votre site est en ligne ! +# Jetez un œil à votre site ! + +La page par défaut de votre site doit dire "Ça marche!", comme c'est le cas sur votre ordinateur local. Vous pouvez essayer d'accéder à l'interface d’administration en ajoutant `/admin/` à la fin de l'URL. Normalement, une page de login devrait s'afficher. Identifiez-vous avec votre nom d'utilisateur et mot de passe et vous verrez que vous pourrez créer de nouveaux messages sur le serveur. N'oubliez pas que les messages dans votre base de données locale n'ont pas été envoyés sur la version en ligne de votre blog. -La page qui s'affiche devrait être la même que celle sur votre ordinateur : "Welcome to Django". Vous pouvez essayer d'accéder à l'interface d’administration en ajoutant `/admin/` à la fin de l'URL. Normalement, une page de login devrait s'afficher. Une fois connectée en utilisant votre nom d'utilisateur et votre mot de passe, vous devriez pouvoir ajouter des nouveaux posts sur le serveur. +Une fois que vous avez créé des messages, vous pouvez revenir à votre configuration locale (pas PythonAnywhere). De là, vous devez travailler sur votre installation locale pour apporter des modifications. C'est la façon habituelle de procéder dans le développement web : faire des modifications localement, envoyer ces modifications sur GitHub, puis télécharger ces modifications vers votre serveur Web de production. Cela vous permet de faire des expériences sans endommager votre site web de production (celui sur Internet). Cool, non ? -*Félicitations !* Le déploiement est l’une des parties les plus épineuses du développement web et il faut souvent plusieurs jours avant d'obtenir quelque chose de fonctionnel. Mais vous avez réussi sans trop d'encombres à mettre votre site en ligne : parfait <3 +*Félicitations !* Le déploiement est l’une des parties les plus épineuses du développement web et il faut souvent plusieurs jours avant d'obtenir quelque chose de fonctionnel. Mais vous avez réussi à mettre votre site en ligne, dans le vrai Internet ! \ No newline at end of file diff --git a/fr/deploy/images/github_get_repo_url_screenshot.png b/fr/deploy/images/github_get_repo_url_screenshot.png index 62a29f5f8d7..ee1560b1e85 100644 Binary files a/fr/deploy/images/github_get_repo_url_screenshot.png and b/fr/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/fr/deploy/images/new_github_repo.png b/fr/deploy/images/new_github_repo.png index 64011e59a52..d1f82e5d863 100644 Binary files a/fr/deploy/images/new_github_repo.png and b/fr/deploy/images/new_github_repo.png differ diff --git a/fr/deploy/images/pythonanywhere_account.png b/fr/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/fr/deploy/images/pythonanywhere_account.png differ diff --git a/fr/deploy/images/pythonanywhere_bash_console.png b/fr/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..68eb2a030e1 Binary files /dev/null and b/fr/deploy/images/pythonanywhere_bash_console.png differ diff --git a/fr/deploy/images/pythonanywhere_beginner_account_button.png b/fr/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/fr/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/fr/deploy/images/pythonanywhere_create_api_token.png b/fr/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..abae45ae37a Binary files /dev/null and b/fr/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/fr/deploy/images/pythonanywhere_web_tab_virtualenv.png b/fr/deploy/images/pythonanywhere_web_tab_virtualenv.png deleted file mode 100644 index 97e87e7b07b..00000000000 Binary files a/fr/deploy/images/pythonanywhere_web_tab_virtualenv.png and /dev/null differ diff --git a/fr/deploy/install_git.md b/fr/deploy/install_git.md index 2190df46aa8..200d6f7836c 100644 --- a/fr/deploy/install_git.md +++ b/fr/deploy/install_git.md @@ -1,17 +1,52 @@ -### Windows +Git est un " système de gestion de versions" utilisé par de nombreux développeurs. Ce logiciel permet de garder une trace des modifications apportées à chaque fichier afin que vous puissiez facilement revenir en arrière ou à une version spécifique. Un peu comme la fonction « suivi des modifications » dans les programmes de traitement de texte (par exemple, Microsoft Word ou LibreOffice Writer), mais beaucoup plus puissant. -Vous pouvez télécharger Git sur [git-scm.com](https://git-scm.com/). Vous pouvez cliquer sur "next" à toutes les étapes, sauf pour la cinquième, "Adjusting your PATH environment" : n'oubliez pas de choisir "Run Git and associated Unix tools from the Windows command-line", situé en bas de la liste des options disponibles. Les autres choix par défaut n'ont pas besoin d'être modifiés. L'option "Checkout Windows-style, commit Unix-style line endings" est parfaite: vous n'avez rien à changer sur cette page. +## Installer Git -### MacOS + -Vous pouvez télécharger Git sur [git-scm.com](https://git-scm.com/). Pour le reste de l'installation, suivez simplement les instructions de l'installateur. +Vous pouvez télécharger Git sur [git-scm.com](https://git-scm.com/). Vous pouvez cliquer sur "suivant" pour toutes les étapes sauf deux : au moment de choisir l'éditeur, sélectionnez Nano ; à l'étape intitulée "Adjusting your PATH environment", sélectionnez "Use Git and optional Unix tools from the Windows Command Prompt" (l'option du bas). Les autres choix par défaut n'ont pas besoin d'être modifiés. Laissez cocher l'option "Checkout Windows-style, commit Unix-style line endings". -### Linux +N'oubliez pas de fermer puis relancer l'invite de commande ou la fenêtre Powershell une fois l'installation terminée. -Git est probablement déjà installé mais, si ce n'est pas le cas, voici les instructions à suivre : + - sudo apt-get install git - # ou - sudo yum install git - # ou - sudo zypper install git \ No newline at end of file +Téléchargez Git sur [git-scm.com](https://git-scm.com/) et suivez les instructions. + +> **Note** Si vous utilisez un OS X 10.6, 10.7 ou 10.8, vous devrez sans doute installer la version de git présente ici : [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) + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo apt install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo dnf install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo zypper install git +``` + + \ No newline at end of file diff --git a/fr/deploy/signup_pythonanywhere.md b/fr/deploy/signup_pythonanywhere.md index 3b6e7b711a2..13999332854 100644 --- a/fr/deploy/signup_pythonanywhere.md +++ b/fr/deploy/signup_pythonanywhere.md @@ -1,5 +1,19 @@ -Si vous ne l'avez pas encore fait, n'oubliez pas de vous créer un compte "Beginner" sur PythonAnywhere. +PythonAnywhere est un service qui permet de faire tourner des programmes en Python sur des serveurs "dans le cloud". Nous allons l'utiliser pour héberger notre site, en direct et sur Internet. - * [www.pythonanywhere.com](https://www.pythonanywhere.com/) +Nous allons donc mettre le blog que nous sommes en train de construire sur PythonAnywhere. Pour commencer, créez un compte « Débutant » (beginner) sur PythonAnywhere (le niveau gratuit est très bien, vous n’avez pas besoin d’une carte de crédit). -> **Note** : Le nom d'utilisateur que vous allez choisir va déterminer l'adresse de votre blog de la manière suivante : `votrenomdutilisateur.pythonanywhere.com`. Si vous ne savez pas quoi prendre, nous vous conseillons de choisir votre surnom ou un nom proche du sujet de votre blog. \ No newline at end of file +* [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +![La page de login de PythonAnywhere contenant un bouton pour créer le compte gratuit pour 'Débutant'](../deploy/images/pythonanywhere_beginner_account_button.png) + +> **Note** Lorsque vous choisissez votre nom d'utilisateur, gardez à l'esprit que l'URL de votre blog prendra la forme `nomutilisateur.pythonanywhere.com`, alors choisissez un pseudonyme ou un nom adapté pour votre blog. Mémorisez votre mot de passe (ajoutez-le à votre gestionnaire de mot de passe, si vous en utilisez un). + +## Création d’un jeton API pour PythonAnywhere + +C'est quelque chose que vous n'aurez à faire qu'une seule fois. Lorsque vous serez inscrit à PythonAnywhere, vous vous retrouverez sur votre tableau de bord. Trouvez le lien en haut à droit de votre page "Compte": + +![Lien du compte en haut à droite sur la page](../deploy/images/pythonanywhere_account.png) + +sélectionnez l'onglet nommé "API token", et cliquez sur le bouton "Créer un nouveau jeton API". + +![L'onglet API sur la page Compte](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/fr/django/README.md b/fr/django/README.md index b11204e524e..62674aa7890 100755 --- a/fr/django/README.md +++ b/fr/django/README.md @@ -1,27 +1,27 @@ # Qu'est-ce que Django? -Django (*/ˈdʒæŋɡoʊ/ jang-goh*) est un framework web gratuit et libre écrit en Python. Un framework web est un ensemble de composants qui vous aide à développer des sites web plus rapidement et plus facilement. +Django (*/ˈdʒæŋɡoʊ/ jang-goh*) est un framework web gratuit et open-source écrit en Python. Un framework web est un ensemble de composants qui vous aide à développer des sites web plus rapidement et plus facilement. Lorsque vous créez un site web, vous avez souvent besoin de la même chose : une manière de gérer l'authentification de vos utilisateurs (créer un compte, se connecter, se déconnecter), une partie dédiée à la gestion de votre site, des formulaires, une manière de mettre en ligne des fichiers, etc. -La bonne nouvelle, c'est que d'autres gens se sont aussi rendus compte de ce problème et ont décidé de s'allier avec des développeurs·ses pour le résoudre. Ensemble, ces personnes ont créé différents frameworks, dont Django, pour fournir un set de composants de base qui peuvent être utilisés lors de la création d'un site web. +Heureusement pour vous, d'autres personnes ont réalisé depuis longtemps que les développeurs web font face aux mêmes problèmes lors de la construction d'un nouveau site, donc ils travaillent ensemble et créent un framework (Django étant un) qui vous donne des composants prêts à l'emploi. -Les frameworks existent pour vous éviter de réinventer la roue à chaque fois. Ils vous aident aussi à alléger la charge de travail liée à la création d'un site web. +Les frameworks existent pour vous éviter d'avoir à réinventer la roue et aider à réduire les frais généraux lorsque vous construisez de nouveaux sites. ## Pourquoi est-ce que vous auriez besoin d'un framework ? -Pour comprendre ce à quoi peut bien servir Django, nous avons besoin de nous intéresser aux multiples rôles des serveurs. Par exemple, la première chose qu'a besoin de savoir un serveur, c'est que vous aimeriez qu'il vous affiche une page web. +Pour comprendre ce qu'est exactement Django, nous devons regarder de plus près le serveur. La première chose est que le serveur doit savoir que vous voulez vous servir une page Web. -Imaginez une boîte aux lettres (un port) dont l'arrivée de lettres (une requête) serait surveillée. C'est le travail qu'effectue le serveur. Le serveur web lit la lettre qu'il a reçue et en réponse, retourne une page web. Généralement, lorsque vous voulez envoyer quelque chose, vous avez besoin de contenu. Django est quelque chose qui va vous aider à créer ce contenu. +Imaginez une boîte aux lettres (un port) dont l'arrivée de lettres (une requête) serait surveillée. C'est le travail qu'effectue le serveur. Le serveur Web lit la lettre et renvoie une page Web en réponse. Généralement, lorsque vous voulez envoyer quelque chose, vous avez besoin de contenu. Django est un outil qui va vous aider à créer ce contenu. ## Que se passe-t-il quand quelqu'un demande un site web à votre serveur ? -Quand une requête arrive sur un serveur web, elle est transmise à Django dont le premier travail va être d'essayer de comprendre ce qui est exactement demandé. Il s'occupe tout d'abord de l'adresse de la page web et essaye de comprendre ce qu'il doit en faire. Ce travail est effectué par l' **urlresolver** de Django (l'adresse d'une page web est appelée URL, Uniform Resource Locator, ce qui nous aide à comprendre le nom *urlresolver*). Comme il n'est pas très malin, il prend une liste de modèles existants et essaye de trouver celui qui correspond à notre URL. Django lit sa liste de modèles du haut vers le bas et si jamais quelque chose correspond, il envoie la requête à la fonction associée (qui s'appelle une *vue (view)*). +Lorsqu'une requête arrive sur un serveur web, elle est transmise à Django dont le premier travail va être de comprendre ce qui est demandé. Il s'occupe tout d'abord de l'adresse de page Web et essaie de savoir quoi faire. Ce travail est effectué par le routeur de Django, l'**urlresolver** (à savoir qu'une adresse web est appelé URL - Uniform Resource Locator - d'où le nom d'*urlresolver*). Ce n'est pas très intelligent - il faut renseigner une liste de modèles pour faire correspondre une URL. Django vérifie dans l'ordre les modèles, et si correspondance il y a, alors il transmet la requête à la fonction associée (appelé *vue*). -Afin d'y voir un peu plus clair, imaginez une postière transportant une lettre. Elle descend la rue et vérifie à chaque maison si le numéro de celle-ci correspond à celui de la lettre. Si jamais les deux numéros correspondent, elle met la lettre dans la boîte aux lettres de cette maison. C'est à peu près comme cela que fonctionne l'urlresolver ! +Afin d'y voir un peu plus clair, imaginez un facteur transportant une lettre. Il descend la rue et vérifie à chaque maison si le numéro de celle-ci correspond à celui de la lettre. Si les deux numéros correspondent, il met la lettre dans la boîte aux lettres de cette maison. C'est à peu près comme cela que fonctionne l'urlresolver ! -C'est dans la fonction *vue* que les choses intéressantes se passent : cela nous permet de jeter un œil dans la base de données pour obtenir des informations. Par exemple, peut-être que l'utilisateur vient de demander de changer quelque chose dans ces données ? Ce serait comme une lettre dont le contenu serait : "Merci de changer la description de mon emploi actuel". La *vue* va tout d'abord vérifier que l'utilisateur est bien autorisé à effectuer ce changement puis elle corrigera la description de l'emploi. Enfin, elle retournera un message de type : "C'est bon, j'ai terminé ! ". La *vue* créera une réponse et c'est Django qui se chargera de la transmettre au navigateur de l'utilisateur. +C'est dans la fonction de la *vue* que les choses se passent : nous allons pouvoir jeter un œil dans la base de données pour obtenir d'avantage d'informations. Par exemple, peut-être que l'utilisateur demande à changer quelque chose dans ces données ? Ce serait comme une lettre dont le contenu serait : "Merci de changer la description de mon emploi actuel". La *vue* va tout d'abord vérifier que l'utilisateur est bien autorisé à effectuer ce changement puis elle corrigera la description de l'emploi. Enfin, la *vue* générera une réponse de type "Travail terminé !" que Django pourra retourner à l'utilisateur. -Bien sûr, ceci n'est qu'une description très simplifiée du processus. Vous n'avez pas besoin de connaitre tous les détails techniques pour le moment : cette vue d'ensemble suffira largement. +Ceci n'est qu'une description très simplifiée du processus. Vous n'avez pas besoin de connaître tous les détails techniques pour le moment : cette vue d'ensemble suffira largement. -Maintenant, nous aurions la possibilité de vous assommer avec des détails complexes sur comment tout cela fonctionne. À la place, nous allons plutôt commencer à construire quelque chose ! Nous vous donnerons toutes les informations importantes au fur et à mesure que vous progresserez. Ce sera plus sympa, non ? +Au lieu de vous assommer avec des détails complexes, nous allons plutôt commencer à construire quelque chose avec Django et nous allons apprendre les choses importantes au fur et à mesure ! \ No newline at end of file diff --git a/fr/django_admin/README.md b/fr/django_admin/README.md index c4e2bc922ae..f952c9f1517 100755 --- a/fr/django_admin/README.md +++ b/fr/django_admin/README.md @@ -1,48 +1,57 @@ -# L'interface d'administration de Django +# Django admin -Pour ajouter, éditer et supprimer les posts que nous venons de modéliser, nous allons utiliser l'interface d'administration de Django. +Pour ajouter, modifier et supprimer les posts que nous venons de créer, nous allons utiliser l'interface Django admin. -Ouvrons le fichier `blog/admin.py` et remplaçons son contenu par ceci : +Ouvrons le fichier `blog/admin.py` dans l'éditeur de code et remplaçons son contenu par ceci : + +{% filename %}blog/admin.py{% endfilename %} ```python from django.contrib import admin from .models import Post admin.site.register(Post) -``` +``` Comme vous pouvez le voir, nous importons le modèle « Post » que nous avons écrit dans le chapitre précédent. Afin que notre modèle soit visible dans l'interface d'administration, nous avons besoin d'enregistrer notre modèle à l'aide de `admin.site.register(Post)`. -Voilà, il est temps de jeter un œil à notre modèle Post. N'oubliez pas d'exécuter `python manage.py runserver` dans votre console afin de lancer le serveur web. Dans votre navigateur, entrez l'adresse http://127.0.0.1:8000/admin/. Si tout va bien, vous verrez une page comme celle-ci: +Voilà, il est temps de jeter un œil à notre modèle Post. N'oubliez pas d'exécuter `python manage.py runserver` dans votre console afin de lancer le serveur web. Retourner sur votre navigateur et taper l'adresse http://127.0.0.1:8000/admin/. Vous verrez une page de login qui ressemble à celle-ci : + +![Page de login](images/login_page2.png) -![Page de login][1] +Afin de vous connecter, vous allez devoir créer un *superuser*, c'est à dire un utilisateur qui contrôlera l'intégralité du site. Retournez à votre ligne de commande : tapez `python manage.py createsuperuser` puis appuyez sur entrée. - [1]: images/login_page2.png +> Conseil : pour pouvoir taper de nouvelles commandes pendant que le serveur tourne, ouvrez une nouvelle console et activez à nouveau votre virtualenv. La section **Démarrer le serveur web** du chapitre **Votre premier projet Django !** explique comment écrire de nouvelles commandes. -Afin de vous connecter, vous allez devoir créer un *superuser*, c'est à dire un utilisateur qui contrôlera l'intégralité du site. Retournez à votre ligne de commande : tapez `python manage.py createsuperuser` puis appuyez sur entrée. Tapez votre nom d'utilisateur (en minuscules, sans espace), votre email et votre mot de passe. Vous ne voyez pas le mot de passe que vous êtes en train de taper ? C'est tout à fait normal, ne vous inquiétez pas ! Tapez simplement votre mot de passe et appuyez sur `entrée` pour continuer. La sortie que vous allez obtenir doit ressembler à celle-ci. Notez que le nom d'utilisateur et l'adresse email doivent correspondre aux informations que vous venez d'entrer. +{% filename %}macOS or 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 + + +Tapez votre nom d'utilisateur (en minuscules, sans espace), votre email et votre mot de passe. **Ne soyez pas surpris de ne pas voir le mot de passe quand vous le saisissez, c'est normal.** Saisissez le à l'aveugle et appuyez sur `Entrée` pour continuer. Vous devrez obtenir quelque chose comme ceci (où le nom d'utilisateur et le mail correspond à ce que vous avez saisi) : + + Username: ola + Email address: ola@example.com Password: Password (again): Superuser created successfully. - + Retournez dans votre navigateur et connectez-vous en tant que superutilisateur grâce à l'utilisateur que vous venez de créer. Vous devriez accéder à l'interface d'administration de Django. -![Django admin][2] - - [2]: images/django_admin3.png - -Allez voir vos posts et expérimentez un peu avec. Ajoutez 5 ou 6 posts. Ne vous occupez pas du contenu - vous pouvez juste copier du texte de ce tutoriel pour aller plus vite :). +![Django admin](images/django_admin3.png) -Sur vos 5 posts, faites en sorte qu'au moins 2 ou 3 posts possèdent une date de publication. Prenez garde à ne pas en donner à tous vos posts car nous allons avoir besoin de ces deux différents cas plus tard. +Allons du côté des Posts et jouons un peu avec. Créez 5 ou 6 blog posts. Ne vous inquiétez pas trop du contenu, qui ne sera visible que depuis votre ordinateur. Vous pouvez copier-coller des morceaux du tutoriel pour aller plus vite. :) -![Django admin][3] +Assurez-vous quelques posts (mais pas tous) aient une date de publication. Cela sera utile plus tard. - [3]: images/edit_post3.png +![Django admin](images/edit_post3.png) -Si jamais vous voulez en savoir un peu plus sur l'interface d'administration de Django, vous pouvez lire la documentation qui lui est associée : https://docs.djangoproject.com/fr/1.10/ref/contrib/admin/ +Si vous voulez en savoir plus sur l'interface d'administration de Django, n'hésitez pas à consulter la documentation du framework : https://docs.djangoproject.com/en/2.2/ref/contrib/admin/ -Il est probablement temps d'aller recharger vos batteries avec un café, un thé ou un truc à grignoter. Vous venez de créer votre modèle Django : vous méritez bien une petite pause ! +Cela peut être un bon moment pour prendre un café (ou un thé) ou quelque chose à manger pour vous redynamiser. Vous avez créé votre premier modèle Django - vous méritez une petite pause! \ No newline at end of file diff --git a/fr/django_admin/images/django_admin3.png b/fr/django_admin/images/django_admin3.png index a450b4f9630..fb221bd18e1 100644 Binary files a/fr/django_admin/images/django_admin3.png and b/fr/django_admin/images/django_admin3.png differ diff --git a/fr/django_admin/images/edit_post3.png b/fr/django_admin/images/edit_post3.png index c8572a73e7d..57299b6f5af 100644 Binary files a/fr/django_admin/images/edit_post3.png and b/fr/django_admin/images/edit_post3.png differ diff --git a/fr/django_admin/images/login_page2.png b/fr/django_admin/images/login_page2.png index 47153ef6960..c16d1aa4289 100644 Binary files a/fr/django_admin/images/login_page2.png and b/fr/django_admin/images/login_page2.png differ diff --git a/fr/django_forms/README.md b/fr/django_forms/README.md index 4f1fa70ec7f..d323b2c9c98 100755 --- a/fr/django_forms/README.md +++ b/fr/django_forms/README.md @@ -1,6 +1,6 @@ # Formulaires Django -La dernière chose que nous voulons faire sur notre site web, c'est créer une manière sympathique d'ajouter ou d'éditer des blog posts. `L'interface d'administration` de Django est cool, mais elle est assez complexe à personnaliser et à rendre jolie. Les `formulaires` vont nous donner un pouvoir absolu sur notre interface : nous allons être capables de faire à peu près tout ce que nous pouvons imaginer ! +La dernière chose que nous voulons faire sur notre site web, c'est créer une manière sympathique d'ajouter ou éditer des blog posts. L'interface d'administration (`/admin`) de Django est cool, mais elle est assez complexe à personnaliser et à rendre jolie. Les formulaires (`forms`) vont nous donner un pouvoir absolu sur notre interface : nous allons être capables de faire à peu près tout ce que nous pouvons imaginer ! Ce qui est pratique avec les formulaires Django, c'est que nous pouvons aussi bien en définir un à partir de rien ou créer un `ModelForm` qui va enregistrer le résultat du formulaire dans un modèle. @@ -12,9 +12,11 @@ Nous allons devoir créer un fichier avec ce nom dans notre dossier `blog`. blog └── forms.py + +Ouvrez maintenant ce fichier dans l'éditeur de code et tapez le code suivant : -Ouvrez maintenant ce fichier et tapez le code suivant : +{% filename %}blog/forms.py{% endfilename %} ```python from django import forms @@ -28,13 +30,13 @@ class PostForm(forms.ModelForm): fields = ('title', 'text',) ``` -Nous avons besoin tout d'abord d'importer les formulaires Django (`from django import forms`), puis, évidemment, notre modèle `Post` (`from .models import Post`). +Tout d'abord, nous avons besoin d'importer les formulaires Django (`from django import forms`), puis notre modèle `Post` (`from .models import Post`). -Comme vous l'avez probablement deviné, `PostForm` est le nom de notre formulaire. Nous avons besoin de préciser à Django que ce formulaire est un `ModelForm`. Pour cela, nous utilisons `forms.ModelForm`. +Comme vous l'avez probablement deviné, `PostForm` est le nom de notre formulaire. Nous avons besoin d'indiquer à Django que ce formulaire est un `ModelForm` (pour que Django fasse certaines choses automatiquement pour nous). Pour cela, nous utilisons `forms.ModelForm`. -Ensuite, nous avons une `Meta Classe` qui nous permet de dire à Django quel modèle il doit utiliser pour créer ce formulaire (`model = Post`). +Ensuite, nous avons la `class Meta` qui nous permet de dire à Django quel modèle il doit utiliser pour créer ce formulaire (`model = Post`). -Enfin, nous précisions quels sont le⋅s champ⋅s qui doivent figurer dans notre formulaire. Dans notre cas, nous souhaitons que seuls `title` et `text` apparaissent dans notre formulaire. Nous obtiendrons les autres données différemment : par exemple, on s'attend à ce que l'auteur (`author`) soit la personne actuellement enregistrée (c'est à dire vous !) et que la date de création `created_date` soit générée automatiquement lors de la création du post (cf code que nous avons écrit). +Enfin, nous précisions quel⋅s sont le⋅s champ⋅s qui doivent figurer dans notre formulaire. Dans notre cas, nous souhaitons que seuls `title` et `text` apparaissent dans notre formulaire. Nous obtiendrons les autres données différemment : par exemple, on s'attend à ce que l'auteur (`author`) soit la personne actuellement connectée (c'est à dire vous !) et que la date de création `created_date` soit générée automatiquement lors de la création du post (cf code que nous avons écrit). Et voilà, c'est tout ! Tout ce qu'il nous reste à faire, c'est d'utiliser ce formulaire dans une *vue* et de l'afficher dans un template. @@ -42,77 +44,101 @@ Nous allons donc une nouvelle fois suivre le processus suivant et créer : un li ## Lien vers une page contenant le formulaire -C'est le moment d'ouvrir le fichier `blog/templates/blog/base.html`. Nous allons ajouter un lien dans un `div` appelé `page-header` : +Avant d'ajouter le lien, nous avons besoin d'icônes que nous allons utiliser comme boutons pour le lien. Pour ce tutoriel, téléchargez [file-earmark-plus.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/file-earmark-plus.svg) et enregistrez-le dans le dossier `blog/templates/blog/icons/` + +> Remarque : Pour télécharger l'image SVG, ouvrez le menu contextuel du lien (en cliquant avec le bouton droit de la souris) et sélectionnez "Enregistrer le lien sous". Dans la boîte de dialogue vous demandant où enregistrer le fichier, choisissez le répertoire `djangogirls` de votre projet Django, et à l'intérieur du sous-répertoire `blog/templates/blog/icons/`, et enregistrez le fichier à cet endroit. + +Il est temps d'ouvrir `blog/templates/blog/base.html` dans l'éditeur de code. Maintenant nous pouvons utiliser ce fichier d'icônes à l'intérieur du template de base comme suit. Dans l'élément `div` à l'intérieur de la section `header` , nous ajouterons un lien avant l'élément `h1`: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + + {% include './icons/file-earmark-plus.svg' %} + ``` -Remarquez que notre nouvelle vue s'appelle `post_new`. +Remarquez que notre nouvelle vue s'appelle `post_new`. L'icône [SVG](https://icons.getbootstrap.com/icons/file-earmark-plus/) est fournie par les [icônes Bootstrap](https://icons.getbootstrap.com/) et elle affichera une icône de page avec le signe plus. Nous utilisons une directive de modèle Django appelée `include`. Cela injectera le contenu du fichier dans le template Django. Le navigateur web sait comment gérer ce type de contenu sans aucun traitement supplémentaire. + +> Vous pouvez télécharger toutes les icônes Bootstrap [ici](https://github.com/twbs/icons/releases/download/v1.11.3/bootstrap-icons-1.11.3.zip). Décompressez le fichier et copiez tous les fichiers image SVG vers un nouveau dossier dans `blog/templates/blog/` intitulé `icons`. De cette façon, vous pouvez accéder à une icône comme `pencil-fill.svg` en référençant le chemin du fichier `blog/templates/blog/icons/pencil-fill.svg` -Après avoir ajouté cette ligne, votre fichier html devrait maintenant ressembler à ceci : +Après avoir ajouté cette ligne, votre fichier HTML devrait maintenant ressembler à ceci : + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} + Django Girls blog - - + - -
+ +
-
+
{% block content %} {% endblock %}
-
+
``` -Sauvegardez votre fichier et rafraichissez la page http://127.0.0.1:8000 : vous devez normalement tomber encore une fois sur l'erreur `NoReverseMatch` ! +Normalement, après avoir sauvegardé et rechargé la page http://127.0.0.1:8000, vous devriez encore tomber sur l'erreur `NoReverseMatch`. Est-ce le cas ? Très bien ! ## URL -Ouvrez le fichier `blog/urls.py` et ajoutez cette ligne : +Ouvrez le fichier `blog/urls.py` dans l'éditeur de code et ajoutez cette ligne : + +{% filename %}blog/urls.py{% endfilename %} ```python - url(r'^post/new/$', views.post_new, name='post_new'), +path('post/new/', views.post_new, name='post_new'), ``` Votre fichier doit maintenant ressembler à ceci : +{% 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'), ] ``` -Une fois la page rechargée, vous allez voir une `AttributeError`, ce qui est normal. Nous n'avons pas encore implémentée la vue `post_new`. Allons nous occuper de ça maintenant. +Une fois la page rechargée, vous allez voir une `AttributeError`, ce qui est normal. Nous n'avons pas encore implémenté la vue `post_new`. Faisons-le maintenant. ## La vue post_new -Ouvrez maintenant le fichier `blog/views.py` et ajoutez les lignes suivantes avec celles du `from` qui existent déjà : +Ouvrez maintenant le fichier `blog/views.py` dans l'éditeur de code et ajoutez les lignes suivantes avec celles du `from` qui existent déjà : + +{% filename %}blog/views.py{% endfilename %} ```python from .forms import PostForm ``` -Puis ajoutez la *vue* : +Puis dans la *vue* : + +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): @@ -124,24 +150,24 @@ Afin de pouvoir créer un nouveau formulaire `Post`, nous avons besoin d'appeler ## Template -Pour cela, nous avons besoin de créer un fichier `post_edit.html` dans le dossier `blog/templates/blog`. Afin que notre formulaire fonctionne, nous avons besoin de plusieurs choses : +Nous avons à présent besoin de créer un fichier `post_edit.html` dans le dossier `blog/templates/blog` et de l'ouvrir dans l'éditeur de code. Afin que notre formulaire fonctionne, nous avons besoin de plusieurs choses : -* Nous voulons afficher le formulaire. Nous pouvons le faire à l'aide d'un simple `{% raw %}{{ form.as_p }}{% endraw %}` par exemple. -* La ligne précédente va avoir besoin d'être enveloppée dans des balises HTML : `...` -* Nous avons besoin d'un bouton `Save (sauvegarder)`. Nous allons le créer à l'aide d'un bouton HTML : `` -* Enfin, nous devons ajouter `{% raw %}{% csrf_token %}{% endraw %}` juste après `
`. C'est très important car c'est ce qui va permettre de sécuriser votre formulaire ! De toute manière, si vous avez oublié ce petit morceau, Django vous le fera remarquer lorsque vous sauvegarderez le formulaire : +* Nous avons besoin d'afficher le formulaire. Pour cela, nous n'avons qu'à utiliser {% raw %}`{{ form.as_p }}`{% endraw %}. +* La ligne précédente va avoir besoin d'être entourée des balises HTML `...
`. +* Nous avons besoin d'un bouton `Valider`. Nous allons le créer à l'aide d'un bouton HTML : ``. +* Enfin, nous devons ajouter {% raw %}`{% csrf_token %}`{% endraw %} juste après `
`. C'est très important car c'est ce qui va permettre de sécuriser votre formulaire ! Si vous oubliez ce détail, Django se plaindra lorsque vous essaierez de sauvegarder le formulaire: -![CSFR Forbidden page][1] +![CSFR Forbidden page](images/csrf2.png) - [1]: images/csrf2.png +Ok, voyons maintenant à quoi devrait ressembler le HTML contenu dans le fichier `post_edit.html` : -Ok, voyons maintenant à quoi devrait ressembler le fichier `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 }} @@ -149,21 +175,21 @@ Ok, voyons maintenant à quoi devrait ressembler le fichier `post_edit.html` : {% endblock %} ``` -Rafraichissons la page ! Et voilà : le formulaire s'affiche ! +Rafraîchissons la page ! Et voilà : le formulaire s'affiche ! -![Nouveau formulaire][2] +![New form](images/new_form2.png) - [2]: images/new_form2.png +Mais attendez une minute! Lorsque vous taperez quelque chose dans les champs `title` et `text` et essayez de le sauvegarder, que se passera-t-il? -Heu, attendez une minute... Quand vous tapez quelque chose dans `title` et `text` et que vous essayez de le sauvegarder, que se passe-t-il ? - -Absolument rien ! Nous retombons sur la même page sauf qu'en plus, notre texte a disparu et aucun post ne semble avoir été créé. Que s'est-il passé ? +Absolument rien ! Nous retombons sur la même page sauf qu'en plus, notre texte a disparu et aucun article ne semble avoir été créé. Que s'est-il passé ? La réponse est : rien ! Nous avons juste encore un peu de travail à accomplir. Retournons à notre *vue*. ## Sauvegarder le contenu du formulaire -Ouvrez à nouveau `blog/views.py`. Actuellement, `post_new` n'est composé que des lignes de code suivantes : +Ouvrez à nouveau `blog/views.py` dans l'éditeur de code. Actuellement, `post_new` n'est composé que des lignes de code suivantes : + +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): @@ -171,9 +197,11 @@ def post_new(request): return render(request, 'blog/post_edit.html', {'form': form}) ``` -Lorsque nous envoyons notre formulaire, nous revenons à la même vue. Cependant, nous avons des données dans `request`, et plus particulièrement dans `request.POST`. Prenez garde que "POST" ici n'a aucun lien avec "blog post" : le nom est lié au fait que nous envoyons des données. Rappelez-vous : nous avions défini la variable `method="POST"` dans le fichier HTML qui contient notre `` ? Tous les champs du formulaire se trouvent maintenant dans `request.POST`. Veillez à ne pas renommer `POST` en quoi que ce soit d'autre : la seule autre valeur autorisée pour `method` est `GET`. Malheureusement, nous n'avons pas le temps de rentrer dans les détails aujourd'hui. +Lorsque nous envoyons notre formulaire, nous revenons à la même vue. Cependant, nous récupérons les données dans `request`, et plus particulièrement dans `request.POST` (le nom "POST" n'a aucun lien avec nos "posts" de blog : il est lié au type de requête effectué à l'envoi des données). Vous rappelez-vous comment dans le fichier HTML, notre définition de la variable `` avait la méthode `method="POST"`? Tous les champs du formulaire se trouvent maintenant dans `request.POST`. Veillez à ne pas renommer `POST` en quoi que ce soit d'autre : la seule autre valeur autorisée pour `method` est `GET`. Malheureusement, nous n'avons pas le temps de rentrer dans les détails aujourd'hui. -Dans notre *vue*, nous avons donc deux situations différentes à gérer. Tout d'abord, nous avons la situation où nous accédons à la page pour la première fois et que nous voulons un formulaire vide. Ensuite, nous avons la seconde situation où nous retournons sur la *vue* et nous voulons que les champs du formulaire contiennent les informations que nous avions tapées. Pour gérer ces deux cas, nous allons utiliser une condition `if` (si). +Donc dans notre *vue* nous avons deux situations différentes à gérer : la première quand on accède à la page pour la première fois et nous voulons un formulaire vide, et la seconde quand on revient à la *vue* avec les données que l'on a saisies dans le formulaire. Pour gérer ces deux cas, nous allons utiliser une condition `if` (si) : + +{% filename %}blog/views.py{% endfilename %} ```python if request.method == "POST": @@ -182,42 +210,52 @@ else: form = PostForm() ``` -Attaquons-nous à remplir ces `[...]`. Si la `method` est `POST`, c'est que nous voulons construire notre `PostForm` avec les données de notre formulaire. Pour cela, nous devons ajouter : +Il faut maintenant remplir à l'endroit des pointillés `[...]`. Si `method` contient `POST` alors on veut construire le `PostForm` avec les données du formulaire, n'est-ce pas ? Nous allons le faire comme cela : + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(request.POST) ``` -Facile ! La prochaine étape est de vérifier si le contenu de notre formulaire est correct. Nous aimerions vérifier, par exemple, que les champs obligatoires soient bien remplis et qu'aucune donnée incorrecte ne soit sauvegardée. Pour cela, nous allons utiliser `form.is_valid()`. +La prochaine étape est de vérifier que le formulaire a été rempli correctement (tous les champs obligatoires ont été remplis et aucune valeur incorrecte n'a été envoyée). Nous allons faire ça en utilisant `form.is_valid()`. Testons donc si notre formulaire est valide et, si c'est le cas, sauvegardons-le ! +{% filename %}blog/views.py{% endfilename %} + ```python if form.is_valid(): post = form.save(commit=False) post.author = request.user post.published_date = timezone.now() post.save() -``` +``` -En gros, nous effectuons deux choses ici : nous sauvegardons le formulaire grâce à `form.save` et nous ajoutons un auteur. Rappelez-vous, il n'y avait pas de champ `author` dans le `PostForm` mais nous avons obligatoirement besoin d'un auteur pour que le formulaire que nous avons créé soit valide. `commit=False` signifie que nous ne voulons pas encore enregistrer notre modèle `Post`. Nous voulons tout d'abord ajouter un auteur. La plupart du temps, vous utiliserez `form.save()` sans `commit=False`. Cependant, nous en avons besoin ici. `post.save()` va nous permettre de sauvegarder les changements, c'est-à-dire l'ajout d'un auteur. Et voilà, maintenant c'est sûr, un nouveau blog post sera créé ! +En gros, nous effectuons deux choses ici : nous sauvegardons le formulaire grâce à `form.save` et nous ajoutons un auteur. Rappelez vous, il n'y avait pas de champ `author` dans le `PostForm` mais nous avons obligatoirement besoin d'un auteur pour que le formulaire que nous avons créé soit valide. `commit=False` signifie que nous ne voulons pas encore enregistrer notre modèle `Post`. Nous voulons d'abord ajouter un auteur. La plupart du temps, vous utiliserez `form.save()` sans `commit=False`. Mais ici nous en avons besoin. `post.save()` sauvegardera les changements, c'est-à-dire l'ajout d'un auteur. Et voilà, un nouveau post de blog est créé ! Enfin, ce serait génial si nous pouvions tout de suite aller à la page `post_detail` du post de blog que nous venons de créer. Pour cela, nous avons besoin d'importer une dernière chose : +{% filename %}blog/views.py{% endfilename %} + ```python from django.shortcuts import redirect ``` -Ajoutez-le au tout début de votre page. Maintenant, nous allons ajouter la ligne qui signifie : "aller à la page `post_detail` pour le nouveau post qui vient d'être créé". +Ajoutez-le au tout début de votre fichier. Maintenant, nous allons ajouter la ligne qui signifie "aller à la page `post_detail` pour le nouveau post qui vient d'être créé": + +{% filename %}blog/views.py{% endfilename %} ```python -return redirect('blog.views.post_detail', pk=post.pk) +return redirect('post_detail', pk=post.pk) ``` -`blog.views.post_detail` est le nom de la vue où nous voulons aller. Rappelez-vous : une *vue* a besoin d'une variable `pk`. Afin de le passer à la vue, nous utilisons `pk=post.pk`, où `post` désigne le blog post nouvellement créé ! +`post_detail` est le nom de la vue où nous voulons aller. Rappelez-vous : une *vue* a besoin d'une variable `pk`. Afin de le passer à la vue, nous utilisons `pk=post.pk`, où `post` désigne le blog post nouvellement créé ! Et si au lieu de parler, nous vous montrions à quoi ressemble maintenant notre *vue* ? +{% filename %}blog/views.py{% endfilename %} + ```python def post_new(request): if request.method == "POST": @@ -227,74 +265,88 @@ def post_new(request): post.author = request.user post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) ``` -Voyons si ça marche. Allez à l'adresse http://127.0.0.1:8000/post/new/, ajoutez un `titre` et du `texte`, puis sauvegardez... Et voilà ! Le nouveau post est bien créé et vous êtes redirigé vers la page `post_detail` ! +Voyons si ça marche. Allez à l'adresse http://127.0.0.1:8000/post/new/, ajoutez des valeurs dans les champs `title` et du `text`, sauvegardez ... et voilà ! Le nouveau post est bien créé et vous êtes redirigé vers la page `post_detail` ! -Vous avez peut-être remarqué que nous avons choisi une date de publication avant de sauvegarder le post. Nous en aurons besoin lorsque nous créerons le *publish button* (bouton publier) dans **l'un des extensions du tutoriel Django Girls** (en anglais). +Vous avez peut-être remarqué que nous avons choisi une date de publication avant de sauvegarder le post. Nous en aurons besoin lorsque nous créerons le *publish button* (bouton publier) dans **l'une des extensions du tutoriel Django Girls** (en anglais). Encore bravo ! +> Comme nous avons récemment utilisé l'interface d'administration de Django, le système pense que nous sommes toujours connectés. Cependant, il y a plusieurs cas qui peuvent amener un utilisateur à être déconnecté : fermer le navigateur, redémarrer la base de données, etc. Si jamais vous obtenez des erreurs lors de la création d'un post qui disent que vous n'êtes pas connecté, retournez sur la page d'administration présente à l'adresse http://127.0.0.1:8000/admin et connectez vous à nouveau. Cependant, vous devinez bien que cette solution n'est pas suffisante à long terme. Afin de corriger ce problème, n'hésitez pas à faire la partie **Devoir : ajouter de la sécurité à son site internet !** qui est située juste après la partie principale du tutoriel. + +![Logged in error](images/post_create_error.png) + ## Validation de formulaire Maintenant, nous allons vous montrer à quel point les formulaires Django sont cools ! Un post de blog a besoin de champs `title` (titre) et `text` (texte). Dans notre modèle `Post`, nous n'avons pas signalé que ces champs n'étaient pas obligatoire (à l'inverse de `published_date`). Django s'attend donc à ce qu'ils soient remplis à chaque fois. Essayez de sauvegarder un formulaire sans mettre de `titre` ou de `texte`. Devinez ce qui va se passer ! -![Validation de formulaire][3] - - [3]: images/form_validation2.png +![Form validation](images/form_validation2.png) Django va s'occuper de la validation : il va regarder si tous les champs de notre formulaire sont en adéquation avec notre modèle. C'est cool, non ? -> Comme nous avons récemment utilisé l'interface d'administration de Django, le système pense que nous sommes encore connectés. Cependant, il y a plusieurs cas qui peuvent amener un utilisateur à être déconnecté : fermer le navigateur, redémarrer la base de données, etc. Si jamais vous obtenez des erreurs lors de la création d'un post qui disent que vous n'êtes pas connecté, retournez sur la page d'administration présente à l'adresse http://127.0.0.1:8000/admin et connectez-vous à nouveau. Cependant, vous devinez bien que cette solution n'est pas suffisante à long terme. Afin de corriger ce problème, n'hésitez pas à faire la partie **Devoir : ajouter de la sécurité à son site internet !** qui est située juste après la partie principale du tutoriel. - -![Erreur de loggin][4] +## Éditer un formulaire - [4]: images/post_create_error.png +Maintenant, nous savons comment ajouter un nouveau post. Comment faire pour en modifier un qui existe déjà ? C'est très similaire à ce que nous venons de faire. Tout d'abord, faisons rapidement quelques choses importantes. (Si vous ne comprenez pas quelque chose, vous devriez demander à votre entraîneur ou regarder les chapitres précédents, car nous avons déjà traité toutes ces étapes.) -## Éditer un formulaire +Tout d'abord, enregistrons l'icône qui représente le bouton d'édition. Téléchargez [pencil-fill.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/pencil-fill.svg) et enregistrez-le dans le dossier `blog/templates/blog/icons/`. -Maintenant, nous savons comme ajouter un nouveau formulaire. Comment faire si nous voulons éditer un formulaire déjà existant ? C'est assez proche de ce que nous venons de faire. Créons ce dont nous avons besoin rapidement. Si jamais des choses vous semblent obscures, n'hésitez pas à demander à votre coach ou à revoir les chapitres précédents. Tout ce que nous allons faire maintenant a déjà été expliqué plus en détail précédemment. +Ouvrez `blog/templates/blog/post_detail.html` dans l'éditeur de code et ajoutez le code suivant dans l'élément `article`: -Ouvrez le fichier `blog/templates/blog/post_detail.html` et ajoutez la ligne suivante : +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} -```python - +```html + ``` -Votre template doit ressembler à ceci : +Votre template doit maintenant ressembler à ceci : + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html {% extends 'blog/base.html' %} {% block content %} -
+
+ {% endblock %} ``` -Maintenant, dans `blog/urls.py`, ajoutez cette ligne : +Ouvrez le fichier `blog/urls.py` dans l'éditeur de code et ajoutez cette ligne : + +{% 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'), ``` Nous allons réutiliser le template de `blog/templates/blog/post_edit.html`. Il ne va donc nous manquer qu'une *vue*. -Ouvrons `blog/views.py` et ajoutons à la toute fin du fichier : +Ouvrons `blog/views.py` dans l'éditeur de code et ajoutons à la toute fin du fichier : + +{% filename %}blog/views.py{% endfilename %} ```python def post_edit(request, pk): @@ -306,91 +358,122 @@ def post_edit(request, pk): post.author = request.user post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm(instance=post) return render(request, 'blog/post_edit.html', {'form': form}) ``` -Vous ne trouvez pas que ça ressemble presque à la vue de `post_new` ? Regardons un peu plus en détail. Tout d'abord, nous passons un paramètre `pk` supplémentaire. Ensuite, nous récupérons le modèle `Post` que nous souhaitons éditer à l'aide de `get_object_or_404(Post, pk=pk)`. Puis, lorsque nous créons un formulaire, nous faisons de ce post deux `instances`. Tout d'abord lorsque nous sauvegardons le formulaire : +Vous ne trouvez pas que ça ressemble presque exactement à la vue de `post_new` ? Regardons un peu plus en détails. Tout d'abord, nous passons un paramètre `pk` supplémentaire. Ensuite, nous récupérons le modèle `Post` que nous souhaitons éditer à l'aide de `get_object_or_404(Post, pk=pk)`. Puis, lorsque nous créons un formulaire, nous passons ce post comme une `instance`, d'abord lorsque nous sauvegardons le formulaire… + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(request.POST, instance=post) ``` -Puis ensuite lorsque nous ouvrons le formulaire associé à ce post afin de l'éditer : +…Puis ensuite lorsque nous ouvrons le formulaire associé à ce post afin de l'éditer : + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(instance=post) ``` -Alors, voyons si ça marche ! Allons à la page `post_detail`. Un bouton d'édition devrait apparaitre dans le coin supérieur droit de la page : +Alors, voyons si ça marche ! Allons à la page `post_detail`. Un bouton d'édition devrait apparaître dans le coin supérieur droit de la page : -![Bouton d'édition][5] +![Edit button](images/edit_button2.png) - [5]: images/edit_button2.png +Lorsque vous cliquez dessus, vous devez voir le formulaire du post de blog apparaître : -Lorsque vous cliquez dessus, vous devez voir le formulaire du post de blog apparaitre : +![Edit form](images/edit_form2.png) -![Éditer un formulaire][6] +N'hésitez pas à changer le titre ou le texte et à enregistrer les modifications! - [6]: images/edit_form2.png +Bravo ! Votre application s'enrichit de plus en plus de fonctionnalités ! -Essayez de manipuler un peu ce que vous venez de créer : ajoutez du texte, changez le titre puis sauvegardez ces changements ! - -Bravo ! Votre application se complexifie et contient de plus en plus de fonctionnalités ! - -Si jamais vous voulez en savoir plus sur les formulaires dans Django, n'hésitez pas à lire la documentation associée : https://docs.djangoproject.com/fr/1.10/topics/forms/ +Si vous souhaitez en apprendre plus sur les formulaires Django, n'hésitez pas à consulter la documentation associée : https://docs.djangoproject.com/en/2.2/topics/forms/ ## Sécurité -C’est génial de pouvoir créer de nouveaux posts juste en cliquant sur un lien ! Mais n’importe qui visitant votre site pourra mettre un nouveau post en ligne, ce qui n’est probablement pas ce que vous souhaitez. Faisons en sorte que le bouton n’apparaisse seulement qu'à vous. +C’est génial de pouvoir créer de nouveaux posts juste en cliquant sur un lien ! Mais maintenant, toute personne visitant votre site sera en mesure de créer un nouveau post, et ce n'est peut-être pas ce que vous voulez. Faisons en sorte que les boutons apparaissent pour vous mais pas pour les autres. -Dans `blog/templates/blog/base.html`, trouvez notre `page-header` `div` et la balise ancre que vous y avez mis plus tôt. Ça doit ressembler à ça : +Ouvrez `blog/templates/blog/base.html` dans l'éditeur de code, trouvez notre `div` `page-header` et la balise ancre que vous y avez mis plus tôt. Ça doit ressembler à ça : + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + + {% include './icons/file-earmark-plus.svg' %} + ``` -On va y ajouter une autre balise `{% if %}` qui ne fera apparaitre le lien qu’aux utilisateurs⋅trices connecté⋅e⋅s dans l’administration : uniquement vous pour le moment ! Changez la balise `` comme ceci : +Nous allons y ajouter une autre balise `{% if %}` qui ne fera apparaitre le lien qu’aux utilisateurs⋅trices connecté⋅e⋅s avec les droits d'administration. C'est à dire pour le moment, seulement vous ! Changez la balise `` comme ceci : + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% if user.is_authenticated %} - + + {% include './icons/file-earmark-plus.svg' %} + {% endif %} ``` -Ce `{% if %}` fait en sorte de n’envoyer le lien au navigateur que si l’utilisateur⋅trice demandant la page est connecté⋅e. Ce n’est pas une protection complète, mais c’est un bon début. Nous reviendrons sur les questions de sécurité dans les extensions du tutoriel. +Ce `{% if %}` fait en sorte de n’envoyer le lien au navigateur que si l’utilisateur⋅trice demandant la page est connecté⋅e. Cela ne n'empêche pas complètement la création de nouveaux posts, mais c’est un bon début. Nous reviendrons sur les questions de sécurité dans les extensions du tutoriel. + +Rappelez-vous l'icône de modification que nous venons d'ajouter à notre page de détails? Nous souhaitons également ajouter les mêmes modifications, afin que les autres utilisateurs ne puissent pas modifier les publications existantes. + +Ouvrez le fichier `blog/templates/blog/post_detail.html` dans l'éditeur de code et trouvez la ligne suivante : + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + + {% include './icons/pencil-fill.svg' %} + +``` + +Changez-la en ceci: -Comme vous êtes probablement connectée, vous ne verrez aucune différence si vous rafraichissez la page. Mais chargez la page dans un autre navigateur ou dans une fenêtre incognito, et vous verrez que le lien n’apparait pas ! +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% if user.is_authenticated %} + + {% include './icons/pencil-fill.svg' %} + +{% endif %} +``` + +Parce vous êtes sans doute déjà connecté⋅e⋅s, vous ne verrez aucune différence si vous rafraîchissez la page. Mais si vous chargez la page dans un navigateur web différent ou dans une fenêtre en mode "navigation privée" ou "incognito", vous verrez que le lien ne s'affiche plus, et l’icône non plus ! ## Encore un petit effort : déployons ! Nos modifications fonctionnent-elles sur PythonAnywhere ? Pour le savoir, déployons à nouveau ! -* Tout d'abord, commitez votre nouveau code et pushez-le à nouveau sur Github -``` +* Tout d'abord, commitez votre nouveau code et pushez le à nouveau sur GitHub: + +{% filename %}command-line{% endfilename %} + $ git status - $ git add --all . + $ git add . $ git status - $ git commit -m "Ajout de vues qui permettent de créer et d'éditer un post de blog sur le site." - $ git push -``` + $ git commit -m "Added views to create/edit blog post inside the site." + $ git pus + -* Puis, dans la console bash de [PythonAnywhere][7]: +* Puis, dans la console bash de [PythonAnywhere](https://www.pythonanywhere.com/consoles/): - [7]: https://www.pythonanywhere.com/consoles/ -``` - $ cd my-first-blog - $ source myvenv/bin/activate - (myvenv)$ git pull - [...] - (myvenv)$ python manage.py collectstatic +{% filename %}Ligne de commande PythonAnywhere{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull [...] -``` + -* Enfin, cliquez sur l'onglet [Web][8] et cliquez sur **Reload**. +(N’oubliez pas de remplacer `` avec votre propre sous-domaine PythonAnywhere, sans les chevrons.) - [8]: https://www.pythonanywhere.com/web_app_setup/ +* Enfin, allez sur ["Web" page](https://www.pythonanywhere.com/web_app_setup/) (utilisez le bouton de menu en haut à droite de la console) et cliquez **Reload**. Actualisez votre blog https://subdomain.pythonanywhere.com pour voir les changements. -Normalement, ça devrait suffire ! Encore bravo :) +Et normalement c'est tout ! Félicitations ! :) \ No newline at end of file diff --git a/fr/django_forms/images/csrf2.png b/fr/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/fr/django_forms/images/csrf2.png and b/fr/django_forms/images/csrf2.png differ diff --git a/fr/django_forms/images/drafts.png b/fr/django_forms/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/fr/django_forms/images/drafts.png and b/fr/django_forms/images/drafts.png differ diff --git a/fr/django_forms/images/edit_button2.png b/fr/django_forms/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/fr/django_forms/images/edit_button2.png and b/fr/django_forms/images/edit_button2.png differ diff --git a/fr/django_forms/images/edit_form2.png b/fr/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/fr/django_forms/images/edit_form2.png and b/fr/django_forms/images/edit_form2.png differ diff --git a/fr/django_forms/images/form_validation2.png b/fr/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/fr/django_forms/images/form_validation2.png and b/fr/django_forms/images/form_validation2.png differ diff --git a/fr/django_forms/images/new_form2.png b/fr/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/fr/django_forms/images/new_form2.png and b/fr/django_forms/images/new_form2.png differ diff --git a/fr/django_forms/images/post_create_error.png b/fr/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/fr/django_forms/images/post_create_error.png and b/fr/django_forms/images/post_create_error.png differ diff --git a/fr/django_installation/README.md b/fr/django_installation/README.md index c775ee7bbc4..9e0e85acc8a 100755 --- a/fr/django_installation/README.md +++ b/fr/django_installation/README.md @@ -1,5 +1,7 @@ # Installation de Django -> **Note** Si vous avez déjà suivi les étapes d'Installation, vous n'avez rien d'autre à faire - vous pouvez aller directement au chapitre suivant ! +> **Note** Si vous utilisez un Chromebook, passez ce chapitre mais prenez soin de suivre les instructions de [configuration pour Chromebook](../chromebook_setup/README.md). +> +> **Note **Si vous avez déjà effectué [l'Installation](../installation/README.md) vous devriez déjà avoir fait ce qui suit. Vous pouvez donc passer directement au chapitre suivant ! {% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/fr/django_installation/instructions.md b/fr/django_installation/instructions.md index 148f325d099..f87d29b88d8 100644 --- a/fr/django_installation/instructions.md +++ b/fr/django_installation/instructions.md @@ -1,5 +1,5 @@ > Note : ce chapitre est en partie inspiré d'un autre tutoriel réalisé par les Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). -> +> > Ce chapitre est en partie inspiré du [tutoriel django-marcador](http://django-marcador.keimlink.de/) qui est sous licence Creative Commons Attribution-ShareAlike 4.0 International License. Le tutoriel django-marcador a été créé par Markus Zapke-Gründemann et al. ## L'environnement virtuel @@ -8,106 +8,222 @@ Avant d'installer Django, nous allons vous faire installer un outil extrêmement Donc, commençons par créer un **environnement virtuel de programmation** (ou *virtualenv*). Chaque projet aura sa propre configuration en Python/Django grâce à virtualenv. Ce qui veut dire que si vous modifiez un site web, ça n'affectera pas les autres sites sur lesquels vous travaillez. Plutôt cool, non ? -Tout ce dont vous avez besoin, c'est de trouver un dossier où vous voulez créer votre `virtualenv` ; vous pouvez choisir votre home par exemple. Sous Windows, le home ressemble à `C:\Utilisateurs\Nom` (où `Nom` est votre login). +Tout ce dont vous avez besoin, c'est de trouver un dossier où vous voulez créer votre `virtualenv` ; vous pouvez choisir votre répertoire "home" par exemple. Sous Windows, le home ressemble à `C:\Utilisateurs\Nom` (où `Nom` est votre login). + +> **Note:** Sur Windows, assurez-vous que le chemin vers ce répertoire ne contienne pas d'accents ou autres caractères spéciaux; si c'est la cas, utilisez un répertoire différent, par exemple `C:\djangogirls`. Dans ce tutoriel, nous allons utiliser un nouveau dossier `djangogirls` que vous allez créer dans votre dossier home : - mkdir djangogirls - cd djangogirls +{% filename %}command-line{% endfilename %} + $ mkdir djangogirls + $ cd djangogirls + Nous allons créer un virtualenv appelé `myvenv`. Pour cela, nous taperons une commande qui ressemblera à : - python3 -m venv myvenv +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + -### Windows +Pour créer un nouveau `virtualenv`, vous devez ouvrir un terminal et exécuter `python -m venv myvenv`. Voici ce à quoi ça devrait ressembler: -Afin de créer un nouveau `virtualenv`, vous avez besoin d'ouvrir votre console (nous en avons déjà parlé dans un chapitre précédent. Est-ce que vous vous en souvenez ?) et tapez `C:\Python34\python -m venv myvenv`. Ça ressemblera à ça : +{% filename %}command-line{% endfilename %} - C:\Utilisateurs\Nom\djangogirls> C:\Python34\python -m venv myvenv + C:\Users\Name\djangogirls> python -m venv myvenv + +Où `myvenv` est le nom de votre `virtualenv`. Vous pouvez choisir un autre nom mais attention : il doit être en minuscules, sans espaces et sans accents ou caractères spéciaux. C'est aussi une bonne idée de choisir un nom plutôt court, car vous aller souvent l'utiliser! -`C:\Python34\python` doit être le nom du dossier où vous avez installé Python et `myvenv` doit être le nom de votre `virtualenv`. Vous pouvez choisir un autre nom mais attention : il doit être en minuscules, sans espaces et sans accents ou caractères spéciaux. C'est aussi une bonne idée de choisir un nom plutôt court, car vous aller souvent l'utiliser ! + -### Linux et OS X + -Pour créer un `virtualenv` sous Linux ou OS X, tapez simplement la commande `python3 -m venv myvenv`. Ça ressemblera à ça : +Pour créer un `virtualenv` sous Linux ou macOS, tapez simplement la commande `python3 -m venv myvenv`. Ça ressemblera à ça : - ~/djangogirls$ python3 -m venv myvenv +{% filename %}command-line{% endfilename %} + $ python3 -m venv myvenv + `myvenv` est le nom de votre `virtualenv`. Vous pouvez choisir un autre nom, mais veillez à n'utiliser que des minuscules et à n'insérer ni espaces, ni caractères spéciaux. C'est aussi une bonne idée de choisir un nom plutôt court, car vous aller souvent l'utiliser! -> **NOTE:** initialiser un environnement virtuel sous Ubuntu 14.04 de cette manière donne l'erreur suivante : -> +> **Note:** sur certaines versions de Debian/Ubuntu vous pouvez avoir l'erreur suivante: +> +> {% 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. +> +> +> Dans ce cas, suivez les instructions ci-dessus et installez le paquet `python9-venv`: {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python3-venv +> +> +> **Note:** Sur certaines version de Debian/Ubuntu, initialiser l’environnement virtuel de cette façon donne l'erreur suivante: +> +> {% filename %}command-line{% endfilename %} +> > Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 > -> +> > Pour résoudre ce problème, utilisez plutôt la commande `virtualenv`. -> -> ~/djangogirls$ sudo apt-get install python-virtualenv -> ~/djangogirls$ virtualenv --python=python3.4 myvenv +> +> {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python-virtualenv +> $ virtualenv --python=python{{ book.py_version }} myvenv > +> +> **Note:** Si vous avez une erreur telle que : +> +> {% filename %}command-line{% endfilename %} +> +> E: Unable to locate package python3-venv +> +> +> alors exécutez plutôt : +> +> {% filename %}command-line{% endfilename %} +> +> sudo apt install python{{ book.py_version }}-venv +> + + ## Travailler avec virtualenv Les commandes listées ci-dessus permettent de créer un dossier appelé `myvenv` (ou le nom que vous avez choisi) qui contient notre environnement virtuel. Pour faire simple, c'est un dossier composé lui-même d'autres dossiers et de fichiers. -#### Windows + Démarrez votre environnement virtuel en exécutant : +{% filename %}command-line{% endfilename %} + C:\Utilisateurs\Nom\djangogirls> myvenv\Scripts\activate + + +> **Note:** sur Windows 10 vous pouvez avoir une erreur dans le PowerShell de Windows disant `execution of scripts is disabled on this system`. Dans ce cas ouvrez une autre console Windows PowerShell avec l'option "ouvrir en tant qu'administrateur". Puis essayer d'exécuter la commande suivante avant de démarrer votre environnement virtuel : +> +> {% 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 +> + + +> **NOTE :** Sous Windows, pour les utilisateurs du très populaire éditeur de texte VS Code, qui comporte un terminal intégré basé sur Windows Powershell, si vous souhaitez conserver le terminal intégré, vous pouvez utiliser la commande suivante pour activer votre environnement virtuel : +> +> $ . myvenv\Scripts\activate.ps1 +> +> +> L'avantage, c'est que vous n'aurez pas à constamment passer de l'éditeur aux lignes de commandes -#### Linux et OS X + + + Démarrez votre environnement virtuel en exécutant : - ~/djangogirls$ source myvenv/bin/activate +{% filename %}command-line{% endfilename %} + $ source myvenv/bin/activate + N'oubliez pas de remplacer `myvenv` par le nom que vous avez choisi pour votre `virtualenv` (le cas échéant) ! > **NOTE :** il arrive parfois que `source` ne soit pas disponible. Dans ce cas, vous pouvez essayer ceci : -> -> ~/djangogirls$ . myvenv/bin/activate +> +> {% filename %}command-line{% endfilename %} +> +> $ . myvenv/bin/activate > -Vous saurez que votre `virtualenv` est lancé quand le prompt de votre console ressemblera à ceci : + + +Vous saurez que votre `virtualenv` est lancé quand le prompt de votre console est précédé de `(myvenv)`. + +Quand vous travaillez dans un environnement virtuel, la commande `python` fera automatiquement référence à la bonne version de Python. Vous pouvez donc utiliser `python` plutôt que `python3`. - (myvenv) C:\Utilisateurs\Nom\djangogirls> +Ok, nous avons installé toutes les dépendances dont nous avions besoin. Nous allons enfin pouvoir installer Django ! +## Installation de Django {#django} -ou : +Maintenant que vous avez activé votre `virtualenv`, vous pouvez installer Django. - (myvenv) ~/djangogirls$ +Avant de faire cela, nous devons nous assurer que nous avons la dernière version de `pip`, le programme que nous allons utiliser pour installer Django: +{% filename %}command-line{% endfilename %} -Vous remarquez que le préfixe `(myvenv)` est apparu ! + (myvenv) ~$ python -m pip install --upgrade pip + -Quand vous travaillez dans un environnement virtuel, la commande `python` fera automatiquement référence à la bonne version de Python. Vous pouvez donc utiliser `python` plutôt que `python3`. +### Installer des paquets avec un fichier "requirements" -Ok, nous avons installé toutes les dépendances dont nous avions besoin. Nous allons enfin pouvoir installer Django ! +Un fichier "requirement" maintient une liste des dépendances qui doivent être installées avec `pip install`: + +Tout d'abord, créez un fichier `requirements.txt` dans votre dossier `djangogirls`, en utilisant l'éditeur de texte que vous avez téléchargé précédemment. Pour ce faire, ouvrez un nouveau fichier dans l'éditeur et sauvegarde-le à l'intérieur du dossier `djangogirls/` en lui donnant le nom `requirements.txt`. Votre dossier ressemble maintenant à ceci : + + djangogirls + ├── myvenv + │ └── ... + └───requirements.txt + + +Dans ce fichier `djangogirls/requirements.txt` vous devez ajouter ceci : -## Installation de Django +{% filename %}djangogirls/requirements.txt{% endfilename %} -Maintenant que vous avez lancé votre `virtualenv`, vous pouvez installer Django à l'aide de `pip`. Dans votre console, tapez `pip install django~=1.10.0`. Notez bien que nous utilisons un tilde suivi du signe égal : `~=`). + Django~={{ book.django_version }} + - (myvenv) ~$ pip install django~=1.10.0 - Downloading/unpacking django==1.10 - Installing collected packages: django - Successfully installed django - Cleaning up... +Maintenant, exécutez `pip install -r requirements.txt` pour installer Django. +{% filename %}command-line{% endfilename %} -Sous Windows : + (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.1MB) + Installing collected packages: Django + Successfully installed Django-{{ book.django_version }} + -> Si jamais vous obtenez des erreurs lorsque vous utilisez pip sous Windows, vérifiez si votre chemin d'accès contient des espaces, des accents ou des caractères spéciaux (ex : `C:\Utilisateurs\Nom d'Utilisateur\djangogirls`). Si c'est le cas, changez de dossier et essayez d'en créer un nouveau en prenant en compte le fait qu'il ne doit donc avoir ni accents, ni espaces, ni caractères spéciaux (ex : `C:\djangogirls`). Après l'avoir déplacé, essayez de retaper la commande précédente. + -Sous Linux : +> Si jamais vous obtenez des erreurs lorsque vous utilisez pip sous Windows, vérifiez si votre chemin d'accès contient des espaces, des accents ou des caractères spéciaux (ex : `C:\Utilisateurs\Nom d'Utilisateur\djangogirls`). Si c'est le cas, changez de dossier et essayez d'en créer un nouveau en prenant en compte le fait qu'il ne doit donc avoir ni accents, ni espaces, ni caractères spéciaux (ex : `C:\djangogirls`). Créez un nouvel environnement virtuel dans le nouveau répertoire, puis supprimez l'ancien et ré-essayez la commande précédente. (Déplacer ou couper/coller le répertoire de l'environnement virtuel ne marchera pas car virtualenv utilise des chemins absolus) + + + + + +> Votre terminal peut se figer quand vous essayez d'installer Django. Si cela arrive, utilisez cette commande au lieu de la précédente : +> +> {% filename %}command-line{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> + + + + > Si vous obtenez une erreur lorsque vous utilisez pip sous Ubuntu 12.04, tapez la commande `python -m pip install -U --force-reinstall pip` pour réparer l'installation de pip dans votre virtualenv. -Et voilà ! Vous êtes (enfin) prête pour créer votre première application Django ! + + +Et voilà ! Vous êtes (enfin) prête pour créer votre première application Django ! \ No newline at end of file diff --git a/fr/django_models/README.md b/fr/django_models/README.md index 0e60bb794b2..ae4b2eaba7c 100755 --- a/fr/django_models/README.md +++ b/fr/django_models/README.md @@ -1,6 +1,6 @@ # Les modèles dans Django -Maintenant, nous aimerions créer quelque chose qui permet de stocker les articles de notre blog. Mais avant de pouvoir faire ça, nous allons tout d'abord devoir vous parler d'un truc qui s'appelle les `objets`. +Maintenant, nous aimerions créer quelque chose qui permet stocker les articles de notre blog. Mais avant de pour pouvoir faire ça, nous allons tout d'abord devoir vous parler d'un truc qui s'appelle les `objets`. ## Les objets @@ -8,31 +8,31 @@ Il existe un concept en programmation qu'on appelle la `programmation orientée Du coup, c'est quoi un objet ? C'est une collection de propriétés et d'actions. Ça a l'air bizarre dit comme ça. Un exemple devrait vous permettre d'y voir un peu plus clair. -Si on veut modéliser un chat, nous allons créer un objet `Chat` qui a quelques propriétés comme `couleur`, `age`, `humeur` (bonne humeur, mauvaise humeur, fatigué ;)). Il peut aussi avoir un `propriétaire` (un objet `Personne`), mais ce n'est pas obligatoire : cette propriété pourrait être vide dans le cas d'un chat sauvage. +Si on veut modéliser un chat, nous allons créer un objet `Chat` qui a des propriétés comme `couleur`, `âge`, `humeur` (bonne humeur, mauvaise humeur, fatigué ;)) et `propriétaire` (ce qui pourrait être un objet `Personne`, ou, s'il s'agit d'un chat sauvage, cette propriété pourrait être simplement vide). -Ensuite, nous pouvons donner des actions au `Chat` : `ronronner`, `gratter` ou `manger`. (Dans ce dernier cas, on donne au chat un objet `NourriturePourChat`, qui peut lui aussi avoir ses propres propriétés, comme le `goût`). +Ensuite, nous pouvons donner des actions au `Chat` : `ronronner`, `gratter` ou `manger`. (Dans ce dernier cas, on donne au chat de la `NourriturePourChat`, ce qui peut être un objet séparé avec ses propres propriétés, comme le `goût`). - Chat + Cat -------- - couleur + color age - humeur - propriétaire - ronronner() - gratter() - nourrir(nourriture_pour_chat) - - - NourriturePourChat + mood + owner + purr() + scratch() + feed(cat_food) + + + CatFood -------- - gout - + taste + L'idée qu'il faut retenir, c'est que l'on décrit les choses du monde réel avec des propriétés (appelées `propriétés des objets`) et des actions (appelées `méthodes`). Du coup, comment modéliser les articles de blog ? C'est bien gentil les chats, mais ce qui nous intéresse, ça reste de faire un blog ! -Pour ça, il faut répondre à la question : qu'est-ce qu'un article de blog ? Quelles propriétés devrait-il avoir ? +Pour ça, il faut réponde à la question : qu'est-ce qu'un article de blog ? Quelles propriétés devrait-il avoir ? Pour commencer, notre blog post doit avoir du texte : il a bien du contenu et un titre, n'est-ce pas ? Et puis, ce serait bien de savoir aussi qui l'a écrit. On a donc besoin d'un auteur. Enfin, on aimerait aussi savoir quand l'article a été écrit et publié. @@ -43,7 +43,7 @@ Pour commencer, notre blog post doit avoir du texte : il a bien du contenu et un author created_date published_date - + Quel genre d'actions pourrions-nous faire sur un article de blog ? Un bon début serait d'avoir une `méthode` qui permet de publier le post. @@ -55,7 +55,7 @@ Voilà, nous avons une idée de ce que nous avons besoin. Allons modéliser tout Maintenant que nous savons ce qu'est un objet, nous allons pouvoir créer un modèle Django pour notre post de blog. -Un modèle Django est un type particulier d'objet : il est sauvegardé dans la `database`. Une base de données est une collection de données. C'est à cet endroit que l'on stocke toutes les informations au sujet des utilisateurs, des blog posts, etc. Pour stocker nos données, nous allons utiliser une base de données SQLite. C'est la base de données par défaut dans Django. Elle sera largement suffisante pour ce que nous voulons faire. +Un modèle Django est un type particulier d'objet : il est sauvegardé dans la `base de données`. Une base de données est une collection de données. C'est à cet endroit que l'on stocke toutes les informations au sujet des utilisateurs, des blog posts, etc. Pour stocker nos données, nous allons utiliser une base de données SQLite. C'est la base de données par défaut dans Django. Elle sera largement suffisante pour ce que nous voulons faire. Pour vous aider à visualiser ce qu'est une base de données, pensez à un tableur avec des colonnes (champs) et des lignes (données). @@ -63,61 +63,77 @@ Pour vous aider à visualiser ce qu'est une base de données, pensez à un table Pour éviter le désordre, nous allons créer une application séparée à l'intérieur de notre projet. Prenez l'habitude de bien tout organiser dès le début. Afin de créer une application, nous avons besoin d'exécuter la commande suivante dans notre console (prenez garde à bien être dans le dossier `djangogirls` où se trouve le fichier `manage.py`) : +{% filename %}macOS and Linux:{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py startapp blog + + +{% filename %}Windows:{% endfilename %} + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + -Vous pouvez voir qu'un nouveau dossier `blog` a été créé et qu'il contient différents fichiers. Vos dossiers et fichiers liés à votre projet doivent maintenant être organisés selon cette structure : +Vous pouvez voir qu'un nouveau dossier `blog` a été créé et qu'il contient différents fichiers. Les dossiers et fichiers liés à votre projet doivent maintenant être organisés selon cette structure : 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 + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + + +Après avoir créé une nouvelle application, vous devez dire à Django de l'utiliser. Nous faisons cela via le fichier `mysite/settings.py`. Ouvrez-le dans votre éditeur de code. Trouvez la section `INSTALLED_APPS` et ajoutez une ligne `'blog.apps.BlogConfig',` juste avant `]`. La section doit maintenant ressembler à ceci : -Après avoir créé une nouvelle application, vous devez dire à Django de l'utiliser. Pour cela, nous allons éditer le fichier `mysite/settings.py`. Trouvez la section `INSTALLED_APPS` et ajoutez `'blog',` juste avant `)`. La section doit maintenant ressembler à ceci : +{% filename %}mysite/settings.py{% endfilename %} ```python -INSTALLED_APPS = ( +INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'blog', -) + 'blog.apps.BlogConfig', +] ``` ### Créer un modèle de blog post -Le fichier `blog/models.py` permet de définir les objets que nous appelons des `modèles`. C'est à cet endroit que nous allons définir ce qu'est un blog post. Pour éviter tout problème (les caractères accentués par exemple!), nous allons garder les termes en anglais. +Le fichier `blog/models.py` permet de définir les objets que nous appelons des `modèles`. C'est à cet endroit que nous allons définir ce que c'est qu'un un blog post. + +Ouvrez le fichier `blog/models.py` dans l'éditeur de code, supprimez tout ce qui s'y trouve et copiez-y le morceau de code suivant : -Ouvrez le fichier `blog/models.py`, supprimez tout ce qui s'y trouve et copiez-y le morceau de code suivant : +{% filename %}blog/models.py{% endfilename %} ```python +from django.conf import settings from django.db import models from django.utils import timezone class Post(models.Model): - author = models.ForeignKey('auth.User') + 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() @@ -133,45 +149,53 @@ Ce gros morceau de code a l'air effrayant mais, ne vous inquiétez pas : nous al Toutes les lignes qui commencent par `from` ou `import` sont des lignes qui permettent d'importer des morceaux d'autres fichiers. Concrètement, au lieu de recopier ou de copier-coller la même chose dans différents fichiers, nous pouvons tout simplement faire référence à certains morceaux d'autres fichiers à l'aide de `from ... import ...`. -`class Post(models.Model):` - C'est cette ligne qui permet de définir notre modèle. C'est un `object`). +`class Post(models.Model):` - C'est cette ligne qui permet de définir notre modèle (ce qui est un `object`). -* Le mot clef spécial `class` permet d'indiquer que nous sommes en train de définir un objet. -* `Post` est le nom de notre modèle. Vous pouvez lui donner un autre nom mais vous ne pouvez pas utiliser de caractères spéciaux ou accentués ni insérer des espaces. Le nom d'une classe commence toujours par une majuscule. -* `models.Model` signifie que Post est un modèle Django. Comme ça, Django sait qu'il doit l'enregistrer dans la base de données. +- Le mot clef spécial `class` permet d'indiquer que nous sommes en train de définir un objet. +- `Post` est le nom de notre modèle. Vous pouvez lui donner un autre nom (mais vous ne pouvez pas utiliser des caractères spéciaux ou accentués et insérer des espaces). Le nom d'une classe commence toujours par une majuscule. +- `models.Model` signifie que Post est un modèle Django. Comme ça, Django sait qu'il doit l'enregistrer dans la base de données. -Maintenant, nous allons pouvoir définir les propriétés dont nous parlions au début de ce chapitre : `title (titre)`, `text (texte)`, `created_date (date de création)`, `published_date (date de publication)` et `author (auteur)`. Pour cela, nous allons avoir besoin de définir le type de chaque champ (Est-ce que c'est du texte? Un nombre ? Une date ? Une relation à un autre objet, un utilisateur par exemple ?). +Maintenant, nous allons pouvoir définir les propriétés dont nous parlions au début de ce chapitre : `title (titre)`, `text (texte)`, `created_date (date de création)`, `published_date (date de publication)` et `author (auteur)`. Pour cela, nous allons avoir besoin de définir le type de chaque champ (Est-ce que c'est du texte? Un nombre ? Une date ? Une relation à un autre objet, comme un objet utilisateur par exemple ?) -* `models.CharField` - Cela nous permet de définir un champ texte avec un nombre limité de caractères. -* `models.TextField` - Cela nous permet de définir un champ texte sans limite de caractères. Parfait pour le contenu d'un blog post ! -* `models.DateTimeField` - Définit que le champ en question est une date ou une heure. -* `models.ForeignKey` - C'est un lien vers un autre modèle. +- `models.CharField` - Cela nous permet de définir un champ texte avec un nombre limité de caractères. +- `models.TextField` - Cela nous permet de définir un champ text sans limite de caractères. Parfait pour le contenu d'un blog post, non ? +- `models.DateTimeField` - Définit que le champ en question est un horodatage (date et heure). +- `models.ForeignKey` - C'est un lien vers un autre modèle. -Malheureusement, nous n'avons pas le temps de vous expliquer tous les bouts de code que nous allons manipuler dans ce tutoriel. Si vous voulez en savoir un peu plus sur les différents champs disponibles dans les modèles ou que vous aimeriez définir quelque chose qui n'est pas listé dans les exemples ci-dessus, n'hésitez pas à consulter la documentation de Django (https://docs.djangoproject.com/fr/1.10/ref/models/fields/#field-types). +Malheureusement, nous n'avons pas le temps de vous expliquer tous les bouts de code que nous allons manipuler dans ce tutoriel. Si vous voulez en savoir plus sur les modèles Django, n'hésitez pas à consulter la documentation officielle de Django (https://docs.djangoproject.com/en/2.2/ref/models/fields/#field-types). -Et sinon, c'est quoi `def publish(self):` ? Il s'agit de notre méthode `publish` dont nous parlions tout à l'heure. `def` signifie que nous créons une fonction/méthode qui porte le nom `publish`. Vous pouvez changer le nom de la méthode si vous le souhaitez. N'oubliez pas les règles de nommage et pensez à utiliser des minuscules et des tirets bas à la place des espaces. Par exemple, une méthode qui calcule le prix moyen d'un produit pourrait s'appeler `calcul_prix_moyen`. +Et sinon, c'est quoi `def publish(self):` ? Il s'agit de notre méthode `publish` dont nous parlions tout à l'heure. `def` signifie que nous créons une fonction/méthode qui porte le nom `publish`. Vous pouvez changer le nom de la méthode si vous le souhaitez. La règle de nommage est d'utiliser des minuscules et des tirets bas à la place des espaces. Par exemple, une méthode qui calcule le prix moyen d'un produit pourrait s'appeler `calcul_prix_moyen`. Les méthodes renvoient (`return`) souvent quelque chose. C'est le cas de la méthode `__str__`. Dans notre tutoriel, lorsque nous appellerons la méthode `__str__()`, nous allons obtenir du texte (**string**) avec un titre de Post. +Notez également que les deux lignes `def publish(self) :` et `def __str__(self) :` sont mises en retrait à l’intérieur de notre classe. Parce que Python est sensible aux espaces, nous devons mettre en retrait (ou "indenter") nos méthodes à l'intérieur de la classe. Sinon, les méthodes ne sont pas considérées comme appartenantes à la classe, et vous pouvez obtenir un comportement inattendu. + Si quelque chose ne vous parait pas clair au sujet des modèles, n'hésitez pas à demander à votre coach ! Cela peut être compliqué à comprendre la première fois, surtout lorsque l'on apprend les objets et les fonctions en même temps. Gardez espoir ! Avec le temps, tout cela vous paraitra de moins en moins magique et de plus en plus évident ! ### Créer des tables pour votre modèle dans votre base de données -La dernière étape pour cette section est d'ajouter notre nouveau modèle à notre base de données. Tout d'abord, nous devons signaler à Django que nous venons de créer notre modèle. Tapez `python manage.py makemigrations blog` dans votre console. Le résultat devrait ressembler à ça : +La dernière étape pour cette section est d'ajouter notre nouveau modèle à notre base de données. Tout d'abord, nous devons signaler à Django que nous venons de créer notre modèle. (Nous venons de le terminer !). Allez sur votre terminal et tapez `python manage.py makemigrations blog`. Le résultat devrait ressembler à ça : + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py makemigrations blog Migrations for 'blog': - 0001_initial.py: + blog/migrations/0001_initial.py: + - Create model Post + +**Remarque :** N’oubliez pas de sauvegarder les fichiers que vous modifiez. Dans le cas contraire, votre ordinateur exécute la version précédente, ce qui pourrait vous donner des messages d’erreur inattendus. Django vient de nous préparer un fichier de migration que nous allons pouvoir appliquer dès maintenant à notre base de données. Pour cela, tapez `python manage.py migrate blog`. Normalement, vous devrez voir ceci s'afficher dans votre console : +{% 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 + - -Youpi ! Notre modèle Post est maintenant intégré à la base de données. Ce serait cool de voir à quoi il ressemble réellement ! Pour ça, il va falloir attaquer la section suivante ! Au boulot ;)! +Youpi ! Notre modèle Post est maintenant intégré à la base de données. Ce serait cool de voir à quoi il ressemble réellement ! Pour ça, il va falloir attaquer la section suivante ! Au boulot ;)! \ No newline at end of file diff --git a/fr/django_orm/README.md b/fr/django_orm/README.md index 9285b2cf808..89bb1a8927a 100755 --- a/fr/django_orm/README.md +++ b/fr/django_orm/README.md @@ -12,21 +12,28 @@ Il est plus simple d'apprendre avec un exemple. Et si nous nous intéressions à Ouvrez la console de votre ordinateur (et non celle de PythonAnywhere) et tapez la commande suivante : - (myvenv) ~/djangogirls$ python manage.py shell +{% filename %}command-line{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py shell + Ceci devrait maintenant s'afficher dans votre console : - (InteractiveConsole) - >>> +{% filename %}command-line{% endfilename %} +```python +(InteractiveConsole) +>>> +``` -Vous êtes maintenant dans la console interactive de Django. C'est comme celle de Python, mais avec toute la magie qu'apporte Django :). Du coup, les commandes Python sont aussi utilisables dans cette console. +Vous êtes maintenant dans la console interactive de Django. C'est comme celle de Python, mais avec toute la magie qu'apporte Django :). Les commandes Python sont aussi utilisables dans cette console. ### Lister tous les objets Essayons tout d'abord d'afficher tous nos posts. Vous pouvez le faire à l'aide de cette commande : +{% filename %}command-line{% endfilename %} + ```python >>> Post.objects.all() Traceback (most recent call last): @@ -34,25 +41,31 @@ Traceback (most recent call last): NameError: name 'Post' is not defined ``` -Ooops ! Voilà que ça nous renvoie une erreur qui nous dit qu'il n'existe pas de Post. En effet, nous avons oublié de commencer par un "import" ! +Oups ! Voilà que ça nous renvoie une erreur qui nous dit qu'il n'existe pas de Post. En effet, nous avons oublié de commencer par un "import" ! + +{% filename %}command-line{% endfilename %} ```python >>> from blog.models import Post ``` -Rien de compliqué : nous importons le modèle `Post` depuis notre `blog.models`. Essayons à nouveau la commande précédente : +Nous importons le modèle `Post` depuis notre `blog.models`. Essayons à nouveau la commande précédente : + +{% filename %}command-line{% endfilename %} ```python >>> Post.objects.all() -[, ] +, ]> ``` -Cela nous permet d'obtenir une liste des posts que nous avons créé tout à l'heure ! Rappelez-vous : nous avions créé ces posts à l'aide de l'interface d'administration de Django. Cependant, nous aimerions maintenant créer de nouveaux posts à l'aide de Python : comment allons-nous nous y prendre ? +Cela nous permet d'obtenir une liste des posts que nous avons créés tout à l'heure ! Rappelez-vous : nous avions créé ces posts à l'aide de l'interface d'administration de Django. Cependant, nous aimerions maintenant créer de nouveaux posts à l'aide de python : comment allons-nous nous y prendre ? ### Créer des objets Voici comment créer un nouveau objet Post dans la base de données : +{% filename %}command-line{% endfilename %} + ```python >>> Post.objects.create(author=me, title='Sample title', text='Test') ``` @@ -61,117 +74,148 @@ Cependant, il nous manque un petit quelque chose : `me`. Nous avons besoin de lu Tout d'abord, il nous faut importer le modèle User : +{% filename %}command-line{% endfilename %} + ```python >>> from django.contrib.auth.models import User ``` Avons-nous des utilisateurs dans notre base de données ? Voyons voir : +{% filename %}command-line{% endfilename %} + ```python >>> User.objects.all() -[] +]> ``` -C'est le superutilisateur que nous avions créé tout à l'heure ! Essayons maintenant d'obtenir une instance de l'utilisateur : +Il s'agit du superutilisateur que nous avons créé tout à l'heure ! Sauvegardons une instance de cet utilisateur (modifie la ligne suivante avec ton nom d'utilisateur) : + +{% filename %}command-line{% endfilename %} ```python -me = User.objects.get(username='ola') +>>> me = User.objects.get(username='ola') ``` -Comme vous pouvez le voir, nous obtenons (`get`) un utilisateur (`User`) avec comme nom d'utilisateur (`username`) 'ola'. Cool ! Bien sûr, vous pouvez utiliser votre nom si vous le souhaitez. +Comme vous pouvez le constater, nous avons maintenant obtenu (`get`) un utilisateur (`User`) avec un nom d’utilisateur `username` qui est égale à « ola ». Très bien ! Nous allons enfin pouvoir créer notre post : +{% filename %}command-line{% endfilename %} + ```python >>> Post.objects.create(author=me, title='Sample title', text='Test') + ``` -Youpi ! Et si on vérifiait quand même si ça a marché ? +Et voilà ! Vous aimeriez voir si ça a vraiment marché ? + +{% filename %}command-line{% endfilename %} ```python >>> Post.objects.all() -[, , ] +, , ]> ``` Et voilà : un post de plus dans la liste ! ### Ajouter plus de posts -Amusez-vous à ajouter d'autres posts pour vous entrainer un peu. Essayez d'ajouter 2-3 posts en plus puis passez à la partie suivante. +Amusez-vous à ajouter d'autres posts pour vous entrainer un peu. Essayez d'ajouter deux ou trois posts en plus puis passez à la partie suivante. ### Filtrer les objets -L'intérêt des QuerySets, c'est que l'on peut les filtrer. Disons que nous aimerions retrouver tous les posts écrits par l'utilisateur Ola. Pour cela, nous allons utiliser `filter` à la place de `all` dans `Post.objects.all()`. Les parenthèses vont nous servir à préciser quelles sont les conditions auxquelles un post de blog doit se conformer pour être retenu par notre QuerySet. Dans notre exemple, `author` est égal à `me`. La manière de le dire en Django c'est : `author=me`. Maintenant, votre bout de code doit ressembler à ceci: +L'intérêt des QuerySets, c'est que l'on peut les filtrer. Disons que nous aimerions retrouver tous les posts écrits par l'utilisateur Ola. Pour cela, nous allons utiliser `filter` à la place de `all` dans `Post.objects.all()`. Les parenthèses vont nous servir à préciser quelles sont les conditions auxquelles un post de blog doit se conformer pour être retenu par notre queryset. Dans notre exemple, la condition est que `author` soit égal à `me`. La manière de le dire en Django c'est : `author=me`. Maintenant, votre bout de code doit ressembler à ceci : + +{% filename %}command-line{% endfilename %} ```python >>> Post.objects.filter(author=me) -[, , , ] +, , , ]> ``` -Et si nous voulions chercher les posts qui contiennent uniquement le mot "titre" dans le champs `title`? +Et si nous voulions chercher les posts qui contiennent uniquement le mot "titre" ("title" en anglais) dans le champs `title`? + +{% filename %}command-line{% endfilename %} ```python >>> Post.objects.filter(title__contains='title') -[, ] +, ]> ``` -> **Note** Il y a deux tirets bas (`_`) entre `title` et `contains`. L'ORM de Django utilise cette syntaxe afin de séparer les noms de champ ("title") et les opérations ou les filtres ("contains"). Si vous n'utilisez qu'un seul tiret bas, vous allez obtenir une erreur du type : "FieldError: Cannot resolve keyword title_contains". +> **Note** Il y a deux tirets bas (`_`) entre `title` et `contains`. L'ORM de Django utilise cette règle afin de séparer les noms de champ ("title") et les opérations ou les filtres ("contains"). Si vous n'utilisez qu'un seul tiret bas, vous allez obtenir une erreur du type : "FieldError: Cannot resolve keyword title_contains". -Comment obtenir une liste de tous les posts publiés ? Cela se fait facilement en filtrant tous les posts qui ont une date de publication, `published_date`, dans le passé : +Vous pouvez aussi obtenir une liste de tous les posts publiés. Pour cela, nous allons filtrer les posts qui possèdent une date de publication (`published_date`) dans le passé : + +{% filename %}command-line{% endfilename %} ```python >>> from django.utils import timezone >>> Post.objects.filter(published_date__lte=timezone.now()) + ``` Malheureusement, le post que nous avons créé dans la console Python n'est pas encore publié. Allons corriger ce problème ! Dans un premier temps, nous aimerions obtenir une instance du post que nous voulons publier : +{% filename %}command-line{% endfilename %} + ```python >>> post = Post.objects.get(title="Sample title") ``` -Ensuite, publions-le grâce à notre méthode `publish`! +Ensuite, publions-le grâce à notre méthode `publish`: + +{% filename %}command-line{% endfilename %} ```python >>> post.publish() ``` -Maintenant, essayez d'obtenir à nouveau la liste des posts publiés. Pour cela, appuyez trois fois sur la flèche du haut et appuyez sur `entrée` : +Maintenant, essayez d'obtenir à nouveau la liste des posts publiés (appuyez trois fois sur la flèche du haut, puis `entrée`) : + +{% filename %}command-line{% endfilename %} ```python >>> Post.objects.filter(published_date__lte=timezone.now()) -[] +]> ``` ### Classer les objets -Les QuerySets permettent aussi de trier la liste des objets. Essayons de les trier par le champ `created_date` : +Les QuerySets permettent aussi de trier la liste des objets. Essayons de les trier par le champs `created_date` : + +{% filename %}command-line{% endfilename %} ```python >>> Post.objects.order_by('created_date') -[, , , ] +, , , ]> ``` -On peut aussi inverser l'ordre de tri en ajouter `-` au début: +On peut aussi inverser l'ordre de tri en ajouter `-` au début : + +{% filename %}command-line{% endfilename %} ```python >>> Post.objects.order_by('-created_date') -[, , , ] +, , , ]> ``` -### Chainer les QuerySets +### Requêtes complexes grâce au chaînage des méthodes -Vous pouvez aussi combiner les QuerySets and les **chainant** les unes aux autres : +Comme vous l'avez vu, quand on applique certaines méthodes à `Post.objects` on obtient un QuerySet en résultat. Les mêmes méthodes peuvent également être appliquées sur un QuerySet, ce qui ensuite donnera lieu à un nouveau QuerySet. Ainsi, vous pouvez combiner leur effet en les **enchaînant** l'une après l'autre : ```python >>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> ``` C'est un outil très puissant qui va vous permettre d'écrire des requêtes complexes. Génial ! Vous êtes maintenant prête à passer à l'étape suivante ! Pour fermer le shell, tapez ceci: +{% filename %}command-line{% endfilename %} + ```python >>> exit() $ -``` +``` \ No newline at end of file diff --git a/fr/django_start_project/README.md b/fr/django_start_project/README.md index d6f4a946a87..e2c00b1c7de 100755 --- a/fr/django_start_project/README.md +++ b/fr/django_start_project/README.md @@ -1,45 +1,64 @@ # Votre premier projet Django ! -> Note : ce chapitre est en partie inspiré d'un autre tutoriel réalisé par les Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). -> -> Des morceaux de ce chapitre sont inspirés du [tutoriel django-marcador][1], disponible sous licence Creative Commons Attribution-ShareAlike 4.0 International. Le tutoriel django-marcador a été créé par Markus Zapke-Gründemann et al. - - [1]: http://django-marcador.keimlink.de/ +> Une partie de ce chapitre s’inspire du tutoriel des Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> +> Des morceaux de ce chapitre sont inspirés du [tutoriel django-marcador](http://django-marcador.keimlink.de/), disponible sous licence Creative Commons Attribution-ShareAlike 4.0 International. Le tutoriel django-marcador a été créé par Markus Zapke-Gründemann et al. Nous allons créer un petit blog ! La première étape consiste à démarrer un nouveau projet Django. En gros, cela veut dire que nous allons lancer quelques scripts fournis par Django qui vont créer un squelette de projet Django. Il s'agit de fichiers et de dossiers que nous utiliserons par la suite. -Il existe certains fichiers et dossiers dont les noms sont extrêmement importants pour Django. Il ne faut pas renommer les fichiers que nous sommes sur le point de créer. Ce n'est pas non plus une bonne idée de les déplacer. Django a besoin de maintenir une certaine structure pour retrouver les éléments importants. +Il y existe certains fichiers et dossiers dont les noms sont extrêmement importants pour Django. Il ne faut pas renommer les fichiers que nous sommes sur le point de créer. Ce n'est pas non plus une bonne idée de les déplacer. Django a besoin de maintenir une certaine structure pour retrouver les éléments importants. > N'oubliez pas de tout exécuter dans votre virtualenv. Si vous ne voyez pas le préfixe `(myvenv)` dans votre console, vous avez besoin d'activer votre virtualenv. Nous vous avons expliqué comment faire ça dans le chapitre **Installation de Django**, dans la partie **Travailler avec virtualenv**. Tapez `myvenv\Scripts\activate` dans votre console Windows ou `source myvenv/bin/activate` dans celle de Mac OS ou Linux afin d'activer votre virtualenv. -Retournons à la création de notre premier projet. Tapez la commande suivante dans votre console MacOS ou Linux. **N'oubliez pas le point `.`à la fin** : + + +Retournons à la création de notre premier projet. Tapez la commande suivant dans votre console MacOS ou Linux. **N'oubliez pas le point `.`à la fin !** + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ django-admin startproject mysite . + + +> Le point `.` est très important : c'est lui qui permet de dire au script d'installer Django dans votre répertoire courant (le point `.` est une référence abrégée à celui-ci). +> +> **Note** : lorsque vous tapez la commande précédente dans votre console, vous ne devez recopier que la partie qui commence par `django-admin`. La partie `(myvenv) ~/djangogirls$` montrée ici n'est qu'un exemple pour vous rappeler de taper la commande dans votre console. + -Pour les utilisatrices de Windows, tapez la commande suivante. **N'oubliez pas le point `.` à la fin** : + - (myvenv) C:\Users\Name\djangogirls> django-admin startproject mysite . +Sur Windows, vous devez taper la commander suivante. ** (N'oubliez pas le point `.` à la fin) ** : +{% filename %}command-line{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . + > Le point `.` est très important : c'est lui qui permet de dire au script d'installer Django dans votre répertoire courant (le point `.` est une référence abrégée à celui-ci). -> -> **Note** : lorsque vous tapez les commandes précédentes dans votre console, vous ne devez recopier que la partie qui commence par `django-admin` ou `django-admin.py`. Les `(myvenv) ~/djangogirls$` et `(myvenv) C:\Users\Name\djangogirls>` du tutoriel sont là pour vous rappeler que ces commandes doivent être tapées dans votre console. +> +> **Note** : lorsque vous tapez la commande précédente dans votre console, vous ne devez recopier que la partie qui commence par `django-admin.exe`. La partie `(myvenv) C:\Users\Name\djangogirls>` montrée ici n'est qu'un exemple pour vous rappeler de taper la commande dans votre console. + + `django-admin.py` est un script qui crée les dossiers et fichiers nécessaires pour vous. Vous devriez maintenant avoir une structure de dossier qui ressemble à celle-ci: djangogirls - ├───manage.py - └───mysite - settings.py - urls.py - wsgi.py - __init__.py + ├── manage.py + ├── mysite + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + +> **Note** : dans votre structure de dossier, vous pourrez voir également le répertoire `myvenv` que nous avons créé avant. -`manage.py` est un script qui aide à gérer le site. Il permet notamment de lancer un serveur web sur notre ordinateur sans rien installer d'autre. +`manage.py` est un script qui aide à gérer ou maintenir le site. Entre autres, il permet notamment de lancer un serveur web sur notre ordinateur sans rien installer d'autre. Le fichier `settings.py` contient la configuration de votre site web. @@ -51,87 +70,191 @@ Ignorons les autres fichiers pour l'instant, nous n'allons pas avoir besoin d'y Apportons quelques changements à `mysite/settings.py`. Ouvrez le fichier avec l'éditeur de code que vous avez installé tout à l'heure. -Ça serait sympa d'avoir l'heure correcte sur notre site Web. Allez sur [wikipedia timezones list][2] et copiez le fuseau horaire qui correspond le mieux à l'endroit où vous vous trouvez (TZ). (par exemple: `Europe/Paris`) +**Note** : Gardez à l’esprit que `settings.py` est un fichier ordinaire, comme les autres. Vous pouvez l’ouvrir depuis l’éditeur de code, en cliquant sur « file-> open » dans le menu. Cela devrait ouvrir la fenêtre habituelle de navigation, où vous allez pouvoir chercher votre fichier `settings.py` et le sélectionner. Autrement, vous pouvez naviguer jusqu’au dossier djangogirls sur votre bureau et faire un clic droit sur le nom du fichier. Sélectionnez ensuite votre éditeur de code dans la liste qui s'affiche. Sélectionner l’éditeur est important car vous pourriez avoir d’autres programmes installés qui peuvent ouvrir le fichier, mais qui ne vous permettraient pas de le modifier. + +Ça serait sympa d'avoir l'heure correcte sur notre site Web. Allez sur la [liste Wikipedia des fuseaux horaires](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) et copiez votre fuseau horaire (TZ) (par exemple `Europe/Berlin`). + +Dans `settings.py`, recherchez la ligne qui contient `TIME_ZONE` et modifiez-la pour choisir votre propre fuseau horaire. Par exemple : - [2]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +{% filename %}mysite/settings.py{% endfilename %} -Dans settings.py, recherchez la ligne qui contient le `TIME_ZONE` et modifiez-la pour choisir votre propre fuseau horaire : +```python +TIME_ZONE = 'Europe/Berlin' +``` + +Un code de langue se compose de la langue, par exemple `en` pour l’anglais ou `de` pour l’allemand et du code du pays, p. ex. `de` pour l’Allemagne ou `ch` pour la Suisse. Si l’anglais n’est pas votre langue maternelle, vous pouvez ajouter votre code de langue afin que les boutons par défaut et les notifications de Django soient traduits. Vous auriez alors le bouton « Cancel » traduits dans la langue que vous avez définie. [Django est livré avec un grand nombre de traductions disponibles](https://docs.djangoproject.com/en/2.2/ref/settings/#language-code). + +Si vous voulez changer la langue, modifiez le code de langue comme montré dans la ligne suivante : + +{% filename %}mysite/settings.py{% endfilename %} ```python -TIME_ZONE = 'Europe/Paris' +LANGUAGE_CODE = 'de-ch' ``` -En remplaçant "Europe/Paris" par la valeur appropriée +Nous allons avoir besoin aussi d'un chemin d’accès pour les fichiers statiques. (Nous allons découvrir les fichiers statiques et CSS plus tard dans le tutoriel) Allez à la *fin* du fichier et juste en dessous de `STATIC_URL`, ajoutez une nouvelle entrée `STATIC_ROOT` : -Nous allons aussi devoir ajouter un chemin d'accès pour les fichiers statiques (nous en apprendrons plus sur les fichiers statiques et CSS plus tard dans le tutoriel). Allez jusqu'à la *fin* du fichier et juste en dessous de la ligne `STATIC_URL`, ajoutez-en une nouvelle avec `STATIC_ROOT` : +{% filename %}mysite/settings.py{% endfilename %} ```python STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') +STATIC_ROOT = BASE_DIR / 'static' +``` + +Lorsque `DEBUG` a valeur `True` et `ALLOWED_HOSTS` est vide, les noms d'hôte acceptés sont `[« localhost », '127.0.0.1 », ' [ :: 1]']`. Notre nom d’hôte sur PythonAnywhere ne sera donc pas accepté une fois que notre application sera déployée. Pour éviter cela, nous allons changer le paramètre suivant : + +{% filename %}mysite/settings.py{% endfilename %} + +```python +ALLOWED_HOSTS = ['127.0.0.1', '.pythonanywhere.com'] ``` +> **Note** : Si vous utilisez un Chromebook, ajoutez cette ligne à la fin de votre fichier settings.py : `MESSAGE_STORAGE = « django.contrib.messages.storage.session.SessionStorage »` +> +> Ajoutez `.amazonaws.com` à `ALLOWED_HOSTS` si vous utilisez cloud9 +> +> Si vous hébergez votre projet sur `Glitch.com`, nous devons protéger la clé secrète Django qui doit rester confidentielle (sinon, toute personne remixant votre projet pourrait la voir) : +> +> - Tout d'abord, nous allons créer une clé secrète aléatoire. Ouvrez à nouveau le terminal Glitch et tapez la commande suivante : +> +> {% filename %}Terminal{% endfilename %} +> +> ```bash +> python -c 'from django.core.management.utils import get_random_secret_key; \ +> print(get_random_secret_key())' +> ``` +> +> Ceci devrait afficher une longue chaîne de caractères aléatoire, parfaite à utiliser comme clé secrète pour votre tout nouveau site web Django. Nous allons maintenant coller cette clé dans un `.env` que Glitch ne vous montrera que si vous êtes propriétaire du site Web. +> +> - Créez un fichier `.env` à la racine de votre projet et ajoutez-y la propriété suivante : +> +> {% filename %}.env{% endfilename %} +> +> ```bash +> # Ici, à l'intérieur des apostrophes, vous pouvez copier et coller la clé aléatoire générée ci-dessus +> SECRET='3!0k#7ds5mp^-x$lqs2%le6v97h#@xopab&oj5y7d=hxe511jl' +> ``` +> +> - Puis mettez à jour le fichier de configuration de Django pour injecter cette valeur secrète et définir le nom du site web Django : +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> SECRET_KEY = os.getenv('SECRET') +> ``` +> +> - Et un peu plus loin, dans le même fichier, nous injectons le nom de votre nouveau site Glitch : +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> ALLOWED_HOSTS = [os.getenv('PROJECT_DOMAIN') + ".glitch.me"] +> ``` +> +> `PROJECT_DOMAIN` est générée automatiquement par Glitch. Elle contient le nom de votre projet. + ## Configuration de la base de données Il existe tout un tas de systèmes de gestion de bases de données qu'il est possible d'utiliser pour stocker les données de votre site. Nous allons utiliser celui par défaut : `sqlite3`. Il est déjà configuré dans cette partie de votre fichier `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', } } ``` Pour créer la base de donnée de notre blog, il faut lancer la commande suivante dans la console : `python manage.py migrate` (vous avez besoin d'être dans le dossier `djangogirls` qui contient le fichier `manage.py`). Si tout se passe bien, vous devriez voir quelque chose comme ça: +{% 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: auth, admin, 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 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 sessions.0001_initial... OK - + Et voilà ! Il ne reste plus qu'à lancer le serveur et voir si notre site web fonctionne ! +## Lancer le serveur web + Pour cela, vous avez besoin d'être dans le dossier qui contient le fichier `manage.py` (le dossier `djangogirls`). Dans votre console, vous pouvez lancer le serveur en tapant `python manage.py runserver`: +{% filename %}command-line{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py runserver + + +Si vous avez un Chromebook, utilisez plutôt la commande suivante : + +{% filename %}Cloud 9{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py runserver 0.0.0.0:8080 + + +ou celle-ci si vous utilisez Glitch : + +{% filename %}Glitch.com terminal{% endfilename %} + + $ refresh + + Si vous utilisez Windows et que vous obtenez l'erreur `UnicodeDecodeError`, tapez plutôt cette commande : +{% filename %}command-line{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + +Ensuite, vous allez vérifier que votre site fonctionne. Pour cela, ouvrez votre navigateur (Firefox, Chrome, Safari, Internet Explorer, ou n'importe quel autre), et entrez l'adresse suivante : -Ensuite, il ne nous reste plus qu'à vérifier que votre site fonctionne. Pour cela, ouvrez votre navigateur (Firefox, Chrome, Safari, Internet Explorer, ou n'importe quel autre), et entrez l'adresse suivante : +{% filename %}navigateur{% endfilename %} http://127.0.0.1:8000/ + + +Si vous utilisez un Chromebook et Cloud9, cliquez plutôt sur l’URL dans la fenêtre pop-up qui devrait figurer dans le coin supérieur droit de la fenêtre de commande où le serveur web est en cours d’exécution. L'URL ressemblera à quelque chose comme : +{% filename %}navigateur{% endfilename %} -Tant qu'il sera lancé, le serveur web va monopoliser votre console. Pour pouvoir taper de nouvelles commandes pendant que le serveur tourne, ouvrez une nouvelle console et activez à nouveau votre virtualenv. Pour arrêter votre serveur web, retournez dans la console où il se trouve et appuyez sur CTRL+C : maintenez les boutons Control et C enfoncés en même temps. Sous Windows, vous devrez peut-être appuyer sur CTRL+Arrêt défil. + https://.vfs.cloud9.us-west-2.amazonaws.com + + +ou sur Glitch : + + https://nom-de-votre-projet-glitch.glitch.me + Bravo ! Vous venez de créer votre premier site web, et de le lancer avec un serveur web ! C'est génial, non? -![Ça a marché !][3] +![L'installation a fonctionné !](images/install_worked.png) + +Notez qu’une fenêtre de commande ne peut exécuter qu’une chose à la fois, et la fenêtre de commande que vous avez ouverte précédemment est en train d'exécuter le serveur web. Tant que le serveur web est en cours d’exécution et en attente de requêtes entrantes, le terminal acceptera du nouveau texte mais ne l'exécutera pas. + +> Nous avons vu le fonctionnement des serveurs web dans le chapitre **Comment fonctionne Internet**. - [3]: images/it_worked2.png +Pour taper et executer des nouvelles commandes pendant que le serveur web est en fonction, ouvrez une nouvelle fenêtre dans votre terminal et activez votre virtualenv. Pour révoir comment ouvrir une nouvelle fenêtre, rendez-vous au chapitre [Introduction à la ligne de commande](../intro_to_command_line/README.md). Pour arrêter votre serveur web, retournez dans la fenêtre où il tourne et appuyez sur CTRL+C : gardez les boutons Control et C appuyés en même temps. (Sous Windows, vous devrez peut-être appuyer sur CTRL+Arrêt défil.) -Prête pour la suite ? Il est temps de créer du contenu! +Prêtes pour la suite ? Il est temps de créer du contenu ! \ No newline at end of file diff --git a/fr/django_start_project/images/install_worked.png b/fr/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..4354c634ddb Binary files /dev/null and b/fr/django_start_project/images/install_worked.png differ diff --git a/fr/django_start_project/images/it_worked2.png b/fr/django_start_project/images/it_worked2.png deleted file mode 100644 index 4412ecfc49e..00000000000 Binary files a/fr/django_start_project/images/it_worked2.png and /dev/null differ diff --git a/fr/django_templates/README.md b/fr/django_templates/README.md index ebba48e71c0..8bb92d9e643 100755 --- a/fr/django_templates/README.md +++ b/fr/django_templates/README.md @@ -6,7 +6,7 @@ Il est temps d'afficher des données ! Pour nous aider, Django fournit des balis En HTML, vous ne pouvez pas mettre directement du code Python car les navigateurs seraient incapables de le comprendre. Les navigateurs ne connaissent que le HTML. Nous vous avons signalé précédemment que HTML est du genre statique, alors que Python est bien plus dynamique. -Les **Balises de template Django** nous permettent de transférer des choses ressemblant à du Python dans du HTML afin de nous permettre de construire des sites web plus rapidement et facilement. Cool, non ? +Les **Balises de template Django** nous permettent de transferer des choses ressemblant à du Python dans du HTML afin de nous permettre de construire des sites web plus rapidement. Cool, non ? ## Template d'affichage de la liste des posts @@ -14,24 +14,28 @@ Dans le chapitre précédent, nous avons donné à notre template une liste de p Afin d'afficher une variable dans un template Django, nous utiliserons des doubles accolades avec le nom de la variable à l'intérieur. Ça ressemble à ceci : +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html {{ posts }} ``` -Essayez de faire la même chose avec votre template `blog/templates/blog/post_list.html`. Remplacez tout ce qui se trouve entre la seconde balise `
` jusqu'au troisième `
` avec la ligne `{{ posts }}`. Sauvegardez votre fichier et rafraichissez votre page pour voir le résultat : - -![Figure 13.1][1] +Essayez de faire la même chose avec votre template `blog/templates/blog/post_list.html`. Ouvrez-le avec votre éditeur et remplacez tout ce qui se trouve entre la seconde balise `
` jusqu'au troisième `
` avec la ligne `{{ posts }}`. Sauvegardez votre fichier et rafraichissez votre page pour voir le résultat : - [1]: images/step1.png +![Figure 13.1](images/step1.png) Comme vous pouvez le voir, tout ce que nous avons, c'est ceci : -```python -[, ] +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +, ]> ``` Cela signifie que Django l'interprète comme une liste d'objets. Essayez de vous rappeler comment afficher des listes en Python. Si vous avez un trou de mémoire, allez voir dans le chapitre **Introduction à Python**. Vous avez trouvé ? Avec des boucles ! Dans un template Django, vous pouvez les écrire de la façon suivante : +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html {% for post in posts %} {{ post }} @@ -40,67 +44,65 @@ Cela signifie que Django l'interprète comme une liste d'objets. Essayez de vous Essayez ceci dans votre template. -![Figure 13.2][2] +![Figure 13.2](images/step2.png) - [2]: images/step2.png +Ça marche ! Cependant, nous aimerions plutôt afficher les posts à la manière des posts statiques, comme lorsque nous les avions créés dans le chapitre **Introduction au HTML**. Vous pouvez mixer HTML et balises de template. Notre `body` ressemble maintenant à ceci : -Ça marche ! Cependant, nous aimerions plutôt les afficher à la manière des posts statiques, comme lorsque nous les avions créés dans le chapitre **Introduction au HTML**. Vous pouvez mixer HTML et balises de template. Notre `body` ressemble maintenant à ceci : +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -
+ {% for post in posts %} -
-

publié: {{ post.published_date }}

-

{{ post.title }}

+
+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} ``` {% raw %}Tout ce qui se situe entre `{% for %}` et `{% endfor %}` va être répété pour chaque objet présent dans la liste. Rafraichissez votre page :{% endraw %} -![Figure 13.3][3] +![Figure 13.3](images/step3.png) - [3]: images/step3.png +Avez-vous remarqué que nous avons utilisé une notation légèrement différente cette fois-ci (`{{ post.title }}` ou `{{ post.text }}`) ? Nous accédons aux données associées à chaque champ défini dans notre modèle `Post`. De même, le `|linebreaksbr` nous permet de rediriger le texte des posts à travers un filtre qui convertit automatiquement les fins de lignes en paragraphes. -Avez-vous remarqué que nous utilisons une notation légèrement différente cette fois (`{{ post.title }}` or `{{ post.text }}`) ? Nous accédons aux données associées à chaque champ défini dans notre modèle `Post`. De même, les barres verticales `|` nous permettent de rediriger le texte des posts à travers un filtre qui convertit automatiquement les fins de lignes en paragraphes. +## Une dernière chose -## Encore une chose ! +Maintenant, ça serait bien de voir si votre site Web fonctionne toujours sur Internet. Nous allons essayer de le re-déployer sur PythonAnywhere. Voici un récapitulatif des étapes… -Maintenant, ça serait bien de voir si votre site Web fonctionne toujours sur Internet. Nous allons essayer de le re-déployer sur PythonAnywhere. Voici un récapitulatif des étapes... +* En premier lieu, envoyez votre code sur GitHub (push) + +{% filename %}command-line{% endfilename %} -* En premier lieu, envoyez votre code sur GitHub (push) -``` $ git status [...] - $ git add --all . + $ git add . $ git status [...] - $ git commit -m "Modified templates to display posts from database." + $ git commit -m "Modification des templates to afficher les posts contenus dans la base de données." [...] $ git push -``` + -* Ensuite, reconnectez-vous à [PythonAnywhere][4] et allez sur la "**Bash console**" (ou démarrez-en une nouvelle), et lancez les commandes suivantes : +* Ensuite, reconnectez-vous à [PythonAnywhere](https://www.pythonanywhere.com/consoles/) et allez sur la "**Bash console**" (ou démarrer-en une nouvelle), et lancez les commandes suivantes : - [4]: https://www.pythonanywhere.com/consoles/ -``` - $ cd my-first-blog +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd .pythonanywhere.com $ git pull [...] -``` - -* Finalement, allez sur l'[onglet Web][5] et cliquez sur **Reload** sur votre application web. Votre site mis-à-jour devrait être en ligne ! + - [5]: https://www.pythonanywhere.com/web_app_setup/ +(N’oubliez pas de remplacer `` avec votre propre nom de sous domaine sur PythonAnywhere, sans les chevrons.) -Félicitations ! Maintenant, pourquoi ne pas essayer d'ajouter un nouveau post à l'aide de l'interface d'administration ? N'oubliez pas d'ajouter une date de publication ! Ensuite, rafraichissez votre page et regardez si votre post apparait. +* Pour finir, n'oubliez pas de recharger votre application web : onglet [Web](https://www.pythonanywhere.com/web_app_setup/) puis cliquez sur le bouton **Reload**. (Pour rejoindre les autres pages de PythonAnywhere à partir de la console, utilisez le bouton de menu dans le coin supérieur droit). Votre mise à jour devrait apparaître sur https://subdomain.pythonanywhere.com--Allez regarder dans le navigateur ! Si les posts sur PythonAnywhere ne correspondent pas à ceux qui apparaissent dans votre version locale du blog, ne vous inquiétez pas. Les deux bases de données, la locale et celle sur PythonAnywhere, ne sont pas synchronisées comme le reste des fichiers. -Ça a marché ? Nous sommes super fières de vous ! Éloignez vous un peu de votre clavier maintenant : vous avez mérité de faire une pause. :) +Félicitations ! Maintenant, allez de l'avant et essayez d'ajouter un nouveau message dans votre administrateur Django (rappelez-vous d'ajouter publication_date!) Assurez-vous que vous êtes dans l'administrateur Django pour votre site pythonanywhere, https://subdomain.pythonanywhere.com/admin. Ensuite, rafraîchissez votre page pour voir si le message apparaît. -![Figure 13.4][6] +Ça a marché ? Nous sommes super fière de vous ! Éloignez vous un peu de votre clavier maintenant : vous avez mérité de faire une pause. :) - [6]: images/donut.png +![Figure 13.4](images/donut.png) \ No newline at end of file diff --git a/fr/django_templates/images/donut.png b/fr/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/fr/django_templates/images/donut.png and b/fr/django_templates/images/donut.png differ diff --git a/fr/django_templates/images/step1.png b/fr/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/fr/django_templates/images/step1.png and b/fr/django_templates/images/step1.png differ diff --git a/fr/django_templates/images/step2.png b/fr/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/fr/django_templates/images/step2.png and b/fr/django_templates/images/step2.png differ diff --git a/fr/django_templates/images/step3.png b/fr/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/fr/django_templates/images/step3.png and b/fr/django_templates/images/step3.png differ diff --git a/fr/django_urls/README.md b/fr/django_urls/README.md index 5a10cdcfa31..2acb1af708e 100755 --- a/fr/django_urls/README.md +++ b/fr/django_urls/README.md @@ -1,125 +1,103 @@ -# Les urls Django +# Les URL de Django -Nous sommes sur le point de construire notre première page web : la page d'accueil de notre blog ! Avant de passer à la partie code, apprenons-en un peu plus sur les urls Django. +Nous sommes sur le point de créer notre première page web : une page d'accueil pour votre blog ! Mais d'abord, commençons par en apprendre un peu plus sur les URL de Django. ## Qu'est-ce qu'une URL ? -Une URL est simplement une adresse web. Vous pouvez voir une URL à chaque fois que vous visitez un site web: l'URL se trouve dans la barre d'adresse (hé oui! `127.0.0.1:8000` est aussi une URL ! `https://djangogirls.org` est aussi une URL) : +Une URL est une adresse web. Vous pouvez voir une URL chaque fois que vous visitez un site web. Elle est visible dans la barre d'adresse de votre navigateur. (Oui ! `127.0.0.1:8000` est aussi une URL ! Et `https://djangogirls.org` est aussi une URL.) -![Url][1] +![URL](images/url.png) - [1]: images/url.png - -Chaque page internet a besoin de sa propre URL. Cela permet à votre application de savoir ce qu'elle doit afficher à un utilisateur lorsqu'il entre une URL. Dans Django, nous utilisons un outil appelé `URLconf` (configuration des URLs) : c'est un ensemble de patterns que Django va essayer de faire correspondre avec l'URL reçue afin d'afficher la vue correspondante. +Chaque page internet a besoin de sa propre URL. C'est grâce à cela que votre application sait ce qu'elle doit afficher à un utilisateur qui ouvre cette URL. Dans Django, nous utilisons un outil appelé `URLconf` (Configuration d'URL). URLconf est un ensemble de modèles que Django va essayé de faire correspondre à l'URL demandée afin de trouver la vue adaptée. ## Comment les URLs fonctionnent-elles dans Django ? Ouvrons le fichier `mysite/urls.py` dans notre éditeur de code et regardons à quoi il ressemble : +{% 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), ] ``` -Comme vous pouvez le voir, Django nous a déjà préparé une partie du travail. +Comme vous pouvez le voir ici, Django a déjà préparé quelque chose pour nous. + +Les lignes entre triples guillemets (`'''` or `"""`) sont appelées docstrings. Vous pouvez les écrire en haut d'un fichier, d'une classe ou d'une méthode pour décrire son fonctionnement. Elle ne seront pas exécutées par Python. -Les lignes qui commencent par `#` permettent de commenter notre code : ces lignes ne seront donc pas exécutées par Python. Pratique, non ? +L'URL admin, que vous avez abordé dans le chapitre précédent est déjà là : -Comme vous pouvez le voir, l'adresse de l'interface d'administration est déjà en place : +{% filename %}mysite/urls.py{% endfilename %} ```python - url(r'^admin/', include(admin.site.urls)), + path('admin/', admin.site.urls), ``` -Cela signifie que pour chaque URL qui commence par `admin/`, Django affichera la *vue* correspondante. Dans cet exemple, vous pouvez constater que toutes les URLs liées à l'interface d'administration sont contenues dans une seule ligne : en plus d'être pratique, cela rend notre fichier beaucoup plus propre et lisible. - -## Regex - -Vous vous demandez sûrement comment Django arrive à faire correspondre les URLs aux vues correspondantes ? Bon, on respire un grand coup car ça va être un peu complexe. Django utilise des `regex` ("expressions régulières"). Les regex ont beaucoup (vraiment beaucoup ! ) de règles qui permettent de donner une description de la chaîne de caractères que l'on recherche (pattern). Étant donné que les regex sont un sujet avancé, nous ne rentrerons pas en détail dans leur fonctionnement. - -Si vous avez quand-même envie de comprendre comment nous avons créé nos patterns, vous pouvez lire ce qui va suivre. Dans notre exemple, nous allons utiliser un petit sous ensemble des règles disponibles pour écrire des patterns : - - ^ -> le début du texte - $ -> la fin du texte - \d -> un chiffre - + -> indique que l'expression précédente doit se répéter au moins une fois - () -> capture une partie du pattern - - -Tout ce qui ne fait pas partie de ces règles et qui est présent dans la description de ce que l'on cherche sera interprété de manière littérale. - -Maintenant, imaginez que vous avez un site web qui a comme adresse : `http://www.mysite.com/post/12345/`. `12345` désigne le numéro de votre post. - -Ce serait vraiment pénible de devoir écrire une vue différente pour chaque post que nous aimerions rédiger. Nous allons créer un pattern qui correspond à cette URL et qui nous permettra aussi d'extraire le numéro de post : `^post/(\d+)/$`. Décomposons-la morceau par morceau pour comprendre ce que nous faisons : - -* **^ post /** indique à Django d'attraper toutes les url qui commencent par `post/` (juste après `^`) -* **(\d+)** signifie qu'il y aura un nombre (un ou plusieurs chiffres) que nous souhaitons capturer et extraire -* **/** dit à Django que le caractère `/` doit suivre le nombre -* **$** marque la fin de l'URL, ce qui signifie que seules les chaînes de caractères se terminant par `/` correspondrons au pattern +Cette ligne signifie que pour toutes les URL commençant par `admin/`, Django trouvera une *vue* correspondante. Dans cet exemple, nous incluons de nombreuses URL admin. Elles ne sont donc pas toutes contenues dans ce petit fichier. C'est plus lisible et plus propre. ## Votre première URL Django ! -Bon, il est temps de créer votre première URL ! Nous voulons que "http://127.0.0.1:8000/" soit la page d’accueil de notre blog et qu'elle nous montre la liste des articles du blog. +Il est temps de créer notre première URL ! Nous voulons que 'http://127.0.0.1:8000/' soit la page d'accueil de notre blog et qu'elle affiche la liste des articles. Nous aimerions aussi garder notre fichier `mysite/urls.py` propre. Pour cela, nous allons importer les URLs de notre application `blog` dans notre fichier principal `mysite/urls.py`. -On y va : supprimez les lignes commentées, c'est-à-dire celles qui commencent par `#`. Ensuite, ajoutez une ligne qui va nous permettre d'importer `blog.urls` dans notre URL principale (`''`). +Allez-y ! Ajoutez une ligne qui importera `blog.urls`. Vous devrez également modifier la ligne ` from django.urls...` car nous utiliseront la fonction `include`. Il vous faudra ajouter cet import à la ligne. + +Votre fichier `mysite/urls.py` devrait maintenant ressembler à ceci : -Votre fichier `mysite/urls.py` devrait maintenant ressembler à ceci: +{% 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 va maintenant rediriger tout ce qui arrive sur "http://127.0.0.1:8000/" vers `blog.urls` puis regardera dans ce fichier pour y trouver la suite des instructions à suivre. -En Python, les expressions régulière commencent toujours par `r` au début de la chaîne de caractères. Cela permet d'indiquer à Python que ce qui va suivre inclut des caractères qu'il ne doit pas interpréter en tant que code Python mais en tant qu'expression régulière. - ## blog.urls -Créez un nouveau fichier vide `blog/urls.py`. OK ! Ajoutez maintenant ces deux premières lignes : +Créez un nouveau fichier vide nommé `urls.py` dans le répertoire `blog`, et ouvrez-le dans l'éditeur de code. Très bien ! Ajoutez ces deux premières lignes : + +{% filename %}blog/urls.py{% endfilename %} ```python -from django.conf.urls import url +from django.urls import path from . import views ``` -Nous venons d'importer les méthodes de Django dont nous avons besoin ainsi que toutes les `vues` liées à notre application `blog`. Cependant, nous n'avons pas encore créé de vues ! Pas de problème : nous y viendrons dans une minute +Nous venons d'importer la fonction `path` de Django ainsi que toutes les `vues` liées à notre application `blog`. (Cependant, nous n'avons pas encore créé de vues ! Pas de problème : nous y viendrons dans une minute !) + +Après ça, nous pouvons ajouter notre premier modèle (pattern) d'URL: -Après ça, nous pouvons ajouter notre premier pattern d'URL: +{% filename %}blog/urls.py{% endfilename %} ```python urlpatterns = [ - url(r'^$', views.post_list, name='post_list'), + path('', views.post_list, name='post_list'), ] ``` -Comme vous pouvez le voir, nous assignons une `vue` appelée `post_list` à l'URL `^$`. Décomposons cette expression régulière : `^` pour début suivie de `$` pour fin. Si nous mettons ces deux symboles ensemble, cela donne l'impression que nous sommes à la recherche d'une chaîne de caractères (string) vide. Ça tombe bien car c'est exactement ce que nous voulons ! En effet, l'URL resolver de Django ne considère pas 'http://127.0.0.1:8000/' comme faisant partie de l'URL. Ce pattern va donc indiquer à Django d'afficher la vue `views.post_list` à un utilisateur de votre site web qui se rendrait à l'adresse "http://127.0.0.1:8000/". - -La dernière partie, `name='post_list'`, est le nom de l'URL qui sera utilisée afin d'identifier la vue. Ce nom peut être le même que celui de la vue ou quelque chose de complètement différent. Plus tard dans ce tutoriel, nous allons utiliser les noms que nous avons donné à nos URLs. Il est donc important de donner un nom unique à chaque URL que nous créons. Pour vous faciliter la tâche, essayez de trouver des noms d'URLs simple à retenir. - -Est-ce que tout fonctionne toujours ? Ouvrez votre navigateur à l'adresse http://127.0.0.1:8000/ pour vérifier. +Comme vous pouvez le voir, nous assignons une `vue` appelée `post_list` à l'URL racine. Ce modèle d’URL correspond à une chaîne vide et le résolveur d'URL de Django ignore le nom de domaine (par exemple, http://127.0.0.1:8000/), soit la première partie de l'URL. Ce pattern va donc indiquer à Django d'afficher la vue `views.post_list` à un utilisateur de votre site web qui se rendrait à l'adresse "http://127.0.0.1:8000/". -![Erreur][2] +La dernière partie, `name='post_list'`, est le nom de l'URL qui sera utilisée afin d'identifier la vue. Ce nom peut être le même que celui de la vue ou quelque chose de complètement différent. Plus tard dans ce tutoriel, nous allons utiliser les noms que nous avons donné à nos URLs. Il est donc important de donner un nom unique à chaque URL que nous créons. Pour vous faciliter la tâche, essayez de trouver des nom d'URLs simple à retenir. - [2]: images/error1.png +Si vous essayez d'aller sur http://127.0.0.1:8000/ maintenant, vous trouverez un message du style « page web non disponible ». C’est parce que le serveur (vous vous souvenez d'avoir tapé `runserver` ?) n'est plus en exécution. Jetez un oeil à la console pour savoir pourquoi. -"It works" a disparu ! Ne vous en faites pas : ce que vous voyez est juste une page d'erreur. N'ayez pas peur des pages d'erreur, elles sont en fait très utiles : +![Erreur](images/error1.png) -Sur cette page, vous pouvez lire le message **no attribute 'post_list'** (il manque un attribut "post_list"). Est-ce que *post_list* vous rappelle quelque chose ? Yep, c'est le nom que nous avons donné à notre vue ! Cela signifie que nous avons posé les fondations mais, que nous n'avons pas encore créé notre *vue*. Pas de problème, on y vient :). +Votre console affiche une erreur, mais ne vous inquiétez pas – c’est en fait très utile : elle vous dit qu’il n’existe aucun attribut « post_list » (**no attribute 'post_list'**). C’est le nom de la *vue* que Django essaie de trouver et d’utiliser, or nous ne l'avons pas encore créée. À ce stade, votre `/admin/` ne fonctionnera pas non plus. Pas de problème, on y vient. Si vous voyez un message d’erreur différent, essayez de redémarrer votre serveur web. Pour faire cela, dans la console qui exécute le serveur web, arrêtez-le en appuyant sur CTRL+C (les touches Control et C simultanément). Sous Windows, vous devrez peut-être appuyer sur Ctrl+Break. Vous devrez alors redémarrer le serveur web en exécutant la commande `python manage.py runserver`. -> Si vous voulez en savoir plus au sujet de la configuration des URLs dans Django, vous pouvez aller consulter la documentation officielle du framework : https://docs.djangoproject.com/fr/1.10/topics/http/urls/ +> Si vous voulez en savoir plus au sujet de la configuration des URLs dans Django, vous pouvez aller consulter la documentation officielle du framework : https://docs.djangoproject.com/en/2.2/topics/http/urls/ \ No newline at end of file diff --git a/fr/django_urls/images/error1.png b/fr/django_urls/images/error1.png index cc17593d19d..50618fca3fe 100644 Binary files a/fr/django_urls/images/error1.png and b/fr/django_urls/images/error1.png differ diff --git a/fr/django_urls/images/url.png b/fr/django_urls/images/url.png index 6cd1bd96291..c22441e930e 100644 Binary files a/fr/django_urls/images/url.png and b/fr/django_urls/images/url.png differ diff --git a/fr/django_views/README.md b/fr/django_views/README.md index 68636b7734f..530a34f1b35 100755 --- a/fr/django_views/README.md +++ b/fr/django_views/README.md @@ -1,14 +1,16 @@ -# Créons nos vues Django! +# Vues Django - C'est l'heure de créer ! -Il est enfin temps de se débarrasser du bug que nous avons créé dans le chapitre précédent :) +Il est enfin temps de se débarrasser du bug que nous avons créé dans le chapitre précédent! :) -C'est dans la *vue* que nous allons ranger toute la partie "logique" de notre application. C'est elle qui va se charger d'aller chercher les informations liées à notre `modèle `que nous venons de créer et de les passer à un `template`. Nous allons créer ce template dans le chapitre suivant. Concrètement, les vues ne sont que des méthodes Python un peu plus élaborées que celles que nous avons manipulées dans la partie **Introduction à Python**. +C'est dans la *vue* que nous allons ranger toute la partie "logique" de notre application. C'est elle qui va se charger d'aller chercher les informations liées à notre `modèle `que nous venons de créer et de les passer à un `template`. Nous allons créer ce template dans le chapitre suivant. Concrètement, les vues ne sont que des fonctions Python un peu plus élaborées que celles que nous avons créées dans la partie **Introduction à Python**. Les vues sont placées dans le fichier `views.py`. Nous allons créer nos *vues* dans le fichier `blog/views.py`. ## blog/views.py -Ok, allons-y ! Ouvrons ce fichier pour voir ce qu'il contient : +Ok, allons-y ! Ouvrons ce fichier dans notre éditeur de code pour voir ce qu'il contient : + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -16,23 +18,27 @@ from django.shortcuts import render # Create your views here. ``` -Il n'y pas encore grand chose dans ce fichier. La vue la plus simple que l'on peut créer ressemble à ceci : +Pas beaucoup de choses pour l'instant. + +N’oubliez pas que les lignes commençant par `#` sont des commentaires, ce qui signifie qu'elles ne sont pas exécutées par Python. + +Nous allons créer une *vue* comme l’indique le commentaire. Ajoutez la vue minimale suivante : + +{% filename %}blog/views.py{% endfilename %} ```python def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -Comme vous pouvez le voir, nous avons créé une méthode (`def`) appelée `post_list` qui prend une `request (requête)` et `return (retourne)` une méthode `render` qui va permettre d'assembler tout ça selon notre template `blog/post_list.html`. +Comme vous pouvez le voir, nous avons créé une fonction (`def`) appelée `post_list` qui prend une `request (requête)` et qui va `return (retourner)` la valeur donnée par une autre fonction `render` qui va assembler notre template `blog/post_list.html`. Sauvegardez votre fichier et allez à l'adresse http://127.0.0.1:8000/ pour voir ce qui s'affiche maintenant. Une autre erreur ! Voyons ce qu'elle nous dit : -![Erreur][1] - - [1]: images/error.png +![Erreur](images/error.png) -Celle-là est plutôt simple : *TemplateDoesNotExist*. Corrigeons ça en créant un template dans la section suivante ! +Cela indique que le serveur tourne, ce qui est bien, mais il y a quelque chose qui ne va pas, non ? Ne vous inquiétez pas, c’est juste une page d’erreur, il ne faut pas avoir peur d'elle ! Au contraire, tout comme les messages d’erreur dans la console, elle nous est très utile. Vous pouvez lire que *TemplateDoesNotExist*. Nous allons corriger ce bug et créer un modèle (template) dans le prochain chapitre ! -> Pour en apprendre un peu plus sur les vues dans Django, consultez la documentation officielle : https://docs.djangoproject.com/fr/1.10/topics/http/views/ +> Pour en apprendre un peu plus sur les vues dans Django, consultez la documentation officielle : https://docs.djangoproject.com/en/2.2/topics/http/views/ \ No newline at end of file diff --git a/fr/django_views/images/error.png b/fr/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/fr/django_views/images/error.png and b/fr/django_views/images/error.png differ diff --git a/fr/dynamic_data_in_templates/README.md b/fr/dynamic_data_in_templates/README.md index 82e15d4a6c9..4c25163a082 100755 --- a/fr/dynamic_data_in_templates/README.md +++ b/fr/dynamic_data_in_templates/README.md @@ -2,11 +2,13 @@ Nous avons différents morceaux en place : le modèle `Post` qui est définit dans le fichier `models.py`, la vue `post_list` dans `views.py` et nous venons de créer notre template. Mais comment allons-nous faire pour faire apparaître nos posts dans notre template HTML ? Car au final, n'est-ce pas le but que nous souhaiterions atteindre ? Nous aimerions prendre du contenu, en l’occurrence notre modèle sauvegardé dans notre base de données, et réussir à joliment l'afficher dans notre template. -C'est à ça que servent les *vues* : connecter les modèles et les templates. Dans notre *vue* `post_list`, nous allons avoir besoin de prendre les modèles dont nous avons besoin et de les passer au template. Concrètement, c'est dans la *vue* que nous allons décider ce qui va s'afficher (modèle) dans un template. +C'est à ça que servent les *vues* : connecter les modèles et les templates. Dans notre *vue* `post_list`, nous allons avoir besoin de prendre les modèles dont nous avons besoin et de les passer au template. C'est dans la *vue* que nous allons décider ce qui va s'afficher (quel modèle) dans un template. Ok, et sinon, on fait comment ? -Nous allons avoir besoin d'ouvrir le fichier `blog/views.py`. Pour l'instant, la *vue* `post_list` ressemble à ceci : +Nous allons avoir besoin d'ouvrir le fichier `blog/views.py` dans l'éditeur de code. Pour l'instant, la *vue* `post_list` ressemble à ceci : + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -15,28 +17,34 @@ def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -Est-ce que vous vous souvenez de comment rajouter des morceaux de code écrits dans d'autres fichiers ? Nous en avons parlé dans un chapitre précédent. Nous allons devoir importer notre modèle qui est défini dans le fichier `models.py`. Pour cela, nous allons ajouter la ligne `from .models import Post` de la façon suivante : +Est-ce que vous vous souvenez de comment rajouter des morceaux de code écris dans d'autres fichiers ? Nous en avons parlé dans un chapitre précédent. Nous allons devoir importer notre modèle qui est défini dans le fichier `models.py`. Pour cela, nous allons ajouter la ligne `from .models import Post` de la façon suivante : + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render from .models import Post ``` -Le point après `from` signifie le *dossier courant* ou *l'application courante*. Comme `views.py` et `models.py` sont dans le même dossier, nous pouvons tout simplement utiliser `.` et le nom du fichier, sans le `.py`. Ensuite, nous importons le modèle (`Post`). +Le point avant `models` signifie *dossier courant* ou *application courante*. Les fichiers `views.py` et `models.py` sont dans le même répertoire. Cela signifie que nous pouvons utiliser `.` suivi par le nom du fichier (sans `.py`). Ensuite, nous importons le modèle (`Post`). Ok, et après ? Afin de pouvoir aller chercher les véritables posts de blog de notre modèle `Post`, nous avons besoin de quelque chose qui s'appelle un `QuerySet`. ## QuerySet -Normalement, ce mot doit vous évoquer quelque chose. Nous en avons un peu parlé dans la section [Django ORM (QuerySets)][1]. +Normalement, ce mot doit vous évoquer quelque chose. Nous en avons un peu parlé dans la section [Django ORM (QuerySets)](../django_orm/README.md). -Maintenant, nous allons nous intéresser à une liste de blog posts qui sont publiés et classés par date de publication (`published_date`). Ça tombe bien, on a déjà fait ça dans la section sur les QuerySets ! +Maintenant, nous allons nous intéresser à comment publier les post classés par date de publication (`published_date`). Ça tombe bien, on a déjà fait ça dans la section sur les QuerySets ! + +{% filename %}blog/views.py{% endfilename %} ```python Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') ``` -Il ne nous reste plus qu'à mettre cette ligne de code à l'intérieur de notre fichier `blog/views.py`, dans la fonction `def post_list(request)` : +Ouvrons donc le fichier `blog/views.py` dans l’éditeur de code et ajoutons le morceau de code suivant à la fonction `def post_list(request)`. N’oubliez pas d’ajouter d’abord `from django.utils import timezone`. + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -48,16 +56,19 @@ def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -Veuillez noter que nous créons une *variable* pour notre QuerySet : `posts`. Considérez que c'est le nom de notre QuerySet. À partir de maintenant, nous allons pouvoir faire référence à notre QuerySet en utilisant ce nom. +Pour afficher notre QuerySet sur la liste des publications de notre blog, il nous reste deux choses à faire: -Notez aussi que notre code utilise la fonction `timezone.now()` que nous allons aussi devoir importer de `timezone`. +1. Passer les `posts` QuerySet dans le contexte du modèle, en changeant l'appel à la fonction `render` . Nous allons le faire maintenant. +2. Modifier le modèle pour afficher le QuerySet `posts` . Nous en parlerons dans un chapitre ultérieur. -Il nous manque encore un petit quelque chose : passer notre QuerySet `posts` à notre template. Nous nous intéresserons plus particulièrement à celui-ci dans la section suivante. +Veuillez noter que nous créons une *variable* pour notre QuerySet : `posts`. Considérez que c'est le nom de notre QuerySet. À partir de maintenant, nous allons pouvoir faire référence à notre QuerySet en utilisant ce nom. -Dans la fonction `render`, nous avons déjà un paramètre `request`, qui désigne tout ce que nous recevons d'un utilisateur par l'intermédiaire d'Internet, et un fichier template appelé `'blog/post_list.html'`. Le dernier paramètre, qui ressemble à `{}`, va nous permettre de glisser des instructions que notre template va suivre. Nous avons besoin par exemple de lui donner des noms : nous allons rester sur `'posts'` pour le moment :). Ça va ressembler à ça : `{'posts': posts}`. La partie située avant `:` est une chaîne de caractères : vous devez donc l'entourer de guillemets `''`. +Dans la fonction `render`, nous avons un paramètre `request`, qui désigne tout ce que nous recevons d'un utilisateur par l'intermédiaire d'Internet, et un autre qui signale le fichier template (`'blog/post_list.html'`). Le dernier paramètre, `{}`, va nous permettre de glisser des informations que notre template va utiliser. Nous devons donner des noms à ces informations (nous allons rester sur `'posts'` pour le moment). :) Ça va ressembler à ça : `{'posts': posts}`. La partie située avant `:` est une chaine de caractères ; vous devez donc l'entourer de guillemets : `''`. Au final, notre fichier `blog/views.py` doit ressembler à ceci maintenant : +{% filename %}blog/views.py{% endfilename %} + ```python from django.shortcuts import render from django.utils import timezone @@ -70,6 +81,4 @@ def post_list(request): Et voilà, c'est bon ! Nous allons retourner du côté de notre template pour que notre QuerySet puisse s'afficher correctement ! -Si vous voulez en savoir plus sur les QuerySets, n'hésitez pas à consulter la documentation officielle du framework : https://docs.djangoproject.com/fr/1.10/ref/models/querysets/ - - [1]: ../django_orm/README.md +Si vous voulez en savoir plus sur les QuerySets, n'hésitez pas à consulter la documentation officielle du framework : https://docs.djangoproject.com/en/2.2/ref/models/querysets/ \ No newline at end of file diff --git a/fr/extend_your_application/README.md b/fr/extend_your_application/README.md index 2e7aab1531e..56e9c2d1b6a 100755 --- a/fr/extend_your_application/README.md +++ b/fr/extend_your_application/README.md @@ -1,119 +1,124 @@ +{% set warning_icon = '' %} + # Finaliser votre application -Nous avons déjà franchi toutes les étapes nécessaires à la création de notre site web : nous savons maintenant comment écrire un modèle, une URL, une vue et un template. Nous avons même réussi à rendre notre site web plus joli ! +Nous avons déjà franchi toutes les étapes nécessaires à la création de notre site web : nous savons maintenant comment écrire un modèle, une URL, une vue et un template. Nous avons même réussi à rendre notre site web plus joli . -C'est le moment de pratiquer tout ce que vous avez appris aujourd'hui ! +C'est le moment de pratiquer tout ce que vous avez appris ! Tout d'abord, il faudrait que notre blog possède une page qui permet d'afficher un post, n'est-ce pas ? -Nous avons déjà un modèle `Post`, nous n'avons donc pas besoin de retourner éditer `models.py`. +Nous avons déjà un modèle `Post`, nous n'avons donc pas besoin d'ajouter quoi que ce soit à `models.py`. ## Créer un lien dans un template -Nous allons tout d'abord ajouter un lien à l'intérieur du fichier `blog/templates/blog/post_list.html`. Pour le moment, ce fichier doit ressembler à ceci : +Nous allons tout d'abord ajouter un lien à l'intérieur du fichier `blog/templates/blog/post_list.html`. Ouvrez-le dans l’éditeur de code et voyez qu'il devrait ressembler à ceci : {% 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 content %} +{% endblock %} ``` -{% raw %}Nous aimerions pouvoir cliquer sur le titre du post et arriver sur une page avec le contenu de celui-ci. Pour cela, changeons `

{{ post.title }}

` pour qu'il pointe vers la page de contenu du post :{% endraw %} +{% raw %}Nous aimerions pouvoir cliquer sur le titre du post et arriver sur une page avec le contenu de celui-ci. Pour cela, changeons `

{{ post.title }}

` pour qu'il pointe vers la page de contenu du post :{% endraw %} + +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} ```html -

{{ post.title }}

+

{{ post.title }}

``` -{% raw %}C'est le moment parfait pour expliquer ce mystérieux `{% url 'post_detail' pk=post.pk %}`. Vous vous souvenez peut-être que la notation `{% %}` nous permet d'utiliser les balises de template Django. Cette fois, nous allons utiliser des balises qui vont s'occuper de créer des URLs à notre place !{% endraw %} +{% raw %}C'est le moment parfait pour expliquer ce mystérieux `{% url 'post_detail' pk=post.pk %}`. Vous vous souvenez peut-être que la notation `{% %}` nous permet d'utiliser les balises de template Django. Cette fois-ci, nous allons utiliser des balises qui vont s'occuper de créer des URLs à notre place !{% endraw %} -`blog.views.post_detail` est le chemin d'accès vers la *vue* `post_detail` que nous aimerions créer. Attention : `blog` désigne notre application (le dossier `blog`) et `views` le fichier `views.py`. Enfin, `post_detail` est le nom de notre *vue*. +La partie `post_detail` signifie que Django s'attend de trouver une URL en `blog/urls.py` avec nom = post_detail -Si nous essayons d'aller à http://127.0.0.1:8000/, nous allons rencontrez une erreur : nous n'avons pas d'URL ou de *vue* pour `post_detail`. L'erreur ressemble à ceci : +Et qu’en est-il de `pk=post.pk` ? `pk` est l’abréviation de clé primaire (« primary key » en anglais), qui est un identifiant unique pour chaque entrée dans une base de données. Chaque modèle Django a un champ qui sert de clé primaire, et peu importe son autre nom, il peut aussi être appelé par le nom « pk ». Comme nous n’avons pas spécifié de clé primaire dans notre modèle `Post`, Django en crée une pour nous (par défaut, un champ nommé « id » contenant un nombre qui augmente pour chaque entrée, c’est-à-dire 1, 2, 3, etc.) et l’ajoute comme champ à chacun de nos posts. Nous accédons à la clé primaire en écrivant `post.pk`, pareil que pour accéder aux autres champs (`title`, `author`, etc.) de notre objet `Post` ! -![Erreur NoReverseMatch][1] +Maintenant si nous jetons un coup d’œil à http://127.0.0.1:8000/, nous rencontrons une erreur. Ceci est prévisible, puisque nous n'avons ni d'URL ni de *view* pour `post_detail`. L'erreur ressemble à ceci : - [1]: images/no_reverse_match2.png +![Erreur NoReverseMatch](images/no_reverse_match2.png) ## Créer une URL vers le contenu d'un post -Allons créer notre URL dans le fichier `urls.py` pour notre *vue* `post_detail`! +Allons créer notre URL dans le fichier `urls.py` pour notre *vue* `post_detail` ! Nous aimerions que le contenu de notre premier post s'affiche à cette **URL** : http://127.0.0.1:8000/post/1/ -Allons créer une URL dans le fichier `blog/urls.py` qui pointera Django vers une *vue* appelée `post_detail`. Cela nous permettra d'afficher l'intégralité d'un post de blog. Ajoutez la ligne `url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'),` dans le fichier `blog/urls.py`. Votre fichier devrait maintenant ressembler à ceci : +Allons créer une URL dans le fichier `blog/urls.py` qui dirigera Django vers une *vue* appelée `post_detail`. Cela nous permettra d'afficher l'intégralité d'un post de blog. Ouvrez le fichier `blog/urls.py` dans l’éditeur de code et ajoutez la ligne `path('post//', views.post_detail, name='post_detail'),` afin que le fichier ressemble à ceci : + +{% 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]+)/$` a l'air plutôt effrayant mais, ne vous inquiétez pas, décortiquons-le ensemble : -* Il commence par `^`, qui désigne le "début" -* `post/` signifie seulement qu'après le début, l'URL doit contenir le mot **post** et **/**. Jusque-là, tout va bien. -* `(?P[0-9]+)` : ok, là, on s'accroche :). Cela signifie que Django va prendre tout ce que vous placez là et le transférer à une vue sous la forme d'une variable appelée `pk`. `[0-9]` nous dit aussi que nous ne voulons que des nombres (tout ce qui est entre 0 et 9 inclus) et non des lettres. `+` signifie qu'il faut, au minimum, un chiffre à cet endroit. Du coup, quelque chose comme `http://127.0.0.1:8000/post//` n'est pas valide tandis que `http://127.0.0.1:8000/post/1234567890/` l'est complètement! -* `/` - nous avons encore besoin d'un **/** -* `$` - "la fin"! - -Concrètement, cela signifie que si vous entrez `http://127.0.0.1:8000/post/5/` dans votre barre d'adresse, Django va comprendre que vous cherchez à atteindre une *vue* appelée `post_detail` et qu'il doit communiquer l'information que `pk` est égal `5` dans cette *vue*. +La partie `post//` spécifie un modèle d’URL – allons voir plus dans le détail : -`pk` est un raccourci pour `primary key`. Ce nom est très souvent utilisé dans les projets Django. Cependant, vous pouvez appeler cette variable comme bon vous semble, toujours dans la limite des règles suivantes : pas d'accents, pas de caractères spéciaux, des minuscules et des `_` à la place des espaces. Par exemple, à la place de `(?P[0-9]+)`, nous pourrions utiliser la variable `post_id`, ce qui donnerait : `(?P[0-9]+)`. +- `post/` signifie que l’URL doit commencer par le mot **post** suivie d’un **/**. OK, pas très compliqué. +- ``– cette partie est plus délicate. Cela signifie que Django s’attend à une valeur entière (int), qu'en suite il transférera à une vue comme variable de nom `pk`. +- `/` – il nous faut un **/** à nouveau avant la fin de l’URL. -Comme nous venons d'ajouter un nouveau pattern d'URL au fichier `blog/urls.py`, rafraîchissons la page : http://127.0.0.1:8000/ Boom ! Encore une erreur ! Mais on s'y attendait ;) +Concrètement, cela signifie que si vous entrez `http://127.0.0.1:8000/post/5/` dans votre barre d'adresse, Django va comprendre que vous cherchez à atteindre une *vue* appelée `post_detail` et qu'il doit communiquer à cette *vue* que `pk` est égal à `5`. -![AttributeError][2] +OK, nous avons ajouté un nouveau modèle d’URL à `blog/urls.py` ! Actualisons la page : http://127.0.0.1:8000/ Boom ! Le serveur a cessé de marcher à nouveau. Jetez un oeil sur la console – comme prévu, il y a encore une autre erreur ! - [2]: images/attribute_error2.png +![AttributeError](images/attribute_error2.png) -Est-ce que vous vous souvenez de ce que nous devons faire ensuite ? Il falloir ajouter une vue ! +Vous souvenez-vous de ce qu'il faut faire ensuite ? Il faut ajouter une vue ! ## Ajouter une vue pour le contenu du post -Cette fois, nous allons donner un paramètre supplémentaire à notre *vue* : `pk`. Notre *vue* va avoir besoin de le récupérer. Pour cela, nous allons définir une fonction : `def post_detail(request, pk):`. Attention : notez bien que nous utilisons le même nom que celui que nous avons spécifié dans le fichier url (`pk`). Oublier cette variable est incorrecte et va générer une erreur ! +Cette fois-ci, nous allons donner un paramètre supplémentaire à notre *vue* : `pk`. Notre *vue* va avoir besoin de le récupérer, n'est ce pas ? Pour cela, nous allons définir une fonction : `def post_detail(request, pk):`. Notez que ce paramètre doit avoir exactement le même nom que celui que nous avons spécifié dans le fichier `urls` (`pk`). Notez aussi qu’oublier de mettre cette variable est incorrect et produira une erreur ! + +Maintenant, nous aimerions obtenir qu'un seul blog post. Pour cela, nous allons utiliser des QuerySets qui ressemblent à ceux-ci: -Maintenant, nous n'aimerions obtenir qu'un seul blog post. Pour cela, nous allons utiliser des QuerySets qui ressemblent à ceux-ci: +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} ```python Post.objects.get(pk=pk) ``` -Cependant, il y a un petit problème dans cette ligne de code. Si aucun de nos `Posts` ne possède cette `primary key (clef primaire)` (`pk`), nous allons nous retrouver avec une super erreur bien cracra! +Cependant, il y a un petit problème dans cette ligne de code. Si aucun de nos `Posts` ne possèdent cette `primary key (clef primaire)` (`pk`), nous allons nous retrouver avec une super erreur bien cracra! -![Erreur DoesNotExist][3] +![Erreur DoesNotExist](images/does_not_exist2.png) - [3]: images/does_not_exist2.png +Dans l'idéal, nous aimerions pouvoir éviter ça! Encore une fois, Django nous offre l'outil parfait pour ça : `get_object_or_404`. Dans le cas où il n'existerait pas de `Post` avec le `pk` indiqué, une page d'erreur beaucoup plus sympathique s'affichera : c'est ce qu'on appelle une `erreur 404 : page non trouvée`. -Dans l'idéal, nous aimerions pouvoir éviter ça! Comme d'habitude, Django nous offre l'outil parfait pour ça : `get_object_or_404`. Dans le cas où il n'existerait pas de `Post` avec le `pk` indiqué, une page d'erreur beaucoup plus sympathique s'affichera : c'est ce qu'on appelle une `erreur 404 : page non trouvée`. - -![Page non trouvée][4] - - [4]: images/404_2.png +![Page non trouvée](images/404_2.png) La bonne nouvelle, c'est que vous pouvez créer vous-mêmes votre page `Page non trouvée` et en faire ce que vous voulez ! Reconnaissez que ce n'est pas le plus important pour le moment donc nous allons zapper cette partie ;). Ok, ajoutons notre *vue* à notre fichier `views.py`! -Ouvrons le fichier `blog/views.py` et ajoutons le code suivant: +Dans le fichier `blog/urls.py` nous avons crée un modèle d'URL `post_detail` qui fait référence à la vue `views.post_detail`. En conséquence, Django s'attend à qu'une fonction `post_detail` soit définie dans le fichier `blog/views.py`. + +Ouvrez maintenant le fichier `blog/views.py` dans l'éditeur de code et ajoutez la ligne suivante après les autres lignes du type `from` qui existent déjà : + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render, get_object_or_404 ``` -Cette ligne est à ajouter en dessous des lignes `from` situées en début de fichier. Ensuite, à la fin de notre fichier, nous allons ajouter notre *vue* proprement dite: +A la fin du fichier nous ajoutons finalement notre *view* : + +{% filename %}blog/views.py{% endfilename %} ```python def post_detail(request, pk): @@ -123,77 +128,87 @@ def post_detail(request, pk): Hop, réactualisons la page http://127.0.0.1:8000/ -![Vue post_list][5] - - [5]: images/post_list2.png +![Vue post_list](images/post_list2.png) -C'est bon, ça a marché ! Mais que se passe-t-il lorsque nous cliquons sur un lien dans un titre de blog post ? +C'est bon, ça a marché ! Mais que ce passe-t-il lorsque nous cliquons sur un lien dans un titre de blog post ? -![Erreur TemplateDoesNotExist][6] - - [6]: images/template_does_not_exist2.png +![Erreur TemplateDoesNotExist](images/template_does_not_exist2.png) Oh non ! Encore une erreur ! Mais cette fois, vous savez quoi faire : nous avons besoin d'un template ! ## Créer un template pour le contenu du post -Nous allons créer un fichier `post_detail.html` dans le dossier `blog/templates/blog`. +Nous allons créer un fichier `post_detail.html` dans le dossier `blog/templates/blog` et nous l'ouvrons ensuite avec notre éditeur de code. + +Entrez le code suivant : -Ça ressemblera à ça : +{% 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 %} ``` -Une nouvelle fois, nous faisons hériter de `base.html`. Dans le `content` block, nous voulons que s'affiche la date de publication d'un post (si elle existe), son titre et son texte. Mais vous souhaitez peut-être quelques éclaircissements avant, non? - -{% raw %}`{% if ... %} ... {% endif %}` est une balise de template que nous pouvons utiliser si nous voulons vérifier quelque chose : souvenez-vous de `if ... else ..` de la section **Introduction à Python**. Dans ce scénario, nous aimerions vérifier si la date de publication d'un post (`published_date`) n'est pas vide.{% endraw %} +Une nouvelle fois, nous faisons hériter de `base.html`. Dans le `content` block, nous voulons afficher la date de publication d'un post (si elle existe), son titre et son texte. Mais vous souhaitez peut-être quelques éclaircissements avant, non? -Ok, vous pouvez maintenant rafraîchir votre page et voir si la page `Page not found` a enfin disparu. +{% raw %}`{% if ... %} ... {% endif %}` est une balise de template que nous pouvons utiliser si nous voulons vérifier quelque chose. (Vous souvenez-vous de `if ... else ..` que nous avons appris dans le chapitre **Introduction à Python** ?) Dans ce cas spécifique, nous voulons vérifier que `published_date` existe.{% endraw %} -![Page détaillée d'un post][7] +Ok, vous pouvez maintenant actualiser votre page et voir si `TemplateDoesNotExist` a enfin disparu. - [7]: images/post_detail2.png +![Page détaillée d'un post](images/post_detail2.png) Yay ! Ça marche! -## Encore un petit effort : déployons ! +# C'est le moment de deployer ! -Nous ferions bien de mettre à jour la version de notre site présente sur PythonAnywhere. On s'accroche et on déploie encore une fois :) +Ce serait bien de mettre à jour la version de notre site sur PythonAnywhere. On s'accroche et on déploie encore une fois :) + +{% filename %}command-line{% endfilename %} $ git status - $ git add --all . + $ git add . $ git status - $ git commit -m "Added view and template for detailed blog post as well as CSS for the site." + $ git commit -m "Ajout de la vue et du template de détail blog post ainsi que du CSS pour le site." $ git push + +Puis, dans la console bash de [PythonAnywhere](https://www.pythonanywhere.com/consoles/): -* Puis, dans la console bash de [PythonAnywhere][8]: - - [8]: https://www.pythonanywhere.com/consoles/ +{% filename %}PythonAnywhere command-line{% endfilename %} - $ cd my-first-blog - $ source myvenv/bin/activate - (myvenv)$ git pull - [...] - (myvenv)$ python manage.py collectstatic + $ cd ~/.pythonanywhere.com + $ git pull [...] + +(N’oubliez pas de remplacer `` avec votre propre sous-domaine PythonAnywhere, sans les chevrons.) + +## Mise à jour des fichiers statiques sur le serveur + +Des serveurs comme PythonAnywhere réservent un traitement particuliers aux "fichiers statiques" (par exemple les fichiers CSS), notamment afin de les charger plus rapidement. En conséquence, à chaque fois que nos fichiers CSS changent, nous devons executer une commande pour que le serveur les mette à jour. Cette commande s'appelle `collectstatic`. + +Démarrez en activant votre virtualenv, s'il n'est pas toujours actif (PythonAnywhere propose la commande `workon`, ce qui est l'équivalent de `source myenv/bin/activate` sur votre ordinateur) : + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ workon .pythonanywhere.com + (ola.pythonanywhere.com)$ python manage.py collectstatic + [...] + -* Enfin, cliquez sur l'onglet [Web][9] et cliquez sur **Reload**. +La commande `manage.py collectstatic` nous rappelle un peu `manage.py migrate`. Nous apportons des changements à notre code, puis nous disons à Django *d'appliquer* ces changements, que ce soit pour la gestion des fichiers statiques ou pour la structure de la base de données. - [9]: https://www.pythonanywhere.com/web_app_setup/ +Maintenant nous sommes prêtes à aller sur [« Web »](https://www.pythonanywhere.com/web_app_setup/) (depuis le menu en haut à droite de la console), appuyer sur **Reload** et voir les résultats à votre adresse https://sous-domaine.pythonanywhere.com. -Normalement, ça devrait suffire ! Encore bravo :) +Normalement, ça devrait suffire ! Encore bravo! :) \ No newline at end of file diff --git a/fr/extend_your_application/images/404_2.png b/fr/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/fr/extend_your_application/images/404_2.png and b/fr/extend_your_application/images/404_2.png differ diff --git a/fr/extend_your_application/images/attribute_error2.png b/fr/extend_your_application/images/attribute_error2.png index 6edcd9933c3..4b8262476d9 100644 Binary files a/fr/extend_your_application/images/attribute_error2.png and b/fr/extend_your_application/images/attribute_error2.png differ diff --git a/fr/extend_your_application/images/does_not_exist2.png b/fr/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/fr/extend_your_application/images/does_not_exist2.png and b/fr/extend_your_application/images/does_not_exist2.png differ diff --git a/fr/extend_your_application/images/no_reverse_match2.png b/fr/extend_your_application/images/no_reverse_match2.png index 306926206f8..aba1c9c8980 100644 Binary files a/fr/extend_your_application/images/no_reverse_match2.png and b/fr/extend_your_application/images/no_reverse_match2.png differ diff --git a/fr/extend_your_application/images/post_detail2.png b/fr/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/fr/extend_your_application/images/post_detail2.png and b/fr/extend_your_application/images/post_detail2.png differ diff --git a/fr/extend_your_application/images/post_list2.png b/fr/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/fr/extend_your_application/images/post_list2.png and b/fr/extend_your_application/images/post_list2.png differ diff --git a/fr/extend_your_application/images/template_does_not_exist2.png b/fr/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/fr/extend_your_application/images/template_does_not_exist2.png and b/fr/extend_your_application/images/template_does_not_exist2.png differ diff --git a/fr/how_the_internet_works/README.md b/fr/how_the_internet_works/README.md index 4445c403ad0..214707e0954 100644 --- a/fr/how_the_internet_works/README.md +++ b/fr/how_the_internet_works/README.md @@ -1,52 +1,47 @@ -# Comment fonctionne l'Internet ? +# Comment fonctionne Internet -> Ce chapitre est inspiré par la présentation "How the Internet works" par Jessica McKellar (http://web.mit.edu/jesstess/www/). +> Pour les lectrices autodidactes : ce chapitre est traité dans la vidéo [How the Internet Works](https://www.youtube.com/watch?v=oM9yAA09wdc). +> +> Ce chapitre s’inspire de la conférence « Comment fonctionne Internet » de Jessica McKellar (http://web.mit.edu/jesstess/www/). -Vous utilisez sûrement Internet tous les jours. Mais savez-vous ce qu'il ce passe vraiment quand vous tapez une adresse comme https://djangogirls.org dans votre navigateur et appuyez sur `Entrée` ? +Vous utilisez sûrement Internet tous les jours. Mais savez-vous ce qui ce passe vraiment quand vous tapez une adresse comme https://djangogirls.org dans votre navigateur et appuyez sur `Entrée`? -Avant tout, il faut savoir qu'un site web n'est rien de plus qu'un tas de fichiers sauvegardés sur un disque dur. Exactement comme vos vidéos, vos musiques ou vos photos. Cependant, les sites web ont quelque chose d'unique : ils contiennent du code informatique appelé HTML. +La première chose que vous devez comprendre c’est qu’un site Web consiste en un tas de fichiers sauvegardés sur un disque dur -- tout comme vos films, musiques ou photos. Cependant, les sites web ont quelque chose d'unique : ils contiennent du code informatique appelé HTML. Si vous n'avez pas l'habitude de la programmation, il peut être difficile de comprendre HTML au début, mais vos navigateurs web (comme Chrome, Safari, Firefox, etc.) adorent ça. Les navigateurs web sont conçus pour comprendre ce code, pour suivre les instructions qu'il contient et présenter les fichiers de votre site web exactement comme vous voulez qu'ils soient présentés. -Comme pour n'importe quel autre fichier, il faut stocker les fichiers HTML sur un disque dur quelque part. Pour Internet, on utilise des ordinateurs spéciaux, très puissants, appelés *serveurs*. Ils n'ont pas d'écran, de clavier ou de souris, car leur rôle est de stocker des données, et de les servir. C'est pour ça qu'on les appelle des *serveurs* -- parce qu'ils sont là pour vous *servir* des données. +Comme pour n'importe quel autre fichier, il faut stocker les fichiers HTML sur un disque dur quelque part. Pour Internet, on utilise des ordinateurs spéciaux, très puissants, appelés *serveurs*. Ils n'ont pas d'écran, de clavier ou de souris, car leur rôle est de stocker des données, et de les servir. C'est pour ça qu'on les appelle des *serveurs* : parce qu'ils sont là pour vous *servir* des données. Bon, d'accord. Mais vous avez envie de savoir à quoi Internet ressemble, n'est-ce-pas ? -On va a fait un dessin ! Internet ressemble à ça : +Nous vous avons fait un dessin ! Voilà à quoi ça ressemble : -![Figure 1.1][1] - - [1]: images/internet_1.png +![Figure 1.1](images/internet_1.png) C'est le bazar, non ? En fait, c'est un réseau de machines connectées entre elles (les *serveurs* dont on parlait plus tôt). Des centaines de milliers de machines ! Des millions de kilomètres de câbles, partout dans le monde ! Vous pouvez aller voir une carte des câbles sous-marins (http://submarinecablemap.com/) pour voir à quel point le réseau est compliqué. Voici une capture d'écran du site : -![Figure 1.2][2] - - [2]: images/internet_3.png +![Figure 1.2](images/internet_3.png) -Fascinant, non ? Cependant, il n'est évidemment pas possible de tirer un câble entre chaque machine connectée à Internet. Du coup, pour atteindre une machine (par exemple, celle où https://djangogirls.org est sauvegardé), on doit faire passer une requête par plein d'autres machines. +Fascinant, non ? Cependant, il n'est pas possible de tirer un câble entre chaque machine connectée à Internet. Du coup, pour atteindre une machine (par exemple, celle où https://djangogirls.org est sauvegardé), on doit faire passer une requête par plein d'autres machines. Ça ressemble ça : -![Figure 1.3][3] - - [3]: images/internet_2.png +![Figure 1.3](images/internet_2.png) C'est un peu comme si, quand vous tapiez https://djangogirls.org, vous envoyiez une lettre qui dit "Chères Django Girls, je voudrais voir le site djangogirls.org. Pouvez-vous me l'envoyer ?" Votre lettre part vers le bureau de poste le plus proche. Ensuite, il file vers un autre, qui est plus proche de votre destinataire. Puis un autre, et encore un autre, jusqu'à sa destination. Une chose à retenir : si vous envoyez beaucoup de lettres (*data packets*) au même endroit, il se pourrait qu'elles transitent par des postes différentes (*routers*). Cela dépend de la manière dont elles sont distribuées à chaque bureau de poste. -![Figure 1.4][4] +![Figure 1.4](images/internet_4.png) - [4]: images/internet_4.png - -Oui oui, c'est aussi simple que ça. Vous envoyez des messages et attendez une réponse. Alors, bien sûr, le papier et le crayon sont remplacés par des octets de données, mais l'idée est la même. +Cela fonctionne comme ça - vous envoyez des messages et attendez une réponse. Vous utilisez des octets de données à la place du papier et du crayon, mais l'idée est la même ! À la place des adresses postales (nom de rue, ville, code postal), nous utilisons des adresses IP. Votre ordinateur commence par demander au DNS (Domaine Name System) de traduire djangogirls.org en une adresse IP. Ça marche un peu comme un de ces vieux annuaires où l'on peut chercher le nom d'une personne et trouver son numéro de téléphone et son adresse. -Quand vous envoyez une lettre, elle a besoin de certaines choses pour transiter correctement, comme une adresse et un timbre. Vous devez aussi utiliser une langue que votre destinataire comprend. C'est la même chose pour les paquets de données que vous envoyez pour voir un site web. Vous utilisez un protocole appelé HTTP (Hypertext Tranfer Protocol). +Quand vous envoyez une lettre, elle a besoin de certaines choses pour transiter correctement : une adresse, un timbre, etc. Vous devez aussi utiliser une langue que votre destinataire comprend. C'est la même chose pour les paquets de données que vous envoyez pour voir un site web. Vous utilisez un protocole appelé HTTP (Hypertext Tranfer Protocol). + +Donc, au final, pour avoir un site web il faut qu'il soit sur un *serveur* (c'est une machine). Lorsque le *serveur* reçoit une *requête/0> (dans une lettre), il envoie votre site Web (dans une autre lettre).

-Donc, au final, pour avoir un site web il faut qu'il soit sur un *serveur* (c'est une machine). Lorsque le *serveur* reçoit une *requête* (dans une lettre), il envoie votre site Web (dans une autre lettre). -Puisqu'on est dans un tutoriel sur Django, vous devez vous demander ce que Django fait. Quand vous envoyez une réponse, vous ne renvoyez pas toujours la même réponse à tout le monde. C'est bien mieux quand les lettres sont personnalisées, surtout quand elles s'adressent à quelqu'un qui vient de vous écrire, non ? Et bien Django vous aide à écrire les lettres personnalisées et intéressantes :). +Puisqu'on est dans un tutoriel sur Django, vous devez vous demander ce que Django fait. Quand vous envoyez une réponse, vous ne renvoyez pas toujours la même réponse à tout le monde. C'est bien mieux quand les lettres sont personnalisées, surtout quand elles s'adressent à quelqu'un qui vient de vous écrire, non ? Et bien Django vous aide à écrire les lettres personnalisées et intéressantes. :) Assez parlé, il est temps de commencer à créer des trucs ! \ No newline at end of file diff --git a/fr/how_the_internet_works/images/internet_1.png b/fr/how_the_internet_works/images/internet_1.png index 9c5bcf0b003..e289eac2b23 100644 Binary files a/fr/how_the_internet_works/images/internet_1.png and b/fr/how_the_internet_works/images/internet_1.png differ diff --git a/fr/how_the_internet_works/images/internet_2.png b/fr/how_the_internet_works/images/internet_2.png index dd5861f376f..e8cf8b77999 100644 Binary files a/fr/how_the_internet_works/images/internet_2.png and b/fr/how_the_internet_works/images/internet_2.png differ diff --git a/fr/how_the_internet_works/images/internet_3.png b/fr/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/fr/how_the_internet_works/images/internet_3.png and b/fr/how_the_internet_works/images/internet_3.png differ diff --git a/fr/how_the_internet_works/images/internet_4.png b/fr/how_the_internet_works/images/internet_4.png index 2661cec1b61..d4748ac48ef 100644 Binary files a/fr/how_the_internet_works/images/internet_4.png and b/fr/how_the_internet_works/images/internet_4.png differ diff --git a/fr/html/README.md b/fr/html/README.md index 9b06a7f8817..e810b99b45e 100755 --- a/fr/html/README.md +++ b/fr/html/README.md @@ -8,7 +8,7 @@ Le format d'un template Django est décrit grâce à un langage qui s'appelle HT ## Qu'est-ce que le HTML ? -HTML est un code simple qui est interprété par votre navigateur (Chrome, Firefox ou Safari) et qui permet d'afficher une page web à l'utilisateur. +HTML est un code qui est interprété par votre navigateur (Chrome, Firefox ou Safari) et qui permet d'afficher une page web à l'utilisateur. L'abréviation HTML signifie « HyperText Markup Language ». **HyperText** signifie que c'est un type de texte qui supporte les hyperliens entre les pages. **Markup** signifie que nous avons pris un document et que nous avons balisé le code pour signifier (ici, au navigateur) comment il faut interpréter la page. Le code HTML est construit à l'aide de **balises**, chacune commençant par `<` et finissant par `>`. Ces balises représentent des **éléments** markup. @@ -21,71 +21,74 @@ Les templates sont sauvegardés dans le dossier `blog/templates/blog`. Tout d'ab blog └───templates └───blog + +Vous pourriez vous demander pourquoi nous avons besoin de deux dossiers portant tous les deux le nom `blog`. Comme vous le découvrirez plus tard, c'est une convention de nommage qui va nous faciliter la vie quand les choses vont commencer à devenir compliquées. -Vous pourriez vous demander pourquoi nous avons besoin de deux dossiers portant tous les deux le nom `blog`. Comme vous le découvrirez plus tard, c'est une simple convention de nommage qui va nous faciliter la vie quand les choses vont commencer à devenir compliquées. - -Et maintenant, créez un fichier `post_list.html` (laisser le vide pour le moment) dans le dossier `blog/templates/blog`. +Et maintenant, créez un fichier `post_list.html` (laisser le vide pour le moment) dans le dossier `templates/blog/blog`. Allons regarder à quoi ressemble notre site maintenant : http://127.0.0.1:8000/ -> Si vous avez une erreur `TemplateDoesNotExists`, essayez de redémarrer votre serveur. Prenez votre ligne de commande et arrêtez votre serveur en appuyant simultanément sur Ctrl+C (les touches Control et C de votre clavier). Vous pouvez le relancer en tapant la commande `python manage.py runserver`. - -![Figure 11.1][1] +> Si vous avez encore l'erreur `TemplateDoesNotExist`, essayez de redémarrer votre serveur. Allez sur votre ligne de commande et arrêtez votre server en appuyant simultanément sur Ctrl+C (les touches Control et C de votre clavier). Vous pouvez le relancer en tapant la commande `python manage.py runserver`. - [1]: images/step1.png +![Figure 11.1](images/step1.png) Et voilà, il n'y a plus d'erreurs ! Bravo :) Cependant, notre site ne peut rien faire d'autre pour le moment qu'afficher une page blanche. La faute à notre template que nous avons laissé vide. Allons corriger ça. -Ajoutez ce qui suit à votre fichier template : +Ouvrez le nouveau fichier dans l’éditeur de code et ajoutez le morceau suivant : + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + -

Hi there!

-

It works!

+ +

Bonjour !

+

Ça marche !

+ ``` Alors, à quoi ressemble notre site web maintenant ? Allons le découvrir : http://127.0.0.1:8000/ -![Figure 11.2][2] - - [2]: images/step3.png +![Figure 11.2](images/step3.png) -Ça marche ! Bon boulot :) +Ça marche ! Bon boulot! :) -* La balise la plus élémentaire, ``, figure toujours au début de n'importe quelle page web tandis que `` est toujours située à la fin. Comme vous pouvez le constater, l'intégralité du contenu de notre page web est située entre la balise de départ, ``, et la balise fermante, `` -* `

` est la balise pour les éléments de type paragraphe. `

` permet de fermer chaque paragraphe. +* La ligne `` n'est pas une balise HTML. Elle ne déclare que le type de document. Ici, elle informe le navigateur web que le type de document est [HTML5](https://html.spec.whatwg.org/#the-doctype). C'est toujours ainsi que débute un fichier HTML5. +* La balise la plus élémentaire, ``, figure toujours au début de n'importe quelle page web tandis que `` est toujours située à la fin. Comme vous pouvez le constater, l'intégralité du contenu de notre page web est située entre la balise de départ, ``, et la balise de fin, `` +* `

` est la balise pour les éléments de type paragraphe. `

` permet de fermer chaque paragraphe. -## Head & body +## Head et Body -Chaque page HTML est divisée en deux éléments : **head** (entête) et **body** (corps). +Chaque page HTML est divisée en deux éléments : **head** (entête) et **body** (corps. -* **head** est un élément qui contient des informations sur le document : son contenu ne s'affichera pas à l'écran. +* **head** est un élément qui contient des informations sur le document : son contenu ne s'affichera pas à l'écran. -* **body** est un élément qui contient tout le reste. Son contenu s'affichera à l'écran et constituera notre page web. +* **body** est un élément qui contient tout le reste. Son contenu s'affichera à l'écran et constituera notre page web. Nous utilisons `` pour transmettre la configuration de la page au navigateur tandis que `` l'informe sur le contenu de la page. -Par exemple, vous pouvez donner un titre à votre site en utilisant l'élément titre dans le `` : +Par exemple, vous pouvez donner un titre à votre page web en utilisant l'élément titre dans le `` : + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + - Le Blog d'Ola + Ola's blog -

Hi there!

-

It works!

+

Bonjour !

+

Ça marche !

``` Sauvegardez votre fichier et actualisez la page. -![Figure 11.3][3] - - [3]: images/step4.png +![Figure 11.3](images/step4.png) Vous avez vu comment le navigateur a compris que « Le Blog d'Ola » est le titre de votre page ? Il a interprété `Le blog d'Ola` et a placé ce texte dans la barre de titre de votre navigateur (c'est ce titre qui va être aussi utilisé lorsque vous créez un marque-page, etc.). @@ -93,117 +96,132 @@ Vous avez aussi probablement remarqué que chaque balise ouvrante possède sa *b Pensez à lorsque vous mettez des choses à l'intérieur de boîtes. Vous avez une grosse boîte, ``; à l'intérieur de celle-ci, on trouve une plus petite boîte, ``, qui contient elle-même d'autres petites boîtes, `

`. -Essayez de vous rappeler cet exemple lorsque vous utilisez les balises *fermantes* et que vous avez des éléments *imbriqués*. Si vous ne suivez pas ces règles, votre navigateur risque de ne pas être capable d'interpréter votre code correctement et risque de mal afficher votre page web. +Essayez de vous rappeler de cet exemple lorsque vous utilisez les balises *fermantes* et que vous avez des éléments *imbriqués*. Si vous ne suivez pas ces règles, votre navigateur risque de ne pas être capable d'interpréter votre code correctement et votre page web sera mal affichée. ## Personnaliser votre template Et si nous en profitions pour nous amuser un peu ? Essayons de personnaliser notre template ! Voici quelques balises que vous pouvez utiliser : -* `

Titre 1

` - pour vos titres les plus importants -* `

Titre 2

` - pour les sous-titres -* `

Titre 3

` ... et ainsi de suite jusqu'à `
` -* `texte` permet de mettre l'accent sur une partie du texte -* `texte` permet de mettre encore plus l'accent sur une partie de texte -* `
` permet d'insérer un saut de ligne (vous ne pouvez rien mettre à l'intérieur d'un élément br) -* `link` permet de créer un lien -* `
  • premier item
  • second item
` permet de créer des listes, comme celle que nous sommes en train de faire ! -* `
` permet de créer une section au sein de la page - -Voici un exemple de template utilisant plusieurs balises : +* `

Titre 1

` pour vos titres les plus importants +* `

Titre 2

` pour les sous-titres +* `

Titre 3

` ... et ainsi de suite jusqu'à `
` +* `

Un paragraphe contenant du texte

` +* `texte` permet de mettre l'accent sur une partie du texte +* `texte` permet de mettre encore plus l'accent sur une partie de texte +* `
` permet d'insérer un saut de ligne (vous ne pouvez rien mettre à l'intérieur d'un élément br et il n'y a pas de balise fermante) +* `link` permet de créer un lien +* `
  • premier item
  • second item
` permet de créer des listes, comme celle que nous sommes en train de faire ! +* `
` permet de créer une section au sein de la page +* `` définit un ensemble de liens de navigation +* `
` spécifie du contenu indépendant et autonome +* `
` définit une section dans un document +* `
` spécifie un en-tête pour un document ou une section +* `
` spécifie le contenu principal d'un document +* `` définit du contenu en dehors du contenu dans lequel il est placé (comme une barre latérale) +* `
` définit un pied de page pour un document ou une section +* `` définit un instant spécifique (ou un horodatage) + +Voici un exemple d’un modèle complet, copiez et collez-le dans `blog/templates/blog/post_list.html` : + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + - Django Girls blog + Blog Django Girls - +
+

Blog Django Girls

+
-
-

published: 14.06.2014, 12:14

-

My first post

+
+ +

Mon premier article

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

-

Mon second post

+
+ +

Mon second article

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.

-
+ ``` -Nous avons créé trois sections à l'aide de `div`. +Nous avons créé ici une section `en-tête` et deux sections `article`. -* Le premier `div` contient le titre de notre blog - c'est à la fois un titre et un lien -* Les deux autres `div` contiennent nos posts avec leur date de publication, un titre de post `h2` qui est cliquable ainsi que deux `p` (paragraphe) de texte : un pour la date et l'autre pour notre post. +* Le premier élément `header` contient le titre de notre blog - c'est à la fois un titre et un lien +* Les deux éléments `article` contiennent nos articles de blog avec une date de publication dans un élément `time` un élément `h2` avec un titre de publication qui est cliquable et un élément `p` (paragraphe) pour le texte de notre blog. Ce qui nous donne : -![Figure 11.4][4] - - [4]: images/step6.png +![Figure 11.4](images/step6.png) Yaaay ! Pour l'instant, notre template nous permet seulement d'afficher les **mêmes informations** alors que nous disions précédemment qu'il doit nous permettre d'afficher des informations **différentes** utilisant le **même format**. -Ce qu'on aimerait pouvoir maintenant, c'est afficher les posts que nous avons créés précédemment dans l'interface d'administration de Django. Penchons-nous là dessus. +Ce qu'on aimerait pouvoir faire maintenant, c'est d'afficher les posts que nous avons créés précédemment dans l'interface d'administration de Django. Penchons-nous là dessus. ## Une dernière chose : déployer ! -Ne serait-il pas génial de pouvoir voir tout ces changements en ligne ? Hop, déployons à nouveau ! +Ne serait-il pas génial de pouvoir voir tous ces changements en ligne ? Hop, déployons à nouveau ! ### Commiter et pusher votre code sur GitHub Tout d'abord, allons voir quels sont les fichiers qui ont changé depuis notre dernier déploiement (lancez ces commandes dans votre console locale et non celle de PythonAnywhere) : - $ git status +{% filename %}command-line{% endfilename %} + $ git status + -Assurez-vous que vous êtes bien dans le dossier `djangogirls`. Voici la commande qui permet de dire à `git` d'inclure tout les changements qui ont eu lieu dans ce dossier : +Assurez-vous d'être dans le dossier `djangogirls`. Voici la commande qui permet de dire à `git` d'inclure tout les changements qui ont eu lieu dans ce dossier : - $ git add --all . +{% filename %}command-line{% endfilename %} + $ git add . + -> **Note** `--all` (traduction de "tout") signifie que `git` va aussi analyser si vous avez supprimé des fichiers (par défaut, il ne s'intéresse qu'aux nouveaux fichiers ou à ceux modifiés). Essayez de vous rappeler du chapitre 3 : `.` permet de désigner le dossier courant. +Avant que nous puissions uploader nos fichiers, regardons ce que `git` à l'intention de faire (tous les fichiers que `git` va uploader vont apparaître en vert) : -Avant que nous puissions uploader nos fichiers, regardons ce que `git` à l'intention de faire (tous les fichiers que `git` va uploader vont apparaitre en vert) : +{% filename %}command-line{% endfilename %} $ git status - + On y est presque : nous devons maintenant lui dire de sauvegarder ces changements dans son historique. Nous allons y ajouter un "message de commit" qui nous permettra de décrire ce qui a été changé. Vous pouvez mettre ce que vous voulez dans un message de commit. Généralement, il est préférable de mettre quelque chose d'utile qui vous permettra de vous souvenir plus tard de ce que vous avez fait. - $ git commit -m "Modification du HTML du site" +{% filename %}command-line{% endfilename %} + $ git commit -m "Modification du HTML du site" + -> **Note** N'oubliez pas d'utiliser de doubles guillemets autour de votre message de commit. +> **Note** Assurez-vous d'utiliser des guillemets doubles autour du message de commit. Une fois que nous avons fait cela, nous pouvons mettre en ligne (pusher) nos modifications sur GitHub : - git push +{% filename %}command-line{% endfilename %} + $ git push + ### Puller les modifications sur PythonAnywhere et recharger son appli web -* Allez sur la page des [consoles de PythonAnywhere][5]. Retournez dans votre **console Bash** ou ouvrez-en une nouvelle puis tapez la commande suivante : +* Allez sur la page des [consoles de PythonAnywhere](https://www.pythonanywhere.com/consoles/). Retournez dans votre **console Bash** ou ouvrez-en une nouvelle puis tapez la commande suivante : - [5]: https://www.pythonanywhere.com/consoles/ +{% filename %}PythonAnywhere command-line{% endfilename %} - $ cd ~/my-first-blog - $ source myvenv/bin/activate - (myvenv)$ git pull - [...] - (myvenv)$ python manage.py collectstatic + $ cd ~/.pythonanywhere.com + $ git pull [...] + +N’oubliez pas de remplacer `` avec votre propre sous-domaine PythonAnywhere, sans les chevrons. Votre nom de sous-domaine est normalement votre nom d'utilisateur PythonAnywhere, mais dans certains cas, il peut être un peu différent (par exemple si votre nom d'utilisateur contient des lettres capitales). Donc, si cette commande ne fonctionne pas, utilisez la commande `ls` (lister fichiers) pour trouver votre sous-domaine/nom de dossier, puis `cd` jusque là. -Voilà ! Votre code modifié est téléchargé. Si vous voulez vérifier ce que vous venez de récupérer, vous pouvez aller jeter un coup d’œil dans l'onglet **Files** de PythonAnywhere. - -* Pour finir, n'oubliez pas de recharger votre application web : onglet [web][6] puis cliquez sur le bouton **Reload**. +Maintenant, vous voyez votre code en train d'être téléchargé. Si vous voulez vérifier que le nouveau code est arrivé sur PythonAnywhere, vous pouvez aller sur la page **"Files"** et y retrouver les fichiers (vous pouvez naviguer dans les différentes pages de PythonAnywhere depuis le menu). - [6]: https://www.pythonanywhere.com/web_app_setup/ +* Pour finir, n'oubliez pas de recharger votre application web : onglet [Web](https://www.pythonanywhere.com/web_app_setup/) puis cliquez sur le bouton **Reload**. -Retournez sur votre site en cliquant sur l'adresse en haut de la page : normalement, vous devriez voir la dernière version. Si ce n'est pas le cas, ce n'est pas grave : n'hésitez pas à demander de l'aide à votre coach :) +Retournez sur votre site en cliquant sur l'adresse en haut de la page : normalement, vous devriez voir la dernière version. Si ce n'est pas le cas, ce n'est pas grave : n'hésitez pas à demander de l'aider à votre coach. :) \ No newline at end of file diff --git a/fr/html/images/step1.png b/fr/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/fr/html/images/step1.png and b/fr/html/images/step1.png differ diff --git a/fr/html/images/step3.png b/fr/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/fr/html/images/step3.png and b/fr/html/images/step3.png differ diff --git a/fr/html/images/step4.png b/fr/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/fr/html/images/step4.png and b/fr/html/images/step4.png differ diff --git a/fr/html/images/step6.png b/fr/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/fr/html/images/step6.png and b/fr/html/images/step6.png differ diff --git a/fr/images/application.png b/fr/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/fr/images/application.png and b/fr/images/application.png differ diff --git a/fr/installation/README.md b/fr/installation/README.md index f8bc70df9c6..5caee69178d 100644 --- a/fr/installation/README.md +++ b/fr/installation/README.md @@ -1,38 +1,54 @@ # Si vous suivez ce tutoriel chez vous -Si vous suivez ce tutoriel chez vous et non dans un [évènement Django Girls](https://djangogirls.org/events/), vous pouvez passer directement au chapitre [Comment fonctionne l'Internet ?](../how_the_internet_works/README.md). +Si vous suivez ce tutoriel chez vous et non dans un [évènement Django Girls](https://djangogirls.org/events/), vous pouvez passer directement au chapitre [Comment fonctionne Internet](../how_the_internet_works/README.md). -Les informations données ici sont couvertes dans le reste du tutoriel. Cette partie permet simplement de regrouper au même endroit tout ce qu'il est nécessaire d'installer avant de participer à un évènement. Les évènements Django Girls incluent une "soirée d'installation" qui permet de prendre un peu d'avance sur la journée de formation proprement dite. - -Rien ne vous empêche de tout installer maintenant si vous le souhaitez. Cependant, si vous avez envie d'apprendre des choses avant d'installer plein de trucs sur votre ordinateur : passez ce chapitre et installez ce dont vous avez besoin au fil des chapitres. +La raison est que toutes les informations nécessaires aux installations seront données au fur et à mesure dans les différents chapitres du tutoriel. Celle-ci est juste une page supplémentaire qui rassemble toutes les instructions d’installation en un seul endroit (ce qui est utile pour certains formats d’atelier). Vous pouvez choisir d’installer tout ce qui est sur cette page dès maintenant si vous le souhaitez. Cependant, si vous avez envie d'apprendre des choses avant d'installer plein de trucs sur votre ordinateur : passez ce chapitre et installez ce dont vous avez besoin au fil des chapitres. Bonne chance ! +# Si vous participez à un atelier + +Si vous participez à un [événement Django Girls](https://djangogirls.org/events/) : + +* Dans certains cas un « party d’installation » a lieu avant l’atelier principal. Si vous vous trouvez à un party d’installation, cette page est pour vous ! Suivez les instructions ici pour installer tout ce dont vous avez besoin pour l’atelier. Demandez de l'aide aux coaches si nécessaire. Ensuite, pendant l'atelier vous pourrez ignorer les instructions d’installation que vous rencontrerez dans le tutoriel. +* Les organisateurs de votre atelier vous ont peut-être proposé de procéder aux installations chez vous. Si c'est le cas, cette page est pour vous ! Suivez les instructions ici, autant que vous le pouvez. Pendant l’atelier principal, quand vous arrivez à une étape nécessitant d'un logiciel que vous n'avez pas réussi à installer toute seule, vous pourrez demander à votre coach. +* Si votre atelier n’a pas de party d'installation (ou si vous l'avez raté), et si les organisateurs ne vous ont pas demandé d’essayer de tout installer en amont, ignorez cette page et allez directement au chapitre [Comment fonctionne Internet](../how_the_internet_works/README.md). Vous allez installer tout ce dont vous avez besoin au fur et à mesure que vous avancez dans le tutoriel. + # Installation -Pendant l'atelier, vous allez apprendre à construire un blog. Afin d'être prête pour le jour J, vous devrez installer les éléments listés sur cette page. +Dans ce tutoriel, vous allez apprendre comment créer un blog. Le tutoriel vous guidera à travers toute les étapes d'installation des différents logiciels, ansi que de création de comptes en ligne nécessaires. Cette page regroupe l’ensemble des instructions concernant installations et comptes en ligne en un seul endroit (ce qui est utile pour certains formats d’atelier). -# Installer Python + {% include "/chromebook_setup/instructions.md" %} -{% include "/python_installation/instructions.md" %} + -# Mettre en place virtualenv et installer Django +# Brève introduction à la ligne de commande {#command-line} -{% include "/django_installation/instructions.md" %} +Dans les étapes ci-dessous vous allez rencontrer les noms « console », « terminal », « invite de commande » ou « ligne de commande ». Tous ces termes signifient la même chose : une fenêtre sur votre ordinateur où vous pouvez rentrer des commandes. Une fois que vous aurez démarré le tutoriel principal, vous apprendrez plus sur la ligne de commande. Pour l’instant, le plus important est que vous appreniez à ouvrir un terminal et que vous voyez à quoi cela ressemble : +{% include "/intro_to_command_line/open_instructions.md" %} + +# Installer Python {#python} -# Installez un éditeur de code +{% include "/python_installation/instructions.md" %} + +# Installer un éditeur de code {#code-editor} {% include "/code_editor/instructions.md" %} -# Installer Git +# Mettre en place virtualenv et installer Django {#virtualenv} + +{% include "/django_installation/instructions.md" %} + +# Installer Git {#git} {% include "/deploy/install_git.md" %} -# Créer un compte GitHub +# Créer un compte GitHub {#github-account} -Allez sur [GitHub.com](https://www.github.com) et créez-vous un nouveau compte gratuitement. +Allez sur [GitHub.com](https://www.github.com) et créez un compte d’utilisateur gratuitement. N’oubliez pas votre mot de passe (ajoutez-le à votre gestionnaire de mots de passe, si vous utilisez un). -# Créer un compte PythonAnywhere +# Créer un compte PythonAnywhere {#pythonanywhere-account} {% include "/deploy/signup_pythonanywhere.md" %} @@ -40,10 +56,14 @@ Allez sur [GitHub.com](https://www.github.com) et créez-vous un nouveau compte Félicitations, vous avez tout installé et êtes prête ! Si vous avez toujours du temps avant l'atelier, il peut être utile de commencer à lire les premiers chapitres : - * [Comment fonctionne l'Internet ?](../how_the_internet_works/README.md) +* [Comment fonctionne Internet](../how_the_internet_works/README.md) + +* [Introduction à la ligne de commande](../intro_to_command_line/README.md) + +* [Introduction à Python](../python_introduction/README.md) - * [Introduction à la ligne de commande](../intro_to_command_line/README.md) +* [Qu'est-ce que Django?](../django/README.md) - * [Introduction à Python](../intro_to_command_line/README.md) +# Profitez de l’atelier ! - * [Qu'est-ce que Django?](../django/README.md) +Lors de l’atelier, vous serez en mesure d'attaquer directement le chapitre [Votre premier projet Django !](../django_start_project/README.md) parce que vous aurez déjà couvert le matériel dans les chapitres précédents. diff --git a/fr/intro_to_command_line/README.md b/fr/intro_to_command_line/README.md index 358d60a21c6..35ffffd6d99 100755 --- a/fr/intro_to_command_line/README.md +++ b/fr/intro_to_command_line/README.md @@ -1,6 +1,8 @@ # Introduction à l'interface en ligne de commande -C'est un peu exaltant, non ? Dans quelques instants, vous allez écrire votre première ligne de code :) +> Pour les lectrices à la maison : ce chapitre est traité dans la vidéo [Votre nouvel ami : la ligne de commande](https://www.youtube.com/watch?v=jvZLWhkzX-8). + +C'est un peu exaltant, non ? Dans quelques instants, vous allez écrire votre première ligne de code! :) **Commençons par vous présenter un nouvel ami : la ligne de commande !** @@ -16,85 +18,137 @@ Cette fenêtre, qu'on appelle aussi **ligne de commande** ou **interface en lign Pour commencer à expérimenter, nous avons d'abord besoin d'ouvrir notre interface en ligne de commande. -### Windows +{% include "/intro_to_command_line/open_instructions.md" %} -Aller dans Menu démarrer → Tous les programmes → Accessoires → Invite de commandes. +## Invite de commande -### Mac OS X +Vous devriez maintenant voir une fenêtre noire ou blanche qui attend vos commandes. -Applications → Utilitaires → Terminal. + -### Linux +Si vous êtes sous Mac ou Linux, vous verrez probablement un `$`, comme ça : -Vous la trouverez probablement dans Applications → Accessoires → Terminal, mais ça dépend de votre système. Si elle n'est pas là, demandez à Google :) +{% filename %}command-line{% endfilename %} -## Prompt + $ + -Vous devriez maintenant voir une fenêtre noire ou blanche qui attend vos commandes. + -Si vous être sous Mac ou Linux, vous verrez probablement un `$`, comme ça : + - $ +Si vous êtes sous Windows, vous verrez probablement un `>`, comme ça : - -Sur Windows, c'est un signe `>`, comme ça : +{% filename %}command-line{% endfilename %} > + + +Jetez un coup d'œil à la section Linux ci-dessus : c'est à cela que la ligne de commande ressemblera une fois que vous serez sur PythonAnywhere. + + + +Chaque commande que vous taperez sera automatiquement précédée par un `$` ou `>` et une espace. Vous ne devez pas les rentrer vous-même, votre ordinateur le fera pour vous. :) +> Petite remarque : il se peut que vous voyiez quelque chose comme `C:\Users\ola>` ou `Olas-MacBookAir:~ola$` avant le signe de prompt. Pas de problème : c'est parfaitement normal. -Chaque commande commence par ce signe, puis un espace. Mais vous n'avez pas besoin de le taper, votre ordinateur le fait pour vous :) +La partie jusque et y compris le `$` ou le `>` est appelée *l’invite de commande*, ou *prompt* (en anglais) pour faire court. Elle vous invite à entrer une commande. -> Petite remarque : il se peut que vous voyiez quelque chose comme `C:\Users\ola>` ou `Olas-MacBookAir:~ola$` avant le signe de prompt. Pas de problème : c'est parfaitement normal. C'est juste parce que dans ce tutoriel, nous tentons de simplifier les choses autant que possible. +Dans le tutoriel, lorsque nous voulons que vous tapiez une commande, nous allons inclure le `$` ou `>` et parfois d'autres information juste avant, à sa gauche. Ignorez cette partie à gauche et tapez uniquement la commande, qui commence après l’invite. ## Votre première commande (YAY !) -Commençons par quelque chose de simple. Tapez la commande suivante : +Commençons en tapant cette commande : + + + +{% filename %}command-line{% endfilename %} $ whoami + + -ou + + +{% filename %}command-line{% endfilename %} > whoami + + + +Puis appuyez sur la touche `entrée`. Voilà ce qui s'affiche chez moi : -Puis, appuyez sur la touche `entrée`. Voilà ce qui s'affiche chez moi : +{% filename %}command-line{% endfilename %} $ whoami olasitarska + - -Comme vous pouvez le voir, l'ordinateur vient d'afficher votre nom d'utilisateur. Sympa, non ? ;) +Comme vous pouvez le voir, l'ordinateur vient d'afficher votre nom d'utilisateur. Sympa, non ? ;) > Essayez de taper chaque commande sans copier-coller. Ça aide à les retenir ! ## Les bases -Les différents systèmes d'exploitation ont des commandes légèrement différentes, donc faites attention à suivre les instructions pour votre système d'exploitation. Allons-y ! +Les différents systèmes d'exploitation ont des commandes légèrement différentes, donc faites attention à suivre les instructions pour votre système d'exploitation. Allons-y ! ### Dossier courant -Ce serait pratique de savoir dans quel répertoire nous nous trouvons. Pour le savoir, tapez la commande suivante et appuyez sur `entrée` : +Ce serait pratique de savoir dans quel répertoire nous nous trouvons. Pour le savoir, tapez la commande suivante et appuyez sur `entrée` : + + + +{% filename %}command-line{% endfilename %} $ pwd /Users/olasitarska + + +> Remarque : « pwd » veut dire « print working directory » (afficher le dossier courant). + -Si vous êtes sous Windows : + + +{% filename %}command-line{% endfilename %} > cd C:\Users\olasitarska + +> Note : « cd » signifie « changer répertoire ». Avec PowerShell vous pouvez utiliser pwd comme sur Linux ou Mac OSX. -Vous verrez probablement quelque chose de similaire sur votre machine. Quand vous ouvrez une ligne de commande, vous démarrez habituellement dans le dossier personnel de votre utilisateur. + -> Remarque : "pwd" veut dire "print working directory" (afficher le dossier courant). +Vous verrez probablement quelque chose de similaire sur votre machine. Quand vous ouvrez une ligne de commande, vous démarrez habituellement dans le dossier personnel de votre utilisateur. * * * +### En savoir plus sur une commande + +De nombreuses commandes que vous pouvez taper à l’invite de commande ont une aide intégrée que vous pouvez afficher et lire ! Par exemple, pour en savoir plus sur le répertoire actuel : + + + +macOS et Linux ont une commande `man`, qui donne des informations sur les commandes. Essayez `man pwd` et regardez ce qui s'affiche, ou ajoutez `man` devant une autre commande pour voir sa documentation. La sortie de `man` est normalement paginée. Utilisez la barre d’espace pour passer à la page suivante et `q` pour quitter l’aide. + + + + + +Ajouter un `/ ?` à la fin de la commande devrait également permettre d'afficher la page d’aide. Vous devrez peut-être faire défiler votre fenêtre de commande vers le haut pour tout voir. Essayez `cd / ?`. + + + ### Lister les fichiers et les dossiers -Du coup, que pouvons-nous trouver dans ce dossier personnel ? Pour le savoir, essayons ceci : +Du coup, que pouvons-nous trouver dans ce dossier personnel ? Voyons voir : + + + +{% filename %}command-line{% endfilename %} $ ls Applications @@ -102,90 +156,147 @@ Du coup, que pouvons-nous trouver dans ce dossier personnel ? Pour le savoir, es Musique Téléchargements ... + + + + -Windows : +{% filename %}command-line{% endfilename %} > dir Directory of C:\Users\olasitarska - 05/08/2014 07:28 PM Applications - 05/08/2014 07:28 PM Bureau - 05/08/2014 07:28 PM Musique - 05/08/2014 07:28 PM Téléchargements + 05/08/2020 07:28 PM Applications + 05/08/2020 07:28 PM Bureau + 05/08/2020 07:28 PM Téléchargements + 05/08/2020 07:28 PM Musique ... + +> Remarque : Dans PowerShell, vous pouvez également utiliser "ls" comme sur Linux et macOS. * * * ### Changer le dossier courant -Maintenant, essayons d'aller sur notre bureau : +Maintenant, essayons d'aller sur notre Bureau : + + + +{% filename %}command-line{% endfilename %} $ cd Bureau + + -Windows : + + +{% filename %}command-line{% endfilename %} + + $ cd Bureau + + +Notez que le nom du répertoire « Bureau » pourrait être traduit dans la langue de votre compte Linux. Si c'est le cas, vous devrez remplacer `Bureau` par sa traduction. Par exemple, `Schreibtisch` pour l’allemand ou <0>Desktop pour l'anglais. + + + + + +{% filename %}command-line{% endfilename %} > cd Bureau + + + +Vérifions que ça a bien changé : -Vérifions que ça a bien changé : + + +{% filename %}command-line{% endfilename %} $ pwd /Users/olasitarska/Bureau + + + + -Windows : +{% filename %}command-line{% endfilename %} > cd C:\Users\olasitarska\Bureau + + -Et voilà ! +Et voilà ! -> Pro tip : si vous tapez `cd B` puis que vous appuyez sur la touche `tabulation`, la ligne de commande va automatiquement compléter le reste du nom. Cela va vous permettre d'aller plus vite et d'éviter des fautes de frappe. Si plusieurs dossiers commencent par un « B », appuyez sur `tabulation` deux fois pour avoir une liste des options. +> Pro tip : si vous tapez `cd B` puis que vous appuyez sur la touche `tabulation`, la ligne de commande va automatiquement compléter le reste du nom. Cela va vous permettre d'aller plus vite et d'éviter des fautes de frappe. Si plusieurs dossiers commencent par un « B », appuyez sur la touche `tabulation` deux fois pour avoir une liste des options. * * * ### Créer un dossier -Que diriez-vous de créer un répertoire dédié aux exercices sur votre bureau ? Vous pouvez le faire de cette façon : +Que diriez-vous de créer un répertoire dédié aux exercices sur votre bureau ? Vous pouvez le faire de cette façon : + + + +{% filename %}command-line{% endfilename %} $ mkdir exercices + + -Windows : + + +{% filename %}command-line{% endfilename %} > mkdir exercices + + -Cette petite commande crée un dossier nommé `exercices` sur votre bureau. Vous pouvez vérifier qu'il est bien là en regardant votre bureau, ou en lançant la commande `ls` ou `dir` ! Essayez donc :) +Cette petite commande crée un dossier nommé `exercices` sur votre bureau. Vous pouvez vérifier qu'il est bien là en regardant votre Bureau, ou en lançant la commande `ls` ou `dir` ! Essayez donc. :) -> Pro tip : Si vous voulez éviter de taper les mêmes commandes plein de fois, essayez d'appuyer sur les touches `flèche haut` et `flèche bas` pour retrouver les dernières commandes que vous avez tapé. +> Pro tip : Si vous voulez éviter de taper les mêmes commandes plein de fois, essayez d'appuyer sur les touches `flèche haut` et `flèche bas` pour retrouver les dernières commandes que vous avez tapées. * * * -### Un peu d'exercice ! +### Exercice ! -Petit défi pour vous : dans votre nouveau dossier `exercices`, créez un dossier appelé `test`. Pour ça, utilisez les commandes `cd` et `mkdir`. +Un petit défi pour vous : dans votre nouveau dossier `exercices`, créez un dossier appelé `test`. (Pour ça, utilisez les commandes `cd` et `mkdir`.) #### Solutions : + + +{% filename %}command-line{% endfilename %} + $ cd exercices $ mkdir test $ ls test + + + + -Windows : +{% filename %}command-line{% endfilename %} > cd exercices > mkdir test > dir - 05/08/2014 07:28 PM test + 05/08/2020 07:28 PM test + + -Félicitations ! :) +Félicitations ! :) * * * @@ -193,88 +304,138 @@ Félicitations ! :) Supprimons tout ce qu'on vient de faire, histoire d'éviter de laisser du bazar. -D'abord, revenons au Bureau : +D'abord, revenons au Bureau : + + + +{% filename %}command-line{% endfilename %} $ cd .. + + -Windows : + + +{% filename %}command-line{% endfilename %} > cd .. + + + +Grâce à `...` et la commande `cd`, vous pouvez aller directement dans le dossier parent de votre répertoire courant (c'est-à-dire le dossier qui contient le dossier dans lequel vous étiez). +Vérifiez où vous êtes : -Grâce à `..` et la commande `cd`, vous pouvez aller directement dans le dossier parent de votre répertoire courant (c'est à dire le dossier qui contient le dossier dans lequel vous étiez). + -Vérifiez où vous êtes : +{% filename %}command-line{% endfilename %} $ pwd /Users/olasitarska/Bureau + + -Windows : + + +{% filename %}command-line{% endfilename %} > cd C:\Users\olasitarska\Bureau + + -Maintenant, il est temps de supprimer notre dossier `exercices` : +Maintenant, il est temps de supprimer le dossier `exercices` : > **Attention** : Supprimer des fichiers avec `del`, `rmdir` ou `rm` est irrévocable, ce qui veut dire que *les fichiers supprimés sont perdus à jamais* ! Du coup, faites très attention avec cette commande. + + +{% filename %}command-line{% endfilename %} + $ rm -r exercices + + + + -Windows : +{% filename %}command-line{% endfilename %} > rmdir /S exercices exercices, Are you sure ? Y + + -Et voilà. Pour être sure que le dossier a bien été supprimé, vérifiez : +Et voilà ! Pour être sure que le dossier a bien été supprimé, vérifions : + + + +{% filename %}command-line{% endfilename %} $ ls + + -Windows : + + +{% filename %}command-line{% endfilename %} > dir + + ### Sortir -C'est tout pour le moment ! Vous pouvez maintenant fermer la ligne de commande. Faisons-le à la manière des bidouilleurs⋅euses. :) +C'est tout pour le moment ! Vous pouvez maintenant fermer la ligne de commande. Faisons-le à la manière des bidouilleurs⋅euses, d’accord ? :) + + + +{% filename %}command-line{% endfilename %} $ exit + + + + -Windows : +{% filename %}command-line{% endfilename %} > exit + + -Cool, non ? :) +Cool, non ? :) ## Résumé -Voici un résumé de quelques commandes utiles : - -| Commande (Windows) | Commande (Mac OS / Linux) | Description | Exemple | -| ------------------ | ------------------------- | --------------------------- | ------------------------------------------------- | -| exit | exit | ferme la fenêtre | **exit** | -| cd | cd | change le dossier courant | **cd test** | -| dir | ls | liste des fichiers/dossiers | **dir** | -| copy | cp | copie un fichier | **copy c:\test\test.txt c:\windows\test.txt** | -| move | mv | déplace un fichier | **move c:\test\test.txt c:\windows\test.txt** | -| mkdir | mkdir | crée un nouveau dossier | **mkdir testdirectory** | -| del | rm | supprime un dossier/fichier | **del c:\test\test.txt** | +Voici un résumé de quelques commandes utiles : + +| Commande (Windows) | Commande (macOS / Linux) | Description | Exemple | +| ------------------ | ------------------------ | -------------------------------- | ------------------------------------------------- | +| exit | exit | ferme la fenêtre | **exit** | +| cd | cd | change le dossier courant | **cd test** | +| cd | pwd | montre le dossier courant | **cd** (Windows) ou **pwd** (macOS / Linux) | +| dir | ls | liste des fichiers/dossiers | **dir** | +| copy | cp | copie un fichier | **copy c:\test\test.txt c:\windows\test.txt** | +| move | mv | déplace un fichier | **move c:\test\test.txt c:\windows\test.txt** | +| mkdir | mkdir | crée un nouveau dossier | **mkdir testdirectory** | +| rmdir (or del) | rm | supprime un fichier | **del c:\test\test.txt** | +| rmdir /S | rm -r | supprime un répertoire | **rm -r testdirectory** | +| [CMD] /? | man [CMD] | affiche l'aide pour une commande | **cd /?** (Windows) ou **man cd** (macOS / Linux) | Ce ne sont que quelques-unes des commandes que vous pouvez utiliser dans votre ligne de commande. Cette liste est suffisante pour réaliser ce tutoriel. -Si vous êtes curieuse, [ss64.com][1] contient une référence complète de toutes les commandes pour tous les systèmes d'exploitation. - - [1]: http://ss64.com +Si vous êtes curieuse, [ss64.com](http://ss64.com) contient une référence complète de toutes les commandes pour tous les systèmes d'exploitation. ## Vous êtes prête ? -Nous allons plonger dans Python ! +Plongeons dans Python ! \ No newline at end of file diff --git a/fr/intro_to_command_line/open_instructions.md b/fr/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..9478a39c7a6 --- /dev/null +++ b/fr/intro_to_command_line/open_instructions.md @@ -0,0 +1,29 @@ + + + +Une des procédures suivantes, selon votre version de Windows et votre clavier, devrait vous permettre d'ouvrir l'invite de commande (il est possible que vous deviez vous débrouiller un peu jusqu'à ce que vous trouvez la bonne) : + +- Allez dans le menu ou écran de démarrage et tapez "Invite de commande" dans l'outil de recherche. +- Cliquez sur le Menu démarrer→ Système Windows → Invite de commandes. +- Aller dans Menu démarrer → Tous les programmes → Accessoires → Invite de commandes. +- Allez sur l’écran de démarrage, passez votre souris dans le coin inférieur gauche de l’écran et cliquez sur la flèche qui s’affiche (sur un écran tactile, plutôt balayer du bas vers le haut de l’écran). La page Apps doit s’ouvrir. Cliquez sur invite de commandes dans la section Système Windows. +- Maintenez la touche Windows enfoncée et appuyez sur la touche « X » de votre clavier. Choisissez « Invite de commandes » dans le menu contextuel. +- Maintenez la touche Windows enfoncée et appuyez sur la touche « R » pour ouvrir une fenêtre « Exécuter ». Tapez « cmd », puis cliquez sur la touche OK. + +![Tapez "cmd" dans la fenêtre "Exécuter"](../python_installation/images/windows-plus-r.png) + +Plus loin dans ce tutoriel, vous aurez besoin de deux fenêtres ouvertes en même temps. Toutefois, sur certaines versions de Windows, si vous avez déjà une fenêtre de commande ouverte et que vous essayez d’en ouvrir une seconde utilisant la même méthode, vous serez renvoyées vers la fenêtre de commande que vous avez déjà ouvert. Essayez-le maintenant sur votre ordinateur pour voir ce qui se passe ! Si vous obtenez seulement une fenêtre de commande, essayez l’une des autres méthodes dans la liste ci-dessus. Au moins une d'entre elles devrait vous donner une nouvelle fenêtre de commande. + + + + + +Allez sur Applications → Utilitaires → Terminal. + + + + + +C’est probablement sous Applications → Accessoires → Terminal ou Applications → Système → Terminal, mais cela peut dépendre de votre système. Si toujours rien, vous pouvez demander à Google. :) + + diff --git a/fr/python_installation/README.md b/fr/python_installation/README.md index 47e71cbd43a..dd80800b48e 100755 --- a/fr/python_installation/README.md +++ b/fr/python_installation/README.md @@ -4,10 +4,12 @@ On est parti ! Tout d'abord, laissez-nous vous en dire un peu plus sur Python. Python est un langage de programmation très populaire qui peut être utilisé pour créer des sites web, des jeux, des logiciels scientifiques, des graphiques et bien d'autres choses encore. -Python a été créé à la fin des années 1980. l'objectif principal des créateurs du langage était de rendre ce langage de programmation lisible aussi bien par des humains que par des machines. Par conséquent, il a l'air beaucoup plus simple à lire que d'autres langages de programmation. Cependant, ne vous fiez pas à son apparente simplicité de lecture et d'apprentissage : Python est un langage très puissant ! +Python a été créé à la fin des années 1980. l'objectif principal des créateurs du langage était de rendre ce langage de programmation lisible aussi bien par des humains que par des machines. C'est pourquoi il semble plus simple que les autres langages de programmation, mais ne vous inquiétez pas - Python est aussi extrêmement puissant ! # Installation de Python -> **Note** : Si vous avez suivi la partie installation du tutoriel, vous n'avez pas besoin d'installer Python à nouveau. Vous pouvez sauter cette partie et passer au chapitre suivant ! +> **Note** Si vous utilisez un Chromebook, passez ce chapitre et prenez soin de suivre les instructions de [configuration pour Chromebook](../chromebook_setup/README.md). +> +> **Note **Si vous avez déjà effectué [l'Installation](../installation/README.md) vous devriez déjà avoir fait ce qui suit. Vous pouvez donc passer directement au chapitre suivant ! {% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/fr/python_installation/images/add_python_to_windows_path.png b/fr/python_installation/images/add_python_to_windows_path.png index 9510d6f2176..3266efb6177 100644 Binary files a/fr/python_installation/images/add_python_to_windows_path.png and b/fr/python_installation/images/add_python_to_windows_path.png differ diff --git a/fr/python_installation/images/python-installation-options.png b/fr/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..a0a6c65d81d Binary files /dev/null and b/fr/python_installation/images/python-installation-options.png differ diff --git a/fr/python_installation/images/windows-plus-r.png b/fr/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/fr/python_installation/images/windows-plus-r.png differ diff --git a/fr/python_installation/instructions.md b/fr/python_installation/instructions.md index c10c2d6b4c4..e93ce5efddd 100644 --- a/fr/python_installation/instructions.md +++ b/fr/python_installation/instructions.md @@ -1,66 +1,117 @@ -> Note : ce sous-chapitre est en partie inspiré d'un autre tutoriel réalisé par les Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) +> Pour les lecteur·rices autodidactes (et qui n'ont pas de soucis avec l'anglais) : Ce chapitre est traité dans la vidéo [Installing Python & Code Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA). +> +> Cette section repose sur un tutoriel de Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) -Django est écrit en Python. Pour réaliser quelque chose en Django, il va nous falloir Python. Commençons par installer ce dernier ! Pour ce tutoriel, nous utilisons la version 3.4 de Python. Si vous avez une version antérieure, il va falloir la mettre à jour. +Django est écrit en Python. Pour réaliser quelque chose en Django, il va nous falloir Python. Commençons par l'installer ! Pour suivre ce tutoriel, l'idéale est d'installer la dernière version de Python 3. Si vous avez une version antérieure, il va falloir la mettre à jour. Si vous avez déjà la version {{ book.py_min_version }} ou supérieure, ça devrait aller. -### Windows +Veuillez installer Python comme suit, même si vous avez déjà installé Anaconda sur votre ordinateur. -Vous pouvez télécharger Python pour Windows sur le site web https://www.python.org/downloads/release/python-343/. Après avoir téléchargé le fichier ***.msi**, lancez-le en double-cliquant sur son icône et suivez les instructions qui s'affichent à l'écran. Attention : il est important de se souvenir du chemin d'accès (le dossier) où vous avez installé Python. Vous en aurez besoin plus tard. + -Une chose à laquelle vous devez faire attention : dans le second écran de l'installateur intitulé "Customize", assurez-vous de bien dérouler l'écran jusqu'en bas et de choisir l'option "Ajouter python.exe au chemin", comme sur l'image ci dessous : +Vérifiez d'abord si votre ordinateur exécute une version 32 bits ou une version 64 bits de Windows, en cherchant "Type du système" dans la page d'information système. Pour accéder à cette page, essayez l'une de ces méthodes : -![N'oubliez pas d'ajouter Python à votre chemin (path)](../python_installation/images/add_python_to_windows_path.png) +* Appuyez sur la touche Windows et la touche Pause/Attn en même temps +* Ouvrez votre panneau de configuration depuis le menu Windows, puis naviguez vers Système et sécurité, puis Système +* Appuyez sur la touche Windows, puis accédez à Paramètres > Système > A propos +* Recherchez dans le menu Démarrer Windows le raccourci "Informations système". Pour ce faire, cliquez sur le bouton Démarrer ou appuyez sur la touche Windows, puis commencez à taper `Informations système`. Des entrées correspondantes apparaîtrons dès que vous tapez. Vous pouvez sélectionner l'entrée une fois qu'elle apparaît. -### Linux +Vous pouvez télécharger Python pour Windows depuis le site web https://www.python.org/downloads/windows/. Cliquez sur le lien "Latest Python 3 Release - Python x.x.x". Si votre ordinateur exécute une version **64-bit** de Windows, téléchargez l'installateur exécutable **Windows x86-64 executable installer**. Sinon, téléchargez **Windows x86 executable installer**. Après avoir téléchargé l'installateur, vous devriez l'exécuter (double-cliquez dessus) et suivre les instructions. + +Une chose à surveiller : lors de l’installation, vous remarquerez une fenêtre marquée « Setup ». Assurez-vous de cocher la case "Add Python {{ book.py_version }} to PATH" ou "Add Python to your environment variables" et cliquez sur "Install Now", comme indiqué ici (cela peut s'afficher un peu différemment si vous installez une autre version): + +![N'oubliez pas d'ajouter Python à votre chemin (path)](../python_installation/images/python-installation-options.png) + +Une fois l’installation terminée, vous verrez une boîte de dialogue contenant un lien que vous pouvez suivre pour en savoir plus sur Python ou sur la version que vous avez installée. Fermez ou annulez cette boîte de dialogue -- vous en apprendrez plus dans ce tutoriel ! + +Note : Si vous utilisez une ancienne version de Windows (7, Vista, ou n'importe quelle version antérieure) et l'installateur Python {{ book.py_version }} échoue avec une erreur, alors installez toutes les mises à jour Windows et essayez d'installer Python à nouveau. Si vous avez toujours l'erreur, essayez d'installer la version {{ book.py_min_release }} de Python depuis [Python.org](https://www.python.org/downloads/windows/). + +> Django {{ book.django_version }} a besoin de Python {{ book.py_min_version }} ou plus récent, qui n'est pas pris pas en charge par Windows XP ou les versions précédentes. + + + + + +> **Note** Avant d'installer Python sur macOS, vous devriez vous assurer que vos paramètres Mac permettent d'installer des programmes qui ne proviennent pas de l'App Store. Allez dans Préférences Système (c'est dans le dossier Applications), cliquez sur "Sécurité & Confidentialité", puis sur l'onglet "Général". Si votre "Autoriser les applications téléchargées de:" est défini sur "Mac App Store", changez-le à "Mac App Store et développeurs identifiés". + +Vous devez aller sur le site https://www.python.org/downloads/ et télécharger l'installateur python: + +* Téléchargez le fichier *macOS installer*, +* Double-cliquez sur le fichier *python-{{ book.py_release }}-macos11.pkg* pour lancer l'installateur. + + + + Il est très probable que Python soit déjà installé sur votre machine. Afin de vérifier qu'il est bien installé (et surtout quelle version vous avez), ouvrez une console et tapez la commande suivante : +{% filename %}ligne de commande{% endfilename %} + $ python3 --version - Python 3.4.3 + Python {{ book.py_release }} -Si Python n'est pas installé ou que vous avez une version différente, vous pouvez l'installer en suivant les instructions suivantes : - -#### Debian ou Ubuntu +Si vous avez une version différente de Python installée, au moins {{ book.py_min_version }} (par exemple {{ book.py_min_release }}), vous n'avez pas besoin de mettre à jour Python. Si Python n'est pas installé, ou si vous voulez une version différente, vérifiez d'abord la distribution Linux que vous utilisez avec la commande suivante : -Tapez cette commande dans votre terminal : +{% filename %}command-line{% endfilename %} - $ sudo apt-get install python3.4 + $ grep '^NAME=' /etc/os-release -#### Fedora (jusqu'à la version 21) +Ensuite, selon le résultat, suivez l'un des guides d'installation sous cette section. + + + + Tapez cette commande dans votre terminal : - $ sudo yum install python3.4 +{% filename %}ligne de commande{% endfilename %} + + $ sudo apt install python3 -#### Fedora (22+) + + + Tapez cette commande dans votre terminal : - $ sudo dnf install python3.4 +{% filename %}ligne de commande{% endfilename %} + + $ sudo dnf install python3 -#### openSUSE +Si vous utilisez une ancienne version de Fedora, vous pourriez avoir une erreur disant que la commande `dnf` n'est pas trouvée. Dans ce cas, vous devez utiliser la commande `yum` à la place. -Tapez cette commande dans votre terminal : + - $ sudo zypper install python3 + +Tapez cette commande dans votre terminal : -### OS X +{% filename %}ligne de commande{% endfilename %} -Vous devez aller sur le site https://www.python.org/downloads/release/python-343/ et télécharger l'installateur Python : + $ sudo zypper install python3 + - * Téléchargez le fichier *Mac OS X 64-bit/32-bit installer*, - * Double-cliquez sur le fichier *python-3.4.3-macosx10.6.pkg* pour lancer l'installateur. + -Vérifiez que l'installation s'est bien déroulée en ouvrant votre *Terminal* et en lançant la commande `python3`: +Vérifiez que l'installation s'est bien déroulée en ouvrant votre terminal et en lançant la commande `python3`: + +{% filename %}ligne de commande{% endfilename %} $ python3 --version - Python 3.4.3 + Python {{ book.py_release }} +La version affichée peut être différente de {{ book.py_release }} -- elle devrait correspondre à la version que vous avez installée. + +**NOTE:** Si vous êtes sur Windows et que vous obtenez un message d'erreur disant que `python3` n'a pas été trouvé, essayez d'utiliser `python` (sans `3`) et vérifiez si elle lance une version de Python {{ book.py_min_version }} ou ultérieure. Si cela ne fonctionne pas non plus, vous pouvez ouvrir une nouvelle ligne de commande et réessayer ; cela se produit si vous utilisez une fenêtre de ligne de commande datant d'avant l'installation de Python. + * * * -Si vous avez des questions ou si quelque chose ne fonctionne pas et que vous ne savez pas quoi faire : demandez de l'aide à votre coach ! Il arrive parfois que les choses ne se déroulent pas comme prévu et il est alors préférable de demander à quelqu'un qui a plus d'expérience. +Si vous avez des questions ou si quelque chose ne fonctionne pas et que vous ne savez pas quoi faire : demandez de l'aide à votre coach ! Il arrive parfois que les choses ne se déroulent pas comme prévu et il est alors préférable de demander à quelqu'un qui a plus d'expérience. \ No newline at end of file diff --git a/fr/python_introduction/README.md b/fr/python_introduction/README.md index 4e454f5c6e3..a6a8c3b52a2 100755 --- a/fr/python_introduction/README.md +++ b/fr/python_introduction/README.md @@ -1,57 +1,77 @@ +{% set warning_icon = '' %} + # Introduction à Python -> Note : ce chapitre est en partie inspiré d'un autre tutoriel réalisé par les Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> Une partie de ce chapitre s’inspire du tutoriel des Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). Allons écrire du code ! ## Le prompt Python -Pour commencer à jouer avec Python, nous avons besoin d'ouvrir une *ligne de commande* sur votre ordinateur. Normalement, vous savez déjà comment le faire -- vous l'avez appris dans le chapitre [Introduction à la ligne de commande][1]. +> Pour les lecteurs à la maison: cette partie est couverte dans la vidéo [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U) . - [1]: ../intro_to_command_line/README.md +Pour commencer à jouer avec Python, nous avons besoin d'ouvrir une *ligne de commande* sur votre ordinateur. Normalement, vous savez déjà comment le faire – vous l'avez appris dans le chapitre [Introduction à la ligne de commande](../intro_to_command_line/README.md). Dès que vous êtes prête, suivez les instructions suivantes. Afin d'ouvrir une console Python, tapez `python` sous Windows ou `python3` sous Mac OS/Linux et appuyez sur `entrée`. -```python -$ python3 -Python 3.4.3 (...) -Type "help", "copyright", "credits" or "license" for more information. ->>> -``` +{% filename %}command-line{% endfilename %} + + $ python3 + Python {{ book.py_release }} (...) + Type "help", "copyright", "credits" or "license" for more information. + >>> + ## Votre première commande Python ! -Après avoir lancé la commande Python, votre prompt (ou invite de commandes) s'est changé en `>>>`. Cela signifie que maintenant, les seules commandes que nous pouvons taper sont dans le langage Python. Vous n'avez pas besoin de taper `>>>` - Python fait ça pour vous. +Après avoir lancé la commande Python, votre prompt (ou invite de commandes) a changé en `>>>`. Cela signifie que maintenant, les seules commandes que nous pouvons taper sont des commandes appartenant au langage Python. Vous n'avez pas besoin de taper `>>>` - Python fait ça pour vous. + +Si vous voulez quitter la console Python, tapez `exit()` ou utilisez le raccourci `Ctrl + Z` pour Windows ou `Ctrl + D` pour Mac/Linux. Après ça, vous ne verrez plus le `>>>`. -Quand vous voudrez sortir de la console Python, tapez `exit()` ou utilisez le raccourci `Ctrl + Z` pour Windows ou `Ctrl + D` pour Mac/Linux. Après ça, vous ne verrez plus le `>>>`. +Pour l'instant, nous ne voulons pas quitter la console Python. Nous voulons en savoir plus. Commençons par écrire quelques operations mathématiques, comme `2 + 3` suivi par la touche `entrée`. -Pour le moment, nous ne voulons pas quitter la console Python car nous nous aimerions mieux la connaitre. Démarrons avec quelque chose de vraiment simple. Par exemple, faisons un peu de math : tapez `2 + 3` et appuyez sur `entrée`. +{% filename %}command-line{% endfilename %} ```python >>> 2 + 3 5 ``` -Pas mal ! Vous voyez comment la réponse est sortie ? Python sait faire des maths ! Vous pouvez essayer d'autres commandes comme : - `4 * 5` - `5 - 1` - `40 / 2` +Pas mal, non ? Vous avez vu comment la réponse a surgi ? Python s'y connait en math ! Vous pouvez essayer d’autres commandes comme : -Amusez-vous un peu avec ça, et revenez ici après :). +- `4 * 5` +- `5 - 1` +- `40 / 2` + +Pour effectuer un calcul exponentiel, disons 2 à la puissance 3, nous tapons : {% filename %}ligne de commande{% endfilename %} + +```python +>>> 2 ** 3 +8 +``` -Comme vous pouvez le constater, Python est une très bonne calculette. Comme vous vous en doutez, il est aussi capable de faire autre chose ... +Amusez-vous un peu avec ça, et revenez ici après. :) -## Chaînes de caractères (Strings) +Comme vous pouvez le constater, Python est une très bonne calculette. Comme vous vous en doutez, il est aussi capable de faire autre chose… + +## Chaines de caractères (Strings) Et si nous essayions avec votre nom ? Tapez votre prénom entre guillemets, comme cela : +{% filename %}command-line{% endfilename %} + ```python >>> "Ola" 'Ola' ``` -Vous venez de créer votre première chaîne de caractères ! C'est une suite de caractères qui peut être traitée par un ordinateur. Une chaîne de caractères doit toujours commencer et terminer par le même caractère. Cela peut être un guillemet simple (`'`) ou un guillemet double (`"`), ça n'a pas d'importance. Cela permet à Python de savoir que tout ce qui se trouve à l'intérieur de ces guillemets est une chaîne de caractères. +Vous venez de créer votre première chaîne de caractères ! C'est une suite de caractères qui peut être traitée par un ordinateur. Une chaine de caractères doit toujours commencer et terminer par le même caractère. Çela peut être un guillemet simple (`'`) ou un guillemet double (`"`), ça n'a pas d'importance. Cela permet à Python de savoir que tout ce qui se trouve à l'intérieur de ces guillemets est une chaîne de caractères. -Il est possible d'assembler des chaînes de caractères comme ceci : +Il est possible d'assembler des chaines de caractères comme ceci : + +{% filename %}command-line{% endfilename %} ```python >>> "Salut " + "Ola" @@ -60,21 +80,27 @@ Il est possible d'assembler des chaînes de caractères comme ceci : Vous pouvez aussi multiplier une chaîne de caractères par un nombre : +{% filename %}command-line{% endfilename %} + ```python >>> "Ola" * 3 'OlaOlaOla' ``` -Si vous avez besoin de mettre une apostrophe dans votre chaîne de caractères, vous avez deux possibilités. +Si vous avez besoin de mettre une apostrophe dans votre chaine de caractères, vous avez deux possibilités. Vous pouvez utiliser des guillemets doubles : +{% filename %}command-line{% endfilename %} + ```python >>> "J'aime la mousse au chocolat" "J'aime la mousse au chocolat" ``` -ou échapper l’apostrophe avec une barre oblique inversée (un backslash, `\`) : +ou échapper l’apostrophe avec une barre oblique inversée (un backslash, `\`) : + +{% filename %}command-line{% endfilename %} ```python >>> 'J\'aime la mousse au chocolat' @@ -83,37 +109,43 @@ ou échapper l’apostrophe avec une barre oblique inversée (un backslash, ` Pas mal, non ? Pour voir votre nom en majuscules, tapez juste : +{% filename %}command-line{% endfilename %} + ```python >>> "Ola".upper() 'OLA' ``` -Vous venez d'utiliser la **fonction** `upper` sur votre chaîne de caractères ! Une fonction (comme `upper()`) est un ensemble d'instructions que Python va effectuer sur un objet donné (`"Ola"`) lorsque vous l’appellerez. +Vous venez d'utiliser la **fonction** `upper` sur votre chaine de caractères! Une méthode (comme `upper()`) est un ensemble d'instructions que Python va effectuer sur un objet donné (`"Ola"`) lorsque vous l’appellerez. + +Si vous voulez savoir combien il y a de lettres dans votre nom, il y a une **fonction** pour ça ! -Si vous voulez savoir combien il y a de lettres dans votre nom, il y a une fonction pour ça ! +{% filename %}command-line{% endfilename %} ```python >>> len("Ola") 3 ``` -Vous avez peut-être remarqué que parfois, on appelle la fonction avec `.` en la plaçant après la chaîne de caractères (comme `"Ola".upper()`) alors qu'à d'autres moment, on appelle d'abord la fonction puis la chaîne de caractères entre parenthèses ? Il s'avère que dans certains cas, les fonctions appartiennent à des objets (c'est le cas de `upper()`) et qu'elles ne peuvent être appliquées qu'à des chaînes de caractères. Dans ce cas, on appelle la fonction une **méthode**. D'autres fois, les fonctions n’appartiennent à rien de particulier et peuvent être utilisées sur différents types d'objets (c'est le cas de `len()`). C'est pour ça que nous passons `"Ola"` comme argument à la fonction `len`. +Vous avez peut-être remarqué que parfois, on appelle la fonction avec `.` en la plaçant après la chaine de caractères (comme `"Ola".upper()`) alors qu'à d'autres moment, on appelle d'abord la fonction puis la chaine de caractères entre parenthèses. Il s'avère que dans certains cas, les fonctions appartiennent à des objets (c'est le cas de `upper()`) et qu'elles ne peuvent être appliquées qu'à des chaines de caractères. Dans ce cas, on appelle la fonction une **méthode**. D'autres fois, les fonctions n’appartiennent à rien de particulier et peuvent être utilisées sur différents types d'objets (c'est le cas de `len()`). C'est pour ça que nous passons `"Ola"` comme argument à la fonction `len`. ### Résumé -OK, assez parlé de chaînes de caractères. Jusque-là, nous avons découvert : +OK, assez parlé de chaines de caractères. Jusque-là, nous avons découvert : -* **le prompt** - taper des commandes (du code) dans le prompt Python donne des réponses dans Python -* **les nombres et les chaînes de caractères** - dans Python, les nombres sont utilisés pour faire des calculs, et les chaînes de caractères pour manipuler du texte -* **opérateurs** - comme + et * qui combinent des valeurs pour en obtenir de nouvelles -* **les fonctions** - comme upper() et len() qui effectuent des actions sur les objets. +- **le prompt** – taper des commandes (du code) dans le prompt Python donne des réponses dans Python +- **les nombres et les chaines de caractères** – dans Python, les nombres sont utilisés pour faire des calculs, et les chaines de caractères pour manipuler du texte +- **opérateurs** – comme `+` et `*`, ils combinent des valeurs pour en produire une nouvelle +- **les fonctions** – comme `upper()` et `len()` qui effectuent des actions sur les objets. -Ce sont des bases présentes dans tous les langages de programmation que vous pouvez apprendre. Prête pour quelque chose de plus compliqué ? Allons-y ! +Ce sont des bases présentes dans tous les langages de programmation existants. Prête pour quelque chose de plus compliqué ? Allons-y ! ## Les erreurs Essayons quelque chose de nouveau. Pouvons-nous obtenir la longueur d’un nombre de la même façon que celle de notre nom ? Tapez `len(304023)` et appuyez sur `entrée` : +{% filename %}{{ warning_icon }} command-line{% endfilename %} + ```python >>> len(304023) Traceback (most recent call last): @@ -121,17 +153,21 @@ Traceback (most recent call last): TypeError: object of type 'int' has no len() ``` -Nous venons d'obtenir notre première erreur ! Elle nous dit que les objets de type "int" (integers, ce qui signifie nombre entier) n'ont pas de longueur. Que pouvons-nous faire, du coup ? Pourquoi ne pas essayer d'écrire notre nombre comme une chaîne de caractères ? Après tout, les chaînes de caractères ont bien une taille, non ? +Nous avons eu notre première erreur! L'icône {{ warning_icon }} est notre façon de vous alerter que le code que vous êtes sur le point d'exécuter ne fonctionnera pas comme prévu. Faire des erreurs (même intentionnellement) est une partie importante de l'apprentissage! + +L'erreur que nous venons d'avoir nous dit que les objets de type "int" (integers, ce qui signifie nombre entier) n'ont pas de longueur. Que pouvons-nous faire, du coup ? Pourquoi ne pas essayer d'écrire notre nombre comme une chaine de caractères ? Après tout, les chaînes de caractères ont bien une taille, non ? + +{% filename %}command-line{% endfilename %} ```python >>> len(str(304023)) 6 ``` -Ça a marché ! Nous avons utilisé la fonction `str` à l'intérieur de la fonction `len`. La fonction `str()` convertit n'importe quoi en chaîne de caractères. +Ça a marché ! Nous avons utilisé la fonction `str` à l'intérieur de la fonction `len`. La fonction `str()` convertit n'importe quoi en chaine de caractères. -* La fonction `str` convertit des choses en **chaînes de caractères** -* La fonction `int` convertit des choses en **entiers** +- La fonction `str` convertit des choses en **chaines de caractères** +- La fonction `int` convertit des choses en **entiers** > Important : il est possible de convertir des nombres en texte, mais il n'est pas toujours possible de convertir du texte en nombres. Parce que, bon, ça vaudrait quoi `int('salut')` ? @@ -141,20 +177,26 @@ Il existe un concept super important en programmation : les variables. Une varia Disons que nous aimerions créer une variable appelée `name` : +{% filename %}command-line{% endfilename %} + ```python >>> name = "Ola" ``` -Vous voyez ? C'est tout bête ! C'est simplement : name vaut Ola. +Nous tapons name égale Ola. -Vous avez peut-être remarqué que contrairement à tout à l'heure, le programme ne renvoie rien. Du coup, comment faire pour vérifier que la variable existe vraiment ? Tapez simplement `name` et appuyez sur `entrée` : +Vous avez peut-être remarqué que contrairement à tout à l'heure, le programme ne renvoie rien. Du coup, comment faire pour vérifier que la variable existe vraiment ? Tapez `name` et appuyez sur `entrée` : + +{% filename %}command-line{% endfilename %} ```python >>> name 'Ola' ``` -Youpi ! Votre première variable :) ! Vous pouvez toujours changer ce à quoi elle fait référence : +Youpi ! Votre première variable ! :) Vous pouvez toujours changer ce à quoi elle fait référence : + +{% filename %}command-line{% endfilename %} ```python >>> name = "Sonja" @@ -162,7 +204,9 @@ Youpi ! Votre première variable :) ! Vous pouvez toujours changer ce à quoi el 'Sonja' ``` -Vous pouvez aussi l'utiliser dans des fonctions : +Vous pouvez aussi l'utiliser avec des fonctions : + +{% filename %}command-line{% endfilename %} ```python >>> len(name) @@ -171,6 +215,8 @@ Vous pouvez aussi l'utiliser dans des fonctions : Génial, non ? Et bien sûr, les variables peuvent être n'importe quoi, y compris des nombres ! Essayez ça : +{% filename %}command-line{% endfilename %} + ```python >>> a = 4 >>> b = 6 @@ -178,7 +224,9 @@ Génial, non ? Et bien sûr, les variables peuvent être n'importe quoi, y compr 24 ``` -Mais que se passe-t-il si nous utilisons le mauvais nom ? Essayez de deviner ! C'est parti ! +Mais que ce passe-t-il si nous utilisons le mauvais nom ? Essayez de deviner ! C'est parti ! + +{% filename %}{{ warning_icon }} command-line{% endfilename %} ```python >>> city = "Tokyo" @@ -190,12 +238,14 @@ NameError: name 'ctiy' is not defined Une erreur ! Comme vous pouvez le voir, Python a différents types d'erreurs, et celle-ci est une **NameError**. Python vous donne cette erreur quand vous essayez d'utiliser une variable qui n'a pas encore été définie. Si vous rencontrez cette erreur par la suite, vérifiez dans votre code que vous n'avez pas fait une faute de frappe dans une variable. -Jouez un peu avec les variables et essayez de voir ce que vous pouvez faire ! +Jouez un peu avec les variables et essayez de voir ce que vous pouvez en faire ! ## La fonction print Essayez ça : +{% filename %}command-line{% endfilename %} + ```python >>> name = 'Maria' >>> name @@ -204,29 +254,35 @@ Essayez ça : Maria ``` -Quand vous tapez `name`, l'interpréteur Python répond avec la *représentation* de la chaîne de caractères associée à la variable "name", c'est à dire les lettres M-a-r-i-a, entourées par des guillemets simples. Quand vous dites `print(name)`, Python va "imprimer" le contenu de la variable sur l'écran, sans les guillemets, ce qui est plus sympa. +Quand vous tapez `name`, l'interpréteur Python répond avec la *représentation* de la chaine de caractères associée à la variable "name", c'est à dire les lettres M-a-r-i-a, entourées par des guillemets simples. Quand vous dites `print(name)`, Python va "imprimer" le contenu de la variable sur l'écran, sans les guillemets, ce qui est plus sympa. Comme nous le verrons plus tard, `print()` est aussi utile lorsque l'on veut afficher des choses depuis l'intérieur de fonctions ou des choses sur plusieurs lignes. ## Les listes -En plus des chaînes de caractères et des entiers, Python possède tout un tas d'autres types d'objets. Nous allons maintenant vous présenter un type appelé **listes**. Les listes sont exactement ce que vous pensez qu’elles sont : des objets qui sont des listes d’autres objets :) +En plus des chaines de caractères et des entiers, Python possède tout un tas d'autres types d'objets. Nous allons maintenant vous présenter un type appelé **list** (liste). Les listes sont exactement ce que vous pensez : des objets qui sont des listes d’autres objets. :) Allez-y, créez une liste : +{% filename %}command-line{% endfilename %} + ```python >>> [] [] -``` +``` Oui, cette liste est vide. Pas très utile, non ? Créons maintenant une liste de numéros de loterie. Nous ne voulons pas nous répéter tout le temps, donc mettons-la dans une variable : +{% filename %}command-line{% endfilename %} + ```python >>> lottery = [3, 42, 12, 19, 30, 59] ``` Voilà, nous avons une liste ! Qu'est ce que nous pourrions en faire ? Commençons par voir combien de numéros de loterie il y a dans cette liste. Une idée de la fonction pour faire ça ? Vous la connaissez déjà ! +{% filename %}command-line{% endfilename %} + ```python >>> len(lottery) 6 @@ -234,12 +290,16 @@ Voilà, nous avons une liste ! Qu'est ce que nous pourrions en faire ? Commenço Hé oui ! `len()` peut aussi vous donner le nombre d'objets dans une liste. Pratique, non ? Peut-être qu'on peut aussi la trier : +{% filename %}command-line{% endfilename %} + ```python >>> lottery.sort() ``` Ça ne renvoie rien : cette fonction a juste changé l'ordre dans lequel les nombres apparaissent dans la liste. Affichons-la encore pour voir ce qu'il s'est passé : +{% filename %}command-line{% endfilename %} + ```python >>> print(lottery) [3, 12, 19, 30, 42, 59] @@ -249,13 +309,17 @@ Comme vous pouvez le voir, les nombres de la liste sont maintenant triés du plu Pouvons-nous inverser cet ordre ? Essayons! +{% filename %}command-line{% endfilename %} + ```python >>> lottery.reverse() >>> print(lottery) [59, 42, 30, 19, 12, 3] ``` -Facile, non ? Si vous voulez ajouter quelque chose à la liste, vous pouvez le faire en tapant cette commande : +Si vous voulez ajouter quelque chose à la liste, vous pouvez le faire en tapant cette commande : + +{% filename %}command-line{% endfilename %} ```python >>> lottery.append(199) @@ -263,7 +327,9 @@ Facile, non ? Si vous voulez ajouter quelque chose à la liste, vous pouvez le f [59, 42, 30, 19, 12, 3, 199] ``` -Si vous ne souhaitez afficher que le premier nombre, vous pouvez le faire en utilisant des **indices**. Un indice est un nombre qui dit où l'élément apparait dans la liste. Les programmeurs⋅euses préfèrent compter à partir de 0 : le premier objet dans notre liste a donc pour indice 0, le suivant 1 et ainsi de suite. Essayez ça : +Si vous ne souhaitez afficher que le premier élément, vous pouvez le faire en utilisant des **indices**. Un indice est un nombre qui indique où se trouve un élément dans la liste. Les programmeurs⋅euses préfèrent compter à partir de 0 : le premier objet dans notre liste a donc pour indice 0, le suivant 1 et ainsi de suite. Essayez ça : + +{% filename %}command-line{% endfilename %} ```python >>> print(lottery[0]) @@ -274,7 +340,9 @@ Si vous ne souhaitez afficher que le premier nombre, vous pouvez le faire en uti Comme vous pouvez le voir, nous pouvons accéder à différents objets dans la liste en utilisant le nom de la liste suivi de l'indice de l'objet entre crochets. -Pour supprimer un objet de votre liste, vous aurez besoin de son **indice** ainsi que de la commande `pop()`. Essayons l'exemple suivant : supprimez le premier numéro de votre liste. +Pour supprimer quelque chose de votre liste, vous devrez utiliser les **indices** comme nous l'avons appris ci-dessus et la méthode `pop()` . Essayons l'exemple suivant : supprimez le premier élément de votre liste. + +{% filename %}command-line{% endfilename %} ```python >>> print(lottery) @@ -282,41 +350,50 @@ Pour supprimer un objet de votre liste, vous aurez besoin de son **indice** ains >>> print(lottery[0]) 59 >>> lottery.pop(0) +59 >>> print(lottery) [42, 30, 19, 12, 3, 199] ``` Ça marche à merveille ! -Jouons encore un peu avec les indices ! Essayez-en des nouveaux : 6, 7, 1000, -1, -6 ou -1000. Est-ce que vous arrivez à prévoir le résultat avant de taper la commande ? Est-ce que ces résultats vous paraissent logiques ? +Jouons encore un peu avec les indices ! Essayez-en des nouveaux : 6, 7, 1000, -1, -6 ou -1000. Est-ce que vous arrivez à prévoir le résultat avant de taper la commande ? Est-ce que ses résultats vous paraissent logiques ? Vous pouvez trouver une liste complète des méthodes disponibles pour les listes dans ce chapitre de la documentation de Python : https://docs.python.org/3/tutorial/datastructures.html ## Dictionnaires -Un dictionnaire est un peu comme une liste. Cependant, nous utilisons des clefs plutôt que des indices pour accéder aux valeurs. Une clef peut être n'importe quelle chaîne de caractère ou n'importe quel nombre. La syntaxe pour définir un dictionnaire vide est la suivante : +> Pour les lectrices autodidactes : cette partie est traitée dans la vidéo [Python Basics: Dictionaries](https://www.youtube.com/watch?v=ZX1CVvZLE6c). + +Un dictionnaire est un peu comme une liste. Cependant, nous utilisons des clefs plutôt que des indices numériques pour accéder aux valeurs. Une clef peut être n'importe quelle chaîne de caractères ou n'importe quel nombre. La syntaxe pour définir un dictionnaire vide est la suivante : + +{% filename %}command-line{% endfilename %} ```python >>> {} {} ``` -C'est comme ça que l'on crée un dictionnaire vide. Hourra ! +Cela montre que vous venez de créer un dictionnaire vide. Hurray ! -Maintenant, essayez d'écrire la commande suivante (et essayez aussi de changer le contenu) : +Maintenant, essayez d'écrire la commande suivante (et essayez aussi de remplacer le contenu par vos informations) : + +{% filename %}command-line{% endfilename %} ```python >>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} ``` -Avec cette commande, vous venez de créer une variable nommée `participant` avec trois paires clef-valeur : +Avec cette commande, vous venez de créer une variable nommée `participant` avec trois paires clef–valeur : -* La clef `name` pointe vers la valeur `'Ola'` (un objet `chaîne de caractères`), -* `country` pointe vers `'Poland'` (une autre `chaîne de caractères`), -* et `favorite_numbers` pointe vers `[7, 42, 92]` (une `liste` contenant trois nombres). +- La clef `name` pointe vers la valeur `'Ola'` (un objet `chaine de caractères`), +- `country` pointe vers `'Poland'` (une autre `chaine de caractères`), +- et `favorite_numbers` pointe vers `[7, 42, 92]` (une `liste` contenant trois nombres). Vous pouvez vérifier le contenu de chaque clef avec cette syntaxe : +{% filename %}command-line{% endfilename %} + ```python >>> print(participant['name']) Ola @@ -324,7 +401,9 @@ Ola Vous voyez, c'est un peu comme une liste; Cependant, vous n'avez pas besoin de vous souvenir de l'indice, juste de son nom. -Que se passe-t-il lorsque nous demandons à Python la valeur correspondant à une clef qui n'existe pas ? Pouvez-vous le deviner ? Essayons voir ! +Que ce passe-t-il lorsque nous demandons à Python la valeur correspondant à une clef qui n'existe pas ? Pouvez-vous le deviner ? Essayons voir ! + +{% filename %}{{ warning_icon }} command-line{% endfilename %} ```python >>> participant['age'] @@ -337,16 +416,20 @@ Oh, une autre erreur ! Celle-ci est une **KeyError**. Python nous donne un coup Vous vous demandez peut-être quand est-ce qu'il faut utiliser un dictionnaire ou une liste ? C'est une bonne question. Réfléchissez-y un instant avant de regarder la réponse à la ligne suivante. -* Vous avez besoin d'une suite ordonnée d'éléments ? Utilisez une liste. -* Vous avez besoin d'associer des valeurs à des clefs, de manière à pouvoir les retrouver efficacement (par clef) par la suite ? Utilisez un dictionnaire. +- Vous avez besoin d'une suite ordonnée d'éléments ? Utilisez une liste. +- Vous avez besoin d'associer des valeurs à des clefs, de manière à pouvoir les retrouver efficacement (par clef) par la suite ? Utilisez un dictionnaire. + +Comme les listes, les dictionnaires sont *mutables*, ce qui signifie qu'ils peuvent être modifiés après leur création. Vous pouvez ajouter de nouvelles paires clé–valeur au dictionnaire après sa création, comme ceci : -Comme les listes, les dictionnaires sont *mutables*, ce qui signifie qu'ils peuvent être modifiés après leur création. Vous pouvez ajouter de nouvelles paires clé/valeur au dictionnaire après sa création, comme ceci : +{% filename %}command-line{% endfilename %} ```python >>> participant['favorite_language'] = 'Python' ``` -Comme pour les listes, la fonction `len()` permet d'obtenir le nombre de paires clef-valeur du dictionnaire. Essayez et tapez la commande suivante : +Comme pour les listes, la fonction `len()` permet d'obtenir le nombre de paires clef–valeur du dictionnaire. Essayez de taper la commande suivante : + +{% filename %}command-line{% endfilename %} ```python >>> len(participant) @@ -355,40 +438,49 @@ Comme pour les listes, la fonction `len()` permet d'obtenir le nombre de paires J'espère que c'est compréhensible pour l'instant :) Prête pour s'amuser un peu plus avec les dictionnaires ? Passez à la ligne suivante pour voir des trucs géniaux. -Vous pouvez utiliser la commande `pop()` pour supprimer un élément du dictionnaire. Par exemple, si vous voulez supprimer l'entrée correspondant à la clé `« favorite_numbers »`, tapez la commande suivante : +Vous pouvez utiliser la méthode `pop()` pour supprimer un élément du dictionnaire. Par exemple, si vous voulez supprimer l'entrée correspondant à la clé `« favorite_numbers »`, tapez la commande suivante : + +{% filename %}command-line{% endfilename %} ```python >>> participant.pop('favorite_numbers') +[7, 42, 92] >>> participant {'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} ``` -Comme vous pouvez le voir dans votre console, la paire clef-valeur correspondant à "favorite_numbers" a été supprimée. +Comme vous pouvez le voir dans votre console, la paire clef–valeur correspondant à "favorite_numbers" a été supprimée. De même, vous pouvez changer la valeur associée à une clef déjà créée dans le dictionnaire. Tapez ceci : +{% filename %}command-line{% endfilename %} + ```python >>> participant['country'] = 'Germany' >>> participant {'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} ``` -Voilà, la valeur de la clé `"country"` a été modifiée de `"Poland"` à `"Germany"`. :) Ce n'est pas cool ça ? Yep ! Un autre truc génial d'appris ! +Voilà, la valeur de la clé `"country"` a été modifiée de `"Poland"` à `"Germany"`. :) Ce n'est pas cool ça ? Yep ! Un autre truc génial d'appris. ### Résumé C'est super ! Vous savez plein de choses sur la programmation maintenant. Dans cette partie, vous avez appris : -* **les erreurs** - vous savez maintenant comment lire et comprendre les erreurs qui apparaissent quand Python ne comprend pas l'une de vos commandes -* **les variables** - des noms pour les objets qui vous permettent de coder plus facilement et de rendre votre code plus lisible -* **les listes** - des listes d'objets stockés dans un ordre particulier -* **les dictionnaires** - des objets stockés sous forme de paires clef-valeur +- **les erreurs** – vous savez maintenant comment lire et comprendre les erreurs qui apparaissent quand Python ne comprend pas l'une de vos commandes +- **les variables** – des noms pour les objets qui vous permettent de coder plus facilement et de rendre votre code plus lisible +- **les listes** – des listes d'objets stockés dans un ordre particulier +- **les dictionnaires** – des objets stockés sous forme de paires clef–valeur On continue ? :) ## Comparer des choses -Comparer des choses est très important en programmation. Quelle serait la chose la plus facile à comparer ? Les nombres, bien sûr ! Voyons voir comment ça marche : +> Pour les lectrices autodidactes : cette partie est traitée dans la vidéo [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4). + +Comparer des choses est très important en programmation. Quelle serait la chose la plus facile à comparer ? Les nombres, bien sûr ! Allons voir comment ça marche : + +{% filename %}command-line{% endfilename %} ```python >>> 5 > 2 @@ -401,14 +493,18 @@ True True >>> 5 != 2 True +>>> len([1, 2, 3]) > len([4, 5]) +True ``` -Nous avons donné à Python des nombres à comparer. Comme vous pouvez le voir, Python peut comparer des nombres, mais aussi des résultats de méthodes. Pas mal, non ? +Nous avons donné à Python quelques nombres à comparer. Comme vous pouvez le voir, Python n'est pas seulement capable de comparer des nombres, mais il peut aussi comparer les valeurs des expressions mathématiques comme `2 * 2` avec le résultat d'une fonction comme le `2` renvoyé par `len([4, 5])`. Pas mal, non ? -Vous vous demandez probablement pourquoi nous avons mis deux signes `==` côte à côte pour savoir si deux nombres étaient égaux ? On utilise déjà `=` pour assigner des valeurs aux variables. Du coup, il faut toujours, oui **toujours**, mettre deux `==` si vous voulez savoir si deux choses sont égales. Nous pouvons aussi dire que certaines choses ne sont pas égales à d'autres Pour cela, nous utilisons le symbole `!=`, comme illustré dans l'exemple ci-dessus. +Vous vous demandez probablement pourquoi nous avons mis deux signes `==` côte à côte pour savoir si deux nombres étaient égaux ? On utilise déjà `=` pour assigner des valeurs aux variables. Du coup, il faut toujours, oui **toujours**, mettre deux `==` si vous voulez savoir si deux choses sont égales. Nous pouvons aussi dire que certaines choses ne sont pas égales à d'autres. Pour cela, nous utilisons le symbole `! =`, comme illustré dans l'exemple ci-dessus. Donnons encore un peu de boulot à Python : +{% filename %}command-line{% endfilename %} + ```python >>> 6 >= 12 / 2 True @@ -418,13 +514,15 @@ False `>` et `<` sont faciles, mais qu'est ce que `>=` et `<=` veulent dire ? Ils se lisent comment ça : -* x `>` y veut dire : x est plus grand que y -* x `<` y signifie: x est inférieure à y -* x `<=` y signifie: x est inférieur ou égal à y -* x `>=` y veut dire : x est supérieur ou égal à y +- x `>` y veut dire : x est plus grand que y +- x `<` y signifie: x est inférieure à y +- x `< =` y signifie: x est inférieur ou égal à y +- x `>=` y veut dire : x est supérieur ou égal à y Super ! Un dernier ? Essayez ça : +{% filename %}command-line{% endfilename %} + ```python >>> 6 > 2 and 2 < 3 True @@ -436,29 +534,36 @@ True Vous pouvez donner à Python autant de nombres à comparer que vous le souhaitez et il vous donnera une réponse. Plutôt malin, non ? -* **and** - si vous utilisez l'opérateur `and` (et), les deux comparaisons doivent être True (vraies) pour que la commande toute entière soit True -* **or** - si vous utilisez l'opérateur `or` (ou), il suffit qu'une des deux comparaisons soit True (vraie) pour que la commande toute entière soit True +- **and** – si vous utilisez l'opérateur `and` (et), les deux comparaisons doivent être True (vraies) pour que la commande toute entière soit True +- **or** – si vous utilisez l'opérateur `or` (ou), il suffit qu'une des deux comparaisons soit True (vraie) pour que la commande toute entière soit True Vous connaissez l'expression "on ne compare pas les choux et les carottes" ? Essayons l'équivalent en Python : +{% filename %}{{ warning_icon }} command-line{% endfilename %} + ```python >>> 1 > 'django' Traceback (most recent call last): File "", line 1, in -TypeError: unorderable types: int() > str() +TypeError: '>' not supported between instances of 'int' and 'str' ``` -Comme vous le voyez, Python n'est pas capable de comparer un nombre (`int`) et une chaîne de caractères (`str`). À la place, il nous montre une **TypeError** et nous dit que les deux types ne peuvent pas être comparés. +Comme vous le voyez, Python n'est pas capable de comparer un nombre (`int`) et une chaine de caractères (`str`). À la place, il nous montre une **TypeError** et nous dit que les deux types ne peuvent pas être comparés. ## Booléen -Au passage, vous venez de découvrir un nouveau type d'objets en Python. On l'appelle **Booléen**. C'est probablement le type le plus simple qui existe. +Vous venez d'apprendre un nouveau type d'objet en Python. Il s'appelle **Boolean**. + +Il n'y a que deux objets Booléens : -Il n'y a que deux objets Booléens : - True (vrai) - False (faux) +- True (vrai) +- False (faux) -Pour que Python comprenne qu'il s'agit d'un Boléen, il faut toujours l'écrire True (première lettre en majuscule, les autres en minuscule). **true, TRUE, tRUE ne marchent pas -- seul True est correct.** (Et c'est aussi vrai pour False.) +Pour que Python comprenne qu'il s'agit d'un Boléen, il faut toujours l'écrire 'True' (première lettre en majuscule, les autres en minuscule). **true, TRUE, tRUE ne marchent pas -- seul True est correct.** (Et c'est aussi vrai pour False.) -Les Booléens aussi peuvent être des variables ! regardez : +Les Booléens aussi peuvent être des variables ! Regardez : + +{% filename %}command-line{% endfilename %} ```python >>> a = True @@ -468,31 +573,37 @@ True Vous pouvez aussi faire ça : +{% filename %}command-line{% endfilename %} + ```python >>> a = 2 > 5 >>> a False ``` -Entrainez-vous et amusez-vous avec les Booleéns en essayant de lancer les commandes suivantes : +Entraînez-vous et amusez-vous avec les Booleéns en essayant de lancer les commandes suivantes : -* `True and True` -* `False and True` -* `True or 1 == 1` -* `1 != 2` +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` Bravo ! Les Booléens sont l'une des fonctionnalités les plus cools en programmation et vous venez juste d'apprendre comment les utiliser ! # Sauvegardez tout ça ! -Pour l'instant, nous avons écrit tout notre code Python directement dans l'interpréteur, ce qui nous limite à une ligne à la fois. Les programmes normaux sont sauvegardés dans des fichiers et sont exécutés par **l'interpréteur** ou le **compilateur** de notre langage de programmation. Jusque-là, c'était ligne par ligne dans **l'interpréteur**. Nous allons avoir besoin de bien plus qu'une ligne de code par la suite alors, vous allez rapidement avoir besoin de : +> Pour les lectrices autodidactes : cette partie est traitée dans la vidéo [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk). + +Pour l'instant, nous avons écrit tout notre code Python directement dans l'interpréteur, ce qui nous limite à une ligne de code à la fois. Les programmes sont typiquement sauvegardés dans des fichiers et sont exécutés par **l'interpréteur** ou le **compilateur** de notre langage de programmation. Jusqu'à présent, nous avons lancé nos programmes une ligne à la fois dans **l'interprèteur** Python. Nous aurons besoin de plus d'une ligne de code pour les prochaines tâches, donc nous aurons rapidement besoin de : + +- Quitter l'interpréteur Python ; +- Ouvrir l'éditeur de code de notre choix ; +- Sauvegarder du code dans un nouveau fichier Python ; +- Le lancer ! -* Quitter l'interpréteur Python -* Ouvrir l'éditeur de code de notre choix -* Sauvegarder du code dans un nouveau fichier Python -* Le lancer ! +Pour quitter l'interpréteur Python que nous sommes en train d'utiliser, il suffit de taper la fonction `exit()` -Pour quitter l'interpréteur Python que nous sommes en train d'utiliser, il suffit de taper la fonction `exit()` : +{% filename %}command-line{% endfilename %} ```python >>> exit() @@ -501,86 +612,141 @@ $ Cela vous ramènera dans la ligne de commande de votre système d'exploitation. -Tout à l'heure, dans la section [L'éditeur de texte][2], nous avons choisi un éditeur de texte. Ouvrez-le et écrivez le code suivant dans un nouveau fichier : +Tout à l'heure, nous avions choisi un éditeur de code de la section [code editor](../code_editor/README.md). Nous allons maintenant ouvrir l'éditeur et écrire du code dans un nouveau fichier (ou, si vous utilisez un Chromebook, créez un nouveau fichier dans le cloud IDE et ouvrez le fichier, qui sera dans l'éditeur de code inclus) : - [2]: ../code_editor/README.md +{% filename %}editor{% endfilename %} ```python print('Hello, Django girls!') ``` -> **Note :** Vous avez probablement constaté que votre code se pare de multiples couleurs : ça fait partie des choses qui rendent la programmation dans un éditeur de texte bien plus agréable. Votre console Python n'avait pas cette fonctionnalité : tout était donc de la même couleur. Dans votre éditeur de texte, vous devriez voir que la fonction `print` possède différentes couleurs. C'est ce qu'on appelle « la coloration syntaxique ». C'est une fonctionnalité très utile lorsque l'on programme. La couleur des choses va vous permettre de détecter des problèmes : une chaîne de caractères non fermée, une faute dans un mot (ce sera par exemple le cas dans la fonction `def` que vous verrez un peu plus bas). C'est ce genre de fonctionnalités qui font que vous aimerez rapidement programmer avec un éditeur de code :) - Vous avez maintenant pas mal de connaissances en Python : n'hésitez pas à écrire du code avec ce que vous avez appris aujourd'hui ! -Sauvegardons maintenant le fichier en lui donnant un nom descriptif. On n'a qu'à l'appeler **python_intro.py** et le sauvegarder sur le bureau. Vous pouvez donner le nom que vous souhaitez à ce fichier mais il est important qu'il se termine par **.py**. L'extension **.py** permet de signaler à votre système d'exploitation que ce fichier est un **fichier exécutable Python** et que Python peut le lancer. +Maintenant, nous devons sauvegarder le fichier et lui donner un nom descriptif. Appelons le fichier **python_intro.py** et sauvegardons-le sur votre bureau. Vous pouvez donner le nom que vous souhaitez à ce fichier mais il est important qu'il se termine par **.py**. L'extension **.py** permet de signaler à votre système d'exploitation que ce fichier est un **fichier exécutable Python** et que Python peut le lancer. + +> **Note :** Vous avez probablement constaté que votre code se pare de multiples couleurs : ça fait partie des choses qui rendent la programmation dans un éditeur de texte bien plus agréable ! Votre console Python n'avait pas cette fonctionnalité : tout était donc de la même couleur. Dans votre éditeur de texte, vous devriez voir que la fonction `print`, par exemple, n'a pas la même couleur d'une chaîne de caractères. C'est ce qu'on appelle « la coloration syntaxique ». C'est une fonctionnalité très utile lorsque l'on programme. La couleur des choses va vous permettre de détecter des problèmes : une chaine de caractères non fermée, une faute dans un mot (ce sera par exemple le cas dans la fonction `def` que vous verrez un peu plus tard). C'est ce genre de fonctionnalités qui font que vous aimerez rapidement programmer avec un éditeur de code. :) Une fois que le fichier est sauvegardé, vous pouvez le lancer ! En utilisant les compétences que vous avez apprises dans la section sur la ligne de commande, utilisez le terminal pour **changer le dossier courant** vers le bureau. + + Sur Mac, ça ressemblera à : +{% filename %}command-line{% endfilename %} + $ cd ~/Desktop + + -Sous Linux, comme ça (il se peut que le mot Bureau soit dans une autre langue) : + + +Sur Linux, ce sera comme ça : + +{% filename %}command-line{% endfilename %} $ cd ~/Desktop + + +(N'oubliez pas que le mot "Bureau" peut être traduit dans votre langue locale.) + + + -Et sous Windows, ce sera comme ça : +Dans l'invite de commande Windows, ce sera comme ceci : + +{% filename %}command-line{% endfilename %} > cd %HomePath%\Desktop + + + + + + +Et sur Windows Powershell, ce sera comme ça : + +{% filename %}command-line{% endfilename %} + > cd $Home\Desktop + -Si vous êtes bloquée, n'hésitez pas à appeler à l'aide. + + +Si vous êtes coincées, demandez de l'aide. C'est exactement pour ça que les coaches sont là ! Maintenant, utilisez Python pour exécuter le code contenu dans votre fichier : +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Hello, Django girls! + +Note: sur Windows 'python3' n'est pas reconnu comme une commande. Au lieu de cela, utilisez 'python' pour exécuter le fichier : + +{% filename %}command-line{% endfilename %} + +```python +> python python_intro.py +``` Super ! Vous venez de lancer votre premier programme python à partir d'un fichier. Cool non ? Et maintenant, passons à un autre outil essentiel de la programmation : -## If...elif...else +## If … elif … else -Quand on code, il y a plein choses qui ne doivent être exécutées que dans certaines conditions. Pour cela, Python possède ce qu'on appelle l'instruction **if** (si). +Quand on code, il y a plein de choses qui ne doivent être exécutées que dans certaines conditions. Pour cela, Python possède ce qu'on appelle l'instruction **if** (si). Remplacez le code dans votre fichier **python_intro.py** avec ceci : +{% filename %}python_intro.py{% endfilename %} + ```python if 3 > 2: ``` -Si nous sauvegardons ce fichier et que nous le lançons, nous obtiendrons l'erreur suivante : +Si nous sauvegardons ce fichier et que nous l'exécutons, nous obtiendrons l'erreur suivante : -```python -$ python3 python_intro.py -File "python_intro.py", line 2 - ^ -SyntaxError: unexpected EOF while parsing -``` +{% filename %}{{ warning_icon }} command-line{% endfilename %} + + $ python3 python_intro.py + File "python_intro.py", line 2 + ^ + SyntaxError: unexpected EOF while parsing + Python s'attend à ce que nous lui donnions des instructions sur ce qu'il faut exécuter lorsque la condition `3 > 2` est vraie (ou plutôt, `True`). Essayons de lui faire afficher "Ça marche !". Remplacez le code dans **python_intro.py** par ceci : +{% filename %}python_intro.py{% endfilename %} + ```python if 3 > 2: - print('It works!') + print('Ça marche !') ``` -Avez-vous remarqué que nous avions décalé la ligne suivante de quatre espaces ? C'est ce que l'on appelle indenter. Nous avons besoin d'indenter pour que Python sache quel code exécuter si le résultat est vrai. Un seul espace suffirait, mais à peu près tous⋅tes les programmeurs⋅euses Python pensent que 4 espaces sont plus clairs. Une seule `tab` (tabulation) compte également comme 4 espaces. +Avez-vous remarqué que nous avions décalé la ligne suivante de quatre espaces ? C'est ce que l'on appelle indenter. Nous avons besoin d'indenter pour que Python sache quel code exécuter si le résultat est vrai. Un seul espace suffirait, mais à peu près tous⋅tes les programmeurs⋅euses Python pensent que 4 espaces sont plus clairs. La touche de tabulation (Tab) devrait ajouter automatiquement 4 espaces, mais cela peut dépendre du paramétrage de votre éditeur de texte. Lorsque vous avez fait votre choix, ne le changez pas ! Si vous avez déjà indenté avec 4 espaces, faites de même dans le reste du fichier - sinon vous risquez de rencontrer des problèmes. Sauvegardez le fichier et relancez le : - $ python3 python_intro.py - Ça marche ! +{% filename %}command-line{% endfilename %} + +```python +$ python3 python_intro.py +Ça marche ! +``` +Note: N'oubliez pas que sur Windows, 'python3' n'est pas reconnu comme une commande. À partir de maintenant, remplacez 'python3' par 'python' pour exécuter le fichier. ### Et que se passe-t-il si une condition n’est pas vraie ? -Dans les exemples précédents, le code était exécuté quand la condition était vraie. Cependant, Python possède aussi des instructions `elif` (sinon si) et `else` (sinon) : +Dans les exemples précédents, Python a exécuté du code parce que celui-ci se trouvait sous une condition qui était vraie. Cependant, Python possède aussi des instructions `elif` (sinon si) et `else` (sinon) : + +{% filename %}python_intro.py{% endfilename %} ```python if 5 > 2: @@ -591,11 +757,15 @@ else: Lorsque vous exécuterez le code, ceci s'affichera : +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py 5 est effectivement plus grand que 2 + +Et si 2 était plus grand que 5, la seconde commande serait exécutée. Voyons comment `elif` fonctionne : -Et si 2 était plus grand que 5, la seconde commande serait exécutée. Facile, non ? Voyons comment `elif` fonctionne : +{% filename %}python_intro.py{% endfilename %} ```python name = 'Sonja' @@ -609,52 +779,80 @@ else: Exécutons le code : +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Hey Sonja! - + Que s'est-il passé ? `elif` vous permet d'ajouter d'autres conditions à exécuter si les précédentes échouent. Vous pouvez ajouter autant de `elif` que vous le souhaitez après le premier `if`. Voici un exemple : +{% filename %}python_intro.py{% endfilename %} + ```python volume = 57 if volume < 20: - print("C'est plutôt calme.") + print("It's kinda quiet.") elif 20 <= volume < 40: - print("Une jolie musique de fond.") + print("It's nice for background music") elif 40 <= volume < 60: - print("Parfait, je peux entendre tous les détails du morceau.") + print("Perfect, I can hear all the details") elif 60 <= volume < 80: - print("Parfait pour faire la fête !") + print("Nice for parties") elif 80 <= volume < 100: - print("Un peu trop fort !") + print("A bit loud!") else: - print("Au secours ! Mes oreilles ! :(") + print("My ears are hurting! :(") ``` Python va tester les différentes conditions puis il affichera ceci : +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Parfait, je peux entendre tous les détails du morceau. + + +## Commentaires + +Les commentaires sont des lignes commençant par `#`. Vous pouvez écrire ce que vous voulez après le `#` et Python va l'ignorer. Les commentaires peuvent rendre votre code plus facile à comprendre pour d'autres personnes. + +Voyons à quoi cela ressemble : + +{% 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!") +``` + +Vous n'avez pas besoin d'écrire un commentaire pour chaque ligne de code, mais il est utile parfois d'expliquer pourquoi votre code fait une certaine chose, ou de fournir un résumé pour les parties les plus complexes. ### Résumé -Avec ces trois derniers exercices, vous avez appris : +Avec ces derniers exercices, vous avez appris : -* **Comment comparer des choses** - en Python, vous pouvez comparer des choses avec `>`, `>=`, `==`, `<=`, `<` et avec les opérateurs `and`, `or` -* **Booléen** - un type d'objet qui n'a que deux valeurs possibles : `True` et `False` -* **Comment sauvegarder des fichiers** - stocker votre code dans des fichiers pour pouvoir écrire des programmes plus longs. -* **if...elif...else** - des instructions que vous permettent de n'exécuter du code que dans certaines conditions. +- **Comment comparer des choses** – en Python, vous pouvez comparer des choses avec `>`, `>=`, `==`, `<=`, `<` et avec les opérateurs `and`, `or` +- **Booléen** – un type d'objet qui n'a que deux valeurs possibles : `True` et `False` +- **Comment sauvegarder des fichiers** – stocker votre code dans des fichiers pour pouvoir écrire des programmes plus longs. +- **if … elif … else** – des instructions que vous permettent de n'exécuter du code que dans certaines conditions. +- **commentaires** – lignes que Python n'exécutera pas et qui vous permettent de documenter votre code. Il est temps d'attaquer la dernière partie de ce chapitre ! ## Vos propres fonctions ! +> Pour les lectrices autodidactes : cette partie est traitée dans la vidéo [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0). + Vous vous souvenez des fonctions comme `len()` que vous pouvez exécuter en Python ? Et bien, bonne nouvelle : vous allez apprendre à écrire vos propres fonctions! -Une fonction est un ensemble d'instructions que Python va exécuter. Chaque fonction en Python commence par le mot-clef `def`. On lui donne un nom, et elle peut avoir des paramètres. Commençons par quelque chose de facile. Remplacer le code de **python_intro.py** par ceci : +Une fonction est un ensemble d'instructions que Python va exécuter. Chaque fonction en Python commence par le mot-clef `def`. On lui donne un nom, et elle peut avoir des paramètres. Essayons ! Remplacer le code de **python_intro.py** par ceci : + +{% filename %}python_intro.py{% endfilename %} ```python def hi(): @@ -666,16 +864,26 @@ hi() Voilà, notre première fonction est prête ! -Vous vous demandez peut-être pourquoi nous avons écrit le nom de la fonction à la fin du fichier. C'est parce que Python lit le fichier et l'exécute du haut vers le bas. Donc pour pouvoir utiliser notre fonction, nous devons la réécrire en bas. +Vous vous demandez peut-être pourquoi nous avons écrit le nom de la fonction à la fin du fichier. Quand nous écrivons `def hi():` et les lignes indentées qui suivent, nous écrivons les instructions disant ce que la fonction `hi` doit faire. Python va lire et mémoriser ces instructions, mais ne va pas exécuter la fonction tout de suite. Pour dire à Python que nous voulons exécuter la fonction, nous devons appeler la fonction avec `hi()`. Python lit le fichier et l’exécute de haut en bas, donc nous devons définir la fonction dans le fichier avant de l’appeler. Lançons notre code pour voir ce qui se passe : +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Hi there! How are you? + + +Note : si cela n'a pas fonctionné, ne paniquez pas ! Le message d'erreur vous aidera à comprendre pourquoi : +- Si vous obtenez un `NameError`, cela est du probablement à une faute de frappe, donc vous devriez vérifier d'avoir utilisé le même nom lors de la création de la fonction avec `def hi():` et lors de l'appel avec `hi()`. +- Si vous obtenez un `IndentationError`, vérifiez que les deux `print` sont à la même distance du début de leur ligne: python veut que tout le code à l'intérieur de la fonction soit bien aligné. +- Si vous n'obtenez rien du tout, vérifiez que le `hi()` à la fin *n'est pas indenté*. Si c'est le cas, cette ligne est considérée par Python comme faisant partie de la fonction, et elle ne sera donc jamais exécutée. -C'était facile ! Construisons maintenant notre première fonction avec des paramètres. Dans l'exemple précédent, nous avions une fonction qui disait "Hi there!" à la personne qui la lançait. Faisons une fonction identique, mais ajoutons un nom cette fois : +Construisons maintenant notre première fonction avec des paramètres. Dans l'exemple précédent, nous avions une fonction que disait "Hi there!" à la personne qui la lançait. Faisons une fonction identique, mais ajoutons un nom cette fois-ci : + +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): @@ -683,6 +891,8 @@ def hi(name): Comme vous le voyez, nous avons donné à notre fonction un paramètre appelé `name` : +{% filename %}python_intro.py{% endfilename %} + ```python def hi(name): if name == 'Ola': @@ -695,17 +905,20 @@ def hi(name): hi() ``` -Rappelez-vous : la fonction `print` est indentée de quatre espaces dans le bloc `if`, car elle est exécutée uniquement quand la condition est satisfaite. Voyons comment ça marche : +Rappelez-vous : la fonction `print` est indentée de quatre espaces dans le bloc `if`, car elle est exécutée uniquement quand la condition est remplie. Voyons comment ça marche : -```python -$ 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' -``` +{% filename %}{{ warning_icon }} command-line{% endfilename %} -Oups, une erreur. Heureusement, Python nous donne un message d'erreur assez utile. Il nous dit que la fonction `hi()` (celle que nous avons définie) a besoin d'un argument (que nous avons appelé `name`). Nous avons oublier de passer cet argument lorsque nous avons appelé notre fonction. Corrigeons la dernière ligne du fichier : + $ 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' + + +Oups, une erreur. Heureusement, Python nous donne un message d'erreur assez utile. Il nous dit que la fonction `hi()` (celle que nous avons définie) a besoin d'un argument (que nous avons appelé `name`). Nous avons oublié de passer cet argument lorsque nous avons appelé notre fonction. Corrigeons la dernière ligne du fichier : + +{% filename %}python_intro.py{% endfilename %} ```python hi("Ola") @@ -713,30 +926,40 @@ hi("Ola") Et exécutez votre code à nouveau : +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Hi Ola! - + Et que se passe-t-il quand on change de nom ? +{% filename %}python_intro.py{% endfilename %} + ```python hi("Sonja") ``` Exécutez votre code à nouveau : +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Hi Sonja! + +Maintenant, que pensez-vous qu'il se passera lorsque nous écrivrons un autre nom (ni Ola, ni Sonja) ? Faites un essai et regardez si vous avez raison. Ceci devrait s'afficher : -Maintenant, que pensez-vous qu'il se passera lorsque nous écrirons un autre nom (ni Ola, ni Sonja) ? Faites un essai et regardez si vous avez raison. Ceci devrait s'afficher : +{% filename %}command-line{% endfilename %} Hi anonymous! + +Super, non ? Avec ça, vous n'avez pas besoin de répéter de lignes de code lorsque vous voulez changer le nom de la personne à saluer. C'est pour cette raison que nous avons besoin de fonctions : vous ne voulez pas avoir à répéter votre code ! -Super, non ? Avec ça, vous n'avez pas besoin de vous répéter lorsque vous voulez changer le nom de la personne à saluer. C'est pour cette raison que nous avons besoin de fonctions : vous ne voulez pas avoir à répéter votre code ! +Faisons quelque chose de plus intelligent – il existe bien plus que deux noms, et écrire une condition pour chacun d'entre eux serait difficile, non ? Remplacez le contenu de votre fichier avec les suivants : -Faisons maintenant quelque chose de plus malin : comme vous le savez, il existe plus de deux prénoms. Cependant, ce serait un peu pénible de devoir écrire une condition pour chacun d'entre eux, n'est-ce pas ? +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): @@ -747,25 +970,33 @@ hi("Rachel") Exécutons à nouveau notre code : +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Hi Rachel! - + Félicitations ! Vous venez juste d’apprendre à écrire des fonctions ! :) ## Les boucles +> Pour les lectrices autodidactes : cette partie est traitée dans la vidéo [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0). + C’est déjà la dernière partie. C’était rapide, non ? :) -Les programmeurs⋅euses n'aiment pas devoir se répéter. L'essence de la programmation est d'automatiser les choses : nous aimerions pouvoir saluer automatiquement chaque personne. Pour cela, nous allons utiliser des boucles. +Les programmeurs⋅euses n'aiment pas devoir se répéter. L'essence de la programmation est d'automatiser les choses. Pour reprendre l'exemple précédent, nous aimerions pouvoir saluer automatiquement chaque personne. Pour cela, nous allons utiliser des boucles. -Vous vous souvenez des listes ? Faisons une liste de Django Girls : +Vous vous souvenez des listes ? Faisons une liste de filles : + +{% filename %}python_intro.py{% endfilename %} ```python girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] ``` -Nous voulons saluer chacune d'entre elles par son nom. Nous avons déjà la fonction `hi` pour faire ça, utilisons donc une boucle : +Nous voulons saluer chacune d'entre elles par son nom. Nous avons déjà la fonction `hi` pour faire ça, utilisons-la donc dans une boucle : + +{% filename %}python_intro.py{% endfilename %} ```python for name in girls: @@ -775,6 +1006,8 @@ L'instruction `for` se comporte un peu comme `if`. Le code qui suit doit donc ê Voilà le code complet à mettre dans votre fichier : +{% filename %}python_intro.py{% endfilename %} + ```python def hi(name): print('Hi ' + name + '!') @@ -787,6 +1020,8 @@ for name in girls: Exécutez votre code : +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Hi Rachel! Next girl @@ -798,36 +1033,40 @@ Exécutez votre code : Next girl Hi You! Next girl + - -Comme vous le voyez, tout ce que nous avons mis dans un `for` avec une indentation est répété pour chaque élément de la liste `girls`. +Comme vous pouvez le constater, tout ce que vous mettez dans la déclaration `for` avec une indentation sera répété pour chaque élément de la liste `filles`. Vous pouvez aussi utiliser `for` sur des nombres grâce à la fonction `range`: +{% filename %}python_intro.py{% endfilename %} + ```python for i in range(1, 6): print(i) ``` -Ce qui affiche : +Cela va afficher : + +{% filename %}command-line{% endfilename %} 1 2 3 4 5 - + `range` est une fonction qui crée une liste de nombres qui se suivent (c'est vous qui définissez l’intervalle à l'aide de paramètres). -Vous pouvez remarquer que le second de ces nombres n'est pas inclus dans la liste que Python nous donne (ce qui signifie que `range(1, 6)` compte de 1 à 5, mais n'inclut pas 6). C'est lié au fait que "range" est à moitié ouvert. Cela signifie qu'il inclut la première valeur mais pas la dernière. +Vous pouvez remarquer que le second de ces nombres n'est pas inclus dans la liste que Python nous donne (ce qui signifie que `range(1, 6)` compte de 1 à 5, mais n'inclue pas 6). Cela est du au fait que "range" est semi-ouvert, c'est-à-dire qu'il prend en compte la première valeur mais pas la dernière. ## Résumé -Et voilà ! **Vous êtes géniale !** Ce chapitre était un peu compliqué et vous devriez être fière de vous ! En tout cas, nous sommes super fières de vous ! +Et voilà ! **Vos assurez un max !** C'était un chapitre difficile, donc vous pouvez être fières de vous. De notre côté, nous sommes fières de vous, pour être parvenu-e si loin dans le cours. Bravo ! -N'hésitez pas à prendre une pause : étirez-vous, marchez un peu ou reposez-vous les yeux. Une fois que vous avez un peu rechargé vos batteries, vous pouvez attaquer le chapitre suivant :) +Pour accéder au tutoriel officiel et complet de Python, visitez https://docs.python.org/3/tutorial/. Cela vous donnera un accès plus exhaustif à l'étude du langage. A bientôt! :) -![Cupcake][3] +N'hésitez pas à prendre une pause : étirez-vous, marchez un peu ou reposez-vous les yeux. Une fois que vous avez un peu rechargé vos batteries, vous pouvez attaquer le chapitre suivant :) - [3]: images/cupcake.png +![Cupcake](images/cupcake.png) \ No newline at end of file diff --git a/fr/python_introduction/images/cupcake.png b/fr/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/fr/python_introduction/images/cupcake.png and b/fr/python_introduction/images/cupcake.png differ diff --git a/fr/template_extending/README.md b/fr/template_extending/README.md index 8670e4bd472..909b525e6df 100755 --- a/fr/template_extending/README.md +++ b/fr/template_extending/README.md @@ -2,7 +2,7 @@ Django vous réserve encore bien des surprises : une assez géniale est **l'héritage de template**. Qu'est ce que ça signifie ? C'est une fonctionnalité qui vous permet de réutiliser certains morceaux de HTML dans différentes pages de votre site web. -Concrètement, cela permet d'éviter de vous répéter dans chaque fichier lorsque vous voulez utiliser la même information ou mise en page. Ainsi, lorsque vous voudrez changer quelque chose, vous n'aurez à le faire qu'une seule fois! +Les modèles permettent d'utiliser les mêmes informations ou mises en page en plusieurs endroits. Vous n'avez pas à vous répéter dans chaque fichier. Et si vous voulez changer quelque chose, vous n'avez pas à le faire dans chaque modèle, mais juste un! ## Créer un template de base @@ -15,109 +15,137 @@ Créons le fichier `base.html` dans le dossier `blog/templates/blog/` : └───blog base.html post_list.html + +Ensuite, ouvrez ce fichier dans l'éditeur de code et collez-y tout ce qui se trouve dans le fichier `post_list.html`. Ça devrait ressembler à ça : -Ensuite, ouvrez ce fichier `base.html` et collez-y tout ce qui se trouve dans le fichier `post_list.html`. Ça devrait ressembler à ça : +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} + Django Girls blog - - + - + -
+
-
+
{% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %}
-
+
``` Puis, dans le fichier `base.html`, remplacez tout ce qui se trouve dans `` (de `` à ``) par ceci : +{% filename %}blog/templates/blog/base.html{% endfilename %} + ```html - -
+ +
-
+
{% block content %} {% endblock %}
-
+
``` -Nous venons concrètement de remplacer tout ce qui se trouve entre `{% for post in posts %}{% endfor %}` par : +{% raw %}Vous pouvez remarquer qu'on vient de remplacer tout ce qui était entre `{% for post in posts %}` et `{% endfor %}` avec : {% endraw %} + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% block content %} {% endblock %} ``` -Qu'est-ce que cela signifie ? Vous venez simplement de créer un `block` : c'est une balise de template qui vous permet d'insérer le HTML de ce block dans d'autres templates qui héritent de `base.html`. Nous vous expliquerons comment faire dans un instant. +Mais pourquoi? Vous venez de créer un `block` ! Vous avez utilisé la balise de modèle `{% block %}` pour créer une partie qui va contenir du HTML. Ce HTML viendra d'un autre modèle qui étendra ce modèle-ci (`base.html`). Nous vous expliquerons comment faire cela dans un instant. + +Enregistrez `base.html` et ouvrez votre `blog/templates/blog/post_list.html` à nouveau dans l'éditeur de code. {% raw %}Vous allez tout supprimer au-dessus de `{% for post in posts %}` et en dessous de `{% endfor %}`. Lorsque vous avez terminé, le fichier ressemblera à ceci :{% endraw %} -Maintenant, sauvegardez votre fichier puis ouvrez à nouveau `blog/templates/blog/post_list.html`. Supprimez tout ce qui n'est pas dans body. Supprimez aussi ``. Votre fichier doit maintenant ressembler à ça : +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} ``` -Maintenant, ajoutez cette ligne au début du fichier : +Nous voulons utiliser ceci dans le cadre de notre modèle pour tous les blocs 'content'. Il est temps d'ajouter ajouter des balises block à ce fichier ! + +{% raw %}Vous voulez que votre balise block corresponde à la balise dans votre fichier `base.html` . Vous voulez aussi qu'il inclue tout le code qui appartient à vos blocs de contenu. Pour faire cela, entourez tout le code de `{% block content %}` et `{% endblock %}`. Comme ceci :{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -{% extends 'blog/base.html' %} +{% block content %} + {% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} ``` -{% raw %}Cela signifie que nous sommes en train d'étendre le modèle du template `base.html` dans `post_list.html`. Une dernière chose à faire : déplacez tout le contenu du fichier dans la partie située entre `{% block content %}` et `{% endblock content %}`. Attention à ne pas déplacer la ligne que nous venons juste d'insérer. Comme ceci :{% endraw %} +Seule une chose reste à faire. Nous devons connecter ces deux modèles ensemble. C'est ça, étendre des modèles ! Nous allons le faire en ajoutant une balise 'extends' au début du fichier. Comme cela : + +{% 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 content %} +{% endblock %} ``` -Et voilà ! Vérifiez que votre site fonctionne toujours correctement :) +Et voilà ! Enregistrez le fichier et vérifiez que votre site fonctionne toujours correctement. :) -> Si jamais vous rencontrez une erreur de type `TemplateDoesNotExists` qui signale que le fichier `blog/base.html` n'existe pas et que `runserver` tourne dans votre console, tuez-le (en appuyant sur les touches Ctrl+C en même temps) et relancez votre server à l'aide de la commande `python manage.py runserver`. +> Si vous obtenez l'erreur `TemplateDoesNotExist`, cela signifie qu'il n'y a pas de fichier `blog/base.html` et que vous avez `runserver` en cours d'exécution dans la console. Arrêtez-le (en appuyant simultanément sur Ctrl+C, les touches Control et C de votre clavier) et relancez-le en tapant la commande `python manage.py runserver`. \ No newline at end of file diff --git a/fr/whats_next/README.md b/fr/whats_next/README.md index 54f47b1ad77..0437a65605c 100755 --- a/fr/whats_next/README.md +++ b/fr/whats_next/README.md @@ -1,39 +1,43 @@ -# La suite? +# Et maintenant ? -Un immense bravo à vous ! **Vous êtes totalement géniale**. Nous sommes fière de vous ! < 3 +Un immense bravo à vous ! **Vous êtes très déterminée**. Nous sommes fières ! <3 ### Que faire maintenant ? -Faites une pause et détendez-vous. Vous venez d'accomplir quelque chose de vraiment énorme. +Faites une pause et détendez-vous ! Vous venez d'accomplir quelque chose de conséquent. -Après ça, vous pouvez : +Ensuite, suivez Django Girls sur [Facebook](http://facebook.com/djangogirls) ou [Twitter](https://twitter.com/djangogirls) pour être au courant des nouvelles. -* Suivez Django Girls sur [Facebook][1] ou [Twitter][2] pour être tenue au courant +### À la recherche de ressources supplémentaires ? - [1]: http://facebook.com/djangogirls - [2]: https://twitter.com/djangogirls +Oui ! Il y a *énormément* de ressources en ligne pour apprendre toutes sortes de compétences de programmation. Il peut être assez difficile de s'orienter et aller plus loin, mais nous vous donnons des pistes pour démarrer. Quelle que soit la raison qui vous a menée à participer à Django Girls, et quels que soient les intérêts que vous avez développés en suivant le tutoriel, voici quelques ressources gratuites (ou des ressources avec de grands composants gratuits) que vous pouvez utiliser pour atteindre vos objectifs. -### À la recherche de ressources supplémentaires ? +#### Django + +- Notre autre livre, [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org/) +- [Tutoriel officiel de Django](https://docs.djangoproject.com/en/2.2/intro/tutorial01/) +- [Vidéos Getting Started With Django](http://www.gettingstartedwithdjango.com/) +- [La spécialisation Python de Coursera](https://www.coursera.org/specializations/django) – vous pouvez accéder gratuitement à certains cours et vous pouvez obtenir un certificat Coursera à la fin + +#### HTML, CSS et JavaScript + +- [Cours de développement web de la Codecademy](https://www.codecademy.com/learn/paths/web-development) +- [freeCodeCamp](https://www.freecodecamp.org/) + +#### Python + +- [Cours Python de la Codecademy](https://www.codecademy.com/learn/learn-python) +- [Cours Python de Google](https://developers.google.com/edu/python/) +- Le livre [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) – les premiers exercices sont gratuits +- [New Coder tutorials](http://newcoder.io/tutorials/) – c'est une série d'exemples pratiques illustrant comment Python peut vous servir +- [edX](https://www.edx.org/course?search_query=python) – vous pouvez accéder à la plupart des cours gratuitement, mais si vous voulez un certificat ou des crédits pour une qualification supérieure, cela coûtera de l'argent +- [La spécialisation Python de Coursera](https://www.coursera.org/specializations/python) – vous pouvez accéder gratuitement à certains cours et vous pouvez obtenir un certificat à la fin +- [Python for Everybody](https://www.py4e.com/) – une version gratuite et ouverte de la spécialisation de Coursera "Python for Everybody" + +#### Travailler avec les données + +- [Cours de science des données de la Codecademy](https://www.codecademy.com/learn/paths/data-science) +- [edX](https://www.edx.org/course/?search_query=python&subject=Data%20Analysis%20%26%20Statistics) – vous pouvez accéder à la plupart des cours gratuitement, mais si vous voulez un certificat ou des crédits pour une qualification supérieure, cela coûtera de l'argent +- [Dataquest](https://www.dataquest.io/) – les 30 premières « missions » sont gratuites -Jetez un coup d’œil à notre autre livre, [Django Girls Tutorial: Extensions][3] (en anglais). - - [3]: http://djangogirls.gitbooks.io/django-girls-tutorial-extensions/ - -Ensuite, vous pouvez essayer les ressources listées ci-dessous. Elles sont toutes recommandables ! -- [Django's official tutorial][4] -- [New Coder tutorials][5] -- [Code Academy Python course][6] -- [Code Academy HTML & CSS course][7] -- [Django Carrots tutorial][8] -- [Learn Python The Hard Way book][9] -- [Getting Started With Django video lessons][10] -- [Two Scoops of Django: Best Practices for Django 1.8 book][11] - - [4]: https://docs.djangoproject.com/en/1.10/intro/tutorial01/ - [5]: http://newcoder.io/tutorials/ - [6]: https://www.codecademy.com/en/tracks/python - [7]: https://www.codecademy.com/tracks/web - [8]: https://github.com/ggcarrots/django-carrots/ - [9]: http://learnpythonthehardway.org/book/ - [10]: http://gettingstartedwithdjango.com/ - [11]: https://twoscoopspress.com/products/two-scoops-of-django-1-8 +On a hâte de voir votre prochaine création ! \ No newline at end of file diff --git a/hu/code_editor/instructions.md b/hu/code_editor/instructions.md index 01c41e862f6..3d89c4da800 100644 --- a/hu/code_editor/instructions.md +++ b/hu/code_editor/instructions.md @@ -8,11 +8,11 @@ A Gedit egy open-source (nyílt forráskódú), ingyenes kódszerkesztő, az ös [Letöltés](https://wiki.gnome.org/Apps/Gedit#Download) -## Sublime Text 3 +## Sublime Text A Sublime Text egy nagyon népszerű editor, ingyenes próbaidővel. Könnyű telepíteni és használni, és minden operációs rendszeren elérhető. -[Letöltés](https://www.sublimetext.com/3) +[Letöltés](https://www.sublimetext.com/) ## Atom @@ -28,4 +28,4 @@ Az első ok az, hogy a kódot **egyszerű szövegként** kell szerkeszteni. Az A másodsorban ezek a programozáshoz tervezett szövegszerkesztők kifejezetten kódszerkesztésre szakosodtak, ami azt jelenti hogy különböző funkciókkal segítik a munkát, mint például a programkód részeinek, szavainak kiemelése annak jelentése alapján, vagy az automatikus kiegészítés. -Ezt mind látni fogjuk a későbbiekben. Hamarosan úgy fogsz gondolni a jó öreg megbízható kódszerkesztődre, mint az egyik kedvenc eszközödre :) \ No newline at end of file +Ezt mind látni fogjuk a későbbiekben. Hamarosan úgy fogsz gondolni a jó öreg megbízható kódszerkesztődre, mint az egyik kedvenc eszközödre :) diff --git a/hu/css/README.md b/hu/css/README.md index e2f0722c829..e4134d6a43c 100644 --- a/hu/css/README.md +++ b/hu/css/README.md @@ -37,15 +37,16 @@ Most nézzük meg kicsit közelebbről ezeket a "**statikus fájl**"-nak nevezet ### Hová pakoljuk a statikus fájlokat? -Amikor -- kicsit korábban -- a `collectstatic` parancsot futtattuk a szerveren, Django már tudta, hol találja a statikus fájlokat a beépíttett "admin" alkalmazáshoz. Most csak annyit kell tennünk, hogy a saját, `blog` alkalmazásunkhoz hozzáadunk néhány statikus fájlt. +Django már tudja, hol találja a statikus fájlokat a beépíttett "admin" alkalmazáshoz. Most csak annyit kell tennünk, hogy a saját, `blog` alkalmazásunkhoz hozzáadunk néhány statikus fájlt. Ehhez pedig létre kell hozunk egy "`static`" nevű könyvtárat a blog applikáción belül: djangogirls - ├── blog - │ ├── migrations - │ └── static - └── mysite + ├── blog + │ ├── migrations + │ ├── static + │   └── templates + └── mysite A Django automatikusan megtalál minden "static" nevű mappát az alkalmazásaid könyvtárain belül, és képes lesz használni azok tartalmát statikus fájlokként. @@ -56,16 +57,14 @@ A Django automatikusan megtalál minden "static" nevű mappát az alkalmazásaid djangogirls └─── blog - └─── statikus + └─── static └─── css └─── blog.css Itt az ideje, hogy a CSS fájlunkba írjunk is valamit! Nyisd meg a `blog/static/css/blog.css` fájlt a kódszerkesztődben. -Most nem fogunk túlságosan belemélyedni a CSS-be, mert nem bonyolult, és magadtól is meg tudod majd tanulni a workshop után. Szerintünk a [Codeacademy][2] HTML & CSS kurzusából mindent megtanulhatsz arról, hogyan teheted széppé a weboldalaidat CSS segítségével. - - [2]: https://www.codecademy.com/tracks/web +Most nem fogunk túlságosan belemélyedni a CSS-be, mert nem bonyolult, és magadtól is meg tudod majd tanulni a workshop után. Ennek a fejezetnek a végén ajánlunk egy ingyenes kurzust, ahol többet tudhatsz meg a CSS-ről. De azért egy pár dolgot megmutatunk. Például megváltoztathatnánk a header színét? Hogy a számítógépek megértsék a színeket, speciális kódokat használnak. `#` jellel kezdődnek, majd 6 betű (A-F) és szám (0-9) következik. Színkódokat például itt találhatsz: http://www.colorpicker.com/. [Előre meghatározott színeket][3] is használhatsz, mint a `red` vagy a `green`. @@ -94,7 +93,7 @@ Olvass utána a [CSS szelektorokról a w3schools oldalán][4]. Mindezek után közölnünk kell a HTML fájlunkkal is, hogy hozzáadtunk pár CSS-t. Nyisd meg a `blog/templates/blog/post_list.html` fájlt és add a következő sort a fájl legelejére: ```html -{% load staticfiles %} +{% load static %} ``` Itt csak betöltünk pár statikus fájlt :). Ezután a `` és a `` tagek közé, a Bootstrap CSS fájlok linkjei után (a böngésző olyan sorrendben olvassa az egyes fájlokat, amilyenben követik egymást, tehát a mi fájlunkban lévő kód lehet, hogy felülír pár kódot a Bootstrap fájlban), a következő sort add: @@ -108,7 +107,7 @@ Most megmondtuk a template-ünknek, hol találja a CSS fájlokat. Így kellene kinéznie a fájlodnak: ```html -{% load staticfiles %} +{% load static %} Django Girls blog @@ -286,10 +285,10 @@ Mentsd el a fájlokat és frissítsd az oldalad. [8]: images/final.png -Nahát! Fantaszikus nem? A kódot, amit beillesztettünk, nem túl nehéz megérteni és a nagyja már csak átolvasva is érthető kell, hogy legyen. +Nahát! Fantaszikus nem? A kódot, amit beillesztettünk, nem túl nehéz megérteni és a nagyja már csak átolvasva is érthető kell, hogy legyen. Mit változtatnál ahhoz, hogy a dátum türkízkék színű legyen? Ne félj kicsit megbuherálni ezt a CSS-t és megváltoztatni pár dolgot. Ha valamit elrontasz, ne aggódj, vissza tudod csinálni! Mindenesetre melegen ajánljuk ezt az ingyenes online [Codeacademy HTML & CSS kurzust][2], mint workshop utáni házi feladatot, hogy mindent tudj arról, hogyan tudod csinosabbá varázsolni a weboldaladat CSS-sel. -Készen állsz a következő fejezetre?! :) \ No newline at end of file +Készen állsz a következő fejezetre?! :) diff --git a/hu/css/images/bootstrap1.png b/hu/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/hu/css/images/bootstrap1.png and b/hu/css/images/bootstrap1.png differ diff --git a/hu/css/images/color2.png b/hu/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/hu/css/images/color2.png and b/hu/css/images/color2.png differ diff --git a/hu/css/images/final.png b/hu/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/hu/css/images/final.png and b/hu/css/images/final.png differ diff --git a/hu/css/images/font.png b/hu/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/hu/css/images/font.png and b/hu/css/images/font.png differ diff --git a/hu/css/images/margin2.png b/hu/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/hu/css/images/margin2.png and b/hu/css/images/margin2.png differ diff --git a/hu/deploy/README.md b/hu/deploy/README.md index 47848ff0bee..4640eb3f49d 100644 --- a/hu/deploy/README.md +++ b/hu/deploy/README.md @@ -6,19 +6,16 @@ Ezidáig a honlapod csak a saját számítógépeden volt elérhető - most tanu Ahogyan azt már tudod, a honlapot egy szerveren kell elhelyezni. Több szerver szolgáltató is elérhető az interneten. Mi egy olyat fogunk használni, amit viszonylag egyszerű kezelni: [PythonAnywhere][1]. A PythonAnywhere ingyenes olyan kisebb alkalmazások számára, amelyeknek nincs sok látogatójuk, tehát a mi esetünkben ez pont megfelelő lesz. - [1]: https://pythonanywhere.com/ + [1]: https://www.pythonanywhere.com/ A másik külső szolgáltatás, amit igénybe fogunk venni a [GitHub][2], ami egy ún. code hosting service (forráskód tárolására és megosztására alkalmas online tárhely). Vannak más hozzá hasonló szolgáltatók is, de szinte minden programozó ezt használja manapság, és nemsokára te is közéjük tartozhatsz! [2]: https://www.github.com -A GitHubról fogjuk a forráskódunkat áthelyezni a PythonAnywhere-be, és fordítva. +Ez a három hely lesz fontos. A saját számítógéped lesz az a hely, ahol fejlesztesz és tesztelsz. Amikor elégedett vagy a módosításaiddal, felmásolod a programodat GitHub-ra. A website-od a PythonAnywhere-en lesz, és a GitHub-ról fogod frissíteni. -# Git - -A Git egy "version control system" (VCS, magyarul verziókezelő rendszer), amit sok programozó használ. Ez a szoftver nyomon követ minden változást a fájlokban, így a későbbiekben is visszatérhetünk egy bizonyos régebbi verzióhoz. Valamelyest hasonlít a "változások nyomon követése" funkcióhoz a Microsoft Wordben, de ez jóval hatékonyabb. -## Git telepítése +# Git > **Megjegyzés** Ha már követted a korábbi telepítési utasításokat, ezt a pontot átugorhatod és kezdheted kialakítani a saját Git csomagtáradat! @@ -40,23 +37,30 @@ A git csomagtár inicializálása olyasvalami, amit minden projekt esetében csa A Git ezután nyomon követ minden változást a fájlokban és mappákban ezen a mappán belül. De vannak bizonyos fájlok, amiket nem szeretnénk figyelembe venni. Ezt úgy tehetjük meg, hogy létrehozunk egy fájlt `.gitignore` névvel a gyökérkönyvtárban. Nyisd meg a szövegszerkesztőt és hozz létre egy új fájlt, amibe az alábbi sorok kerülnek: - *.pyc - __pycache__ - myvenv - db.sqlite3 - .DS_Store +{% filename %}.gitignore{% endfilename %} +``` +*.pyc +*~ +__pycache__ +myvenv +db.sqlite3 +/static +.DS_Store +``` Majd mentsd le `.gitignore` néven a "djangogirls" legfelsőbb mappájában. > **Megjegyzés** Nagyon fontos, hogy a fájl neve ponttal kezdődjön! Ha bármi gond adódna a fájl létrehozásánál (pl. Mac számítógépeken a Finder alapvetően nem engedi, hogy a fájlnév ponttal kezdődjön), akkor használd a "Save as" lehetőséget. +> **Megjegyzés** A `.gitignore` file-ban megadott file-ok egyike a `db.sqlite3`. Ez a file a lokális adatbázisod, ez tárolja az összes blogposztodat. Nem akarjuk hozzáadni a repository-hoz, mert a PythonAnywhere-en lévő weboldal egy másik adatbázist fog használni. Az az adatbázis lehet SQLite, mint a fejlesztői gépeden, de többnyire egy MySQL nevűt fogsz használni, amely jóval több látogatót tud kiszolgálni mint az SQLite. Akármelyiket választod, azzal hogy az SQLite adatbázisod kihagyjuk a GitHub másolatból, az összes blogpost amelyet eddig létrehoztál csak lokálisan lesz elérhető, a publikus weboldalon újra létre kell majd ezeket hozni. Gondolj úgy a lokális adatbázisodra, mint egy játszótérrel, ahol kipróbálhatsz különböző dolgokat és nem kell attól tartanod, hogy valódi posztokat fogsz törölni a blogodról. + Jó ötlet a `git status` parancs használata még a `git add` előtt, valamint ezen kívül még bármikor, ha tudni szeretnéd, hogy mi változott. Ez majd segít elkerülni olyan szituációkat, mint például rossz fájlok hozzáadása ill. feltöltése a csomagtárba. A `git status` parancs információt szolgáltat minden nem követett (not tracked) / megváltozott (modified) /feltöltésre felkészített fájlról (staged files) stb. A kimenet ehhez hasonló lesz: $ git status On branch master - Initial commit + No commits yet Untracked files: (use "git add ..." to include in what will be committed) @@ -167,20 +171,21 @@ Ez majd betölti a forráskódod másolatát a PythonAnywhere-be. Ellenőrizhete Ugyanúgy, ahogy a saját gépeden csináltad, a PythonAnywhere-en is létrehozhatsz virtualenvet. Írd be a Bash konzolba: +{% filename %}PythonAnywhere parancssor{% endfilename %} ``` $ cd my-first-blog -$ virtualenv --python=python3.4 myvenv -Running virtualenv with interpreter /usr/bin/python3.4 +$ virtualenv --python=python3.6 myvenv +Running virtualenv with interpreter /usr/bin/python3.6 [...] Installing setuptools, pip...done. $ source myvenv/bin/activate -(mvenv) $ pip install django whitenoise +(myvenv) $ pip install django~=1.11.0 Collecting django [...] -Successfully installed django-1.8.2 whitenoise-2.0 +Successfully installed django-1.11.3 ``` @@ -188,40 +193,19 @@ Successfully installed django-1.8.2 whitenoise-2.0 -### Statikus fájlok összegyűjtése. - -Kíváncsi vagy, mi ez a "whitenoise" nevű dolog? Egy eszköz az úgynevezett "statikus fájlok" kiszolgálására. A statikus fájlok olyan fájlok, amelyek nem változnak meg rendszeresen, vagy nem futtatnak programkódot - mint például a HTML vagy a CSS fájlok. A szervereken ezek másképp működnek, mint a saját gépünkön, ezért szükségünk van egy olyan eszközre, mint a "whitenoise", hogy kiszolgáljuk őket. - -A statikus fájlokról többet is tanulsz majd a tutorial során, amikor a CSS-t fogod szerkeszteni a honlapodhoz. +## Tegyük közzé a blogot a weben! -Egyelőre csak egy `collectstatic` parancsot kell lefuttatnod a szerveren. Ez megmondja a Django-nak, hogy gyűjtse össze a szerveren az összes statikus fájlt, amire szüksége lesz. Ezek most többnyire olyan fájlok, amik az adminfelület kinézetét adják. +Most már fent van a kódod a PythonAnywhere-en, kész a virtuális környezet, össze vannak gyűjtve a statikus fájlok, és az adatbázist is elkészítetted. Készen állsz, hogy webes alkalmazást csinálj belőle! - (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 - +Menj vissza a PythonAnywhere dashboardra (a logóra kattintva megteheted), majd kattints a **Web** tabra. Végül nyomd meg a **Add a new web app** gombot. -Írd be, hogy "yes", és el is tűnik! Te is imádod, ha kiírathatsz a gépeddel egy csomó érthetetlen szöveget? Én mindig fura hangokat adok ki ilyenkor, nagyon jól illik hozzá. Brp, brp, brp... +Miután leokéztad a domainnevedet, válaszd a **manual configuration**-t (kézi konfiguráció - vigyázz, *ne* a "Django" opciót válaszd!) a párbeszédablakban. Aztán válaszd ki a **Python 3.4**-et, majd nyomd meg a Nextet. - 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'. - +> **Megjegyzés** Fontos, hogy a "Manual configuration" lehetőséget válaszd, ne a "Django"-t. Túl menők vagyunk a PythonAnywhere-es Django setuphoz:) ### Adatbázis létrehozása PythonAnywhere-en -Van még valami, ami máshogy működik a saját gépeden és a szerveren: különböző szervert használnak. Így a felhasználói fiókok és a blogposztok különbözőek lehetnek a szerveren és a gépeden. +Van még valami, ami máshogy működik a saját gépeden és a szerveren: különböző adatbázist használnak. Így a felhasználói fiókok és a blogposztok különbözőek lehetnek a szerveren és a gépeden. A szerveren ugyanúgy tudod létrehozni az adatbázist, mint a saját gépeden, a `migrate` és `createsuperuser` parancsokkal: @@ -234,16 +218,6 @@ A szerveren ugyanúgy tudod létrehozni az adatbázist, mint a saját gépeden, (mvenv) $ python manage.py createsuperuser -## Tegyük közzé a blogot a weben! - -Most már fent van a kódod a PythonAnywhere-en, kész a virtuális környezet, össze vannak gyűjtve a statikus fájlok, és az adatbázist is elkészítetted. Készen állsz, hogy webes alkalmazást csinálj belőle! - -Menj vissza a PythonAnywhere dashboardra (a logóra kattintva megteheted), majd kattints a **Web** tabra. Végül nyomd meg a **Add a new web app** gombot. - -Miután leokéztad a domainnevedet, válaszd a **manual configuration**-t (kézi konfiguráció - vigyázz, *ne* a "Django" opciót válaszd!) a párbeszédablakban. Aztán válaszd ki a **Python 3.4**-et, majd nyomd meg a Nextet. - -> **Megjegyzés** Fontos, hogy a "Manual configuration" lehetőséget válaszd, ne a "Django"-t. Túl menők vagyunk a PythonAnywhere-es Django setuphoz:) - ### Virtuális környezet beállítása Most a PythonAnywhere config oldalára kerülsz, ahol különböző dolgokat állíthatsz be az appeddel kapcsolatban. Ha bármit meg szeretnél változtatni később, ide kell visszajönnöd. @@ -275,13 +249,16 @@ if path not in sys.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()) +from django.contrib.staticfiles.handlers import StaticFilesHandler +application = StaticFilesHandler(get_wsgi_application()) ``` > **Megjegyzés** Ne felejtsd el a saját felhasználóneveddel helyettesíteni a ``-et! +> **Megjegyzés** A negyedik sorban gondoskodunk arról, hogy Python megtalálja a programunkat. Fontos, hogy ez az elérési út helyes legyen, és különösen hogy ne legyenek benne fölösleges szóközök. Különben "ImportError" hibát fogsz találni a logfile-ban. -Ennek a fájlnak az a dolga, hogy megmondja a PythonAnywhere-nek, hol lakik a webes alkalmazásunk, és mi annak a fájlnak a neve, ahol a Django beállításai vannak. Ezenkívül a "whitenoise"-t is beállítja, ami a statikus fájlok kiszolgálásában segít. +Ennek a fájlnak az a dolga, hogy megmondja a PythonAnywhere-nek, hol lakik a webes alkalmazásunk, és mi annak a fájlnak a neve, ahol a Django beállításai vannak. + +A `StaticFilesHandler` a CSS-ünkről gondoskodik. Helyi fejlesztéskor a `runserver` parancs látja el ezt a feladatot. Kicsivel később behatóbban megismerkedünk a statikus file-okkal, amikor a weboldalunk CSS-ét szerkesztjük. Nyomd meg a **Save** (Mentés) gombot, majd menj vissza a **Web** fülre. @@ -311,4 +288,6 @@ Ha hibát látsz, amikor megpróbálod meglátogatni az oldaladat, az első hely A honlapod alapértelmezett oldala a "Welcome to Django", ugyanúgy, mint a saját gépeden. Add hozzá az `/admin/`-t az URL végéhez, és az adminfelületre kerülsz. Jelentkezz be a felhasználóneveddel és a jelszavaddal, és látni fogod, hogy itt is tudsz új Postokat létrehozni. +Ha már létrehoztál pár blogpostot, válts vissza a helyi gépedre (nem PythonAnywhere). Ezután a helyi gépeden érdemes dolgoznod. Ez gyakori munkafolyamat webfejlesztéskor - lokális fejlesztés, a változtatások feltöltése GitHub-ra, majd letöltése az éles webszerverre. Ez lehetővé teszi, hogy kisérletezz a éles webszervered elrontása nélkül. Vagány, mi? + Megérdemelsz egy *HATALMAS* vállveregetést! A szerver deployment a webfejlesztés legbonyolultabb részei közé tartozik, és a fejlesztők gyakran napokat töltenek azzal, hogy mindent működésre bírjanak. De neked most komolyan van egy működő weboldalad, az Interneten, és nem is tartott sokáig megcsinálni! diff --git a/hu/deploy/images/github_get_repo_url_screenshot.png b/hu/deploy/images/github_get_repo_url_screenshot.png index 62a29f5f8d7..ee1560b1e85 100644 Binary files a/hu/deploy/images/github_get_repo_url_screenshot.png and b/hu/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/hu/deploy/images/new_github_repo.png b/hu/deploy/images/new_github_repo.png index 64011e59a52..d1f82e5d863 100644 Binary files a/hu/deploy/images/new_github_repo.png and b/hu/deploy/images/new_github_repo.png differ diff --git a/hu/deploy/images/pythonanywhere_web_tab_virtualenv.png b/hu/deploy/images/pythonanywhere_web_tab_virtualenv.png index 97e87e7b07b..6069f6da831 100644 Binary files a/hu/deploy/images/pythonanywhere_web_tab_virtualenv.png and b/hu/deploy/images/pythonanywhere_web_tab_virtualenv.png differ diff --git a/hu/deploy/install_git.md b/hu/deploy/install_git.md index 77b9051fa9a..a23bb46401e 100644 --- a/hu/deploy/install_git.md +++ b/hu/deploy/install_git.md @@ -1,17 +1,59 @@ -### Windows +A Git egy "version control system" (VCS, magyarul verziókezelő rendszer), amit sok programozó használ. Ez a szoftver nyomon követ minden változást a fájlokban, így a későbbiekben is visszatérhetünk egy bizonyos régebbi verzióhoz. Valamelyest hasonlít a "változások nyomon követése" funkcióhoz a Microsoft Wordben, de ez jóval hatékonyabb. + +## Git telepítése + + A Gitet innen töltheted le: [git-scm.com](https://git-scm.com/). Telepítése: csak kattints a "next" gombra egészen addig, amíg el nem érsz az ötödik lépésig - "Adjusting your PATH environment" címmel - itt válaszd ki a "Run Git and associated Unix tools from the Windows command-line" lehetőséget (keresd alul). Ezen kívül a többi maradhat az alapbeállításon. Checkout Windows-style, commit Unix-style line endings - ezek is maradhatnak így. -### MacOS + + + Töltsd le a Git-tet az alábbi linken: [git-scm.com](https://git-scm.com/), majd kövesd az utasításokat. -### Linux +> **Megjegyzés** Ha OS X 10.6, 10.7, vagy 10.8-et használsz, Az ezen a linken elérhető verziót kell telepítened: [Git teleptő OS X Snow Leopard-ra](https://sourceforge.net/projects/git-osx-installer/files/git-2.3.5-intel-universal-snow-leopard.dmg/download) + + + + + +{% filename %}parancssor{% endfilename %} +```bash +$ sudo apt install git +``` + + + + + +{% filename %}parancssor{% endfilename %} +```bash +$ sudo yum install git +``` + + + + + +{% filename %}parancssor{% endfilename %} +```bash +$ sudo dnf install git +``` + + + + -Ha még nincs telepítve, elérhető a a package manager-en keresztül, szóval próbáld meg az alábbiakat: +{% filename %}parancssor{% endfilename %} +```bash +$ sudo zypper install git +``` - sudo apt-get install git - # vagy - sudo yum install git - # vagy - sudo zypper install git + diff --git a/hu/django_admin/README.md b/hu/django_admin/README.md index 41fcb46710d..fb295d3f4f9 100644 --- a/hu/django_admin/README.md +++ b/hu/django_admin/README.md @@ -19,7 +19,11 @@ Most nézzük meg, hogy néz ki a Post modell. Ne felejtsd el futtatni a `python [1]: images/login_page2.png -A bejelentkezéshez létre kell hoznod egy *superuser*-t - egy olyan felhasználót, akinek mindenhez van hozzáférése az oldalon. Menj vissza a parancssorba, és írd be a `python manage.py createsuperuser` parancsot, majd nyomj entert. A következő lépésekben meg kell adnod egy felhasználónevet (ne használj nagybetűket és szóközt), emailcímet és jelszót. Ne ijedj meg, ha nem látod a jelszót, amikor begépeled - ennek így kell lennie. Csak írd be, és nyomj `enter`t a folytatáshoz. Az outputnak így kell kinéznie (természetesen a felhasználónév és az email az lesz, amit te adtál meg): +A bejelentkezéshez létre kell hoznod egy *superuser*-t - egy olyan felhasználót, akinek mindenhez van hozzáférése az oldalon. Menj vissza a parancssorba, és írd be a `python manage.py createsuperuser` parancsot, majd nyomj entert. + +> Ne felejtsd, hogy ahhoz hogy új parancsokat tudj lefuttatni, miközben a webszerver fut, új terminál ablakot kell nyitnod és abban aktiválnod a virtualenvet. Erről Az első Django projekted! fejezetben, a Webszerver elindítása szakaszban volt szó. + +A következő lépésekben meg kell adnod egy felhasználónevet (ne használj nagybetűket és szóközt), emailcímet és jelszót. Ne ijedj meg, ha nem látod a jelszót, amikor begépeled - ennek így kell lennie. Csak írd be, és nyomj `enter`t a folytatáshoz. Az outputnak így kell kinéznie (természetesen a felhasználónév és az email az lesz, amit te adtál meg): (myvenv) ~/djangogirls$ python manage.py createsuperuser Username: admin @@ -43,6 +47,6 @@ Nyisd meg a Posts részt, és kísérletezz vele egy kicsit. Hozz létre 5-6 blo [3]: images/edit_post3.png -Ha szeretnél többet megtudni a Django adminról, a Django dokumentációban tudsz olvasni róla: https://docs.djangoproject.com/en/1.8/ref/contrib/admin/ +Ha szeretnél többet megtudni a Django adminról, a Django dokumentációban tudsz olvasni róla: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/ Itt az ideje, hogy kávézz vagy teázz egyet, vagy egyél valamit, hogy új erőre kapj. Elkészítetted az első Django modelledet - megérdemelsz egy kis lazítást! \ No newline at end of file diff --git a/hu/django_admin/images/django_admin3.png b/hu/django_admin/images/django_admin3.png index a450b4f9630..ea01ab951bf 100644 Binary files a/hu/django_admin/images/django_admin3.png and b/hu/django_admin/images/django_admin3.png differ diff --git a/hu/django_admin/images/edit_post3.png b/hu/django_admin/images/edit_post3.png index c8572a73e7d..d577b111424 100644 Binary files a/hu/django_admin/images/edit_post3.png and b/hu/django_admin/images/edit_post3.png differ diff --git a/hu/django_admin/images/login_page2.png b/hu/django_admin/images/login_page2.png index 47153ef6960..6ae26e9959a 100644 Binary files a/hu/django_admin/images/login_page2.png and b/hu/django_admin/images/login_page2.png differ diff --git a/hu/django_forms/README.md b/hu/django_forms/README.md index 6a83a7af970..865cbbb1e2d 100644 --- a/hu/django_forms/README.md +++ b/hu/django_forms/README.md @@ -48,12 +48,12 @@ Itt az ideje, hogy megnyisd a `blog/templates/blog/base.html` fájlt. Itt hozzá ``` -Figyelem: az új nézetünket `post_new`-nak fogjuk hívni. +Figyelem: az új nézetünket `post_new`-nak fogjuk hívni. A `"glyphicon glyphicon-plus"` class a bootstrap theme biztosítja, és egy pluszjelet fog megjeleníteni. Miután hozzáadtad ezt a sort, így fog kinézni a html fájlod: ```html -{% load staticfiles %} +{% load static %} Django Girls blog @@ -211,10 +211,10 @@ from django.shortcuts import redirect Ezt írd a fájlod elejére. És most megmondhatjuk a Django-nak: menj az új blogposzt `post_detail` oldalára. ```python -return redirect('blog.views.post_detail', pk=post.pk) +return redirect('post_detail', pk=post.pk) ``` -A `blog.views.post_detail` a nézet neve, ahova most menni akarunk. Emlékszel, hogy ez a *view* egy `pk` változót kér? Ahhoz, hogy ezt megkapja, a `pk=post.pk` részt használjuk, ahol a `post` az új blogposztunkat jelenti! +A `post_detail` a nézet neve, ahova most menni akarunk. Emlékszel, hogy ez a *view* egy `pk` változót kér? Ahhoz, hogy ezt megkapja, a `pk=post.pk` részt használjuk, ahol a `post` az új blogposztunkat jelenti! Rendben, elég sokat beszéltünk, de most már látni szeretnéd, hogy néz ki a teljes *view*, igaz? @@ -227,7 +227,7 @@ def post_new(request): post.author = request.user post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) @@ -239,6 +239,12 @@ Talán észrevetted, hogy a poszt elmentése előtt beállítjuk a közzététel Ez nagyszerű! +> Mivel nemrég használtuk a Django admin felületét, a rendszer most azt hiszi, hogy be vagyunk jelentkezve. Néhány esetben előfordul, hogy a rendszer kijelentkeztet minket (pl. ha bezárod a böngészőt vagy újraindítod az adatbázist). Ha azt veszed észre, hogy a hibaüzenetek arra utalnak, hogy nincs bejelentkezett felhasználó, menj az admin oldalra -http://127.0.0.1:8000/admin - és jelentkezz be újra. Ez ideiglenesen megoldja a problémát. Van egy hosszútávú megoldás is a **Házi feladat: tedd biztonságosabbá a weboldalad!** fejezetben a tutorial fő része után. + +![Bejelentkezési hiba][4] + + [4]: images/post_create_error.png + ## Form validáció Most megmutatjuk, mennyire menők a Django űrlapok. Egy blogposztnak kell, hogy legyen `title` és `text` mezője. A `Post` modellben nem jelentettük ki külön, hogy ezek a mezők nem kötelezőek (ellentétben a `published_date` mezővel), ezért a Django elvárja, hogy ki legyenek töltve. @@ -251,12 +257,6 @@ Próbáld meg elmenteni az űrlapot `title` vagy `text` nélkül. Találd ki, mi A Django gondoskodik az összes mező ellenőrzéséről. Hát nem fantasztikus? -> Mivel nemrég használtuk a Django admin felületét, a rendszer most azt hiszi, hogy be vagyunk jelentkezve. Néhány esetben előfordul, hogy a rendszer kijelentkeztet minket (pl. ha bezárod a böngészőt vagy újraindítod az adatbázist). Ha azt veszed észre, hogy a hibaüzenetek arra utalnak, hogy nincs bejelentkezett felhasználó, menj az admin oldalra -http://127.0.0.1:8000/admin - és jelentkezz be újra. Ez ideiglenesen megoldja a problémát. Van egy hosszútávú megoldás is a **Házi feladat: tedd biztonságosabbá a weboldalad!** fejezetben a tutorial fő része után. - -![Bejelentkezési hiba][4] - - [4]: images/post_create_error.png - ## Űrlapok szerkesztése Most már tudod, hogyan tudsz új formot hozzáadni. De mi van, ha egy létező űrlapot szeretnél módosítani? Az eddigiekhez nagyon hasonlóan fog működni. Gyorsan készítsük néhány fontos dolgot (ha nem értesz valamit, kérdezd meg a coachodat, vagy nézz bele az előző fejezetekbe, hiszen ezeket a lépéseket már mind megcsináltad egyszer). @@ -306,7 +306,7 @@ def post_edit(request, pk): post.author = request.user post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm(instance=post) return render(request, 'blog/post_edit.html', {'form': form}) @@ -340,7 +340,7 @@ Változtasd meg a címet vagy a szöveget, és mentsd el! Gratulálunk! Az alkalmazásod egyre és egyre jobb! -Ha szeretnél többet tudni a Django formokról, olvass róluk a dokumentációban: https://docs.djangoproject.com/en/1.8/topics/forms/ +Ha szeretnél többet tudni a Django formokról, olvass róluk a dokumentációban: https://docs.djangoproject.com/en/1.11/topics/forms/ ## Biztonság diff --git a/hu/django_forms/images/csrf2.png b/hu/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/hu/django_forms/images/csrf2.png and b/hu/django_forms/images/csrf2.png differ diff --git a/hu/django_forms/images/drafts.png b/hu/django_forms/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/hu/django_forms/images/drafts.png and b/hu/django_forms/images/drafts.png differ diff --git a/hu/django_forms/images/edit_button2.png b/hu/django_forms/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/hu/django_forms/images/edit_button2.png and b/hu/django_forms/images/edit_button2.png differ diff --git a/hu/django_forms/images/edit_form2.png b/hu/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/hu/django_forms/images/edit_form2.png and b/hu/django_forms/images/edit_form2.png differ diff --git a/hu/django_forms/images/form_validation2.png b/hu/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/hu/django_forms/images/form_validation2.png and b/hu/django_forms/images/form_validation2.png differ diff --git a/hu/django_forms/images/new_form2.png b/hu/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/hu/django_forms/images/new_form2.png and b/hu/django_forms/images/new_form2.png differ diff --git a/hu/django_forms/images/post_create_error.png b/hu/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/hu/django_forms/images/post_create_error.png and b/hu/django_forms/images/post_create_error.png differ diff --git a/hu/django_installation/instructions.md b/hu/django_installation/instructions.md index 139c8f2100c..e0f6b13de91 100644 --- a/hu/django_installation/instructions.md +++ b/hu/django_installation/instructions.md @@ -10,6 +10,8 @@ Tehát először is hozzunk létre egy **virtuális környezetet** (virtual envi Csak annyit kell tenned, hogy kiválasztasz egy könyvtárat, ahova a `virtualenv`et szeretnéd telepíteni, például a home könyvtárat. Windowson ez így nézhet ki: `C:\Users\Name` (ahol a `Name` a felhasználód neve). +> __Megjegyzés__ Windows-on gondoskodj arról, hogy ez a könyvtár nem tartalmaz ékezetes vagy speciális karaktereket; ha a van ékezetes karakter a felhasználónevedben, használj egy másik könyvtárt, például `C:\djangogirls`. + Ehhez a tutorialhoz egy új, `djangogirls` nevű mappát fogunk használni a home könyvtáradon belül: mkdir djangogirls @@ -21,24 +23,43 @@ Most pedig létrehozunk egy `myvenv` nevű virtuális környezetet. A kód álta python3 -m venv myvenv -### Windows + -Ahhoz, hogy létrehozz egy új `virtualenv`-et, meg kell nyitni a konzolt (pár fejezettel ezelőtt tanultál róla - emlékszel?) és a ezt a parancsot kell lefuttatnod: `C:\Python34\python -m venv myvenv`. Ez fog történni: +Ahhoz, hogy létrehozz egy új `virtualenv`-et, meg kell nyitni a konzolt (pár fejezettel ezelőtt tanultál róla - emlékszel?) és a ezt a parancsot kell lefuttatnod: `C:\Python35\python -m venv myvenv`. Ez fog történni: - C:\Users\Name\djangogirls> C:\Python34\python -m venv myvenv + C:\Users\Name\djangogirls> C:\Python35\python -m venv myvenv -itt a `C:\Python34\python` azt a könyvtárat jelenti, ahova korábban a Pythont telepítetted, és a `myvenv` a `virtualenv`-ed neve. Bármi más nevet is használhatsz, de maradj a kisbetűs szavaknál, és ne használj szóközt, ékezeteket, vagy más speciális karaktereket. Jó ötlet rövid nevet adni - sokszor be kell majd gépelned! +itt a `C:\Python35\python` azt a könyvtárat jelenti, ahova korábban a Pythont telepítetted, és a `myvenv` a `virtualenv`-ed neve. Bármi más nevet is használhatsz, de maradj a kisbetűs szavaknál, és ne használj szóközt, ékezeteket, vagy más speciális karaktereket. Jó ötlet rövid nevet adni - sokszor be kell majd gépelned! + + -### Linus és OS X + -A `virtualenv` létrehozása Linux és OS X környezetben is csak annyiból áll, hogy a `python3 -m venv myvenv` parancsot futtatod. Így fog kinézni: +A `virtualenv` létrehozása Linux és macOS környezetben is csak annyiból áll, hogy a `python3 -m venv myvenv` parancsot futtatod. Így fog kinézni: ~/djangogirls$ python3 -m venv myvenv A `myvenv` a`virtualenv`-ed neve. Más nevet is használhatsz, de maradj a kisbetűs szavaknál, és ne használj szóközt, ékezeteket, vagy más speciális karaktereket. Jó ötlet rövid nevet adni - sokszor be kell majd gépelned! +> **MEGJEGYZÉS:** Debian/Ubuntu némelyik verziójánál az alábbi hibaüzenetet kaphatod: + +>{% filename %}parancssor{% 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. +>``` +> +> Ebben az esetben a fenti leírást követve telepítsd a `python3-venv` csomagot: +>{% filename %}parancssor{% endfilename %} +>``` +>$ sudo apt install python3-venv +>``` + > **MEGJEGYZÉS:** A virtuális környezetet létrehozó parancs Ubuntu 14.04 alatt ezt a hibát adja: > > Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 @@ -46,22 +67,50 @@ A `myvenv` a`virtualenv`-ed neve. Más nevet is használhatsz, de maradj a kisbe > > Hogy ezt elkerüld, használd a `virtualenv` parancsot. > -> ~/djangogirls$ sudo apt-get install python-virtualenv -> ~/djangogirls$ virtualenv --python=python3.4 myvenv +> ~/djangogirls$ sudo apt install python-virtualenv +> ~/djangogirls$ virtualenv --python=python3.6 myvenv > +> **MEGJEGYZÉS:** Ha az alábbi hibaüzenetet kapod: + +>{% filename %}parancssor{% endfilename %} +>``` +>E: Unable to locate package python3-venv +>``` + +> Akkor az alábbit futtasd: +> +>{% filename %}parancssor{% endfilename %} +>``` +>sudo apt install python3.6-venv +>``` + + + ## Hogyan dolgozhatsz virtuális környezetben A fenti parancs létrehozott egy `myvenv` nevű (vagy bármi más név, amit választottál) könyvtárat, ami a virtuális környezetünket tartalmazza (ez tulajdonképpen csak egy csomó könyvtár és fájl). -#### Windows + Így indíthatod el a virtuális környezetet: C:\Users\Name\djangogirls> myvenv\Scripts\activate +> __MEGJEGYZÉS:__ Windows 10-en lehet hogy egy hibaüzenetet kapsz Windows PowerShell-ben, amely szerint `execution of scripts is disabled on this system` (scriptek futtatása le van tiltva ezen a rendszeren). Ebben az esetben nyiss egy másik Windows PowerShell-t a "Run as Administrator" (adminisztrátorként futtatás) opcióval. Majd próbáld meg az alábbi parancsot beírni mielőtt elindítod a virtuális környezetedet: +> +>{% filename %}parancssor{% 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 +>``` -#### Linus és OS X + + + Így indíthatod el a virtuális környezetet: @@ -84,6 +133,7 @@ vagy: (myvenv) ~/djangogirls$ + Figyeld meg, hogy megjelent a `(myvenv)` előtag! @@ -93,21 +143,50 @@ Oké, most már minden feltétel teljesült. Végre installálhatjuk a Django-t! ## A Django telepítése -Most, hogy elindítottad a `virtualenv`-et, a `pip` segítségével tudod telepíteni a Django-t. Futtasd ezt a parancsot a konzolban: `pip install django==1.8` (figyelj oda, hogy dupla egyenlőségjelet használj: `==`). +Most, hogy elindítottad a `virtualenv`-et, telepiteni tudod a Django-t. - (myvenv) ~$ pip install django==1.8 - Downloading/unpacking django==1.8 - Installing collected packages: django - Successfully installed django - Cleaning up... - +Mielőtt ezt megtennénk, meg kell győződnünk arról, hogy a `pip` legfrissebb verzióját használjuk, amelynek segítségével fogjuk tudni telepíteni a Django-t: -Windowson +{% filename %}parancssor{% endfilename %} +``` +(myvenv) ~$ python3 -m pip install --upgrade pip +``` -> Ha hibát kapsz, amikor a pip-et hívod Windowson, nézd meg, hogy tartalmaz-e a projekted elérési útvonala szóközt, ékezetet, vagy speciális karaktereket (pl. `C:\Users\User Name\djangogirls`). Ha igen, helyezd át az egészet egy olyan helyre, ahol nincsenek szóközök, ékezetek vagy speciális karakterek (javaslat: `C:\djangogirls`). Miután áthelyezted, próbáld meg újra lefuttatni az előző parancsot. +Ezután futtasd ezt a parancsot a konzolban: `pip install django~=1.11` (figyelj oda, hogy egy tilde karaktert használunk, amelyet egy egyenlőségjel követ: `~=`). -Linuxon +{% filename %}parancssor{% endfilename %} +``` +(myvenv) ~$ pip install django~=1.11.0 +Collecting django~=1.11.0 + Downloading Django-1.11.3-py2.py3-none-any.whl (6.8MB) +Installing collected packages: django +Successfully installed django-1.11.3 +``` + + + +> Ha hibát kapsz, amikor a pip-et hívod Windowson, nézd meg, hogy tartalmaz-e a projekted elérési útvonala szóközt, ékezetet, vagy speciális karaktereket (pl. `C:\Users\User Name\djangogirls`). Ha igen, használj helyette egy olyan könyvtárat, ahol nincsenek szóközök, ékezetek vagy speciális karakterek (javaslat: `C:\djangogirls`). Hozd létre az új könyvtárat, és abban egy új virtualenvet, majd töröld ki a régit és az új helyen próbáld futtatni az előző parancsot. (A virtualenv könyvtár áthelyezése nem fog működni, mert a virtualenv abszolút elérési utakat használ.) + + + + + +> A parancssorod "megfagyhat" miután telepíteni próbálod a Django-t. Ha ez történik, az előző parancs helyett próbáld meg ezt: +> +>{% filename %}parancssor{% endfilename %} +>``` +>C:\Users\Name\djangogirls> python -m pip install django~=1.11.0 +>``` + + + + > Ha Ubuntu 12.04 alatt hibát kapsz, amikor a pip-et próbálod hívni, futtasd a `python -m pip install -U --force-reinstall pip` parancsot, hogy megjavítsd a virtualenv-ben a pip feltelepített verzióját. + + Ennyi! Most pedig (végre) létrehozhatod a Django alkalmazásodat! diff --git a/hu/django_models/README.md b/hu/django_models/README.md index b80121951bf..b9781b90814 100644 --- a/hu/django_models/README.md +++ b/hu/django_models/README.md @@ -80,10 +80,10 @@ Azt fogod látni, hogy egy új `blog` könyvtár keletkezett, és már most van └── views.py -Miután létrejött az alkalmazás, meg kell mondanunk a Django-nak, hogy használja is azt. A `mysite/settings.py` tehetjük meg. Keresd meg az `INSTALLED_APPS` részt, és adj hozzá egy sort a `)` fölött, amiben ez áll: `'blog'`. Így kell kinéznie ennek a résznek: +Miután létrejött az alkalmazás, meg kell mondanunk a Django-nak, hogy használja is azt. A `mysite/settings.py` tehetjük meg. Keresd meg az `INSTALLED_APPS` részt, és adj hozzá egy sort a `]` fölött, amiben ez áll: `'blog'`. Így kell kinéznie ennek a résznek: ```python -INSTALLED_APPS = ( +INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -91,7 +91,7 @@ INSTALLED_APPS = ( 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', -) +] ``` ### Hozzuk létre a blogposzt modelljét @@ -101,12 +101,13 @@ A `Model` nevű objektumokat a `blog/models.py` fájlban definiáljuk - tehát i Nyisd meg a `blog/models.py`-t, törölj ki mindent, és ezt a kódot írd bele: ```python +from django.conf import settings from django.db import models from django.utils import timezone class Post(models.Model): - author = models.ForeignKey('auth.User') + author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) title = models.CharField(max_length=200) text = models.TextField() created_date = models.DateTimeField( @@ -134,19 +135,21 @@ Azok a sorok, amik úgy kezdődnek, hogy `from` vagy `import`, más fájlokban l * a `Post` a modellünk neve. Más nevet is adhatnál neki (de kerüld el a speciális karaktereket - pl ékezetes karakterek - és a szóközt). Az osztályok (classok) nevét mindig nagybetűvel kezdjük. * a `models.Model` azt jelenti, hogy a Post egy Django Model, így a Django tudni fogja, hogy el kell menteni az adatbázisba. -Most pedig azokat a tulajdonságokat definiáljuk, amikről korábban beszéltünk:`title` (cím), `text` (szöveg), `created_date` (létrehozás dátuma), `published_date` (közzététel dátuma) és `author` (szerző). Ahhoz, hogy ezt megtehessük, mindegyik mezőnek meg kell határoznunk a típusát (Szöveg lesz benne? Egy szám? Dátum? Egy másik objektumhoz fog tartozni, például egy User-hez (felhasználó)?). +Most pedig azokat a tulajdonságokat definiáljuk, amikről korábban beszéltünk:`title` (cím), `text` (szöveg), `created_date` (létrehozás dátuma), `published_date` (közzététel dátuma) és `author` (szerző). Ahhoz, hogy ezt megtehessük, mindegyik mezőnek meg kell határoznunk a típusát (Szöveg lesz benne? Egy szám? Dátum? Egy másik objektumhoz fog kapcsolni, például egy User-hez (felhasználó)?). * `models.CharField` - így definiálsz olyan szövegmezőt, ami meghatározott számú karaktert tartalmazhat. * `models.TextField` - ez hosszú szövegekhez van, korlátozás nélkül. Pont jó egy blogbejegyzéshez, igaz? * `models.DateTimeField` - ez dátumot és időt tartalmaz. * `models.ForeignKey` - ez egy másik modellel való kapcsolatot jelent. -Most nem magyarázzuk el nagyon részletesen a kódot, mert túl sok idő lenne. Ha szeretnél többet tudni a Model mezőkről, és hogy milyen más dolgokat lehet definiálni bennünk, olvashatsz róla a Django dokumentációban (https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-types). +Most nem magyarázzuk el nagyon részletesen a kódot, mert túl sok idő lenne. Ha szeretnél többet tudni a Model mezőkről, és hogy milyen más dolgokat lehet definiálni bennünk, olvashatsz róla a Django dokumentációban (https://docs.djangoproject.com/en/1.11/ref/models/fields/#field-types). És mi a helyzet a `def publish(self):` résszel? Ez pontosan az a `publish` (közzététel) method, amiről korábban beszéltünk. A `def` azt jelenti, hogy ez egy függvény (function) / method, és a `publish` ennek a methodnak a neve. Ha szeretnéd, megváltoztathatod a metódus nevét. Az a szabály, hogy csak kisbetűket használunk, és szóköz helyett underscore-t (alulvonás). Például egy olyan method neve, ami az átlagárat számolja ki, ez lehetne: `calculate_average_price`. A methodok gyakran `return`-ölnek (visszaadnak) valamit. Erre van is egy példa a `__str__` methodban. Ebben az esetben amikor meghívjuk a `__str__()`-t, egy szöveget kapunk vissza (**string**), ami a Post címe. +Vedd észre azt is, hogy mind `def publish(self):` mind `def __str__(self):` indentálva van a class-on bellül. Python számára fontosak a szóközök, ezért a method-okat indentálni kell az osztályokon bellül. Ha ez elmarad, akkor a method nem az adott osztályhoz fog tartozni, és furcsán fog viselkedni a program. + Ha valami még nem teljesen világos a modellekkel kapcsolatban, nyugodtan kérdezd meg a coachodat! Tudjuk, hogy bonyolult, főleg, ha egyszerre tanulsz az objektumokról és a függvényekről. De reméljük, már sokkal kevésbé tűnik varázslatnak az egész! ### Készíts táblákat a modelleknek az adatbázisodban @@ -158,6 +161,7 @@ Az utolsó lépés, hogy hozzáadjuk az új modellünket az adatbázishoz. Elős 0001_initial.py: - Create model Post +**Megjegyzés** Ne felejtsd el elmenteni a módosított file-okat. Különben a számítógéped az előző változatot futtatja le, amely váratlan hibaüzeneteket eredményezhet. A Django létrehozott nekünk egy migrációs fájlt, amit most futtatni fogunk az adatbázison. Írd be, hogy `python manage.py migrate blog`, és ezt az outputot kell kapnod: @@ -169,4 +173,4 @@ A Django létrehozott nekünk egy migrációs fájlt, amit most futtatni fogunk Applying blog.0001_initial... OK -Hurrá! Bekerült az adatbázisba a Post modellünk! Jó lenne látni is, nem igaz? A következő fejezetben kiderül, hogy néz ki! \ No newline at end of file +Hurrá! Bekerült az adatbázisba a Post modellünk! Jó lenne látni is, nem igaz? A következő fejezetben kiderül, hogy néz ki! diff --git a/hu/django_orm/README.md b/hu/django_orm/README.md index 7e09e6db212..6d7172ac15f 100644 --- a/hu/django_orm/README.md +++ b/hu/django_orm/README.md @@ -41,7 +41,7 @@ Hoppá, egy hiba! Azt mondja, hogy nincs olyan, hogy Post. Igaza van -- elfelejt Ez egyszerű: importáljuk a `Post` modellt a `blog.models`-ből. Próbáljuk meg újra megjeleníteni a Post-okat: >>> Post.objects.all() - [, ] + , ]> Egy lista a posztokból, amiket korábban megírtál! Ezeket még a Django admin felületén hoztad létre. Viszont ugyanezt meg tudod tenni a Python segítségével is. De vajon hogyan? @@ -63,7 +63,7 @@ Először importáljuk az User modellt: Milyen felhasználók vannak az adatbázisban? Próbáld meg ezt: >>> User.objects.all() - [] + ]> Ez a superuser, amit korábban hoztál létre! Most vegyük ennek a felhasználónak egy instance-ét: @@ -81,7 +81,7 @@ Most pedig végre létrehozhatjuk a posztot: Hurrá! Meg akarod nézni, hogy működött-e? >>> Post.objects.all() - [, , ] + , , ]> Ott is van, egy újabb poszt a listában! @@ -95,14 +95,14 @@ A móka kedvéért hozz létre még 2-3 posztot, hogy lásd, hogyan működik. H A QuerySet-ek egyik nagy előnye, hogy filterezhetjük (szűrhetjük) őket. Mondjuk le szeretnénk kérdezni az összes posztot, amit az ola User írt. Itt a `filter`-t fogjuk használni az `all` helyett a `Post.objects.all()`-ban. A zárójelek között megadhatjuk, hogy milyen feltétel(ek)nek kell teljesülnie ahhoz, hogy egy blogposzt bekerülhessen a querysetünkbe. Ebben az esetben az `author` (szerző) egyenlő `me`-vel (én). Ezt a Django-ban így írjuk le: `author=me`. Most így néz ki a kódunk: >>> Post.objects.filter(author=me) - [, , , ] + , , , ]> És ha össze szeretnénk gyűjteni minden olyan posztot, aminek a `title` (cím) mezőjében szerepel a 'title' szó? >>> Post.objects.filter(title__contains='title') - [, ] + , ]> > **Note** A `title` és a `contains` (vagyis 'tartalmaz') között két underscore karakter (`_`) van. A Django ORM ezt a szintaxist használja arra, hogy elkülönítse a mezők neveit ("title") a műveletektől vagy filterektől ("contains"). Ha csak egy underscore-t használt, egy ilyen hibát fogsz kapni: "FieldError: Cannot resolve keyword title_contains" (kb "Mezőhiba: a title_contains kulcsszó nem található"). @@ -126,7 +126,7 @@ Aztán közzétesszük a `publish` methoddal! Most próbáld meg újra lekérdezni a közzétett posztok listáját (nyomd meg háromszor a felfelé nyilat, és nyomj `enter`t): >>> Post.objects.filter(published_date__lte=timezone.now()) - [] + ]> ### Objektumok sorbarendezése @@ -134,13 +134,13 @@ Most próbáld meg újra lekérdezni a közzétett posztok listáját (nyomd meg A QuerySetek segítségével sorba is rendezheted az objektumok listáját. Először próbáljuk meg a létrehozás dátuma (`created_date` mező) alapján rendezni őket: >>> Post.objects.order_by('created_date') - [, , , ] + , , , ]> Meg is fordíthatjuk a sorrendet, ha az elejére egy `-` jelet teszünk: >>> Post.objects.order_by('-created_date') - [, , , ] + , , , ]> ### QuerySetek összefűzése @@ -155,4 +155,4 @@ Ez egy nagyon hatékony módszer, és a segítségével bonyolult query-ket írh Remek! Most már készen állsz a következő részre! Hogy kilépj a shellből, gépeld be ezt: >>> exit() - $ \ No newline at end of file + $ diff --git a/hu/django_start_project/README.md b/hu/django_start_project/README.md index eefe4c3787a..88a969dc415 100644 --- a/hu/django_start_project/README.md +++ b/hu/django_start_project/README.md @@ -39,11 +39,13 @@ A `django-admin.py` egy script, ami könyvtárakat és fájlokat hoz létre neke __init__.py +> **Megjegyzés**: A könyvtárszerkezetedben a `venv` könyvtár is meg fog jelenni, amelyet nemrég hoztunk létre. + A `manage.py` egy script, ami az oldal menedzselésében segít. Segítségével elindíthatsz egy webszervert a saját gépeden, anélkül, hogy bármit kellene installálnod, és más dolgokra is jó. A `settings.py` tartalmazza a weboldalat konfigurációját (beállításait),. -Emlékszel, mit olvastál a postásról, aki azt próbálja kitalálni, hova vigye a levelet? Az `urls.py` fájl tartalmazza a mintákat, amiket az `urlresolver` használ.. +Emlékszel, mit olvastál a postásról, aki azt próbálja kitalálni, hova vigye a levelet? Az `urls.py` fájl tartalmazza a mintákat, amiket az `urlresolver` használ. Most ne foglalkozzunk a többi fájllal, mert azokat nem fogjuk módosítani. Az egyetlen dolog, amit ne felejts el, hogy ne töröld ki őket véletlenül! @@ -67,7 +69,7 @@ Szükségünk lesz még arra, hogy megadjuk a statikus fájlokhoz vezető elér ```python STATIC_URL = '/static/' - STATIC_ROOT = os.path.join(BASE_DIR, 'static') + STATIC_ROOT = BASE_DIR / 'static' ``` Amikor a DEBUG értéke True és az ALLOWED_HOSTS üres, a hosztnév alapértelmezetten ['localhost', '127.0.0.1', '[::1]']. Ez deploy után nem fog működni a PythonAnywhere-en, ezért változtassuk meg ezt a beállítást így: @@ -86,12 +88,12 @@ Ez már be van állítva a `mysite/settings.py` fájlodban: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'NAME': BASE_DIR / 'db.sqlite3', } } ``` -Hogy létrehozz egy adatbázist a blogodhoz, futtasd le a következő parancsot a konzolban: `python manage.py migrate` (fontos, hogy a `djangogirls` könyvtárban legyél, ami tartalmazza a `djangogirls` fájlt). Ha minden jól megy, valami ilyesmit kell látnod: +Hogy létrehozz egy adatbázist a blogodhoz, futtasd le a következő parancsot a konzolban: `python manage.py migrate` (fontos, hogy a `djangogirls` könyvtárban legyél, ami tartalmazza a `manage.py` fájlt). Ha minden jól megy, valami ilyesmit kell látnod: (myvenv) ~/djangogirls$ python manage.py migrate Operations to perform: @@ -117,6 +119,8 @@ Hogy létrehozz egy adatbázist a blogodhoz, futtasd le a következő parancsot Készen is vagyunk! Itt az ideje, hogy elindítsd a webszervert, és meglásd, hogy működik-e. +## Webszerver elindítása + Ehhez abban a könyvtárban kell lenned, ahol a `manage.py` fájl van (a `djangogirls` könyvtárban). A konzolban a következő paranccsal tudod elindítani a szervert: `python manage.py runserver`. (myvenv) ~/djangogirls$ python manage.py runserver @@ -132,12 +136,16 @@ Most nincs más dolgod, mint ellenőrizni, hogy fut-e a weboldalad. Nyisd meg a http://127.0.0.1:8000/ -A webszerver átvette az irányítást a parancssorod fölött, egészen addig, amíg le nem állítod. Hogy újabb parancsokat írhass be, amíg fut a szerver, új terminálablakot kell nyitnod, és újraaktiválni a virtuális környezetedet. Hogy leállítsd a szervert, lépj vissza az ablakba, ahol fut, és nyomd meg a CTRL + C (Control és C billentyű egyszerre) billentyűkombinációt. (Windowson lehet, hogy a Ctrl+Break fog működni). - Gratulálunk! Létrehoztad az első weboldaladat, és futtatad is egy webszerver segítségével! Hát nem fantasztikus? ![It worked!][3] [3]: images/it_worked2.png +A webszerver átvette az irányítást a parancssorod fölött, egészen addig, amíg le nem állítod. A terminálba tudsz gépelni, de nem fog lefuttatni új parancsokat. Ez azért van, mert a webszervernek folyamatosan kell futnia, hogy a beérkező lekérdezéseket (request-eket) fogadja. + +> Webszerverek működését a Hogy működik az Internet? fejezetben tekintettük át. + +Hogy újabb parancsokat írhass be, amíg fut a szerver, új terminálablakot kell nyitnod, és újraaktiválni a virtuális környezetedet. Hogy leállítsd a szervert, lépj vissza az ablakba, ahol fut, és nyomd meg a CTRL + C (Control és C billentyű egyszerre) billentyűkombinációt. (Windowson lehet, hogy a Ctrl+Break fog működni). + Készen állsz a következő lépésre? Itt az ideje, hogy létrehozzunk némi tartalmat! diff --git a/hu/django_start_project/images/it_worked2.png b/hu/django_start_project/images/it_worked2.png index 4412ecfc49e..4efa554e567 100644 Binary files a/hu/django_start_project/images/it_worked2.png and b/hu/django_start_project/images/it_worked2.png differ diff --git a/hu/django_templates/README.md b/hu/django_templates/README.md index ad8d0bb7f39..d4407fe2a35 100644 --- a/hu/django_templates/README.md +++ b/hu/django_templates/README.md @@ -26,7 +26,7 @@ Próbáld ki a `blog/templates/blog/post_list.html` template-ben. Cserélj ki mi Ahogy látod, ez minden, amink van: - [, ] + , ]> Ez azt jelenti, hogy a Django objektumok listájaként értelmezi. Emlékszel a **Bevezetés a Python-ba** című fejezetből, hogy hogyan jelenítünk meg listákat? Igen, for loop-okkal! Egy Django template-ben ezt így tudod megtenni: @@ -65,13 +65,13 @@ Próbáld ki a template-edben. [3]: images/step3.png -Észrevetted, hogy most egy kicsit más megjelölést használtunk: `{{ post.title }}`? Az adatokat a `Post` modelben meghatározott mezők szerint érjük el. Emellett `|linebreaksbr` kíséri a szöveget, ezáltal egy filteren keresztül új bekezdéssé alakítja az új sorokat. +Észrevetted, hogy most egy kicsit más megjelölést használtunk: `{{ post.title }}`? Az adatokat a `Post` modelben meghatározott mezők szerint érjük el. Emellett `|linebreaksbr` kíséri a szöveget, ezáltal egy filteren keresztül új bekezdéssé alakítja az újsor karaktereket. ## Még valami Jó lenne látni, hogy a weblapod még mindig működik az Interneten, nem igaz? Telepítsük újra a PythonAnywhere-en. Itt a lépések összefoglalója... -* Először tedd fel a kódot a Github-ra +* Először tedd fel a kódot a GitHub-ra ``` $ git status [...] @@ -93,14 +93,14 @@ $ git pull [...] ``` -* Végül, a [Web][5] menüpontban klikkelj a **Reload**-ra. A frissítések ott vannak! +* Végül, a [Web][5] menüpontban klikkelj a **Reload**-ra. A frissítések ott vannak! Ha a blogposztok a PythonAnywhere oldaladon nem egyeznek a helyi gépeden lévő blogban lévőkkel, az nem probléma. Az adatbázisok a helyi gépeden és PythonAnywhere-en nem szinkronizálódnak a többi file-al együtt. [5]: https://www.pythonanywhere.com/web_app_setup/ -Gratulálunk! Folytatásképp hozz létre új bejegyzéseket a Django adminban (ne felejts el published_date-t hozzáadni), majd frissítsd az oldalt, hogy lásd, megjelentek-e. +Gratulálunk! Folytatásképp hozz létre új bejegyzéseket a Django adminban (ne felejts el published_date-t hozzáadni). Ellenőrizd, hogy a pythonanywhere oldalhoz tartozó admin oldalon https://yourname.pythonanywhere.com/admin vagy. Majd frissítsd az oldalt, hogy lásd, megjelentek-e. Olyan, mint a varázslat? Büszkék vagyunk Rád! Hagy ott egy kicsit a gépet, megérdemelsz egy kis szünetet. :) ![13.4 ábra][6] - [6]: images/donut.png \ No newline at end of file + [6]: images/donut.png diff --git a/hu/django_templates/images/donut.png b/hu/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/hu/django_templates/images/donut.png and b/hu/django_templates/images/donut.png differ diff --git a/hu/django_templates/images/step1.png b/hu/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/hu/django_templates/images/step1.png and b/hu/django_templates/images/step1.png differ diff --git a/hu/django_templates/images/step2.png b/hu/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/hu/django_templates/images/step2.png and b/hu/django_templates/images/step2.png differ diff --git a/hu/django_templates/images/step3.png b/hu/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/hu/django_templates/images/step3.png and b/hu/django_templates/images/step3.png differ diff --git a/hu/django_urls/README.md b/hu/django_urls/README.md index 61db2cdefd6..e43f4e1ec3f 100644 --- a/hu/django_urls/README.md +++ b/hu/django_urls/README.md @@ -16,22 +16,23 @@ Az interneten minden oldalnak szüksége van egy saját URL-re. Innen tudja az a Nyisd meg a `mysite/urls.py` fájlt a kódszerkesztőben, és nézd meg: +{% filename %}mysite/urls.py{% endfilename %} ```python -from django.conf.urls import include, url +"""mysite URL Configuration + +[...] +""" +from django.conf.urls import url from django.contrib import admin urlpatterns = [ - # Examples: - # url(r'^$', 'mysite.views.home', name='home'), - # url(r'^blog/', include('blog.urls')), - - url(r'^admin/', include(admin.site.urls)), + url(r'^admin/', admin.site.urls), ] ``` Amint láthatod, a Django már előre iderakott nekünk pár dolgot. -Azok a sorok, amik így kezdődnek: `#`, kommentek - ez azt jelenti, hogy ezeket a sorokat a Python nem futtatja le. Hasznos, igaz? +A hármas idézőjelek (`'''` vagy `"""`) közötti sorok neve docstring (dokumentációs sztring) – Írhatsz ilyet egy file, osztály (class) vagy method elején, hogy leírhatsd hogy mit csinál. Python nem fogja lefuttatni ezeket a sorokat. Az admin URL, amit az előző fejezetben már meglátogattál, már itt van: @@ -71,7 +72,7 @@ Itt az ideje, hogy létrehozzuk az első URL-t! Azt szeretnénk, ha a 'http://12 Fontos, hogy tisztán tartsuk a `mysite/urls.py` fájlt, ezért a `blog` alkalmazásból fogjuk importálni az url-eket. -Töröld ki a kikommentelt soroket (azokat, amik `#` jellel kezdődnek), és adj hozzá egy sort, ami importálja a `blog.urls` a fő url-be (`''`). +Rajta, add hozzá a sort, ami beimportálja `blog.urls`-t. Figyelmd meg, hogy az `include` függvényt használjuk, ezért hozzá **kell** adnod azt az import-ot a file első sorához. A `mysite/urls.py` fájlod most így néz ki: @@ -122,4 +123,4 @@ Már nincs ott az "It works", igaz? Ne aggódj, ez csak egy hibaoldal, semmi fé Azt olvashatod, hogy **no attribute 'post_list'**, vagyis "nincs post_list nevű attribútum". Eszedbe jut valami a *post_list*-ről? Így neveztük el a view-t! Ez azt jelenti, hogy minden a megfelelő helyen van, csak még nem hoztuk létre a *view*-t. Ne aggódj, mindjárt eljutunk odáig. -> Ha többet szeretnél megtudni a Django URLconf-ról, nézz bele a hivatalos dokumentációba: https://docs.djangoproject.com/en/1.8/topics/http/urls/ \ No newline at end of file +> Ha többet szeretnél megtudni a Django URLconf-ról, nézz bele a hivatalos dokumentációba: https://docs.djangoproject.com/en/1.11/topics/http/urls/ \ No newline at end of file diff --git a/hu/django_urls/images/error1.png b/hu/django_urls/images/error1.png index cc17593d19d..250028e996b 100644 Binary files a/hu/django_urls/images/error1.png and b/hu/django_urls/images/error1.png differ diff --git a/hu/django_urls/images/url.png b/hu/django_urls/images/url.png index 6cd1bd96291..b59f9dce992 100644 Binary files a/hu/django_urls/images/url.png and b/hu/django_urls/images/url.png differ diff --git a/hu/django_views/README.md b/hu/django_views/README.md index 9dabfe619b2..6592bc15bd5 100644 --- a/hu/django_views/README.md +++ b/hu/django_views/README.md @@ -35,4 +35,4 @@ Mentsd el a fájlt, menj a http://127.0.0.1:8000/ címre és lássuk, mink van. Ez egyszerű: *TemplateDoesNotExist*. Javítsuk ki ezt a hibát, és hozzunk létre egy template-et a következő fejezetben! -> Tanulj meg többet a Django nézetekről a hivatalos dokumentációból: https://docs.djangoproject.com/en/1.8/topics/http/views/ \ No newline at end of file +> Tanulj meg többet a Django nézetekről a hivatalos dokumentációból: https://docs.djangoproject.com/en/1.11/topics/http/views/ \ No newline at end of file diff --git a/hu/django_views/images/error.png b/hu/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/hu/django_views/images/error.png and b/hu/django_views/images/error.png differ diff --git a/hu/dynamic_data_in_templates/README.md b/hu/dynamic_data_in_templates/README.md index b4c81dc739c..97edb5a51f1 100644 --- a/hu/dynamic_data_in_templates/README.md +++ b/hu/dynamic_data_in_templates/README.md @@ -71,4 +71,4 @@ def post_list(request): És megvan! Itt az idő visszatérni a template-hez és megjeleníteni ezt a QuerySet-et! -Ha utána szeretnél olvasni a QuerySet-nek, itt megteheted: https://docs.djangoproject.com/en/1.8/ref/models/querysets/ \ No newline at end of file +Ha utána szeretnél olvasni a QuerySet-nek, itt megteheted: https://docs.djangoproject.com/en/1.11/ref/models/querysets/ \ No newline at end of file diff --git a/hu/extend_your_application/README.md b/hu/extend_your_application/README.md index 0ec2859cc32..ffe6a9c5bfa 100644 --- a/hu/extend_your_application/README.md +++ b/hu/extend_your_application/README.md @@ -25,7 +25,7 @@ Kezdjük azzal, hogy hozzáadunk egy linket a `blog/templates/blog/post_list.htm

{{ post.text|linebreaksbr }}

{% endfor %} -{% endblock content %} +{% endblock %} ``` @@ -39,6 +39,8 @@ Kezdjük azzal, hogy hozzáadunk egy linket a `blog/templates/blog/post_list.htm A `blog.views.post_detail` egy elérési út a `post_detail` *view*-hez, amit létre akarunk hozni. Jegyezd meg: `blog` az applikációnk neve (a `blog` könyvtár), `views` a `views.py` nevéből van, és az utolsó rész - `post_detail` - a *nézet* neve. +És a `pk=post.pk` rész? A `pk` a "primary key" (elsődleges kulcs) rövidítése, amely mindegyik bejegyzésnek egy egyedi neve az adatbázisban. Nem adtunk meg egy elsődleges kulcsot a `Post` modellünkben, ezért Django létre fog nekünk hozni egyet (alapértelmezetten egy számot fog használni, amely egyesével nő, pl. 1, 2, 3) és ezt egy `pk` nevű mezőben hozzáadja mindegyik posthoz. Az elsődleges kulcsot `post.pk`-al érhetjük el, ugyan úgy mint a többi mezőt (`title`, `author`, stb.) a `Post` objektumban! + Most amikor a http://127.0.0.1:8000/ címre megyünk, lesz egy hibaüzenetünk (ahogy vártuk is, mivel nincsen sem URL, sem *view* a `post_detail`-hez). Így fog kinézni: ![NoReverseMatch hiba][1] @@ -63,7 +65,11 @@ urlpatterns = [ ] ``` -Ez a rész `^post/(?P[0-9]+)/$` elég ijesztően néz ki, de ne aggódj,elmagyarázzuk: - `^`-vel kezdődik -- "eleje" - `post/` azt jelenti, hogy az eleje után az URL-nek tartalmaznia kell ezt: **post** és **/**. Eddig jó. - `(?P[0-9]+)` - ez a rész trükkösebb. Ez azt jelenti, a Django fogja, amit ideraksz, és átirányítja egy nézethez egy `pk` nevű változóként. `[0-9]` azt közli, hogy ez csak egy számjegy lehet, betű nem (tehát minden 0 és 9 között). `+` azt jelenti, hogy egy vagy több számjegynek kell lennie. Tehát `http://127.0.0.1:8000/post//` nem érvényes, de `http://127.0.0.1:8000/post/1234567890/` teljesen jó! - `/` - kell még egy **/** - `$` - "vége"! +Ez a rész `^post/(?P[0-9]+)/$` elég ijesztően néz ki, de ne aggódj,elmagyarázzuk: +- `^`-vel kezdődik -- "eleje" - `post/` azt jelenti, hogy az eleje után az URL-nek tartalmaznia kell ezt: **post** és **/**. Eddig jó. +- `(?P[0-9]+)` - ez a rész trükkösebb. Ez azt jelenti, a Django fogja, amit ideraksz, és átirányítja egy nézethez egy `pk` nevű változóként. `[0-9]` azt közli, hogy ez csak egy számjegy lehet, betű nem (tehát minden 0 és 9 között). `+` azt jelenti, hogy egy vagy több számjegynek kell lennie. Tehát `http://127.0.0.1:8000/post//` nem érvényes, de `http://127.0.0.1:8000/post/1234567890/` teljesen jó! +- `/` - kell még egy **/** - `$` +- "vége"! Ez azt jelenti, hogy ha beírod a `http://127.0.0.1:8000/post/5/` címet a böngésződbe, akkor a Django megérti, hogy egy `post_detail` nevű 1>nézetet keresel, és közvetíti az információt, hogy a `pk` `5-tel` egyenlő annál a *nézetnél*. diff --git a/hu/extend_your_application/images/404_2.png b/hu/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/hu/extend_your_application/images/404_2.png and b/hu/extend_your_application/images/404_2.png differ diff --git a/hu/extend_your_application/images/attribute_error2.png b/hu/extend_your_application/images/attribute_error2.png index 6edcd9933c3..33a3b36b1d3 100644 Binary files a/hu/extend_your_application/images/attribute_error2.png and b/hu/extend_your_application/images/attribute_error2.png differ diff --git a/hu/extend_your_application/images/does_not_exist2.png b/hu/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/hu/extend_your_application/images/does_not_exist2.png and b/hu/extend_your_application/images/does_not_exist2.png differ diff --git a/hu/extend_your_application/images/no_reverse_match2.png b/hu/extend_your_application/images/no_reverse_match2.png index 306926206f8..aba1c9c8980 100644 Binary files a/hu/extend_your_application/images/no_reverse_match2.png and b/hu/extend_your_application/images/no_reverse_match2.png differ diff --git a/hu/extend_your_application/images/post_detail2.png b/hu/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/hu/extend_your_application/images/post_detail2.png and b/hu/extend_your_application/images/post_detail2.png differ diff --git a/hu/extend_your_application/images/post_list2.png b/hu/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/hu/extend_your_application/images/post_list2.png and b/hu/extend_your_application/images/post_list2.png differ diff --git a/hu/extend_your_application/images/template_does_not_exist2.png b/hu/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/hu/extend_your_application/images/template_does_not_exist2.png and b/hu/extend_your_application/images/template_does_not_exist2.png differ diff --git a/hu/how_the_internet_works/README.md b/hu/how_the_internet_works/README.md index 770f08d8e23..d5d2fb2069f 100644 --- a/hu/how_the_internet_works/README.md +++ b/hu/how_the_internet_works/README.md @@ -6,7 +6,7 @@ Biztosan minden nap internetezel. Tudod, igazából mi történik, mikor beírod Az első dolog, amit fontos megérteni, hogy egy weboldal nem más, mint egy csomó fájl egy merevlemezre mentve. Olyanok, mint a filmjeid, a zenéid, vagy a képeid. De van valami, ami a weboldalakat egyedivé teszi: a HTML nevű számítógépes kód. -Ha nem igazán ismered a programozást, akkor nehéz lehet megértened először a HTML-t, de ne aggódj a böngésződ (Chrome, Safari, Firefox, stb.) imádja. A webböngészőket úgy tervezték, hogy megértsék ezt a kódot, kövessék azt, ami abban van, és megjelenítsenek mindent pont úgy, ahogy szeretnéd. +Ha nem igazán ismered a programozást, akkor nehéz lehet megértened először a HTML-t, de ne aggódj, a böngésződ (Chrome, Safari, Firefox, stb.) imádja. A webböngészőket úgy tervezték, hogy megértsék ezt a kódot, kövessék azt, ami abban van, és megjelenítsenek mindent pont úgy, ahogy szeretnéd. Mint minden fájlt, a HTML-t is merevlemezen kell tárolni. Az Internethez speciális, erős számítógépeket használunk, a *szervereket*. Ezekhez a gépekhez nem tartozik képernyő, egér vagy billentyűzet, mert a fő feladatuk az adatok tárolása és szolgáltatása. Ezért hívjuk őket *szervernek*, vagyis kiszolgálónak -- ők *szolgálják ki* neked az adatokat. diff --git a/hu/how_the_internet_works/images/internet_1.png b/hu/how_the_internet_works/images/internet_1.png index 9c5bcf0b003..e289eac2b23 100644 Binary files a/hu/how_the_internet_works/images/internet_1.png and b/hu/how_the_internet_works/images/internet_1.png differ diff --git a/hu/how_the_internet_works/images/internet_2.png b/hu/how_the_internet_works/images/internet_2.png index dd5861f376f..e8cf8b77999 100644 Binary files a/hu/how_the_internet_works/images/internet_2.png and b/hu/how_the_internet_works/images/internet_2.png differ diff --git a/hu/how_the_internet_works/images/internet_3.png b/hu/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/hu/how_the_internet_works/images/internet_3.png and b/hu/how_the_internet_works/images/internet_3.png differ diff --git a/hu/how_the_internet_works/images/internet_4.png b/hu/how_the_internet_works/images/internet_4.png index 2661cec1b61..d4748ac48ef 100644 Binary files a/hu/how_the_internet_works/images/internet_4.png and b/hu/how_the_internet_works/images/internet_4.png differ diff --git a/hu/html/README.md b/hu/html/README.md index 1eb19bbdda4..46211c0880c 100644 --- a/hu/html/README.md +++ b/hu/html/README.md @@ -102,6 +102,7 @@ Most szórakozásképpen próbáld módosítani a template-edet! Itt van néhán * `

A heading

` - a legfontosabb címedhez * `

A sub-heading

` cím a következő szintre * `

A sub-sub-heading

` ... és így tovább, egészen `
`-ig +* `

Egy bekezdésnyi szöveg

` * `text` dőlt szöveghez * `text` a szöveg kiemeléséhez * `
` új sor kezdéséhez (nem mindenhová rakhatsz br-t) @@ -109,7 +110,7 @@ Most szórakozásképpen próbáld módosítani a template-edet! Itt van néhán * `
  • first item
  • second item
` létrehoz egy listát, akárcsak ezt itt! * `
` az oldal szakaszainak megadásához -Itt a példa egy teljes template-re: +Itt a példa egy teljes template-re, másold be a `blog/templates/blog/post_list.html` file-ba: ```html @@ -155,7 +156,7 @@ Amit igazából szeretnénk, hogy igazi posztokat jelenítünk meg, amiket a Dja Jó lenne lenne látni ezt az egészet élesben az interneten, ugye? Csináljunk egy újabb PythonAnywhere deploy-t: -### Commit, és push a Github-ra +### Commit, és push a GitHub-ra Először nézzük meg, hogy milyen fájlok változtak a legutóbbi deploy óta (futtasd az alábbi parancsot a gépeden, ne PythonAnywhere-en): @@ -167,7 +168,7 @@ A `djangogirls` mappában kell lenned, és a `git`-tel add hozzá az összes vá $ git add --all . -> **Megjegytés** `-A` (az "all" rövidítése) azt jelenti, hogy a `git` felismeri, ha fájlokat törölsz (alapból csak az új, és módosított fájlokat ismeri fel). Korábban már volt róla szó (a 3. fejezetben), hogy a `.` az aktuális mappát jelenti. +> **Megjegyzés** `-a` (az "all" rövidítése) azt jelenti, hogy a `git` felismeri, ha fájlokat törölsz (alapból csak az új, és módosított fájlokat ismeri fel). Korábban már volt róla szó (a 3. fejezetben), hogy a `.` az aktuális mappát jelenti. Mielőtt továbbmegyünk ellenőrizzük, hogy a `git` mit szeretne feltölteni (zölddel jelennek meg azok a fájlok, amiket a `git` fel akar tölteni): @@ -181,7 +182,7 @@ Már majdnem készen is vagyunk, de előtte el kell mentenünk a változtatások > **Megjegyzés** Győződj meg róla, hogy idézőjelet használsz a commit üzenetnél. -Miután ezzel megvagy, töltsd fel (push) a változtatásaidat Github-ra: +Miután ezzel megvagy, töltsd fel (push) a változtatásaidat GitHub-ra: $ git push @@ -196,9 +197,6 @@ Miután ezzel megvagy, töltsd fel (push) a változtatásaidat Github-ra: $ source myvenv/bin/activate (myvenv)$ git pull [...] - (myvenv)$ python manage.py collectstatic - [...] - A fájljaid már itt is vannak. Ha le akarod csekkolni, akkor menj át a **Files tab**-ra és nézd meg a kódodat PythonAnywhere-en. diff --git a/hu/html/images/step1.png b/hu/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/hu/html/images/step1.png and b/hu/html/images/step1.png differ diff --git a/hu/html/images/step3.png b/hu/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/hu/html/images/step3.png and b/hu/html/images/step3.png differ diff --git a/hu/html/images/step4.png b/hu/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/hu/html/images/step4.png and b/hu/html/images/step4.png differ diff --git a/hu/html/images/step6.png b/hu/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/hu/html/images/step6.png and b/hu/html/images/step6.png differ diff --git a/hu/images/application.png b/hu/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/hu/images/application.png and b/hu/images/application.png differ diff --git a/hu/intro_to_command_line/README.md b/hu/intro_to_command_line/README.md index 1599cd88f51..897f37d45af 100644 --- a/hu/intro_to_command_line/README.md +++ b/hu/intro_to_command_line/README.md @@ -16,46 +16,77 @@ A **parancssor** (command line, vagy **command-line interface**) nevű ablak egy Hogy belevághass a kísérletezésbe, először meg kell nyitnod a parancssort. -### Windows + Start menu → All Programs → Accessories → Command Prompt. -### Mac OS X + -Applications → Utilities → Terminal. -### Linux + + +Launchpad → Other → Terminal. + + + + Valószínűleg itt találod meg: Applications → Accessories → Terminal, de ez a rendszeredtől függ. Ha nincs ott, csak keress rá a Google-n :) + + ## Parancssor Egy fehér vagy fekete ablakot kell látnod, ami csak a te parancsaidra vár. + + Ha Mac-ed vagy Linux-od van, valószínűleg egy `$`-t kell látnod: $ + + + + A Windows-on ez egy `>` jel: > + + Minden sornak ezzel a jellel és az azt követő space-el kell kezdődnie, de ezt nem neked kell begépelned. A számítógéped megteszi helyetted :) > Csak egy gyors megjegyzés: így is kinézhet a parancssorod: `C:\Users\ola>` vagy `Olas-MacBook-Air:~ ola$`, és ez teljesen jó így. Ebben az útmutatóban csak próbáljuk a lehető leginkább leegyszerűsíteni. +A sor elején lévő rész, a `$` vagy `>` karakterig (azt is beleértve) a *parancssori prompt* vagy röviden *prompt* a neve. Azt jelzi, hogy a számítógép a te utasításodra vár. + +A tutorial során, amikor egy parancsot kell beírnod, ki fogjuk írni a `$` vagy `>` karaktert, és olykor még bővebb promptot. Nyugodtan hagyd figyelmen kívül a baloldali részt, és csak a prompt után kezdődő parancsot gépeld be. + ## Az első parancsod (YAY!) Kezdjük valami egyszerűvel. Gépeld be ezt a parancsot: - $ whoami - + + +{% filename %}parancssor{% endfilename %} +``` +$ whoami +``` + + + + + -vagy +{% filename %}parancssor{% endfilename %} +``` +> whoami +``` - > whoami + Majd nyomj `enter`t. Ezt az eredményt kapod: @@ -76,26 +107,41 @@ Minden operációs rendszer parancssora kissé különböző prancsokat igényel Jó lenne tudni, hogy most hol vagyunk, nem? Nézzük. Írd be ezt a parancsot, és nyomj `enter`t: - $ pwd - /Users/olasitarska - + -Ha Windows-od van: +{% filename %}parancssor{% endfilename %} +``` +$ pwd +/Users/olasitarska +``` - > cd - C:\Users\olasitarska - +> Megjegyzés: a 'pwd' jelentése: 'print working directory' ('munkakönyvtár kiírása'). + + -Valószínűleg valami hasonlót fogsz látni a gépeden. Amikor megnyitod a parancssort, általában a felhasználó 'home' könyvtárába kerülsz. -> Megjegyzés: a 'pwd' jelentése: 'print working directory'. + + +{% filename %}parancssor{% endfilename %} +``` +> cd +C:\Users\olasitarska +``` +> Megjegyzés: a 'cd' jelentése: 'change directory' ('könyvtár váltása'). Ha PowerShell-t használsz, használhatod a pwd parancsot is, mint Linuxon vagy macOS-en. + + + + +Valószínűleg valami hasonlót fogsz látni a gépeden. Amikor megnyitod a parancssort, általában a felhasználó 'home' könyvtárába kerülsz. * * * ### Fájlok és könyvtárak kilistázása - + És mi van benne? Szuper lenne kideríteni. Nézzük meg: + + $ ls Applications Desktop @@ -103,8 +149,9 @@ Valószínűleg valami hasonlót fogsz látni a gépeden. Amikor megnyitod a par Music ... + -Windows: + > dir Directory of C:\Users\olasitarska @@ -114,6 +161,7 @@ Windows: 05/08/2014 07:28 PM Music ... + * * * @@ -121,25 +169,43 @@ Windows: Most pedig lépjünk be a Desktop (vagy Asztal) mappába: - $ cd Desktop - + + +{% filename %}parancssor{% endfilename %} +``` +$ cd Desktop +``` + + + -Windows: - > cd Desktop +{% filename %}parancssor{% endfilename %} +``` +> cd Desktop +``` + Nézzük meg, hogy tényleg megváltozott-e: - $ pwd - /Users/olasitarska/Desktop - + -Windows: +{% filename %}parancssor{% endfilename %} +``` +$ pwd +/Users/olasitarska/Desktop +``` + - > cd - C:\Users\olasitarska\Desktop - + + +{% filename %}parancssor{% endfilename %} +``` +> cd +C:\Users\olasitarska\Desktop +``` + Itt is van! @@ -151,13 +217,22 @@ Itt is van! Mit szólnál, ha létrehoznánk egy gyakorló (practice) könyvtárat az asztalon? Így tudod megtenni: - $ mkdir practice - + -Windows: +{% filename %}parancssor{% endfilename %} +``` +$ mkdir practice +``` + + + - > mkdir practice - + +{% filename %}parancssor{% endfilename %} +``` +> mkdir practice +``` + Ez a parancs létre fog hozni egy `practice` nevű mappát az asztalodon. Ha megnézed az asztalt, meggyőződhetsz róla, hogy tényleg ott van-e, de a `ls` vagy `dir` paranccsal is megteheted! Próbáld ki :) @@ -171,18 +246,28 @@ Egy kis kihívás: hozz létre egy `test` nevű mappát a frissen elkészített #### Megoldás: - $ cd practice - $ mkdir test - $ ls - test - + -Windows: +{% filename %}parancssor{% endfilename %} +``` +$ cd practice +$ mkdir test +$ ls +test +``` + - > cd practice - > mkdir test - > dir - 05/08/2014 07:28 PM test + + + +{% filename %}parancssor{% endfilename %} +``` +> cd practice +> mkdir test +> dir +05/08/2014 07:28 PM test +``` + Gratulálunk! :) @@ -195,61 +280,110 @@ Nem szeretnénk káoszt hagyni magunk után, szóval töröljünk le mindent, am Először vissza kell mennünk az Asztal-ra: - $ cd .. - + + +{% filename %}parancssor{% endfilename %} +``` +$ cd .. +``` + + + -Windows: - > cd .. +{% filename %}parancssor{% endfilename %} +``` +> cd .. +``` + Ha a `cd` parancsot `..`-tal használod, a jelenlegi könyvtárból a parent (szülő) könyvtárba jutsz (ez az a mappa, ami tartalmazza azt a mappát, ahol éppen vagy). Ellenőrizzük le, hogy hol vagyunk: - $ pwd - /Users/olasitarska/Desktop - + -Windows: +{% filename %}parancssor{% endfilename %} +``` +$ pwd +/Users/olasitarska/Desktop +``` + - > cd - C:\Users\olasitarska\Desktop - + + + +{% filename %}parancssor{% endfilename %} +``` +> cd +C:\Users\olasitarska\Desktop +``` + Most pedig itt az ideje, hogy kitöröljük a `practice` könyvtárat: > **Figyelem**: A fájlok törlése a `del`, `rmdir`, vagy a `rm` parancsokkal visszafordíthatatlan, tehát a *törölt fájlok örökre eltűnnek*! Legyél nagyon óvatos ezzel a paranccsal. - $ rm -r practice - + + +{% filename %}parancssor{% endfilename %} +``` +$ rm -r practice +``` + -Windows: + - > rmdir /S practice - practice, Are you sure ? Y + +{% filename %}parancssor{% endfilename %} +``` +> rmdir /S practice +practice, Are you sure ? Y +``` + Kész! Ellenőrizzük le, hogy tényleg megtörtént-e: - $ ls - + -Windows: +{% filename %}parancssor{% endfilename %} +``` +$ ls +``` + - > dir + + + +{% filename %}parancssor{% endfilename %} +``` +> dir +``` + ### Kilépés Ennyi volt! Most már biztonságosan kiléphetsz a parancssorból. Csináljuk hacker módra, jó?:) - $ exit - + + +{% filename %}parancssor{% endfilename %} +``` +$ exit +``` + + + -Windows: - > exit +{% filename %}parancssor{% endfilename %} +``` +> exit +``` + Szuper, nem? :) diff --git a/hu/python_installation/images/add_python_to_windows_path.png b/hu/python_installation/images/add_python_to_windows_path.png index 9510d6f2176..3266efb6177 100644 Binary files a/hu/python_installation/images/add_python_to_windows_path.png and b/hu/python_installation/images/add_python_to_windows_path.png differ diff --git a/hu/python_installation/instructions.md b/hu/python_installation/instructions.md index fca0e75ca0a..de7509b87b5 100644 --- a/hu/python_installation/instructions.md +++ b/hu/python_installation/instructions.md @@ -1,8 +1,8 @@ > Ez a fejezet a Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) tutorialján alapszik -A Django Python nyelven íródott. Ahhoz, hogy bármit létrehozhassunk a Django-ban, szükségünk van a Pythonra is. Kezdjük a telepítésével! Azt szeretnénk, hogy a Python 3.4-es verziója legyen telepítve -- ha ennél korábbi verzióval rendelkezel, akkor frissítened kell. +A Django Python nyelven íródott. Ahhoz, hogy bármit létrehozhassunk a Django-ban, szükségünk van a Pythonra is. Kezdjük a telepítésével! Azt szeretnénk, hogy a Python 3.6-es verziója legyen telepítve -- ha ennél korábbi verzióval rendelkezel, akkor frissítened kell. -### Windows + A Python-t az alábbi weboldalról tudod letölteni: https://www.python.org/downloads/release/python-343/. Az ***.msi** fájlt a letöltés után futtasd (dupla kattintás), és kövesd az utasításokat. Fontos, hogy emlékezz a path-ra (könyvtárra), ahova letöltötted. Később szükséged lesz rá! @@ -10,7 +10,22 @@ Egy fontos dolog, amire figyelj oda: a telepítővarázsló második képernyőj ![Ne felejtsd el hozzáadni a Pythont a Path-hoz](../python_installation/images/add_python_to_windows_path.png) -### Linux + + + + +> **Megjegyzés** Mielőtt telepítenéd a Pythont macOS-en, bizonyosodj meg arról hogy a Mac beállításaid megengedik olyan csomagok telepítését, amelyek nem az App Store-ból származnak. Nyisd meg a System Preferences ablakot (az Applications mappában), kattints a "Security & Privacy" gombra majd a "General" fülre. Ha az "Allow apps downloaded from:" beállítás "Mac App Store"-ra van állítva, állítsd át "Mac App Store and identified developers"-ra. + +Menj a https://www.python.org/downloads/release/python-343/ oldalra, és töltsd le a Python installert: + + * Töltsd le a *macOS 64-bit/32-bit installer* fájlt, + * Kattints duplán a *python-3.4.3-macosx10.6.pkg*-re, hogy futtasd a telepítőt. + + + + Nagyon valószínű, hogy a Python már telepítve van a gépedre. Ahhoz, hogy ezt leellenőrizd (illetve hogy megnézd, melyik verzió van a gépeden), nyisd meg a konzolt és írd be az alábbi parancsot: @@ -20,39 +35,34 @@ Nagyon valószínű, hogy a Python már telepítve van a gépedre. Ahhoz, hogy e Ha még nincs Pythonod, vagy másik verziót szeretnél telepíteni, így teheted meg: -#### Debian vagy Ubuntu + -Írd be az alábbi parancsot a konzolba: - - $ sudo apt-get install python3.4 - + -#### Fedora (21-es verzióig) - -Írd be az alábbi programot a konzolba: +Írd be az alábbi parancsot a konzolba: - $ sudo yum install python3.4 + $ sudo apt install python3.4 + -#### Fedora (22+) + Írd be az alábbi programot a konzolba: $ sudo dnf install python3.4 + -#### openSUSE + Írd be az alábbi programot a konzolba: $ sudo zypper install python3 -### OS X - -Menj a https://www.python.org/downloads/release/python-343/ oldalra, és töltsd le a Python installert: - - * Töltsd le a *Mac OS X 64-bit/32-bit installer* fájlt, - * Kattints duplán a *python-3.4.3-macosx10.6.pkg*-re, hogy futtasd a telepítőt. + Bizonyosodj meg arról, hogy sikeres volt a telepítés! Nyisd meg a *Terminált* és futtasd le a `python3` parancsot: @@ -60,6 +70,10 @@ Bizonyosodj meg arról, hogy sikeres volt a telepítés! Nyisd meg a *Terminált Python 3.4.3 + +**Megjegyzés** Ha windows-t használsz és egy hibaüzenetet kapsz, mely szerint `python3` nem található, próbáld meg `python` néven (a `3` nélkül) és ellenőrizd hogy Python 3.6-e. + + * * * Ha kétségeid vannak, vagy valami elromlott, és nem tudod, mit csinálj - csak kérdezd meg a coachodat! Néha a dolgok nem mennek teljesen simán, és jobb megkérdezni valakit, akinek több tapasztalata van a témában. diff --git a/hu/python_introduction/README.md b/hu/python_introduction/README.md index 08dccfbb47b..36966e6ca99 100644 --- a/hu/python_introduction/README.md +++ b/hu/python_introduction/README.md @@ -32,7 +32,11 @@ Most épp nem szeretnénk kilépni a Python konzolból. Inkább többet szeretn 5 -Szuper! Láttad, ahogy előugrott a válasz? A Python tud matekozni! Kipróbálhatsz más parancsokat is, mint például: - `4 * 5` - `5 - 1` - `40 / 2` +Szuper! Láttad, ahogy előugrott a válasz? A Python tud matekozni! Kipróbálhatsz más parancsokat is, mint például: + +- `4 * 5` +- `5 - 1` +- `40 / 2` Szórakozz egy kicsit ezzel aztán gyere vissza ide :). @@ -267,7 +271,7 @@ Ebben a Python dokumentációban megtalálod a listákra értelmezett összes me ## Szótárak -A szótár hasonló a listához, de a szótár elemeit nem indexekkel hanem kulcsokkal (key) érjük el. A kulcs lehet bármilyen string vagy szám. Az üres szótár létrehozására szolgáló utasítás a következő: +A szótár (dictionary) hasonló a listához, de a szótár elemeit nem indexekkel hanem kulcsokkal (key) érjük el. A kulcs lehet bármilyen string vagy szám. Az üres szótár létrehozására szolgáló utasítás a következő: >>> {} {} @@ -406,7 +410,7 @@ Hallottad már azt a kifejezést hogy "almákat narancsokkal összehasonlítani" >>> 1 > 'django' Traceback (most recent call last): File "", line 1, in - TypeError: unorderable types: int() > str() + TypeError: '>' not supported between instances of 'int' and 'str' Láthatod, hogy ugyanúgy, mint a kifejezéseknél, a Python nem tudja összehasonlítani a számot (`int`) a stringgel (`str`). Ehelyett **TypeError** típusú hibát dob, azaz megmondja, hogy két különböző típust nem lehet egymással összehasonlítani. @@ -451,7 +455,7 @@ Egész mostanig a python interpreterbe írkáltuk a parancsokat, ami arra korlá * Mensünk el benne valami kódot egy python fájlba * És futtassuk! -Ahhoz hogy kilépjünk a Python interpreterből, egyszerűen írjuk be, hogy ~~~ exit()~~~: +Ahhoz hogy kilépjünk a Python interpreterből, egyszerűen írjuk be, hogy `exit()`: >>> exit() $ @@ -467,36 +471,65 @@ Egy előző részben már kiválasztottuk a kedvenc [kódszerkesztő][2]nket. Mo print('Hello, Django girls!') ``` -> **Megj.** Vegyük észre a kód editorok legnagyszerűbb tulajdonságát: a színeket! A Python konzolban minden egyszínű volt, most a `print` függvény más színű, mint a string. Ezt úgy hívják: "syntax highlighting" (szintaxis-kiemelés), és kódoláshoz nagyon hasznos. A kód színe mindenféle utalásokat hordoz magában, pl. egy lezáratlan string vagy egy elírás egy kulcsszó nevében (pl. a `def` a függvényeknél, amint látni fogjuk mindjárt). Ez az egyik oka annak, hogy kódszerkesztőt használuk :) - Mostanra már tapasztalt Python programozó lettél, úgyhogy írj valami kódot, amit ma tanultál. Most mentsük el a fájlt, és adjunk neki valami jellemző nevet. Nevezzünk **python_intro.py**-nak, és mentsük el a desktopra. Bárhogy nevezhetjük a fájlt, de a kiterjesztés fontos, hogy **.py** legyen. A **.py** kiterjesztés megmondja az operációs rendszerünknek, hogy **python futtatható programfájl**-lal van dolga. +> **Megj.** Vegyük észre a kód editorok legnagyszerűbb tulajdonságát: a színeket! A Python konzolban minden egyszínű volt, most a `print` függvény más színű, mint a string. Ezt úgy hívják: "syntax highlighting" (szintaxis-kiemelés), és kódoláshoz nagyon hasznos. A kód színe mindenféle utalásokat hordoz magában, pl. egy lezáratlan string vagy egy elírás egy kulcsszó nevében (pl. a `def` a függvényeknél, amint látni fogjuk mindjárt). Ez az egyik oka annak, hogy kódszerkesztőt használuk :) + Most hogy a fájl el van mentve, itt az ideje, hogy lefuttassuk. Felhaszálva a tudásodat a parancssoros részből, navigálj a terminálban a desktopra a **könyvtárváltás** parancs segítségével. + + Mac-en a parancs valahogy így néz ki: - $ cd ~/Desktop - +{% filename %}parancssor{% endfilename %} +``` +$ cd ~/Desktop +``` + + + Linuxon így (A "Desktop" lehet, hogy le van fordítva a te nyelvedre): - $ cd ~/Desktop - +{% filename %}parancssor{% endfilename %} +``` +$ cd ~/Desktop +``` + + + + + +Windowson így néz ki: + +{% filename %}parancssor{% endfilename %} +``` +> cd %HomePath%\Desktop +``` + -És Windowson így néz ki: - > cd %HomePath%\Desktop - Ha megakadtál volna, kérj nyugodtan segítséget. Most pedig futtasd le a Python kódot, így: - $ python3 python_intro.py - Hello, Django girls! +{% filename %}parancssor{% endfilename %} +``` +$ python3 python_intro.py +Hello, Django girls! +``` +Note: Windows-on 'python3' néven nem található parancs. Helyette használd a 'python' néven: + +{% filename %}parancssor{% endfilename %} +```python +> python python_intro.py +``` Rendben! Épp lefuttattad az első Python programodat fájlból. Jó érzés, ugye? @@ -534,6 +567,7 @@ Mentsd el, és futtasd le még egyszer: $ python3 python_intro.py It works! +Note: Emlékezz arra, hogy Windows-on, 'python3' néven nem található parancs. Ha nálad is ez a helyzet, mostantól helyettesítsd 'python3'-t 'python'-al a file-ok futtatásához. ### Mi történik, ha egy feltétel nem teljesül (vagyis nem True)? @@ -596,14 +630,31 @@ A Python sorban mindegyik feltételt megnézi, és kiírja: Perfect, I can hear all the details +## Megjegyzések + +A megjegyzések olyan sorok amelyek `#`-el kezdődnek. Bármit beírhatsz a `#` után, és Python figyelmen kívül fogja hagyni. Megjegyzések segíthetnek abban hogy a kódod mások számára érthető legyen. + +Lássuk, hogyan néz ki: + +{% filename %}python_intro.py{% endfilename %} +```python +# Hangerő beállítása, ha túl hangos vagy túl halk +if volume < 20 or volume > 80: + volume = 50 + print("That's better!") +``` + +Nem kell minden sorhoz megjegyzést írnod, de nagyon hasznosak annak elmagyarázásához hogy miért csinál valamit a kódod, vagy hogy összefoglalót nyújtson amikor valami bonyolult feladatot végez. + ### Összefoglaló Az előző három feladatban ezekről tanultál: -* **dolgok összehasonlítása** - Pythonban a `>`, `>=`, `==`, `<=`, `<` jelekkel, és az `and`, `or` operátorokkal hasonlíthatsz össze dolgokat -* **Boolean** - egy olyan fajta objektum, ami csak két értéket vehet fel: `True` vagy `False` -* **Fájlok elmentése** - a kódot fájlokban is tárolhatod, így hosszabb programokat is lefuttathatsz. -* **if...elif...else** - állítások, amik arra jók, hogy a kód csak bizonyos feltételek teljesülése esetén fusson le. +* __dolgok összehasonlítása__ - Pythonban a `>`, `>=`, `==`, `<=`, `<` jelekkel, és az `and`, `or` operátorokkal hasonlíthatsz össze dolgokat +* __Boolean__ - egy olyan fajta objektum, ami csak két értéket vehet fel: `True` vagy `False` +* __Fájlok elmentése__ - a kódot fájlokban is tárolhatod, így hosszabb programokat is lefuttathatsz. +* __if...elif...else__ - állítások, amik arra jók, hogy a kód csak bizonyos feltételek teljesülése esetén fusson le. +- __comments__ - sorok, amelyeket Python nem futtat le, amelyekkel dokumentálni tudod a kódodat. Elérkeztünk a fejezet utolsó részéhez! @@ -631,8 +682,12 @@ Futtassuk le, és nézzük meg, mi történik: Hi there! How are you? +Megjegyzés: ha nem működött, ne ess pánikba! A hibaüzenet segít kitalálni, hogy mi a baj: +- Ha `NameError`-t kapsz, valószinűleg valamit elgépeltél, ellenőrizd, hogy ugyan azt a nevet használtad amikor létrehoztad a függvényt `def hi():`-al és amikor meghívtad `hi()`-al. +- Ha `IndentationError` hibát kapsz, ellenőrizd, hogz mind a két `print` sor elején azonos mennyiségű üres hely (szóköz karakter) van: python számára a függvényen bellüli összes kódnak szépen illesztve kell lennie. +- Ha nincs egyáltalán semmilyen kimenet, ellenőrizd hogy az utolsó `hi()` *nincs* indentálva - ha így lenne, az a sor is a függvény része lesz és ezért soha nem fog lefutni. -Ez könnyű volt! Most írjuk meg az első olyan függvényt, aminek vannak paraméterei. Az előző példát fogjuk használni - egy függvény, ami köszön annak, aki futtatja, de most nevet is adunk hozzá: +Most írjuk meg az első olyan függvényt, aminek vannak paraméterei. Az előző példát fogjuk használni - egy függvény, ami köszön annak, aki futtatja, de most nevet is adunk hozzá: ```python def hi(name): @@ -727,7 +782,7 @@ Mindegyiküket üdvözölni szeretnénk. Ehhez már megvan a `hi` függvényünk for name in girls: ``` -A ~~~for~~~ statement hasonlóan működik, mint az ~~~if~~~statement; mindkettő alatt 4 szóközzel kell indentálni a következő sort. +A ```for``` statement hasonlóan működik, mint az ```if``` statement; mindkettő alatt 4 szóközzel kell indentálni a következő sort. Itt a teljes kód, ami a fájlban lesz: diff --git a/hu/python_introduction/images/cupcake.png b/hu/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/hu/python_introduction/images/cupcake.png and b/hu/python_introduction/images/cupcake.png differ diff --git a/hu/template_extending/README.md b/hu/template_extending/README.md index a2a3c37ff39..1f4b3990c70 100644 --- a/hu/template_extending/README.md +++ b/hu/template_extending/README.md @@ -20,7 +20,7 @@ Hozz létre egy `base.html` fájlt a `blog/templates/blog/`-ban: Majd nyisd meg, és másolj át mindent a `post_list.html`-ből a `base.html`-be, így: ```html -{% load staticfiles %} +{% load static %} Django Girls blog @@ -99,7 +99,7 @@ Most mentsd el, és nyisd meg újra a `blog/templates/blog/post_list.html`-t. T {% extends 'blog/base.html' %} -{% raw %}Ez azt jelenti, hogy most a `base.html` template-et egészítjük ki a `post_list.html`-ben. Már csak egy dolog van hátra: az előző sor kivételével rakj mindent `{% block content %}` és `{% endblock content %}` közé. Így:{% endraw %} +{% raw %}Ez azt jelenti, hogy most a `base.html` template-et egészítjük ki a `post_list.html`-ben. Már csak egy dolog van hátra: az előző sor kivételével rakj mindent `{% block content %}` és `{% endblock %}` közé. Így:{% endraw %} ```html {% extends 'blog/base.html' %} @@ -114,7 +114,7 @@ Most mentsd el, és nyisd meg újra a `blog/templates/blog/post_list.html`-t. T

{{ post.text|linebreaksbr }}

{% endfor %} -{% endblock content %} +{% endblock %} ``` Ez az! Nézd meg, hogy még mindig működik-e a weboldalad :) diff --git a/hu/whats_next/README.md b/hu/whats_next/README.md index aaade19d5df..1ce0d03b72a 100644 --- a/hu/whats_next/README.md +++ b/hu/whats_next/README.md @@ -17,7 +17,7 @@ Aztán majd ne felejtsd el: Igen! Először is nézd meg a másik könyvünket, a [Django Girls Tutorial: Extensions][3]-t. - [3]: http://djangogirls.gitbooks.io/django-girls-tutorial-extensions/ + [3]: https://tutorial-extensions.djangogirls.org Később megpróbálkozhatsz a lenti listában lévő anyagokkal is. Ezeket mind nagyon ajánljuk! @@ -30,11 +30,11 @@ Később megpróbálkozhatsz a lenti listában lévő anyagokkal is. Ezeket mind - [Getting Started With Django video lessons][10] - [Two Scoops of Django: Best Practices for Django 1.8 book][11] - [4]: https://docs.djangoproject.com/en/1.8/intro/tutorial01/ + [4]: https://docs.djangoproject.com/en/1.11/intro/tutorial01/ [5]: http://newcoder.io/tutorials/ [6]: https://www.codecademy.com/en/tracks/python [7]: https://www.codecademy.com/tracks/web [8]: https://github.com/ggcarrots/django-carrots/ [9]: http://learnpythonthehardway.org/book/ - [10]: http://gettingstartedwithdjango.com/ + [10]: http://www.gettingstartedwithdjango.com/ [11]: https://twoscoopspress.com/products/two-scoops-of-django-1-8 diff --git a/hy/GLOSSARY.md b/hy/GLOSSARY.md new file mode 100644 index 00000000000..800d5339124 --- /dev/null +++ b/hy/GLOSSARY.md @@ -0,0 +1,3 @@ +# code editor + +Code editor- ը ծրագիր է, որը թույլ է տալիս պահպանել ձեր կոդը, որպեսզի հետագայում կկարողանաք վերադառնալ դրան: Դուք կարող եք իմանալ, թե որտեղից կարելի է այն ձեռք բերել [ Code editor chapter ](./code_editor/README.md) \ No newline at end of file diff --git a/hy/README.md b/hy/README.md new file mode 100644 index 00000000000..86243645c21 --- /dev/null +++ b/hy/README.md @@ -0,0 +1,51 @@ +# Django Girls ձեռնարկը + +[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial) + +> Այս աշխատանքը լիցենզավորված է Creative Commons Attribution-ShareAlike 4.0 միջազգային լիցենզիայով: Այս արտոնագրի պատճենը դիտելու համար այցելեք https://creativecommons.org/licenses/by-sa/4.0/ + +## Բարի գալուստ + +Բարի գալուստ Django Girls ձեռնարկը: Մենք ուրախ ենք ձեզ այստեղ տեսնել: :) Այս ձեռնարկի ընթացքում մենք ձեզ ճանապարհորդելու ենք վեբ տեխնոլոգիաների տակ, առաջարկելով ձեզ մի ակնարկ այն բոլոր կտորների մասին, որոնք անհրաժեշտ է միավորել, որպեսզի համացանցն աշխատի այնպես, ինչպես մենք գիտենք: + +Ինչպես բոլոր անհայտ բաների դեպքում, սա էլ կլինի արկածախնդրություն, բայց ոչ մի անհանգստություն, քանի որ դուք արդեն համարձակություն եք գործադրել այստեղ լինելու համար, լավ կլինեք: :) + +## Ներածություն + +Երբևէ զգացե՞լ եք, որ աշխարհն ավելի ու ավելի շատ է վերաբերում այն ​​տեխնոլոգիային, որի հետ (դեռ չեք կարող) առնչվել: Երբևէ մտածե՞լ եք, թե ինչպես ստեղծել կայք, բայց երբևէ բավարար շարժառիթ չի՞ ունեցել գործելու: Երբևէ մտածե՞լ եք, որ ծրագրակազմի աշխարհը չափազանց բարդ է ձեզ համար, որպեսզի փորձեք նույնիսկ ինքնուրույն ինչ-որ բան անել: + +Դե, մենք լավ լուր ունենք ձեզ համար: Ծրագրավորումն այնքան էլ դժվար չէ, որքան թվում է, և մենք ուզում ենք ցույց տալ, թե որքան զվարճալի կարող է լինել: + +Այս ձեռնարկը կախարդական կերպով չի վերածի ձեզ ծրագրավորողի: Եթե ​​ցանկանում եք դրանում լավ տիրապետել, ձեզ հարկավոր են ամիսներ կամ նույնիսկ տարիներ սովորել և պրակտիկայով զբաղվել: Բայց մենք ուզում ենք ձեզ ցույց տալ, որ կայքերի ծրագրավորումը կամ ստեղծումը այնքան էլ բարդ չէ, որքան թվում է: Մենք կփորձենք բացատրել տարբեր կտորներ և կտորներ, ինչպես կարող ենք, այնպես որ դուք ձեզ ահաբեկված չեք զգա տեխնոլոգիայից: + +Հուսով ենք, որ կկարողանանք այնպես անել, որ դուք սիրեք տեխնոլոգիան, ինչպես մեզ: + +## Ի՞նչ կսովորեք ձեռնարկի ընթացքում: + +Ձեռնարկն ավարտելուց հետո դուք կունենաք մի փոքր աշխատող վեբ հավելված ՝ ձեր սեփական բլոգը: Մենք ձեզ ցույց կտանք, թե ինչպես տեղադրել այն առցանց, այնպես որ մյուսները կտեսնեն ձեր աշխատանքը: + +Դա (քիչ թե շատ) այսպիսի տեսք կունենա. + +![Figure 0.1](images/application.png) + +> Եթե ​​ինքնուրույն աշխատում եք ձեռնարկի հետ և չունեք մարզիչ, որը կօգնի ձեզ ցանկացած խնդրի դեպքում, մենք ձեզ համար ունենք չաթ համակարգ ՝ [![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg) ](https://gitter.im/DjangoGirls/tutorial): Մենք խնդրեցինք մեր մարզիչներին և նախորդ մասնակիցներին ժամանակ առ ժամանակ այնտեղ գտնվել և օգնել ուրիշներին ձեռնարկի միջոցով: Մի վախեցեք այնտեղ ձեր հարցը տալուց: + +Լավ, [ եկեք սկսենք ամենասկզբից… ](./how_the_internet_works/README.md) + +## Տանը ձեռնարկին հետեւելը + +Հիանալի է մասնակցել Django Girls սեմինարին, բայց մենք տեղյակ ենք, որ միշտ չէ, որ հնարավոր է մեկին մասնակցել: Ահա թե ինչու մենք ձեզ խրախուսում ենք փորձել հետեւել այս ձեռնարկին տանը: Ընթերցողների համար տանը մենք ներկայումս պատրաստում ենք տեսանյութեր, որոնք ավելի հեշտ կդարձնեն ձեռնարկին ինքնուրույն հետևելը: Դա դեռ ընթացքի մեջ է, բայց շուտով ավելի ու ավելի շատ բաներ լուսաբանվելու են [ Կոդավորումը աղջիկների համար ](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed) YouTube ալիքում: + +Արդեն լուսաբանված յուրաքանչյուր գլխում կա մի հղում, որը մատնանշում է ճիշտ տեսանյութը: + +## Մասին և ներդրում + +Այս ձեռնարկը վարում է [ DjangoGirls ](https://djangogirls.org/) - ը: Եթե ​​սխալներ եք հայտնաբերել կամ ցանկանում եք թարմացնել ձեռնարկը, խնդրում ենք [ հետևել ներդրվող ուղեցույցներին ](https://github.com/DjangoGirls/tutorial/blob/master/README.md): + +## Կցանկանայի՞ք մեզ օգնել ձեռնարկը թարգմանել այլ լեզուներով: + +Ներկայումս թարգմանությունները պահվում են crowdin.com հարթակում ՝ + +https://crowdin.com/project/django-girls-tutorial + +Եթե ​​ձեր լեզուն նշված չէ [ crowdin- ի ](https://crowdin.com/) վրա, խնդրում ենք [ բացել նոր թողարկում ](https://github.com/DjangoGirls/tutorial/issues/new) ՝ տեղեկացնելով մեզ լեզվի մասին, որպեսզի կարողանանք ավելացնել այն: \ No newline at end of file diff --git a/hy/SUMMARY.md b/hy/SUMMARY.md new file mode 100644 index 00000000000..b95ca764cf9 --- /dev/null +++ b/hy/SUMMARY.md @@ -0,0 +1,35 @@ +# Ամփոփում + +* [Ներածություն](README.md) +* [Installation (Տեղադրում)](installation/README.md) + * [Command Line](installation/README.md#command-line) + * [Python](installation/README.md#python) + * [Code Editor](installation/README.md#code-editor) + * [Virtual Environment](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) +* [Installation (chromebook) (Տեղադրում)](chromebook_setup/README.md) +* [Ինչպես է աշխատում ինտերնետը](how_the_internet_works/README.md) +* [ Command line-ի (Հրամանի տողի) ներածություն](intro_to_command_line/README.md) +* [Python- ի տեղադրում](python_installation/README.md) +* [Կոդի խմբագիր](code_editor/README.md) +* [Ներածություն Python- ին](python_introduction/README.md) +* [ Ի՞նչ է Django- ն:](django/README.md) +* [ Django- ի տեղադրում](django_installation/README.md) +* [Ձեր առաջին Django նախագիծը:](django_start_project/README.md) +* [Django մոդելներ](django_models/README.md) +* [ Django ադմին](django_admin/README.md) +* [Deploy!](deploy/README.md) +* [Django URLs](django_urls/README.md) +* [ Django views- Ստեղծագործելու ժամանակն է:](django_views/README.md) +* [ HTML- ի ներածություն](html/README.md) +* [ Django ORM (Querysets)](django_orm/README.md) +* [Դինամիկ տվյալներ կաղապարներում](dynamic_data_in_templates/README.md) +* [ Django templates (կաղապարներ)](django_templates/README.md) +* [ CSS - դարձրեք այն գեղեցիկ](css/README.md) +* [Template extending](template_extending/README.md) +* [ Ընդլայնել ձեր դիմումը](extend_your_application/README.md) +* [Django Forms](django_forms/README.md) +* [ Ի՞նչ է հաջորդը](whats_next/README.md) \ No newline at end of file diff --git a/hy/chromebook_setup/README.md b/hy/chromebook_setup/README.md new file mode 100644 index 00000000000..e3f529a8c5f --- /dev/null +++ b/hy/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# Chromebook տեղադրում + +> ** Նշում ** Եթե դուք արդեն աշխատել եք [installation steps](../installation/README.md) (ներբեռնման), ապա այլևս կարիգ չկա դա կրկնել. կարող եք անմիջապես անցնել [Introduction to Python](../python_introduction/README.md) (Python- ի Ներածություն) բաժնին: + +{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/hy/chromebook_setup/instructions.md b/hy/chromebook_setup/instructions.md new file mode 100644 index 00000000000..8044c18601f --- /dev/null +++ b/hy/chromebook_setup/instructions.md @@ -0,0 +1,159 @@ +Եթե ​​Chromebook չեք օգտագործում, կարող եք անմիջապես անցնել այս բաժնի վրայով: Եթե ​​այո, ձեր տեղադրման փորձը մի փոքր այլ կլինի: Դուք կարող եք անտեսել այն տեղադրման հրահանգների մնացած հատվածը: + +### Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com) + +Cloud IDE- ը գործիք է, որը Ձեզ տալիս է կոդերի խմբագրման և ինտերնետ համակարգչից օգտվելու հնարավորություն, որի վրա կարող ես տեղադրել, գրել և գործարկել ծրագրային ապահովումը: предоставляющий тебе редактор кода и доступ к компьютеру в интернете, на котором ты можешь установить, записать и выполнить программу. Այս դասընթացի շրջանակներում Cloud IDE-ին կօգտագործվի որպես Ձեր *տեղային գործիք *. Դուք աշխատելու եք տերմինալում (ինչպես և ձեր դասընկերները macOS- ում, Ubuntu- ում կամ Windows- ում), բայց ձեր տերմինալը միացված կլինելու այն համակարգչին, որը գտնվում է Նիդեռլանդներում կամ Գերմանիայում, որը cloud IDE- ը ստեղծել է հատուկ Ձեզ համար: Ահա ամպային IDE- ների ցուցումները (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com): Դուք կարող եք ընտրել ամպային IDE- ներից մեկը եւ հետեւեք IDE ամպի հրահանգին: + +#### PaizaCloud Cloud IDE + +1. Գնալ [PaizaCloud Cloud IDE](https://paiza.cloud/) +2. Ստեղծել account +3. Սեղմեք *New Server* և ընտրեք Django app +4. Սեղմեք Terminal կոճակը (պատուհանի ձախ կողմում) + +Այժմ դուք պետք է տեսնեք ինտերֆեյս՝ լուսանցքի նշումով և ձախ կողմում գտնվող կոճակներ: Կտտացրեք «Տերմինալ» կոճակին ՝ տերմինալի պատուհանը բացելու համար ՝ հետևյալ հաղորդագրությամբ. + +{% filename %}Terminal{% endfilename %} + + $ + + +PaizaCloud Cloud 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 կառավարման վահանակում որոնման տողում մուտքագրեք * Cloud9 * և կտտացրեք այն +5. Cloud 9-ի կառավարման վահանակում կտտացրեք * Ստեղծել միջավայր * +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 $ + + + +Այս ստորին հատվածը ձեր տերմինալն է: Դուք կարող եք օգտագործել տերմինալը հրահանգներ ուղարկելու համար հեռավար Cloud 9 համակարգչին: Կարող եք փոփոխել այդ պատուհանի չափերը այն մի փոքր մեծացնելով: + +#### Glitch.com Cloud IDE + +1. Գնացեք [ Glitch.com ](https://glitch.com/) +2. Գրանցվեք հաշվի համար (https://glitch.com/signup) կամ օգտագործեք ձեր GitHub հաշիվը, եթե ունեք: (Տե՛ս GitHub- ի ցուցումները ստորև): +3. Սեղմեք * New Project (Նոր նախագիծ )* և ընտրեք * hello-webpage (բարև-կայք) * +4. Սեղմեք «Գործիքներ» ցանկի ցուցակի վրա (պատուհանի ներքևի ձախ կողմում), ապա «Տերմինալ» կոճակին ՝ տերմինալի ներդիրը բացելու համար ՝ այսպիսի հուշմամբ. + +{% filename %}Terminal{% endfilename %} + + app@name-of-your-glitch-project:~ + + +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 +``` + +Այս ֆայլերը ստեղծվելուց հետո անցեք Տերմինալ և կատարեք հետևյալ հրամանները ՝ ձեր առաջին Django նախագիծը ստեղծելու համար. + +{% filename %}Terminal{% endfilename %} + + django-admin.py startproject mysite . + refresh + + +Որպեսզի մանրամասն սխալի հաղորդագրություններ տեսնեք, կարող եք ակտիվացնել Django debug/Django կարգաբերման տեղեկամատյանները ձեր Glitch հավելվածի համար: Պարզապես ավելացրեք հետևյալը `mysite/settings.py` ֆայլի վերջում: + +{% 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, + }, + }, +} +``` + +Սա կստեղծի ` debug.log ` ֆայլ, որը մանրամասնում է Django- ի գործողությունները և ցանկացած սխալ հաղորդագրություններ, որոնք կարող են ի հայտ գալ, շատ ավելի հեշտ դարձնելով դրանց շտկումը, եթե ձեր կայքը չի աշխատում: + +Glitch նախագծի նախնական վերագործարկումը պետք է ձախողվի: (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. + +### Virtual Environment + +(Virtual environment) Վիրտուալ միջավայրը (որը կոչվում է նաև virtualenv) նման է մեր անձնական տուփի. մենք կարող ենք ավելացնել օգտակար համակարգչային ծածկագիր (code) այն նախագծի համար, որի շուրջ մենք աշխատում ենք: Մենք օգտագործում ենք դրանք, որպեսզի պահպանենք տարբեր ծածկագրերի կոդերի մասնիկներ առանձին, այնպես որ դրանք չխառնվեն այլ նախագծերի հետ: + +Run: + +{% filename %}Cloud 9{% endfilename %} + + mkdir djangogirls + cd djangogirls + python3 -m venv myvenv + source myvenv/bin/activate + pip install django~={{ book.django_version }} + + +(նշենք, որ վերջին տողի վրա մենք օգտագործում ենք ալիք, որին հաջորդում է հավասար նշանը ՝ ` ~ = `): + +### GitHub + +Ստեղծեք GitHub հաշիվ: + +### PythonAnywhere + +Django Girls ձեռնարկը ներառում է բաժին այն մասին, թե ինչ է կոչվում Տեղակայում/Deployment-ը որը ձեր նոր վեբ հավելվածն աշխատեցնող ծածկագիր ստանալու գործընթացն է և տեղափոխումն այն հանրությանը հասանելի համակարգիչ (կոչվում է սերվեր/server) և այլն մարդիկ կարող են տեսնել ձեր աշխատանքը: + +Այս բաժինը մի փոքր տարօրինակ է, երբ մեզ մոտ Chromebook է, քանի որ մենք արդեն օգտագործում ենք համակարգիչ, որը գտնվում է ինտերնետային տիրույթում (ի տարբերություն, ասենք, նոութբուքի): Այնուամենայնիվ, այն դեռ օգտակար է, քանի որ մենք կարող ենք մեր Cloud 9 -ի աշխատանքային տարածքը համարել որպես «ընթացքի մեջ»/"in progress" գտնվող աշխատանքների տիրույթ, իսկ Python Anywhere-ը ՝ պատրաստի աշխատանքները ցուցադրելու տիրույթ, քանի որ այն ավելի ամբողջական տեսք ունի: + +Այսպիսով, գրանցվեք Python Anywhere նոր հաշվի համար ՝ [www.pythonanywhere.com](https://www.pythonanywhere.com). \ No newline at end of file diff --git a/hy/code_editor/README.md b/hy/code_editor/README.md new file mode 100644 index 00000000000..6c2d23cd2d7 --- /dev/null +++ b/hy/code_editor/README.md @@ -0,0 +1,11 @@ +# Code editor + +> Տնային ուսուցման համար. Այս գլուխն ընդգրկված է [Installing Python & Code Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s) video.(Python-ի և տեքստի խմբագրի ծրագրերի ներբեռնումը: + +Դուք պատրաստվում եք գրել ձեր առաջին ծածկագիրը (cod-ը), այնպես որ ժամանակն է ներբեռնել ծածկագրի խմբագիր: + +> **Հավելում** :Եթե Chromebook եք օգտագործում, բաց թողեք այս գլուխը և համոզվեք, որ հետևում եք [Chromebook Setup](../chromebook_setup/README.md) (Chromebook- ի կարգավորման) հրահանգներին: Ձեր ընտրած ամպի IDE- ն (PaizaCloud Cloud IDE կամ AWS Cloud9) պարունակում է կոդի խմբագիր, և երբ ձեր IDE- ում ֆայլ եք բացում File ընտրացանկից, դուք ավտոմատ կերպով օգտագործում եք խմբագիր: +> +> Նշում. գուցե դուք դա արել եք ավելի վաղ [Installation chapter](../installation/README.md) (տեղադրման գլխում). Եթե այո, ապա կարող եք անմիջապես անցնել հաջորդ գլխին: + +{% include "/code_editor/instructions.md" %} \ No newline at end of file diff --git a/hy/code_editor/instructions.md b/hy/code_editor/instructions.md new file mode 100644 index 00000000000..7fc915875d8 --- /dev/null +++ b/hy/code_editor/instructions.md @@ -0,0 +1,37 @@ +Կան շատ տարբեր խմբագիրներ, և դա հիմնականում կախված է անձնական նախասիրություններից: Շատ Python ծրագրավորողներ օգտագործում են բարդ, բայց միևնույն ժամանակ հզոր IDE֊ներ (Integrated Development Environments - Միասնական Նախագծման Միջավայր), ինչպիսն է օրինակ PyCharm֊ը։ Որպես սկսնակ, դա, հավանաբար, ավելի քիչ հարմար է, սակալյն մեր առաջարկությունները հավասարապես հզոր են, բայց շատ ավելի պարզ: + +Մեր առաջարկները ներկայացված են ստորև, բայց ազատորեն հարցրեք ձեր մարզչին, թե որոնք են իրենց նախընտրությունները. Նրանցից օգնություն ստանալն շատ ավելի հեշտ կլինի: + +## Visual Studio Code + +Visual Studio Code- ը նախատեսված է կոդերի խմբագրման համար: Այն ստեղծված՝է Microsoft- ի կողմից Windows- ի, Linux- ի և macOS- ի համար: Այն իր մեջ ներառում է վրիպազերծիչ, ներդրված Git կառավարում, շարահյուսության լուսաբանման, խելացի կոդի ինքնալրացման և կոդի վերափոխման գործիքներ: + +[Ներբեռնիր այն այստեղից](https://code.visualstudio.com/) + +## Gedit + +Gedit- ը բաց կոդով, անվճար խմբագիր է, որը հասանելի է բոլոր օպերացիոն համակարգերի համար: + +[Ներբեռնիր այն այստեղից](https://wiki.gnome.org/Apps/Gedit#Download) + +## Sublime Text + +Sublime Text- ը շատ ճանաչված խմբագիր է `անվճար գնահատման փորձաշրջանով, և այն հասանելի է բոլոր օպերացիոն համակարգերի համար: + +[Ներբեռնիր այն այստեղից](https://www.sublimetext.com/) + +## Atom + +Atom- ը ևս մեկ սիրված խմբագիր է: Այն անվճար է, ազատ և բաց ծրագրային ապահովմամբ (բաց կոդով) և հասանելի է Windows- ի, macOS- ի և Linux- ի համար: Ատոմը մշակվում է [ GitHub ](https://github.com/) - ի կողմից: + +[Ներբեռնիր այն այստեղից](https://atom.io/) + +## Ինչու՞ է մեզ անհրաժեշտ կոդերի խմբագիր: + +Կարող եք հարցնել. Ինչու՞ տեղադրել կոդերի խմբագրման առանձին ծրագիր, երբ կարող ենք օգտագործել Word- ը կամ Notepad- ը: + +Առաջին պատճառն այն է, որ կոդը պետք է լինի ** պարզ տեքստ**, իսկ խնդիրը կապված Word- ի և Textedit- ի հետ այն է, որ նրանք չեն պահպանում կոդը այդ տեսքով, այլ օգտագործում են հարստացված տեքստեր (ներառելով տառատեսակը և ձևաչափը), ինչպիսիք են [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format): + +Երկրորդ պատճառն այն է, որ մասնագիտացված խմբագիրները տրամադրում են բազմաթիվ օգտակար ծրագրավորման առանձնահատկություններ, ինչպիսիք են գունային կոդով ծածկագրված ծածկագիրը `ըստ դրա նշանակության և ավտոմատ փակվող չակերտների: + +Հետագայում այդ ամենը գործի մեջ կտեսնենք: Շուտով դուք կսկսեք մտածել ձեր կոդերի խմբագրի մասին `որպես փորձված ու իսկական սիրված գործիք :) diff --git a/hy/css/README.md b/hy/css/README.md new file mode 100644 index 00000000000..921be5c7867 --- /dev/null +++ b/hy/css/README.md @@ -0,0 +1,331 @@ +# CSS - դարձրեք այն գեղեցիկ: + +Մեր բլոգը դեռ բավականին վատ տեսք ունի, այնպես չէ՞: Ժամանակն է այն ավելի գրավիչ դարձնել: Դրա համար մենք կօգտագործենք CSS: + +## Ի՞նչ է CSS- ը: + +Cascading Style Sheets (CSS-կասկադի ոճի թերթեր) դա լեզու է, որն օգտագործվում է նշագրման լեզվով գրված կայքի տեսքն ու ձևաչափումը նկարագրելու համար (ինչպես HTML-ն է): Համարեք սա որպես դիմահարդարում մեր կայքի համար :) + +Բայց մենք չենք ուզում զրոյից սկսել, այնպես չէ՞: Մենք կօգտագործենք այն ամենը, ինչ այլ ծրագրավորողներ տեղադրել են ինտերնետում անվճար: Նորից անվադող հորինելն այնքան էլ հետաքրքիր չէ :) + +## Եկեք օգտագործենք Bootstrap! + +Bootstrap- ը գեղեցիկ կայքեր մշակելու ամենատարածված HTML և CSS շրջանակներից մեկն է. Https://getbootstrap.com/ + +Այն գրվել է Twitter ծրագրավորողների կողմից, իսկ այժմ մշակվում է կամավորների կողմից ամբողջ աշխարհից: + +## Տեղադրեք Bootstrap- ը + +Bootstrap- ը տեղադրելու համար խմբագրում բացեք ` .html ` կոդը պարունակող ֆայլը և այս տողերն ավելացրեք `` վերնագրում. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + +``` + +Սա ձեր ծրագրին ոչ մի ֆայլ չի ավելացնի: Այս կոդը պարզապես ցույց է տալիս, որ այդ ֆայլերը գոյություն ունեն ինտերնետում: Այսպիսով, բացեք կայքը և թարմացրեք էջը: Ահա՝ դուք կտեսնեք փոփոխությունները: + +![Պատկեր 14.1](images/bootstrap1.png) + +Արդեն ավելի գեղեցիկ տեսք ունի: + +## Ստատիկ ֆայլեր Django- ում + +Վերջապես, մենք ավելի մանրամասն կանդրադառնանք այն ամենին, ինչ կոչվում է **static files** (ստատիկ ֆայլեր): Ստատիկ ֆայլերը` բոլոր CSS ֆայլերը և պատկերներ են: Դրանց բովանդակությունը կախված չէ հարցման ենթատեքստից և արդյունքը նույնը կլինի յուրաքանչյուր օգտագործողի համար: + +### Որտե՞ղ տեղադրել ստատիկ ֆայլեր Django- ում: + +Django- ն արդեն գիտի, թե որտեղ կարելի է գտնել ստատիկ ֆայլերը «ադմինիստրատոր» ներդրված ծրագրի համար: Այժմ մենք պետք է ստատիկ ֆայլեր ավելացնենք մեր սեփական ծրագրում ՝ `blog` (բլոգ): + +Մենք դա կանենք ՝ ստեղծելով `static` folder (ստատիկ պանակ) մեր բլոգի հավելվածի ներսում: + + djangogirls + ├── blog + │ ├── migrations + │ ├── static + │ └── templates + └── mysite + + +Django- ն ձեր ծրագրի պանակների մեջ ավտոմատ կերպով կգտնի «ստատիկ» կոչվող ցանկացած պանակ: Այնուհետև դրանց բովանդակությունը կարող եք օգտագործել որպես ստատիկ ֆայլեր: + +## Ձեր առաջին CSS ֆայլը: + +Եկեք ստեղծենք CSS ֆայլ ՝ ձեր վեբ էջում ձեր սեփական ոճը ստեղծելու համար: Ստեղծեք նոր ` css ` պանակ `static` (ստատիկ) պանակի ներսում: Դրանից հետո ստեղծեք ` blog.css ` կոչվող նոր ֆայլ այս ` css ` պանակի ներսում: Պատրա՞ստ եք + + djangogirls + └─── blog + └─── static + └─── css + └─── blog.css + + +Ժամանակն է գրել CSS մի քանի տող: Ձեր կոդի խմբագրիչում բացեք `blog/static/css/blog.css` ֆայլը: + +Այս դասընթացում մենք չենք կենտրոնանալու CSS-ի ուսուցման մեջ: Էջի վերջում առաջարկվում են անվճար CSS դասընթացներ, եթե ցանկանում եք ինքնուրույն սովորել CSS: + +Բայց եկեք պարզապես մի փոքր ուսումնասիրենք: Գուցե՞ մենք կարող ենք փոխել մեր վերնագրերի գույները: Գույները հասկանալու համար համակարգիչները օգտագործում են հատուկ ծածկագրեր (կոդեր): Այս կոդերը սկսվում են ` # ` - ից, որին հաջորդում են 6 տառ (A – F) և թվեր (0–9): Օրինակ ՝ կապույտի կոդը `#0000FF` է: Շատ գույների գունային կոդերը կարող եք գտնել այստեղ ՝ http://www.colorpicker.com/: Կարող եք նաև օգտագործել [ կանխորոշված ​​գույներ ](http://www.w3schools.com/colors/colors_names.asp), ինչպիսիք են `red` և `green` (կարմիրը և կանաչը). + +Ձեր ` blog/static/css/blog.css ` ֆայլում պետք է ավելացնեք հետևյալ ծածկագիրը. + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +h1 a, h2 a { + color: #C25100; +} + +``` + +` h1 a ` - ը CSS ընտրող է: Սա նշանակում է, որ մենք օգտագործում ենք մեր ոճերը `a`տարրի ներսում գտնվող ցանկացած `h1` տարրի նկատմամբ; `h2 a` ընտրիչը նույնն է անում`h2`տարրերի համար: Այսպիսով, երբ մենք ունենք `

link

` պես մի բան, կկիրառվի `h1 a` ոճը: Այս դեպքում մենք հրահանգում ենք, որ այն փոխի իր գույնը և դարձնի `#C25100`, որը մուգ նարնջագույն է: Կամ կարող եք այստեղ տեղադրել ձեր սեփական գույնը, բայց համոզված լինելով, որ այն լավ հակադրություն ունի սպիտակ ֆոնի վրա: + +CSS ֆայլում մենք որոշում ենք HTML ֆայլի տարրերի ոճերը: Էլեմենտները նույնացնելու առաջին եղանակը դրանց անվանումներն են: Պետք է հիշել այս պիտակները (tag-երը) HTML- ից: ` a `, ` h1 `, և ` body ` սրանք բոլորը տարրերի անունների օրինակներ են: Մենք նաև տարրերը նույնացնում ենք ըստ հատկանիշի `class` կամ հատկանիշը `id`. Class և id-ը անուններ են, որոնք դուք ինքներդ եք վերագրում տարրերին: Դասերը (сlass) սահմանում են տարրերի խմբեր, իսկ նույնացուցիչները (id) մատնանշում են հատուկ տարրեր: Օրինակ, դուք կարող եք նույնականացնել հետևյալ տարրը ՝ օգտագործելով տարրի անունը + +```html + +``` + +CSS ընտրողների մասին ավելին կարող եք կարդալ այստեղ [CSS Selectors at w3schools](http://www.w3schools.com/cssref/css_selectors.asp). + +Մենք նաև պետք է մեր HTML ձևանմուշին ասենք, որ մենք ավելացրել ենք CSS ոճեր: Կոդի խմբագրում բացեք `blog/templates/blog/post_list.html` ֆայլը և հենց սկզբում ավելացրեք այս տողը. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% load static %} +``` + +Մենք պարզապես ներբեռնում ենք ստատիկ ֆայլեր :) `` և `` միջև, Bootstrap CSS ֆայլեր ֆայլերից հետո, ավելացրեք այս տողը. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +Բրաուզերը կարդում է ֆայլերը տրված հերթականությամբ, ուստի մենք պետք է համոզվենք, որ դրանք ճիշտ տեղում են: Հակառակ դեպքում, մեր ֆայլի կոդը կարող է գերակշռվել կոդով Bootstrap ֆայլերում: Մենք պարզապես պատմեցինք մեր ձևանմուշին (template), թե որտեղ է գտնվում մեր CSS ֆայլը: + +Ձեր ֆայլն այժմ պետք է ունենա այսպիսի տեսք. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% load static %} + + + + Django Girls blog + + + + +
+

Django Girls Blog

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

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} + + +``` + +Շատ լավ, պահեք ֆայլը և թարմացրեք կայքը: + +![Պատկեր 14.2](images/color2.png) + +Հիանալի աշխատանք: Գուցե մենք ցանկանում ենք մեր կայքին որոշակի տարածք և ձախ հատվածում լուսանցք ավելացնել: Եկեք փորձենք! + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +body { + padding-left: 15px; +} +``` + +Ավելացրեք դա ձեր CSS- ին, պահեք ֆայլը և տեսեք, թե ինչպես է այն աշխատում: + +![Պատկեր 14.3](images/margin2.png) + +Միգուցե կարո՞ղ ենք հարմարեցնել մեր վերնագրի տառատեսակը: Տեղադրեք սա `` in `blog/templates/blog/post_list.html` ձեր ֆայլում: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +Ինչպես նախկինում, ստուգեք հրահանգը և տեղադրեք `blog/static/css/blog.css` հղումը: Այս տողում Google Fonts- ից (https://www.google.com/fonts) ներմուծեք * Lobster * կոչվող տառատեսակը: + +Գտեք ` h1 a ` հայտարարագրի բլոկը (ամրագոտիների միջեւ ծածկագիրը ` {` և `} `) CSS ֆայլում ` blog/static/css/blog.css` Ձևավոր փակագծերի միջև ավելացրեք `font-family: 'Lobster';` տողը և թարմացրեք էջը. + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +h1 a, h2 a { + color: #C25100; + font-family: 'Lobster'; +} +``` + +![Պատկեր 14.3](images/font.png) + +Հիանալի է! + +Ինչպես նշվեց վերևում, CSS- ն ունի դասակարգման հասկացություն: Դրանք թույլ են տալիս անվանել HTML կոդի մի մաս և կիրառել ոճեր միայն այդ մասի վրա ՝ առանց այլ մասերի վրա ազդելու: Սա կարող է շատ օգտակար լինել: Գուցե դուք ունեք երկու բաժիններ, որոնք տարբեր դերեր ունեն (ինչպես օրինակ վերնագիրն և բուն հաղորդագրությունը): Դասակարգումը (Class) կարող է օգնել ձեզ տարբեր տեսքեր ստանալ: + +Առաջ անցնենք և անվանեք HTML կոդի որոշ մասեր: Փոխարինեք Ձեր վերնագիրը հետևյալով `header` : + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +Եվ հիմա ձեր ` post` ավելացրեք դասի ` article` բլոգի գրառում պարունակող: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+``` + +Այժմ եկեք ավելացնենք բլոկի սահմանումները տարբեր ընտրողների համար: Selector-ները (ընտրողները), որոնք սկսվում են ` - ով: ` դասին հատուկ են: Համացանցում կան բազմաթիվ հիանալի հղումներ և բացատրություններ CSS- ի վերաբերյալ, որոնք կարող են օգնել ձեզ հասկանալ հետևյալ կոդը: Առայժմ, պատճենեք և տեղադրեք այն ձեր `blog/static/css/blog.css` ֆայլում. + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +.page-header { + 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 { + color: #ffffff; + font-size: 36pt; + text-decoration: none; +} + +h1, +h2, +h3, +h4 { + font-family: 'Lobster', cursive; +} + +.date { + color: #828282; +} + +.save { + float: right; +} + +.post-form textarea, +.post-form input { + width: 100%; +} + +.top-menu, +.top-menu:hover, +.top-menu:visited { + color: #ffffff; + float: right; + font-size: 26pt; + margin-right: 20px; +} + +.post { + margin-bottom: 70px; +} + +.post h2 a, +.post h2 a:visited { + color: #000000; +} + +.post > .date, +.post > .actions { + float: right; +} + +.btn-default, +.btn-default:visited { + color: #C25100; + background: none; + border-color: #C25100; +} + +.btn-default:hover { + color: #FFFFFF; + background-color: #C25100; +} +``` + +Հետո, փոփոխեք հաղորդագրությունները ցուցադրող HTML կոդը: Փոխարինեք սարանով ՝ + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} +
+ +

{{ 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 %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
+``` + +Պահեք այդ ֆայլերը և թարմացրեք ձեր կայքը: + +![Պատկեր 14.4](images/final.png) + +Օօօօ Հիանալի տեսք ունի, այնպես չէ՞ Նայեք մեր տեղադրած կոդին: Մենք դասակարգումներ (classes) ենք ավելացրել HTML- ին և օգտագործել դրանք CSS- ում: Որտե՞ղ կկատարեք փոփոխություն, եթե ցանկանում եք, որ ամսաթիվը փիրուզագույն լինի: + +Մի վախեցեք խճճվել CSS- ով `փորձեք փոխություններ անել: CSS- ով "խաղալը" կօգնի ձեզ հասկանալ, թե ինչ ֆունկցոնալություն ունեն տարբեր գործիքներ: Եթե ​​ինչ-որ բան փչացնում եք, մի անհանգստացեք. Միշտ կարող եք չեղարկել այն: + +Խորհուրդ ենք տալիս անցնել «Հիմնական HTML & HTML5» և «Հիմնական CSS» առցանց դասընթացներ [freeCodeCamp](https://learn.freecodecamp.org/): Դրանք կարող են օգնել ձեզ դարձնել ձեր կայքերը ավելի գեղեցիկ HTML և CSS- ին տիրապետելու միջոցով: + +Պատրա՞ստ եք հաջորդ գլխին: :) \ No newline at end of file diff --git a/hy/css/images/bootstrap1.png b/hy/css/images/bootstrap1.png new file mode 100644 index 00000000000..bd81cd14373 Binary files /dev/null and b/hy/css/images/bootstrap1.png differ diff --git a/hy/css/images/color2.png b/hy/css/images/color2.png new file mode 100644 index 00000000000..3f82e7d3922 Binary files /dev/null and b/hy/css/images/color2.png differ diff --git a/hy/css/images/final.png b/hy/css/images/final.png new file mode 100644 index 00000000000..067c83d36cc Binary files /dev/null and b/hy/css/images/final.png differ diff --git a/hy/css/images/font.png b/hy/css/images/font.png new file mode 100644 index 00000000000..310f9e85f18 Binary files /dev/null and b/hy/css/images/font.png differ diff --git a/hy/css/images/margin2.png b/hy/css/images/margin2.png new file mode 100644 index 00000000000..895828b688d Binary files /dev/null and b/hy/css/images/margin2.png differ diff --git a/hy/deploy/README.md b/hy/deploy/README.md new file mode 100644 index 00000000000..3361881df0a --- /dev/null +++ b/hy/deploy/README.md @@ -0,0 +1,232 @@ +# Հրապարակում + +> **Նշում** Հաջորդ գլուխը, որոշ դեպքերում կարող է մի փոքր դժվար թվալ: Եղեք համառ և ավարտին հասցրեք այն, սերվերային կայքի տեղադրումը վեբ մշակման կարևոր մասն է: Այս գլուխը միտումնավոր տեղադրված է ձեռնարկի մեջտեղում, որպեսզի ձեր ուսուցիչը կարողանա օգնել ձեզ կայք թողարկելու բարդ գործընթացում: Այս կերպ Դուք կարող եք ինքնուրույն լրացնել բոլոր գլուխները, նույնիսկ եթե ժամանակը սուղ է: + +Մինչ այժմ ձեր կայքը հասանելի էր միայն ձեր համակարգչում: Այժմ դուք կսովորեք, թե ինչպես «տեղակայել/շահագործման հանձնել» ձեր կայքը: Տեղակայումը ձեր ծրագիրը ինտերնետում հրապարակելու գործընթացն է, որպեսզի մարդիկ վերջապես տեսնեն ձեր ստեղծած աշխատանքը: :) :) + +Ինչպես արդեն գիտեք, կայքը պետք է տեղակայված լինի սերվերի վրա: Ինտերնետում կան շատ սերվերների մատակարարներ, մենք կօգտագործենք [PythonAnywhere](https://www.pythonanywhere.com/) - ը: PythonAnywhere- ն անվճար է փոքր ծրագրերի համար, որոնք ունեն փոքր թվով այցելուներ, ինչը մեզ համար ավելի քան բավարար է: + +Մյուս արտաքին ծառայությունը, որը մենք կօգտագործենք, [ GitHub ](https://www.github.com) է, որը ծածկագրերի հոսթինգի (hosting-սպասարկման) ծառայություն է: Կան նաև այլ նմանատիպ ծառայություններ, բայց այսօր գրեթե յուրաքանչյուր ծրագրավորող ունի GitHub հաշիվ, և հիմա դուք նույնպես:: + +Այս երեք տեղերը ձեզ համար կարևոր կլինեն: Ձեր տեղական համակարգիչը կլինի այն վայրը, որտեղ դուք կկատարեք մշակում և փորձարկում: Երբ գոհ լինեք փոփոխություններից, ձեր ծրագրի պատճենը կտեղադրեք GitHub- ում: Ձեր կայքը կլինի PythonAnywhere- ում, և դուք այն կթարմացնեք ՝ GitHub-ից ձեր կոդի նոր օրինակը ստանալու միջոցով: + +# Git + +> ** Նշում ** Եթե դուք արդեն կատարել եք [installation steps](../installation/README.md), (տեղադրման քայլերը), ապա դա նորից անելու անհրաժեշտություն չկա. Կարող եք անցնել հաջորդ բաժին և սկսել ստեղծել ձեր Git պահոցը: + +{% include "/deploy/install_git.md" %} + +## Ստեղծեք մեր Git պահոցը: + +Git- ը հետևում է ֆայլերի որոշակի հավաքածուի փոփոխությանը, որը կոչվում է պահոց (կրճատ ՝ «repo»): Եկեք ստեղծենք մեկը մեր նախագծի համար: Բացեք վահանակ և գործարկեք այս հրամանները `djangogirls` գրացուցակում. + +> **Նշում** Նախքան պահեստի նախնականացումը սկսեք, ստուգեք ձեր ընթացիկ աշխատանքային գրացուցակը `օգտագործելով `pwd` (macOS/Linux) կամ `cd` (Windows) հրամաններ: Դուք պետք է լինեք ` djangogirls ` պանակում (folder): + +{% 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 պահոցը (git repository)միայն մեկ անգամ (և այլևս ստիպված չեք լինի կրկին մուտքագրել ձեր` օգտվողի անունն ու էլ. Փոստի հասցեն): + +Git- ը հետևելու է տվյալ գրացուցակի բոլոր ֆայլերի և գրացուցակների փոփոխություններին, սակայն մենք գերադասում ենք անտեսել դրանցից մի քանիսը: Դա անելու համար մենք պետք է պահեստի բազային գրացուցակում ստեղծենք ` .gitignore ` կոչվող ֆայլ: Բացեք ձեր խմբագիրը և ստեղծեք նոր ֆայլ հետևյալ բովանդակությամբ. + +{% filename %}.gitignore{% endfilename %} + + # Python + *.pyc + *~ + __pycache__ + + # Env + .env + myvenv/ + venv/ + + # Database + db.sqlite3 + + # Static folder at project root + /static/ + + # macOS + ._* + + +Եվ այն պահպանեք որպես ` .gitignore ` "djangogirls" արմատային գրացուցակում: + +> ** Նշում ** Ֆայլի անվան սկզբում գտնվող կետը կարևոր է: Եթե ​​նման ֆայլեր ստեղծելու խնդիրներ ունեք (Mac- ը թույլ չի տա ձեզ, կետով սկսվող անունով ֆայլ ստեղծել օրինակ, Finder- ի միջոցով), ապա օգտագործեք "Save As" (-պահել որպես) կոճակը ձեր կոդի խմբագրի ընտրացանկում, դա հաստատ անվտանգ է: Եվ համոզվեք, որ ֆայլի անվանման մեջ չեք ավելացնում `.txt`, `.py` կամ որևէ այլ ընդլայնում - Git- ը դա կճանաչի միայն այն դեպքում, եթե անունը պարունակում է միայն `.gitignore`.: Այն ֆայլեր, որոնց անունները սկսվում են (օրինակ `.gitignore` ով) Linux- ը և MacOS-ը դրանք ընդունում են որպես թաքնված, և սովորական `ls` հրամանը ցույց չի տալիս այս ֆայլերը: Փոխարենը օգտագործեք `ls -a` հրամանը `.gitignore` ֆայլը տեսնելու համար: +> +> **Նշում** Ձեր `.gitignore` ֆայլում նշված ֆայլերից մեկը `db.sqlite3` է: Այս ֆայլը ձեր (local database) տեղական տվյալների շտեմարանն է, որտեղ պահվում են ձեր օգտվողների բոլոր գրառումները: Մենք հետևելու ենք վեբ ծրագրավորման ստանդարտ պրակտիկային, ինչը նշանակում է, որ մենք կօգտագործենք առանձին տվյալների բազաներ ձեր տեղական թեստային կայքի և PythonAnywhere- ում ձեր կենդանի կայքի համար: PythonAnywhere տվյալների բազան կարող է լինել SQLite, ճիշտ այնպես, ինչպես ձեր զարգացման սարքում, բայց սովորաբար դուք կօգտագործեք MySQL անունով շտեմարան, որը կարող է սպասարկել այցելուների շատ ավելի մեծ քանակության, քան SQLite- ը: Ամեն դեպքում, անտեսելով ձեր SQLite տվյալների շտեմարանը GitHub- ի համար, նշանակում է, որ մինչ այժմ ձեր ստեղծած բոլոր հաղորդագրություններն ու գերշահագործողները հասանելի կլինեն միայն տեղական մակարդակում, և արտադրության համար անհրաժեշտ է ստեղծել նորերը: Դուք պետք է ձեր տեղական տվյալների բազայի (local database-ի) մասին մտածեք որպես լավ խաղահրապարակ, որտեղ կարող եք փորձարկել տարբեր բաներ և չվախենալ, որ ձեր իրական գրառումները կջնջեք ձեր բլոգից: + +Լավ է օգտագործել `git status` (git կարգավիճակի) հրամանը նախքան`git add` (git ավելացնելը) կամ ցանկացած այլ պահ, երբ վստահ չեք, թե ինչն է փոխվել: Դա կօգնի Ձեզ զերծ մնալ տհաճ անակնկալներից, ինչպիսիք են սխալ ֆայլերի ավելացումը կամ կատարումը: `git status` (git կարգավիճակ) հրամանը վերադարձնում է տեղեկատվություն git- ում նախկինում չնկատված / փոփոխված / ներկայացված բոլոր ֆայլերի, ինչպես նաև մասնաճյուղի կարգավիճակի և այլնի մասին: Արդյունքը պետք է նման լինի հետևյալին. + +{% filename %}command-line{% endfilename %} + + $ git status + On branch master + + 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) + + +Եվ վերջապես մենք կպահպանենք մեր փոփոխությունները: Անցեք վահանակին և մուտքագրեք այս հրամանները. + +{% 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 + + +## Հրապարակեք ձեր կոդը GitHub- ում + +Անցեք [GitHub.com](https://www.github.com) կայք և գրանցվեք նոր անվճար օգտվողի հաշվի համար: (Եթե դա արդեն արել եք սեմինարի նախապատրաստական ​​փուլում, հիանալի է): Համոզվեք, որ հիշում եք ձեր գաղտնաբառը (ավելացրեք այն գաղտնաբառերի կառավարչին (password manager), եթե այն օգտագործում եք): + +Հաջորդը, ստեղծեք նոր պահեստ ` "my-first-blog" (իմ առաջին բլոգը) անունով: "initialize with a README" վանդակը պետք չէ ընտրել, բաց թողեք .gitignore- ը (այս ֆայլը ձեռքով կստեղծենք) և թողեք License որպես None: + +![](images/new_github_repo.png) + +> **Նշում** . `my-first-blog` (իմ առաջին բլոգ) պահեստի անվանումը շատ կարևոր է: Իհարկե կարող եք այլ անվանումով հանդես գալ, բայց այն բազմիցս հանդիպում է հրահանգներում, և ամեն անգամ ստիպված կլինեք փոխել այն ձեր սեփականով: Միգուցե ավելի հեշտ է պահպանել `my-first-blog` անվանումը: + +Հաջորդ էկրանին կտեսնեք ձեր ռեպոյի կլոնային URL- ը, որը դուք կօգտագործեք հետևյալ հրահանգների միջոցով: + +![](images/github_get_repo_url_screenshot.png) + +Այժմ մենք պետք է ձեր համակարգչում կապենք տեղական Git պահոցը GitHub- ի հետ: + +Մուտքագրեք հետևյալը ձեր վահանակի (console-ի) մեջ (փոխարինեք `` - ը ձեր GitHub հաշիվը ստեղծելիս մուտքագրած օգտանունով, բայց առանց անկյունային գծերի. իսկ URL-ը պետք է համապատասխանի ձեր տեսած կլոնային URL- ին): + +{% filename %}command-line{% endfilename %} + + $ git remote add origin https://github.com//my-first-blog.git + $ git push -u origin master + + +GitHub մուտք գործելուց հետո ձեզանից կպահանջվի ձեր GitHub օգտվողի անունն ու գաղտնաբառը (կա՛մ հենց այնտեղ ՝ հրամանի տողի պատուհանում, կա՛մ ելնող պատուհանում), և հավատարմագրերը մուտքագրելուց հետո պետք է հայտնվի նման մի բան. + +{% filename %}command-line{% endfilename %} + + 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/ola/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), the [Django Girls Tutorial](https://github.com/DjangoGirls/tutorial), և շատ այլ բաց կոդով ծրագրեր GitHub- ում: :) + +# PythonAnywhere- ում մեր բլոգի տեղադրումը + +## Գրանցվեք PythonAnywhere հաշվում + +> **Նշում** Եթե ավելի վաղ դուք արդեն գրանցվել եք PythonAnywhere հաշվում, ապա կարիգ չկա այն կրկնել: + +{% include "/deploy/signup_pythonanywhere.md" %} + +## Մեր կայքի տեղադրումը PythonAnywhere- ում + +Վերադարձեք [PythonAnywhere Dashboard](https://www.pythonanywhere.com/) հիմնական ընտրացանկ ՝ կտտացրեք պատկերանշանին և ընտրեք "Bash" վահանակը (console) գործարկելու տարբերակը. Սա PythonAnywhere-ի command line-ի (հրամանի տողի) տարբերակն է, ինչպես ձեր համակարգչում: + +![PythonAnywhere վեբ տարբերակի 'New Console' (Նոր վահանակ) բաժնում ՝ օգտագործելով «Bash» կոճակը](images/pythonanywhere_bash_console.png) + +> **Հղում** PythonAnywhere- ը հիմնված է Linux- ի վրա, այնպես որ, եթե դուք օգտագործում եք Windows, ապա console-ը (վահանակը) մի փոքր այլ տեսք կունենա ձեր համակարգչի վրա: + +PythonAnywhere- ում վեբ հավելվածի տեղադրումը ենթադրում է GitHub- ից ձեր կոդի բեռնումը և PythonAnywhere-ի կարգավորումը `որպեսզի այն ճանաչի և գործարկի որպես վեբ ծրագիր: Դա ձեռքով անելու եղանակներ կան, բայց PythonAnywhere- ը տրամադրում է օգնող գործիք, որն ամեն ինչ կանի ձեր փոխարեն: Եկեք նախ տեղադրենք այն. + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ pip install --user pythonanywhere + + +Վահանակը պետք է տպի նման մի բան, ինչպիսին է `Collecting pythonanywhere` և վերջում `Successfully installed (...) pythonanywhere- (...)`. + +Այժմ մենք գործարկում ենք օգնականին ՝ GitHub-ից մեր հավելվածը ավտոմատ կերպով կարգավորելու համար: PythonAnyplace- ի վահանակի մեջ մուտքագրեք հետևյալ հրահանգը (մի մոռացեք օգտագործել ձեր GitHub օգտվողի անունը `` -ի փոխարեն, որպեսզի URL- ը համապատասխանի GitHub-ի կլոնավորված URL- ին): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ pa_autoconfigure_django.py --python=3.10 https://github.com//my-first-blog.git + + +Երբ տեսնեք, թե ինչպես է այն աշխատում, կարող եք հասկանալ, թե կոնկրետ ինչ է այն անում. + +- Ներբեռնեք ձեր կոդը GitHub- ից +- Virtualenv-ի ստեղծումը PythonAnyplace- ում `ճիշտ այնպես, ինչպես ձեր համակարգչում է +- Թարմացրեք ձեր settings file-ը (կարգավորումների ֆայլը) տեղակայման որոշ կարգավորումներում (deployment settings) +- Ստեղծեք տվյալների բազա PythonAnywhere-ում ՝ օգտագործելով այս `manage.py migrate` հրամանը +- Ձեր ստատիկ ֆայլերի (static files) կարգավորում (դրանց մասին մենք կիմանանք ավելի ուշ) +- Եվ կարգավորեք PythonAnywhere- ը `ձեր վեբ հավելվածը API- ի միջոցով սպասարկելու համար + +Այս բոլոր քայլերը ավտոմատացված են PythonAnywhere- ում, բայց դրանք այն նույն քայլերն են, որոնք պետք է կատարվեն սերվերի ցանկացած այլ մատակարարի հետ: + +Հիմնական բանը, որն այժմ պետք է նկատել, այն է, որ PythonAnywhere տվյալների բազան իրականում ամբողջովին տարանջատված է ձեր համակարգչի տվյալների բազայից: Սա նշանակում է, որ նրանք կարող են ունենալ տարբեր հաղորդագրություններ և ադմինիստրատորի հաշիվներ: Արդյունքում, ինչպես արդեն արեցինք մեր համակարգչում, մենք պետք է ադմինիստրատորի հաշիվը նախապատրաստենք `createsuperuser` - ով: PythonAnywhere- ը ավտոմատ կերպով կակտիվացնի ձեր virtualenv-ին, այնպես որ ձեզ հարկավոր է միայն գործարկել՝ + +{% filename %}PythonAnywhere command-line{% endfilename %} + + (ola.pythonanywhere.com) $ python manage.py createsuperuser + + +Մուտքագրեք ադմինիստրատորի հաշվի (admin user) տեղեկատվությունը: Քանի դեռ չեք ցանկանում ձեր PythonAnywhere գաղտնաբառն ավելի ապահով դարձնել, ցանկալի է օգտագործել ձեր համակարգչում օգտագործածները, որպեսզի խառնաշփոթ չլինի, + +Այժմ, եթե ցանկանում եք, կարող եք նաև հայացք նետել ձեր կոդին PythonAnywhere- ում ՝ օգտագործելով `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 + + +Կարող եք նաև մտնել "Files" («Ֆայլեր») ներդիր էջ և շրջել ՝ օգտագործելով PythonAnywhere- ի ներկառուցված ֆայլերի զննիչը (built-in file browser): (Վահանակի էջից վերևի աջ անկյունում գտնվող ցանկի կոճակից կարող եք անցնել PythonAnywhere- ի այլ էջեր: Էջերից մեկում հայտնվելուց հետո, վերին մասում այլ էջերի հղումներ կան:) + +## Դու օնլայն եք: + +Ձեր կայքը այժմ հանրային ինտերնետում է: Անցեք PythonAnywhere- ի "Web" ներդիրին `ձեր կայքի հղումը ( link-ը) ստանալու համար: Կարող եք այն կիսել յուրաքանչյուրի հետ, ում ցանկանում եք: :) + +> **Նշում** Սա սկսնակների ձեռնարկ է, և մենք կայքը տեղակայելիս օգտագործել ենք մի քանի հնարքներ, որոնք անվտանգության տեսանկյունից իդեալական չեն: Եթե ​​որոշեք դրանով նախագիծ կառուցել կամ նորը սկսել, ապա պետք է ստուգեք [Django deployment checklist](https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/) -ը՝ (Django- ի տեղակայման ստուգաթերթը) ձեր կայքի անվտանգության վերաբերյալ որոշ խորհուրդների համար: + +## Վրիպազերծման խորհուրդներ + +Ահա մի քանի ընդհանուր պատճառներ, եթե ​​ `pa_autoconfigure_django.py` սկրիպտը գործարկելիս սխալ եք տեսնում + +- PythonAnywhere API նշան բանալի չի ստեղծվել ՝ մուտքն ապահովելու համար: +- GitHub պահոցի URL- ում սխալ է տեղի ունեցել +- Եթե ​​տեսնում եք սխալ *"Could not find your settings.py"* (Չկարողացա գտնել ձեր settings.py) հետևյալ բովանդակությամբ, դա հավանաբար այն պատճառով է, որ դուք ի վիճակի չէիք ձեր բոլոր ֆայլերը ավելացնել Git- ին և / կամ դրանք հաջողությամբ չկարողացաք բեռնել GitHub- ում: Եվս մեկ անգամ նայեք վերևում գտնվող Git հատվածին և ստուգեք հրահանգները: +- Եթե ​​նախկինում գրանցվել եք PythonAnywhere հաշվում և ունեցել եք ստատիկ սխալ, ապա, հավանաբար, ձեր հաշվի համար ունեք SQLite- ի հին տարբերակ (օրինակ ՝ 3.8.2): Այս դեպքում մուտք գործեք նոր հաշիվ և փորձեք վերևում գտնվող PythonAnywhere բաժնի հրահանգները: + +Եթե ​​ձեր կայք այցելելիս սխալ եք տեսնում, ապա տեղեկատվության կարգավորման համար, նախ նայիր **error log** (սխալների մատյանը): Դրա հղումը կարող եք գտնել PythonAnywhere ["Web" page](https://www.pythonanywhere.com/web_app_setup/) էջում: Տեսեք, արդյոք կան սխալի հաղորդագրություններ. վերջինները ներքևում են: + +Այնտեղ կարող եք տեսնել նաև [general debugging tips on the PythonAnywhere help site](http://help.pythonanywhere.com/pages/DebuggingImportError). (PythonAnywhere- ի օգնության կայքի ընդհանուր սխալների վերացման խորհուրդներ) + +Եվ հիշեք. Ձեր մարզիչը այստեղ է ՝ օգնելու: + +# Ստուգեք ձեր կայքը: + +Ձեր կայքի դեֆոլտ էջում պետք է գրվի "It worked!"-(Այն աշխատեց), ճիշտ այնպես, ինչպես դա անում է ձեր տեղական համակարգչում: Փորձեք URL- ի վերջում ավելացնել `/admin/` և դուք կտեղափոխվեք ադմինիստրատորի կայք: Մուտք գործեք ձեր օգտվողի անունով և գաղտնաբառով և կտեսնեք, որ կարող եք նոր գրառումներ ավելացնել սերվերում. Հիշեք, որ ձեր փորձարկման տվյալների բազայից գրառումները չեն ուղարկվի ձեր կենդանի բլոգ: + +Մի քանի գրառում ստեղծելուց հետո կարող եք վերադառնալ ձեր տեղական կարգավորմանը (ոչ PythonAnywhere): Այստեղ է, որ պետք է աշխատել փոփոխություններ ստեղծելու վրա: Սա վեբ մշակման ընդհանուր աշխատանքային գործընթաց է. Տեղական փոփոխություններ կատարեք, այդ փոփոխությունները վերբեռնեք GitHub- ում և մղեք իրական վեբ սերվերի վրա: Սա թույլ է տալիս աշխատել և փորձարկել `առանց ձեր կայքը խափանելու: Բավականին լավ է, այնպես չէ՞ + +Դուք արժանի եք գովասանքի: Սերվերների տեղակայումը վեբ մշակման ամենաբարդ փուլերից մեկն է, և դա իրականացնելը հաճախ տևում է մի քանի օր, մինչ դրանք կաշխատեն: Բայց դուք ստացաք կենդանի կայք ՝ իրական ինտերնետում: \ No newline at end of file diff --git a/hy/deploy/images/github_get_repo_url_screenshot.png b/hy/deploy/images/github_get_repo_url_screenshot.png new file mode 100644 index 00000000000..ee1560b1e85 Binary files /dev/null and b/hy/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/hy/deploy/images/new_github_repo.png b/hy/deploy/images/new_github_repo.png new file mode 100644 index 00000000000..d1f82e5d863 Binary files /dev/null and b/hy/deploy/images/new_github_repo.png differ diff --git a/hy/deploy/images/pythonanywhere_account.png b/hy/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/hy/deploy/images/pythonanywhere_account.png differ diff --git a/hy/deploy/images/pythonanywhere_bash_console.png b/hy/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..68eb2a030e1 Binary files /dev/null and b/hy/deploy/images/pythonanywhere_bash_console.png differ diff --git a/hy/deploy/images/pythonanywhere_beginner_account_button.png b/hy/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/hy/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/hy/deploy/images/pythonanywhere_create_api_token.png b/hy/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..abae45ae37a Binary files /dev/null and b/hy/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/hy/deploy/install_git.md b/hy/deploy/install_git.md new file mode 100644 index 00000000000..b2863460a9c --- /dev/null +++ b/hy/deploy/install_git.md @@ -0,0 +1,52 @@ +Git- ը «տարբերակների կառավարման համակարգ է» ("version control system"), որն օգտագործվում է շատ ծրագրավորողների կողմից: Այս ծրագիրը վերահսկում է փոփոխությունները, որոնք տեղի են ունենում ֆայլերում, որպեսզի հետագայում կարողանաք վերականգնել ծածկագրի վիճակը ցանկալի ժամանակահատվածում: Մի փոքր նման է բառ մշակող ("track changes" )ծրագրերի գործառույթին (օրինակ ՝ Microsoft Word կամ LibreOffice Writer) բայց շատ ավելի հզոր: + +## Git-ի ներբեռնում + + + +Կարող ես ներբեռնել Git-ը այս հղումով [git-scm.com](https://git-scm.com/). "next" (հաջորդ) կարող եք ընտրել բոլոր քայլերին, բացառությամբ երկուսի. Քայլ որտեղ այն խնդրում է ընտրել ձեր խմբագրին (choose your editor), պետք է ընտրեք Nano- ն, իսկ «Ձեր PATH միջավայրի կարգավորումը»-("Adjusting your PATH environment") խորագրի ներքո ընտրեք "Use Git and optional Unix tools from the Windows Command Prompt"(«Օգտագործեք Git և ընտրովի Unix գործիքներ Windows հրամանի տողը»)(ներքևի տարբերակը): Մնացած բոլոր պարամետրերը կարող եք թողնել: "Checkout Windows-style, commit Unix-style line endings" տարբերակը լավ ընտրություն կլինի: + +Տեղադրումը հաջող ավարտելուց հետո մի մոռացեք վերսկսել հրամանի տողը կամ PowerShell- ը: + + + +Ներբեռնեք Git- ը [git-scm.com](https://git-scm.com/) կայքից և հետևեք հրահանգներին: + +> ** Նշում ** Եթե դուք օգտագործում եք OS X 10.6, 10.7 կամ 10.8, ապա պետք է ներբեռնեք git- ի այս տարբերակը ՝ [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) + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo apt install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo dnf install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo zypper install git +``` + + \ No newline at end of file diff --git a/hy/deploy/signup_pythonanywhere.md b/hy/deploy/signup_pythonanywhere.md new file mode 100644 index 00000000000..8fdbc043ab9 --- /dev/null +++ b/hy/deploy/signup_pythonanywhere.md @@ -0,0 +1,19 @@ +PythonAnyway- ը ծառայություն է Python կոդի «ամպի մեջ» ("in the cloud") սերվերների վրա աշխատելու համար: Մենք այն օգտագործում ենք ինտերնետում մեր կայքը տեղակայելու համար: + +Գրանցվեք PythonAnywhere հաշիվը որպես "Beginner" («Սկսնակ», անվճար տարբերակը բավարար է, կրեդիտ քարտ չի պահանջվում): + +* [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +![PythonAnywhere գրանցման էջում կա 'Beginner' (Սկսնակ) անվճար հաշիվ ստեղծելու կոճակ](../deploy/images/pythonanywhere_beginner_account_button.png) + +> **Նշում** . Օգտանուն ընտրելիս հիշեք, որ բլոգի URL-ը կունենա այսպիսի տեսք `yourusername.pythonanywhere.com`, այնպես որ ընտրեք կամ ձեր սեփական մականունը կամ բլոգի թեմային վերաբերող անուն: Նաև համոզվեք, որ կհիշեք ձեր գաղտնաբառը (ավելացրեք այն ձեր գաղտնաբառերի կառավարչին,եթե նման բան օգտագործում եք): + +## PythonAnywhere- ում API token-ի (նշանի) ստեղծում + +Սա մի բան է, որը դուք պետք է անեք միայն մեկ անգամ: Երբ գրանցվեք PythonAnywhere- ում, ձեզ կտեղափոխեն կառավարման վահանակ (dashboard): Գտեք ձեր "Account" (հաշիվ) էջի վերևի աջ մասի հղումը ՝ + +![Հաշվի հղումը գտնվում է էջի վերևի աջ հատվածում](../deploy/images/pythonanywhere_account.png) + +ապա ընտրեք "API token" անունով ներդիրը և սեղմեք "Create new API token". (ստեղծել նոր API նշան) կոճակը: + +![API token (API նշանի) ներդիրը Account page-ում (հաշվի էջում)](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/hy/django/README.md b/hy/django/README.md new file mode 100644 index 00000000000..087714c84f2 --- /dev/null +++ b/hy/django/README.md @@ -0,0 +1,27 @@ +# Ի՞նչ է Django- ն: + +Django- ն (/ˈdʒæŋɡoʊ/ *jang-goh*) Python- ում գրված անվճար և բաց կոդով վեբ հավելվածների շրջանակ է: Վեբ շրջանակը բաղադրիչների հավաքածու է, որոնք կօգնեն ձեզ արագ և հեշտ զարգացնել կայքերը: + +Երբ կայքեր եք մշակում, ձեզ անհրաժեշտ են նմանատիպ բաղադրիչներ ինչպիսիք են. օգտվողներին նույնականացնելու միջոցներ (մուտք, ելք, գրանցում), կայքի վահանակ, ձևաթղթեր, ֆայլեր վերբեռնելու գործիքներ և այլն: + +Բարեբախտաբար, այլ մարդիկ արդեն նկատել են որ վեբ մշակողները նման խնդիրներ են ունենում նոր կայք կառուցելիս, ուստի նրանք միավորվեցին և ստեղծեցին շրջանակներ (դրանցից մեկը Django- ն է), որոնք մեզ առաջարկում են պատրաստի ձևանմուշներ (components) օգտագործման համար: + +Երբ նոր կայք եք կառուցում շրջանակներ (Frameworks) օգնում են զարգացման գործընթացը հեշտացնել և նորից հեծանիվ չհորինել: + +## Ինչու՞ է ձեզ անհրաժեշտ շրջանակ: + +Հասկանալու համար, թե ինչի համար է մեզ հարկավոր Django- ն, մենք պետք է ավելի ուշադիր հետևենք սերվերներին: Նախ, սերվերը պետք է իմանա, որ դուք ցանկանում եք, որ այն ձեզ որպես վեբ էջ ծառայի: + +Պատկերացրեք փոստարկղ (նավահանգիստ), որը վերահսկվում է մուտքային նամակների (հարցումների) համար: Դա արվում է վեբ սերվերի( web server-ի) կողմից: Վեբ սերվերը (server) կարդում է էլ. Փոստը, այնուհետև ուղարկում է պատասխան վեբ էջի միջոցով: Բայց երբ ուզում ես ինչ-որ բան ուղարկել, պետք է այն որոշակի բովանդակություն ունենա: Իսկ Django- ն կօգնի ձեզ ստեղծել բովանդակություն (content): + +## Ի՞նչ է պատահում, երբ ինչ-որ մեկը վեբ կայք է խնդրում ձեր սերվերից: + +Երբ որևէ հարցումը է գալիս վեբ սերվերին, այն փոխանցվում է Django- ին, որը փորձում է պարզել, թե կոնկրետ ինչ է իրենից պահանջվում: Նախ այն վերցնում է ինտերնետային կայքի հասցեն և հետք փորձում հասկանալ, թե ինչ անել: Այս հատվածը իրականացնում է Django- ի ** urlresolver ** ը (նշենք, որ կայքի հասցեն կոչվում է URL - Uniform Resource Locator - այնպես որ * urlresolver * անունն իմաստ ունի): Այն շատ խելացի չէ. ուստի այն պարզապես վերցնում է օրինաչափությունների ցուցակ և փորձում համապատասխանեցնել URL- ի հետ: Django- ն վերևից ներքև ստուգում է օրինաչափությունները, և եթե ինչ-որ բան համընկնում է, ապա Django- ն հարցումը փոխանցում է համապատասխան գործառույթին (որը կոչվում է դիտում *view*): + +Պատկերացրեք նամակներով փոստատարի: Նա քայլում է փողոցով և ստուգում տան համարները նամակի վրա նշված հասցեի հետ: Եթե ​​դրանք համընկնում են, ապա նա նամակ է թողնում: Այսպես է աշխատում urlresolver- ը: + +Բայց ամենահետաքրքիր բաները տեղի են ունենում դիտման *view* գործառույթում. Օրինակ, մենք կարող ենք մուտք գործել տվյալների բազա՝ որոշ տեղեկություններ որոնելու համար: Միգուցե օգտագործողը խնդրե՞լ է փոխել որոշ տեղեկություններ: Օրինակ նամակը ասոմ է ՝ «Խնդրում եմ, փոխեք իմ աշխատանքի նկարագիրը»: *view* դիտման գործառույթը կարող է ստուգել, թե ​​արդյոք դուք դա անելու թույլտվություն ունեք, ապա թարմացրեք աշխատանքի նկարագրությունը և հետ ուղարկեք հաղորդագրություն."Done!" (Կատարված է) Դրանից հետո *view* առաջացնում է պատասխան, և Django- ն կարող է այն ուղարկել օգտվողի վեբ բրաուզերին: + +Վերոնշյալ նկարագրությունը մի փոքր պարզեցված է, բայց ձեզ հարկավոր չէ իմանալ բոլոր տեխնիկական «նրբությունները» հենց հիմա: Բավական է հասկանալ հիմնական գաղափարը: + +Այսպիսով, առանց մանրամասների մեջ շատ խորանալու, եկեք սկսենք ինչ-որ բան ստեղծեք Django- ի հետ և այդ ընթացքում կսովորենք բոլոր կարևոր առանձնահատկությունները: \ No newline at end of file diff --git a/hy/django_admin/README.md b/hy/django_admin/README.md new file mode 100644 index 00000000000..2ad3043c013 --- /dev/null +++ b/hy/django_admin/README.md @@ -0,0 +1,57 @@ +# Django ադմին + +Հենց նոր մոդելավորված գրառումները ավելացնելու, խմբագրելու և ջնջելու համար մենք կօգտագործենք Django ադմինիստրատորը: + +Բացեք `blog/admin.py` ֆայլը ծածկագրի խմբագրում և դրա բովանդակությունը փոխարինեք հետևյալով. + +{% filename %}blog/admin.py{% endfilename %} + +```python +from django.contrib import admin +from .models import Post + +admin.site.register(Post) +``` + +Ինչպես տեսնում եք, մենք ներմուծել ենք (include-ներառել) Post-ի մոդելը, որը սահմանված էր նախորդ գլխում: Որպեսզի մեր մոդելը հասանելի լինի ադմինիստրատորի էջում, մենք պետք է այն գրանցենք ՝ օգտագործելով այս `admin.site.register(Post)` գրառումը: + +Լավ, ժամանակն է նայել մեր Post մոդելը: Հիշեք, որ վեբ սերվերը գործարկելու համար վահանակում գործարկեք այս `python manage.py runserver` հրամանը: Գնացեք ձեր browser (դիտարկիչ) և մուտքագրեք այս http://127.0.0.1:8000/admin/ հասցեն: Դուք կտեսնեք մուտքի թույլտվության էջ. + +![Մուտք էջ](images/login_page2.png) + +Մուտք գործելու համար հարկավոր է ստեղծել *superuser* ՝ օգտվողի հաշիվ, որն ամբողջությամբ վերահսկում է կայքը: Վերադարձեք հրամանի տող, մուտքագրեք `python manage.py createsuperuser` և սեղմեք Enter: + +> Հիշեք ՝ վեբ սերվերի գործարկման ընթացքում նոր հրամաններ գրելու համար բացեք նոր տերմինալային պատուհան և ակտիվացրեք ձեր վիրտուալ միջավայրը (virtualenv): Մենք վերանայեցինք, թե ինչպես գրել նոր հրամաններ ** Ձեր առաջին Django նախագիծը ** (Your first Django project)գլուխը, **Մեկնարկելով վեբ սերվերը** (Starting the web server) բաժնում: + +{% filename %}macOS or Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py createsuperuser + + +{% 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. + + +Վերադարձեք ձեր բրաուզեր (browser) և մուտք գործեք ձեր ընտրած օգտվողի անունով և գաղտնաբառով: Այնուհետև Դուք պետք է տեսնեք Django կառավարման վահանակ (Django admin dashboard): + +![Django ադմին](images/django_admin3.png) + +Գնացեք գրառումներ/ Posts բաժին և մի փոքր փորձարկեք այն: Ավելացրեք հինգ կամ վեց բլոգային գրառումներ (blog posts): Մի անհանգստացեք բովանդակության համար. Դուք այն տեսնում եք միայն ձեր տեղական համակարգչում. Դուք կարող եք պատճենել և տեղադրել տեքստը այս ձեռնարկից ՝ ժամանակ խնայելու համար: :) + +Համոզվեք, որ առնվազն երկու կամ երեք գրառում (բայց ոչ բոլորը) հրապարակման ամսաթիվ ունեն: Ապագայում դա կարող է օգտակար լինել: + +![Django ադմին](images/edit_post3.png) + +Եթե ​​ցանկանում եք ավելին իմանալ Django- ի ադմինիստրատորի մասին, տես պաշտոնական փաստաթղթերի այս բաժինը ՝ https://docs.djangoproject.com/en/2.2/ref/contrib/admin/ + +Հավանաբար, ճիշտ ժամանակն է մեկ բաժակ սուրճով (կամ թեյով) ինքներդ ձեզ ոքևորելու և ձեր էներգիան լրացնելու համար ինչ-որ բան ուտելու համար: Դուք պարզապես ստեղծեցիք ձեր առաջին Django մոդելը և արժանի եք ընդմիջման: \ No newline at end of file diff --git a/hy/django_admin/images/django_admin3.png b/hy/django_admin/images/django_admin3.png new file mode 100644 index 00000000000..fb221bd18e1 Binary files /dev/null and b/hy/django_admin/images/django_admin3.png differ diff --git a/hy/django_admin/images/edit_post3.png b/hy/django_admin/images/edit_post3.png new file mode 100644 index 00000000000..57299b6f5af Binary files /dev/null and b/hy/django_admin/images/edit_post3.png differ diff --git a/hy/django_admin/images/login_page2.png b/hy/django_admin/images/login_page2.png new file mode 100644 index 00000000000..c16d1aa4289 Binary files /dev/null and b/hy/django_admin/images/login_page2.png differ diff --git a/hy/django_forms/README.md b/hy/django_forms/README.md new file mode 100644 index 00000000000..0b22cb8ad61 --- /dev/null +++ b/hy/django_forms/README.md @@ -0,0 +1,481 @@ +# Django ֆորմաներ + +Վերջին բանը, որ մենք ուզում ենք անել մեր կայքում, բլոգի գրառումներն ավելացնելու և խմբագրելու հարմարավետ միջոց ստեղծելն է: Django- ի `admin` -ը (ադմինիստրատորը) հիանալի է, բայց դրա դիզայնը դժվար է փոխել: `forms` -ի հետ մենք բացարձակ վերահսկողություն կունենանք մեր ինտերֆեյսի վրա: Մենք կարող ենք իրագործել գրեթե այն ամենը, ինչ կարող ենք պատկերացնել: + +Django ձևերի (Django forms-ի) մեջ հաճելին այն է, որ մենք կարող ենք զրոյից ստեղծել նոր ձև, կամ օգտագործել `ModelForm`-ը ՝ ձևերի պարունակությունը մոդելում պահելու համար: + +Սա հենց այն է, ինչ մենք ուզում ենք անել. Մենք ձև կստեղծենք `Post` մոդելի համար: + +Ինչպես Django-ի յուրաքանչյուր կարեւոր մաս, ձևերը (forms) նույնպես ունեն իրենց սեփական ֆայլը . ` form.py `: + +Մենք պետք է այս անունով ֆայլ ստեղծենք `blog` գրացուցակում: + + blog + └── forms.py + + +Շատ լավ, եկեք բացենք այն կոդերի խմբագրում և մուտքագրենք հետևյալ կոդը. + +{% filename %}blog/forms.py{% endfilename %} + +```python +django ներմուծման ձևերից + +.models- ից ներմուծում են Post + +դասի PostForm (forms. ModelForm): + + class Meta: + model = Post + fields = ('title', 'text',) + + +``` + +Նախ մենք պետք է ներմուծենք Django ձևերը/Django forms (`from django import forms` /django ներմուծման ձևերից) և մեր `Post` մոդելը/model (` .models- ից ներմուծում ենք Post `): + +` PostForm ` - ը, ինչպես, հավանաբար, ենթադրում եք, մեր ձևի անունն է: Մենք պետք է Django- ին ասենք, որ այս ձևը ` ModelForm ` է (այնպես որ Django- ն ինչ-որ կախարդանք անի մեզ համար). դրա համար պատասխանատու է `forms.ModelForm` - ը: + +Հաջորդը, մենք ունենք ` class Meta `, որտեղ մենք սահմանում ենք (Django- ին), թե որ մոդելը կօգտագործվի այս ձևը ստեղծելու համար (` model = Post `): + +Վերջապես, մենք կարող ենք հստակեցնել, թե որ դաշտը (կամ դաշտերը) պետք է առկա լինեն մեր ֆորմայում: Այս սցենարում մենք ուզում ենք միայն ` title (վերնագիրը) ` և ` text(տեքստը) ` ցուցադրվեն. Հեղինակը պետք է լինի այն օգտվողը, ով մուտք է գործել իր օգտվողի անունով (այսինքն դու!) և ` created_date(ստեղծված_ ամսաթիվը) `պետք է ավտոմատ կերպով տեղադրվի գրառման ստեղծման ժամանակ (այսինքն ՝ կոդով), այնպես չէ՞: + +Եվ վերջ այսքանը! Մեզ մնում է միայն օգտագործել ձևը *view* և ցուցադրել այն template-ում(ձևանմուշում): + +Այսպիսով, մեկ անգամ ևս մենք կստեղծենք link(հղում) դեպի էջ, URL, դիտում և template (ձևանմուշ): + +## Link (Հղում) դեպի էջի ձևը + +Հղումը չավելացնելուց առաջ մեզ պետք են մի քանի պատկերակներ, որոնք կօգտագործվեն որպես հղման կոճակներ: Այս ձեռնարկի համար ներբեռնեք [ file-earmark-plus.svg ](https://raw.githubusercontent.com/twbs/icons/main/icons/file-earmark-plus.svg) և պահեք այն ` blog/templates/blog/icons/ ` թղթապանակում: + +> Նշում. SVG պատկերը ներբեռնելու համար բացեք համատեքստային ընտրացանկը հղման վրա (սովորաբար դրա վրա աջ կտտացնելով) և ընտրեք <> («Պահել հղումը որպես»): Պատուհանում հարցնելով, թե որտեղ պետք է ֆայլը պահպանել, անցեք ձեր Django նախագծի ` djangogirls ` գրացուցակը, իսկ դրա ներքո ՝ ` blog/templates/blog/icons/ ` ենթագրացուցակ, և ֆայլը այնտեղ պահեք: + +Codeամանակն է ծածկագրի խմբագրում բացել `blog/templates/blog/base.html`: Այժմ մենք կարող ենք օգտագործել այս պատկերակային ֆայլը բազային ձևանմուշի մեջ ՝ հետևյալ կերպ. ` div ` տարրում ` headrer ` բաժնում, մենք կավելացնենք հղում ` h1 ` տարրից առաջ. + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + {% include './icons/file-earmark-plus.svg' %} + +``` + +Նկատի ունեցեք, որ մենք ուզում ենք մեր նոր տեսակետը կոչել ` post_new `: [SVG icon](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.11.3/bootstrap-icons-1.11.3.zip): Անջատեք ֆայլը և պատճենեք բոլոր SVG պատկերային ֆայլերը ` blog/templates/blog/ ` ներսում գտնվող նոր պանակի մեջ, որը կոչվում է ` icons `: Այդ կերպ Դուք կարող եք մուտք գործել ` pencil-fill.svg ` պես պատկերակ ՝ օգտագործելով ֆայլի ուղի `blog/templates/blog/icons/pencil-fill.svg ` + +Տողը խմբագրելուց հետո ձեր HTML ֆայլը այժմ պետք է ունենա այսպիսի տեսք. + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% load static %} + + + + Django Girls blog + + + + + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ + +``` + +http://127.0.0.1:8000 էջը փրկելուց և թարմացնելուց հետո կտեսնեք ծանոթ ` NoReverseMatch ` error(սխալ) : Այդպե՞ս է: Լավ + +## URL + +Կոդի խմբագրում բացում ենք ` blog/urls.py` և ավելացնում տող. + +{% filename %}blog/urls.py{% endfilename %} + +```python +path('post/new/', views.post_new, name='post_new'), +``` + +Եվ վերջնական ծածկագիրը կտեսնի այսպես. + +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views + +urlpatterns = [ + 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 ` դիտումը: Եկեք ավելացնենք հենց հիմա: + +## post_new view + +բացեք ` բլոգը / views.py ` ֆայլը ծածկագրի խմբագրում և ավելացնել տողերի մնացած տողերի հետևյալ տողերը. + +{% filename %}blog/views.py{% endfilename %} + +```python +.forms- ից ներմուծում է PostForm +``` + +Եվ հետո մեր * տեսակետը *: + +{% filename%} blog/views.py {% endfilename%} + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Նոր ` Post ` ձև ստեղծելու համար հարկավոր է զանգահարել ` PostForm () ` և փոխանցել այն ձևանմուշին: Մենք կվերադառնանք այս *view*, բայց առայժմ արագ եկեք ձևանմուշ ստեղծենք ձևի համար: + +## Կաղապար + +Մենք պետք է ` post_edit.html` գրացուցակում ` blog/templates/blog` ֆայլ ստեղծենք և բացենք այն կոդերի խմբագրում: Ձևը գործ դնելու համար մեզ մի քանի բան է պետք. + +* Մենք պետք է ցուցադրենք ձևը: Մենք կարող ենք դա անել (օրինակ) {% raw %}`{{ form.as_p }}`{% endraw %} - ով: +* Վերևի տողը պետք է փաթաթված լինի HTML ձևի տարրով. ` ... `: +* Մեզ պետք է ` Save` կոճակը: Մենք դա անում ենք HTML կոճակի միջոցով. ``: +* Եվ, վերջապես, `
` թեգը բացելուց անմիջապես հետո մենք պետք է ավելացնենք {% raw %} ` {% csrf_token %} ` {% endraw %}: Սա շատ կարևոր է, քանի որ դրանով ապահովվում են ձեր ձևերի անվտանգությունը: Եթե ​​մոռանաք այս բիթի մասին, Django- ն կբողոքարկի, երբ փորձեք պահպանել ձևը. + +![CSFR Forbidden page](images/csrf2.png) + +Լավ, այնպես որ եկեք տեսնենք, թե ինչպես պետք է HTML- ը ` post_edit.html ` - ում: + +{% filename %}blog/templates/blog/post_edit.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} +

New post

+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} +``` + +Թարմացնելու ժամանակն է: Այո Ձեր ձևը ցուցադրվում է: + +![New form](images/new_form2.png) + +Բայց սպասեք մի րոպե: Երբ ինչ-որ բան եք մուտքագրում ` title ` և ` title ` դաշտերում և փորձում եք այն պահպանել, ի՞նչ կլինի: + +Ոչինչ Մենք նորից նույն էջում ենք, և մեր տեքստը այլևս չկա ... և ոչ մի նոր գրառում չի ավելացվում: Այսպիսով, ի՞նչն է սխալ եղել: + +Պատասխանն է. Ոչինչ: Մենք պետք է մի փոքր ավելի շատ աշխատանք կատարենք մեր * view*: + +## Ձևը պահելը + +Մեկ անգամ եւս բացեք ` blog/views.py ` կոդը խմբագրիչի մեջ: Ներկայումս ` post_new ` տեսքում մենք ունենք միայն հետևյալը. + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Ձևը ներկայացնելիս մեզ հետ են բերում նույն տեսակետը, բայց այս անգամ մենք ունենք ևս մի քանի տվյալներ ` request` - ում, ավելի կոնկրետ ` request. POST ` (անվանումն ունի ոչ մի կապ չունի բլոգի "post"(«գրառման») հետ. դա կապ ունի այն փաստի հետ, որ մենք "psoting" («տեղադրում ենք») տվյալներ): Հիշո՞ւմ եք, թե ինչպես HTML ֆայլում մեր `
` սահմանումն ուներ փոփոխական ` method="POST" `: Ձևի բոլոր դաշտերն այժմ գտնվում են ` request.POST `: Դուք չպետք է վերանվանեք ` POST ` ը որևէ այլ բանի (` method ` միակ այլ վավեր արժեքը ` GET ` է, բայց մենք ժամանակ չունենք բացատրելու, թե ինչ տարբերություն է): + +Այսպիսով, մեր * view* մենք ունենք կարգավորման երկու առանձին իրավիճակ. Առաջին ՝ երբ մենք առաջին անգամ մուտք ենք գործում էջ և ուզում ենք դատարկ ձև, և երկրորդ, երբ վերադառնում ենք * view* բոլոր մուտքագրված ձևի տվյալներով: Այսպիսով, մենք պետք է պայման դնենք (դրա համար կօգտագործենք ` if `): + +{% filename %}blog/views.py{% endfilename %} + +```python +if request.method == "POST": + [...] +else: + form = PostForm() +``` + +Լրացրեք կետերը ` [...] `: Եթե ​​` method` ` POST ` է, ապա մենք ուզում ենք կառուցել ` PostForm- ը ` ձևից ստացված տվյալներով, այնպես չէ՞: Մենք դա կանենք հետևյալ կերպ. + +{% filename%} blog/views.py{% endfilename%} + +```python +form = PostForm(request.POST) +``` + +Հաջորդ բանը `ստուգել, ​​թե արդյոք ձևը ճիշտ է (բոլոր պահանջվող դաշտերը դրված են և սխալ արժեքներ չեն ներկայացվել): Մենք դա անում ենք ` form.is_valid () ` - ի միջոցով: + +Մենք ստուգում ենք, արդյոք ձևը վավեր է, և եթե այո, ապա այն կարող ենք պահպանել: + +{% filename %}blog/views.py{% endfilename %} + +```python +if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() +``` + +Ըստ էության, մենք այստեղ ունենք երկու բան. Մենք ձևը պահում ենք ` form.save ` և ավելացնում ենք հեղինակ. ` commit = False ` նշանակում է, որ մենք դեռ չենք ուզում պահպանել ` Post ` մոդելը. Մենք նախ ուզում ենք ավելացնել հեղինակին: Շատ ժամանակ դուք կօգտագործեք ` form.save () ` առանց ` commit = False `, բայց այս դեպքում մենք պետք է այն մատակարարենք: ` post.save () ` կպահպանի փոփոխությունները (ավելացնելով հեղինակին) և կստեղծվի բլոգում նոր գրառում: + +Վերջապես, զարմանալի կլիներ, եթե մենք կարողանայինք անմիջապես անցնել ` post_detail ` էջը մեր նորաստեղծ բլոգում տեղադրելու համար, այնպես չէ՞: Դա անելու համար մեզ անհրաժեշտ է ևս մեկ ներմուծում. + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import redirect +``` + +Ավելացրեք այն ձեր ֆայլի հենց սկզբում: Եվ հիմա մենք կարող ենք ասել. «Անցեք ` post_detail ` էջը նորաստեղծ գրառման համար». + +{% filename %}blog/views.py{% endfilename %} + +```python +return redirect('post_detail', pk=post.pk) +``` + +` post_detail ` այն տեսքի անունն է, որին մենք ցանկանում ենք այցելել: Հիշո՞ւմ եք, որ այս * view* պահանջում է ` pk ` փոփոխական: Այն դիտումներին փոխանցելու համար մենք օգտագործում ենք ` pk = post.pk `, որտեղ ` post` նոր ստեղծվող բլոգային գրառում է: + +Լավ, մենք շատ ենք խոսել, բայց հավանաբար ուզում ենք տեսնել, թե ինչպիսին է այժմ * view * ճիշտ է: + +{% filename%} բլոգ /views.py {% endfilename%} + +```python +def post_new(request): + if request.method == "POST": + form = PostForm(request.POST) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Տեսնենք ՝ կաշխատի՞: Անցեք http://127.0.0.1:8000/post/new/ էջին, ավելացրեք `վերնագիր` և `տեքստ`, պահեք այն… և voilà: Ավելացվեց բլոգի նոր գրառումը, և մենք վերահասցեագրվում ենք ` հաղորդագրության_մանրամասնություն ` էջ: + +Գուցե նկատած լինեիք, որ մենք տեղադրում ենք հրապարակման ամսաթիվը նախքան հաղորդագրությունը պահելը: Ավելի ուշ, մենք կներկայացնենք * հրապարակման կոճակ * ** Django Girls Tutorial- ում ՝ Extensions **: + +Դա հիանալի է! + +> Քանի որ մենք վերջերս օգտագործել ենք Django ադմինիստրատորի միջերեսը, համակարգը ներկայումս կարծում է, որ մենք դեռ մուտք ենք գործել: Կան մի քանի իրավիճակներ, որոնք կարող են հանգեցնել մեզ դուրս գալուն (զննարկիչը փակելը, DB- ն վերագործարկելը և այլն): Եթե ​​հաղորդագրություն ստեղծելիս հայտնաբերում եք, որ սխալներ եք գրանցում մուտք գործած օգտվողի բացակայության վերաբերյալ, ապա անցեք ադմինիստրատորի էջ http://127.0.0.1:8000/admin և կրկին մուտք գործեք: Դրանով խնդիրը ժամանակավորապես կկարգավորվի: ** Տնային առաջադրանք. Ձեզ սպասում է մշտական ​​շտկում ՝ հիմնական ձեռնարկից հետո անվտանգություն ավելացրեք ձեր կայքում: ** + +![Logged in error](images/post_create_error.png) + +## Ձևի վավերացում + +Այժմ մենք ձեզ ցույց կտանք, թե որքան զով են Django- ի ձևերը: Բլոգի գրառումը պետք է ունենա ` title ` և ` text ` դաշտեր: Մեր ` Post` մոդելում մենք չասացինք, որ այս դաշտերը (ի տարբերություն ` published_date `) չեն պահանջվում, ուստի Django- ն, ըստ նախնականի, ակնկալում է, որ դրանք կսահմանվեն: + +Փորձեք պահպանել ձևը առանց ` title ` և ` text `: Գուշակիր, թե ինչ կլինի: + +![Form validation](images/form_validation2.png) + +Django- ն հոգ է տանում հաստատելու, որ մեր ձևի բոլոր դաշտերը ճիշտ են: Հիանալի չէ՞: + +## Խմբագրել ձևը + +Այժմ մենք գիտենք, թե ինչպես ավելացնել նոր գրառում: Բայց ի՞նչ կլինի, եթե մենք ուզում ենք խմբագրել գոյություն ունեցողը: Սա շատ նման է մեր արածին: Եկեք արագ ստեղծենք մի քանի կարևոր բաներ: (Եթե ինչ-որ բան չեք հասկանում, պետք է հարցնեք ձեր մարզչին կամ նայեք նախորդ գլուխներին, քանի որ մենք արդեն ծածկել ենք այս բոլոր քայլերը): + +Նախ, եկեք պահենք պատկերակը, որը ներկայացնում է խմբագրման կոճակը: Ներբեռնեք [ 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` էլեմենտի մեջ ավելացրեք հետևյալ ծածկագիրը. + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + +``` + +այնպես, որ ձևանմուշն այսպիսին լինի. + +{% filename%} բլոգ / ձևանմուշներ / բլոգ / post_detail.html {% endfilename%} + +```html +{% extends 'blog/base.html' %} + +{% block content %} + +{% endblock %} +``` + +Բացեք ` blog/urls.py ` ծածկագրի խմբագրում և ավելացրեք այս տողը. + +{% filename %}blog/urls.py{% endfilename %} + +```python + path('post//edit/', views.post_edit, name='post_edit'), +``` + +Մենք կրկին կօգտագործենք ` blog/templates/blog/post_edit.html ` ձևանմուշը, այնպես որ վերջին բացակայողը * view -է*: + +Եկեք բացենք ` blog/views.py` ծածկագրի խմբագրում և ավելացնենք սա ֆայլի հենց վերջում. + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_edit(request, pk): + post = get_object_or_404(Post, pk=pk) + if request.method == "POST": + form = PostForm(request.POST, instance=post) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm(instance=post) + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Սա կարծես գրեթե նույնն է, ինչ մեր ` post_new ` տեսակետը: Բայց ոչ ամբողջությամբ: Մեկի համար մենք ` url- ից ` փոխանցում ենք լրացուցիչ ` pk ` պարամետր: Հաջորդը, մենք ստանում ենք ` Post ` մոդելը, որը ցանկանում ենք խմբագրել ` get_object_or_404(Post, pk=pk)`, իսկ հետո, երբ ձև ենք ստեղծում, այս գրառումն անցնում ենք որպես ` instance`, այնպես էլ, երբ ձևը պահում ենք + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(request.POST, instance=post) +``` + +… Եվ երբ մենք այս գրառմամբ նոր բացեցինք ձևաթուղթ ՝ խմբագրելու համար. + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(instance=post) +``` + +Լավ, եկեք փորձենք, արդյոք այն աշխատում է: Եկեք գնանք ` post_detail` էջին: Վերին աջ անկյունում պետք է լինի խմբագրման կոճակ. + +![Edit button](images/edit_button2.png) + +Երբ կտտացրեք այն, կտեսնեք ձևը մեր բլոգի գրառման հետ. + +![Edit form](images/edit_form2.png) + +Ազատորեն փոխեք վերնագիրը կամ տեքստը և պահպանեք փոփոխությունները: + +Շնորհավորում եմ Ձեր դիմումը ավելի ու ավելի ամբողջական է դառնում: + +Եթե ​​Django ձևերի վերաբերյալ ավելի շատ տեղեկատվության կարիք ունեք, պետք է կարդաք փաստաթղթերը. https://docs.djangoproject.com/hy/2.2/topics/forms/ + +## Անվտանգություն + +Հղումը կտտացնելով նոր հաղորդագրություններ ստեղծելու կարողությունը զարմանալի է: Բայց հենց հիմա, յուրաքանչյուր ոք, ով այցելում է ձեր կայք, կկարողանա նոր բլոգային գրառում կատարել, և դա, հավանաբար, ձեր ուզածը չէ: Եկեք այնպես անենք, որ կոճակը ցուցադրվի ձեզ համար, բայց ոչ ուրիշ մեկի: + +Բացեք ` blog/templates/blog/base.html` կոդերի խմբագրում, գտեք մեր ` div ` ` վերնագրի ներսում ` և խարիսխի տարրը, որը դուք ավելի վաղ այնտեղ եք տեղադրել , Այն պետք է ունենա այսպիսի տեսք. + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + {% include './icons/file-earmark-plus.svg' %} + +``` + +Մենք դրան կավելացնենք ևս ` {% if%} ` պիտակը, որը կստիպի հղումը ցույց տալ միայն այն ադմինիստրատոր մուտք գործած օգտվողների համար: Հենց հիմա, դու հենց դու ես: Փոխեք `` տարրը ՝ այսպիսի տեսք ունենալու համար. + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% if user.is_authenticated %} + + {% include './icons/file-earmark-plus.svg' %} + +{% endif %} +``` + +Սա ` {% if %} ` կհանգեցնի այն, որ հղումը կուղարկվի զննարկիչ, միայն եթե էջը հայցող օգտվողը մուտք է գործում: Սա ամբողջությամբ չի պաշտպանում նոր հաղորդագրությունների ստեղծումը, բայց դա լավ առաջին քայլ է: Մենք ավելի շատ անվտանգություն ենք ծածկելու ընդլայնման դասերին: + +Հիշո՞ւմ եք խմբագրման պատկերակը, որը մենք պարզապես ավելացրել ենք մեր մանրամասն էջին: Մենք ուզում ենք նաև նույն փոփոխությունն ավելացնել այնտեղ, այնպես որ այլ մարդիկ չեն կարողանա խմբագրել առկա հաղորդագրությունները: + +Բացեք ` blog/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 %} +``` + +Քանի որ, ամենայն հավանականությամբ, մուտք եք գործել կայք, եթե թարմացնեք էջը, այլ բան չեք տեսնի: Էջը բեռնեք այլ զննարկչում կամ ինկոգնիտո պատուհանում (Windows Edge- ում կոչվում է «InPrivate»), և կտեսնեք, որ հղումը չի ցուցադրվում, և պատկերակը նույնպես չի ցուցադրվում: + +## Եվս մեկ բան. Տեղաբաշխեք ժամանակ: + +Տեսնենք, արդյոք այս ամենը աշխատում է PythonAnywhere- ում: Anotherամանակն է նոր տեղակայման: + +* Նախ, կատարեք ձեր նոր ծածկագիրը և սեղմեք այն դեպի GitHub: + +{% filename %}command-line{% endfilename %} + + $ git status + $ git add . + $ git status + $ git commit -m "Added views to create/edit blog post inside the site." + $ git push + + +* Հետո, [ PythonAnywhere Bash կոնսոլում ](https://www.pythonanywhere.com/consoles/) + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Մի մոռացեք փոխարինել `` ձեր իրական PythonAnywhere ենթադոմեյնով ՝ առանց անկյունային փակագծերի:) + +* Ի վերջո, անցեք [ "Web" page](https://www.pythonanywhere.com/web_app_setup/) (օգտագործեք մենյուի վերևի աջ մասում ընտրացանկի կոճակը) և սեղմեք ** Reload**: Թարմացրեք ձեր https://subdomain.pythonanywhere.com բլոգը ՝ փոփոխությունները տեսնելու համար: + +Եվ դա պետք է լինի դա: Շնորհավորանքներ :) \ No newline at end of file diff --git a/hy/django_forms/images/csrf2.png b/hy/django_forms/images/csrf2.png new file mode 100644 index 00000000000..ee946324f92 Binary files /dev/null and b/hy/django_forms/images/csrf2.png differ diff --git a/hy/django_forms/images/drafts.png b/hy/django_forms/images/drafts.png new file mode 100644 index 00000000000..1d62f8866f4 Binary files /dev/null and b/hy/django_forms/images/drafts.png differ diff --git a/hy/django_forms/images/edit_button2.png b/hy/django_forms/images/edit_button2.png new file mode 100644 index 00000000000..804674f0965 Binary files /dev/null and b/hy/django_forms/images/edit_button2.png differ diff --git a/hy/django_forms/images/edit_form2.png b/hy/django_forms/images/edit_form2.png new file mode 100644 index 00000000000..3d4e525d5d0 Binary files /dev/null and b/hy/django_forms/images/edit_form2.png differ diff --git a/hy/django_forms/images/form_validation2.png b/hy/django_forms/images/form_validation2.png new file mode 100644 index 00000000000..6e333af3077 Binary files /dev/null and b/hy/django_forms/images/form_validation2.png differ diff --git a/hy/django_forms/images/new_form2.png b/hy/django_forms/images/new_form2.png new file mode 100644 index 00000000000..8f2a1088070 Binary files /dev/null and b/hy/django_forms/images/new_form2.png differ diff --git a/hy/django_forms/images/post_create_error.png b/hy/django_forms/images/post_create_error.png new file mode 100644 index 00000000000..d140e8e2419 Binary files /dev/null and b/hy/django_forms/images/post_create_error.png differ diff --git a/hy/django_installation/README.md b/hy/django_installation/README.md new file mode 100644 index 00000000000..cf2e7794630 --- /dev/null +++ b/hy/django_installation/README.md @@ -0,0 +1,7 @@ +# Django- ի տեղադրում + +> **Նշում** Եթե Chromebook եք օգտագործում, բաց թողեք այս գլուխը և համոզվեք, որ հետևում եք [Chromebook Setup/Chromebook- ի կարգավորման](../chromebook_setup/README.md) ցուցումներին: +> +> **Նշում** Եթե դուք արդեն ավարտել եք տեղադրումը [installation steps](../installation/README.md) , կարող եք ուղղակիորեն անցնել հաջորդ գլխին: + +{% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/hy/django_installation/instructions.md b/hy/django_installation/instructions.md new file mode 100644 index 00000000000..a8dac854ad6 --- /dev/null +++ b/hy/django_installation/instructions.md @@ -0,0 +1,230 @@ +> Այս բաժնի մի մասը հիմնված է Geek Girls Carrots- ի (https://github.com/ggcarrots/django-carrots) ձեռնարկների վրա: +> +> Այս բաժնի մի մասը հիմնված է [django-marcador- ի վրա ձեռնարկ](http://django-marcador.keimlink.de/) լիցենզավորված Creative Commons- ի ներքո Attribution-ShareAlike 4.0 միջազգային լիցենզիա: Django-marcador ձեռնարկի հեղինակային իրավունքի պաշտպանն են Markus Zapke-Gründemann et al. + +## Վիրտուալ միջավայր + +Նախքան Django- ն տեղադրելը, մենք ձեզ կառաջարկենք տեղադրել չափազանց օգտակար գործիք, որը կօգնի ձեր կոդավորման միջավայրը կոկիկ պահել ձեր համակարգչում: Հնարավոր է բաց թողնել այս քայլը, բայց խորհուրդ է տրվում իրականացնել: Հնարավոր լավագույն կարգավորումից սկսելը ապագայում ձեզ շատ դժվարություններ կփրկի: + +Այսպիսով, եկեք ստեղծենք ** վիրտուալ միջավայր/virtual environment** (կոչվում է նաև *virtualenv* ): Virtualenv- ը մեկուսացնելու է ձեր Python / Django- ի տեղադրումը ՝ ըստ նախագծի: Սա նշանակում է, որ որևէ փոփոխություն, որ կատարեք մեկ կայքում, չի ազդի որևէ այլ կայքի վրա, որը դուք նույնպես զարգացնում եք: Կոկիկ է, այնպես չէ՞: + +Դուք պետք է ընդամենը գտնեք գրացուցակ, որում ցանկանում եք ստեղծել `virtualenv`; ձեր տան գրացուցակը, օրինակ. Windows- ում այն ​​կարող է նման լինել `C:\Users\Name` (որտեղ ` Name ` - ը ձեր մուտքի անունն է): + +> ** ՆՇՈՒՄ. ** Windows- ում համոզվեք, որ այս գրացուցակը չի պարունակում շեշտադրված կամ հատուկ նիշեր. եթե ձեր օգտանունը պարունակում է ընդգծված նիշեր, օգտագործեք այլ գրացուցակ, օրինակ ՝ `C:\djangogirls`: + +Այս ձեռնարկի համար մենք կօգտագործենք նոր գրացուցակ ` djangogirls ` ձեր տան գրացուցակից. + +{% filename %}command-line{% endfilename %} + + $ mkdir djangogirls + $ cd djangogirls + + +Մենք պատրաստելու ենք մի վիրտուալ անուն, որը կոչվում է ` myvenv `: Ընդհանուր հրամանը կլինի ձևաչափով/format. + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + + + +Նոր `virtualenv` ստեղծելու համար հարկավոր է բացել հրամանի տողը և գործարկել `python -m venv myvenv`: Դա կունենա այսպիսի տեսք. + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls> python -m venv myvenv + + +Որտեղ ` myvenv ` - ը ձեր `virtualenv` անունն է: Կարող եք օգտագործել ցանկացած այլ անուն, բայց հավատարիմ մնացեք փոքրատառերին և մի օգտագործեք բացատներ, շեշտադրումներ կամ հատուկ նիշեր: Լավ է նաև, որ անունը կարճ մնա. Դուք դեռ շատ կանդրադառնաք դրան: + + + + + +Մենք կարող ենք ստեղծել ` virtualenv ` ինչպես Linux- ի, այնպես էլ macOS- ի վրա ՝ գործարկելով `python3 -m venv myvenv`: Դա կունենա այսպիսի տեսք. + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + +` myvenv ` - ը ձեր `virtualenv` անունն է: Կարող եք օգտագործել ցանկացած այլ անուն, բայց հավատարիմ մնացեք փոքրատառերին և բացատներ մի օգտագործեք: Լավ է նաև, որ անունը կարճ մնա. Դուք դեռ շատ կանդրադառնաք դրան: + +> ** ՆՇՈՒՄ. ** Debian / Ubuntu- ի որոշ տարբերակների վրա կարող եք ստանալ հետևյալ սխալը. +> +> {% filename %}command-line{% endfilename %} +> +> Վիրտուալ միջավայրը հաջողությամբ չի ստեղծվել, քանի որ ensurepip- ը հասանելի չէ: Debian / Ubuntu համակարգերում անհրաժեշտ է տեղադրել python3-venv փաթեթը ՝ օգտագործելով հետևյալ հրամանը: +> apt install python3-venv +> Հնարավոր է, որ ձեզ հարկավոր է օգտագործել sudo(սուդո) այդ հրահանգով: +> Python3-venv փաթեթը տեղադրելուց հետո վերստեղծեք ձեր 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 +> + + + +## Վիրտուալենվի/virtualenv-ի հետ աշխատանք + +Վերոնշյալ հրամանը կստեղծի ` myvenv ` գրացուցակ (կամ մեկ այլ ՝ ձեր ընտրած ցանկացած անուն), որը կպարունակի վիրտուալ միջավայր/ virtual environment (հիմնականում ֆայլերի և պանակների շարք): + + + +Սկսեք ձեր վիրտուալ միջավայրը/virtual environment-ը `գործարկելով. + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls> myvenv\Scripts\activate + + +> ** Նշում. ** Windows 10-ի դեպքում Windows PowerShell- ում կարող է ստացվել սխալի հաղորդագրություն, որում ասվում է, որ `execution of scripts is disabled on this system/սցենարը անջատված է այս համակարգում` Այս դեպքում բացեք մեկ այլ Windows PowerShell «Գործարկեք որպես ադմինիստրատոր»/"Run as Administrator" տարբերակով: Դրանից հետո փորձեք մուտքագրել հետևյալ հրամանը ՝ նախքան ձեր վիրտուալ միջավայրի/virtual environment-ի սկսելը. +> +> {% 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 +> + + + +> **Նշում** Հանրաճանաչ խմբագիր VS Code- ի օգտագործողների համար, որոնք գալիս են Windows PowerShell- ի վրա հիմնված ինտեգրված տերմինալ, եթե ցանկանում եք հավատարիմ մնալ ինտեգրված տերմինալին, կարող եք գործարկել հետևյալ հրահանգը ՝ ձեր վիրտուալ միջավայրն ակտիվացնելու համար. +> +> $ . myvenv\Scripts\activate.ps1 +> +> +> Առավելությունն այն է, որ անհրաժեշտ չէ փոխություն անել խմբագրի պատուհանի և հրամանի տողի միջև: + + + + + +Սկսեք ձեր վիրտուալ միջավայրը/virtual environment-ը `գործարկելով. + +{% filename %}command-line{% endfilename %} + + $ source myvenv/bin/activate + + +Մի մոռացեք ` myvenv ` -ը փոխարինել ձեր ընտրած ` virtualenv ` անունով: + +> **Նշում**երբեմն `source/աղբյուրը` կարող է անհասանելի լինել: Այդ դեպքում օգտագործեք հետևյալ մեթոդը. +> +> {% filename %}command-line{% endfilename %} +> +> $ . myvenv/bin/activate +> + + + +Դուք կհասկանաք, որ virtualenv- ն աշխատում է, երբ հրամանի տողում տեսնեք `(myvenv)` նախածանցը: + +Վիրտուալ միջավայրի հետ աշխատելիս ` python ` հրամանն ինքնաբերաբար կվերաբերվի լեզվի ճիշտ տարբերակին, այնպես որ ձեզ հարկավոր չէ օգտագործել ` python3 `: + +Հիանալի է, հիմա մենք բոլոր կարեւոր կախվածությունները կպահենք մեկ տեղում: Վերջապես, դուք կարող եք տեղադրել Django- ն: + +## Django- ի տեղադրում {#django} + +Այժմ, երբ ձեր `virtualenv`-ն աշխատում է, կարող եք տեղադրել Django- ն: + +Բայց մինչ այդ մենք պետք է համոզվենք, որ մենք ունենք `pip`- ի վերջին տարբերակը տեղադրված, դա այն ծրագիրն է, որը մենք կօգտագործենք Django- ն տեղադրելու համար. + +{% filename %}command-line{% endfilename %} + + (myvenv) ~$ python -m pip install --upgrade pip + + +### Փաթեթների տեղադրում պահանջներով + +Պահանջների ֆայլը/A requirements file պահում է կախվածության ցուցակը որը տեղադրվելու է օգտագործելով `pip install`: + +Սկզբից ` djangogirls/ ` թղթապանակի մեջ ստեղծեք ` requirements.txt ` ֆայլ ՝ օգտագործելով ավելի վաղ տեղադրած կոդերի խմբագրիչը: Դուք դա անում եք կոդի խմբագրում/code editor-ում նոր ֆայլ բացելով, այնուհետև պահպանելով այն որպես `requirements.txt/ պահանջներ` `djangogirls/` թղթապանակում: Ձեր թղթապանակն այսպիսի տեսք կունենա. + + djangogirls + ├── myvenv + │ └── ... + └───requirements.txt + + +Հետևյալ կոդը ավելացրեք ձեր `djangogirls/requirements.txt` ֆայլում. + +{% filename %}djangogirls/requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +Django- ն տեղադրելու համար այժմ մուտքագրեք `pip install -r requirements.txt`: + +{% filename %}command-line{% endfilename %} + + (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.1MB) + Installing collected packages: Django + Successfully installed Django-{{ book.django_version }} + + + + +> Եթե ​​Windows- ում pip գործարկելիս սխալ եք ստացել, ստուգեք, որ նախագծի գրացուցակը չի պարունակում հեռավորություններ կամ հատուկ նիշեր (օրինակ, `C:\Users\User Name\djangogirls`): Եթե ​​սա է խնդիրը, ապա խնդրում ենք ձեր նախագիծը տեղափոխել մեկ այլ վայր, որի հասցեն չի պարունակի բացատներ և հատուկ նիշեր (խորհուրդ ենք տալիս ՝ `C:\djangogirls`): Նոր գրացուցակում ստեղծեք նոր virtualenv, այնուհետև ջնջեք հինը և կրկնեք վերը նշված հրահանգները: (Virtualenv գրացուցակի տեղափոխումը չի գործի, քանի որ virtualenv- ն օգտագործում է բացարձակ ուղիներ): + + + + + +> Հրամանի տողը կարող է սառեցնել Django- ն տեղադրելու փորձից հետո: Եթե ​​դա տեղի ունենա, ապա վերը նշված հրամանի փոխարեն օգտագործեք այս մեկը. +> +> {% filename %}command-line{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> + + + + + +> Եթե ​​Ubuntu 12.04-ին pip զանգահարելիս սխալի եք հանդիպում, գործարկեք `python -m pip install -U --force-reinstall pip` ՝ վիրտուալում pip- ի տեղադրումն ամրագրելու համար: + + + +Վերջ Դուք այժմ (վերջապես) պատրաստ եք ստեղծել Django հավելված: \ No newline at end of file diff --git a/hy/django_models/README.md b/hy/django_models/README.md new file mode 100644 index 00000000000..4a3e17276f8 --- /dev/null +++ b/hy/django_models/README.md @@ -0,0 +1,203 @@ +# Django մոդելներ + +Մեզ ինչ-որ բան է պետք ՝ մեր բոլոր բլոգային գրառումները պահելու համար, դա հենց այն է ինչ մենք հիմա կստեղծենք: Բայց նախ եկեք խոսենք `objects/օբյեկտներ` կոչվող իրերի մասին: + +## Օbjects/Օբյեկտներ + +Ծրագրավորման մեջ կա մի հասկացություն, որը կոչվում է օբյեկտիվ կողմնորոշում(կամ օբյեկտի վրա հիմնված ծրագրավորում:): Գաղափարն այն է, որ հրահանգների ձանձրալի հաջորդականության փոխարեն, մենք մոդելավորում ենք իրերը և նկարագրում, թե ինչպես են դրանք փոխազդում միմյանց հետ: + +Այսպիսով, ինչ է օբյեկտը: Դա հատկությունների և գործողությունների հավաքածու է: Տարօրինակ է թվում, բայց մենք մի օրինակ կբերենք: + +Եթե ​​մենք ուզում ենք կատու մոդելավորել, ապա կստեղծենք `Cat/ կատու`t օբյեկտ, որն ունի որոշակի հատկություններ, օրինակ ՝ `color/գույն`, `age/տարիք` `mood/տրամադրություն ` ՝ (վատ, լավ, քնկոտ;)), `owner/սեփականատեր` (օրինակ ՝ մեկ այլ առարկա. Անձ կամ, եթե կատուն վայրի է, այս հատկությունը դատարկ կլինի): + +`Cat/Կատու` օբյեկտը կունենա որոշակի գործողությունների շարք. `purr/մլավել`, `scratch/ճանկռել`, կամ `feed/կերակրել` (որտեղ մենք կատուին տալիս ենք մի քանի `CatFood` (կատվի սնունդ), որը կարող է նաև լինել իր սեփական հատկություններով առանձին առարկա օրինակ `taste/համ` ): + + Cat + -------- + color + age + mood + owner + purr() + scratch() + feed(cat_food) + + + CatFood + -------- + taste + + +Այսպիսով, հիմնականում գաղափարը՝ օբյեկտի նկարագրումն է կոդի մեջ՝ հատկություններով (կոչվում են `object properties/օբյեկտի հատկություններ`) և գործողություններով (կոչվում են `methods/մեթոդներ`): + +Այսպիսով, ինչպե՞ս ենք մոդելավորելու բլոգի հաղորդագրությունները: Մենք ուզում ենք բլոգ կառուցել, այնպես չէ՞: + +Մենք պետք է պատասխանենք այն հարցին. Ի՞նչ է բլոգի գրառումը: Ի՞նչ հատկություններ պետք է այն ունենա: + +Դե, հաստատ մեր բլոգային գրառմանը պետք է ինչ-որ տեքստ իր բովանդակությամբ և վերնագիրով, այնպես չէ՞: Լավ կլինի իմանալ նաև, թե ով է այն գրել, այնպես որ հեղինակը մեզ պետք է: Վերջապես, մենք պետք է իմանանք, թե երբ է ստեղծվել գրառումը և երբ է հրապարակվել: + + Post + -------- + title + text + author + created_date + published_date + + +Ի՞նչ բաներ կարող եք անել բլոգում գրառման միջոցով: Լավ կլիներ որ գրառումը հրապարակող ինչ-որ մեթոդ լիներ, ճի՞շտ է: + +Այսպիսով, մեզ հարկավոր է `publish/հրապարակման` մեթոդ: + +Դե, քանի որ մենք որոշել ենք, թե ինչ ենք ուզում ստանալ, եկեք սկսենք մոդելավորել այն Django- ում: + +## Django մոդել + +Իմանալով, թե ինչ է օբյեկտը, մենք կարող ենք ստեղծել Django մոդել մեր բլոգի գրառման համար: + +Django- ում մոդելը հատուկ տեսակի առարկա է. Այն պահվում է ` տվյալների բազայում/database`.: Տվյալների բազան/database-ը տարբեր տվյալների հավաքածու է: Սա այն վայրն է, որտեղ դուք կպահեք տեղեկատվություն օգտվողների, ձեր բլոգի հաղորդագրությունների և այլնի մասին: Մենք կօգտագործենք SQLite տվյալների բազա ՝ մեր տվյալները պահելու համար: Սա ներքին կարգավորման/default Django տվյալների շտեմարանն է. Այս փուլում նրա հնարավորությունները բավարար են մեր պահանջների համար: + +Դուք կարող եք տվյալների շտեմարանում մոդելի մասին մտածել որպես աղյուսակ ՝ սյունակներով (դաշտերով/columns (fields) և տողերով (տվյալներով)/rows (data): + +### Դիմումների ստեղծում + +Ամեն ինչ կոկիկ պահելու համար մենք մեր ծրագրի ներսում կստեղծենք առանձին ծրագիր: Շատ հաճելի է ամեն ինչ կազմակերպել հենց սկզբից: Ծրագիր / Application ստեղծելու համար մենք պետք է հրամանի տողում մուտքագրենք հետևյալ հրահանգը ( `djangogirls` գրացուցակից, որտեղ գտնվում է `manage.py` ֆայլը). + +{% filename %}macOS and Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py startapp blog + + + +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + + +Դուք կնկատեք, որ ստեղծվել է նոր `blog` գրացուցակ, որն այժմ պարունակում է մի շարք ֆայլեր: Այսպիսով, մեր նախագծում գրացուցակները և ֆայլերը պետք է ունենան այսպիսի տեսք. + + djangogirls + ├── blog + │ ├── admin.py + │ ├── apps.py + │ ├── __init__.py + │ ├── migrations + │ │ └── __init__.py + │ ├── models.py + │ ├── tests.py + │ └── views.py + ├── db.sqlite3 + ├── manage.py + ├── mysite + │ ├── __init__.py + │ ├── settings.py + │ ├── urls.py + │ └── wsgi.py + ├── myvenv + │ └── ... + └── requirements.txt + + + +Դիմումը/application-ը ստեղծվելուց հետո մենք պետք է Django- ին ասենք, որ այն այժմ պետք է օգտագործի այն: Մենք դա անում ենք `mysite/settings.py` ֆայլում - բացեք այն ձեր կոդի խմբագրում/code editor: Մենք պետք է գտնենք `INSTALLED_APPS` և ավելացնենք `'blog.apps.BlogConfig',` պարունակող տող, հենց վերևում `]` : Այսպիսով, վերջնական արդյունքը պետք է ունենա այսպիսի տեսք. + +{% filename %}mysite/settings.py{% endfilename %} + +```python +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog.apps.BlogConfig', +] +``` + +### Բլոգի գրառման մոդելի ստեղծում + +`blog/models.py` այս ֆայլում մենք բնութագրում ենք `Models/մոդելներ` կոչվող բոլոր օբյեկտները. Սա մի տեղ է, որտեղ մենք կսահմանենք մեր բլոգի գրառումը/blog post-երը: + +Բացեք `blog/models.py` այս ֆայլը կոդերի խմբագրում, ջնջեք ամբողջ տեքստը և փոխարենը տեղադրեք հետևյալ կոդը. + +{% filename %}blog/models.py{% endfilename %} + +```python +from django.conf import settings +from django.db import models +from django.utils import timezone + + +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) + + def publish(self): + self.published_date = timezone.now() + self.save() + + def __str__(self): + return self.title +``` + +> Համոզվեք, որ `str` մեթոդի յուրաքանչյուր կողմում օգտագործեք երկու տակի գծիկ (`_`) : Այս կոնվենցիան հաճախ օգտագործվում է Python ծրագրավորման մեջ , և երբեմն կոչվում է "dunder" (կարճ ՝ «կրկնակի ընդգծում»/ "double-underscore"): + +Սարսափելի է թվում, ճի՞շտ է: Բայց մի անհանգստացեք. Մենք կբացատրենք, թե ինչ են նշանակում այս տողերը: + +Բոլոր տողերը, որոնք `from` կամ `import` են սկսվում, թույլ են տալիս մուտք գործել կոդ այլ ֆայլերից: Այսպիսով, բոլոր ֆայլերի միջև միևնույն կոդը պատճենելու և տեղադրելու փոխարեն, մենք կարող ենք այն հղել ՝ օգտագործելով `... + import ...`. + +`class Post(models.Model):` –այս տողը սահմանում է մեր մոդելը (դա `object/օբյեկտ`-ն է): + +- `class/դասը` հատուկ բանալիբառ է, որը ցույց է տալիս, որ մենք օբյեկտ ենք սահմանում: +- `Post` -ը մեր մոդելի անունն է: Ցանկության դեպքում մենք կարող ենք փոխել այն (բայց պետք է խուսափել հատուկ նիշերից և սպիտակ տարածությունից): Միշտ դասի անունը սկսեք մեծատառով: +- `models.Model` նշանակում է, որ Post օբյեկտը Django մոդել է, ուստի Django- ն գիտի, որ անհրաժեշտ է այն պահպանել տվյալների բազայում: + +Այժմ մենք սահմանում ենք այն հատկությունները, որոնց մասին մենք խոսում էինք ՝ `title/վերնագիրը`, `text/տեքստը`, `created_date/ստեղծման ամսաթիվը`, `published_date/հրապարակման ամսաթիվը` և `author/հեղինակ`. Դա անելու համար մենք պետք է պարզենք յուրաքանչյուր դաշտի տեսակը (արդյո՞ք այն տեքստային է): Թվայի՞ն Ամսաթի՞վ Կապը մեկ այլ օբյեկտի հետ, ինչպես օգտագործողը:) + +- `models.CharField` - այսպես մենք սահմանում. տեքստի դաշտ նիշերի քանակի սահմանափակումով: +- `models.TextField` -սա երկար տեքստի համար է ՝ առանց սահմանի: Իդեալական է թվում բլոգի գրառման բովանդակության համար, այնպես չէ՞: +- `models.DateTimeField` - սա ամսաթիվ և ժամ է: +- `models.ForeignKey` –սա հղում է դեպի այլ մոդել: + +Մենք չենք բացատրի կոդերի յուրաքանչյուր մասն այստեղ, քանի որ դա չափազանց շատ ժամանակ կպահանջի: Ստուգեք Django- ի պաշտոնական փաստաթղթերը. Եթե ցանկանում եք ավելին իմանալ մոդելի դաշտերի և տարբեր օբյեկտներ սահմանելու մասին, այս հղումը կարող է օգնել. (https://docs.djangoproject.com/en/2.2/ref/models/fields/#field-types) : + +Ինչ կասե՞ք `def publish(self):` (def հրապարակելուն (ինքնուրույն): Սա հենց այն `publish/հրապարակման` եղանակն է, որի մասին նախկինում խոսում էինք: `def` նշանակում է, որ սա function/method-ֆունկցիա / մեթոդ է, և `publish`-ը մեթոդի անունն է: Ցանկության դեպքում կարող եք փոխել մեթոդի անվանումը: Անվանման կանոնն այն է, որ մենք բացատների փոխարեն օգտագործում ենք փոքրատառ և ստորին գծեր: Օրինակ, միջին գինը հաշվարկող մեթոդը կարելի է անվանել `calculate_average_price`: + +Մեթոդները հաճախ ինչ-որ բան են `վերադարձնում/ return` : Դրա մի օրինակ կա `__str__` մեթոդում: Այս սցենարում, երբ մենք զանգահարենք `__str__()`, մենք կստանանք գրության վերնագիր ունեցող տեքստ (**string/տող**): + +Նաև նկատեք, որ `def publish(self):` և `def __str__(self):` կտրված են մեր դասի ներսում: Քանի որ Python- ը զգայուն է սպիտակ տարածության նկատմամբ, մենք պետք է դասի մեջ ներմուծենք մեր մեթոդները: Հակառակ դեպքում, մեթոդները չեն պատկանի դասին, և դուք կարող եք ինչ-որ անսպասելի արդյունք ունենալ: + +Եթե ​​մոդելների հետ կապված ինչ-որ բան դեռ պարզ չէ, ազատորեն հարցրեք ձեր ուսուցչին: Մենք գիտենք, որ դա իսկապես բարդ է, հատկապես, երբ զուգահեռաբար ուսումնասիրում ես, թե ինչ են օբյեկտներն/objects ու գործառույթները/functions: Բայց հուսանք, որ այս ամենը քեզ հիմա մոգություն չի թվում: + +### Ստեղծեք աղյուսակներ ձեր տվյալների բազայում + +Վերջին քայլը տվյալների բազայում մեր նոր մոդելի ավելացումն է: Նախ, մենք պետք է տեղյակ պահենք Django- ին, որ մենք փոփոխություններ ենք մտցրել մեր մոդելի մեջ: (Մենք հենց նոր ստեղծեցինք այն) Գնացեք ձեր վահանակի պատուհանում և մուտքագրեք `python manage.py makemigrations blog`: Այն պետք է ունենա նման տեսք: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py makemigrations blog + Migrations for 'blog': + blog/migrations/0001_initial.py: + + - Create model Post + + +** Նշում. ** Մի մոռացեք պահպանել ձեր խմբագրած ֆայլերը: Հակառակ դեպքում, ձեր համակարգիչը կգործարկի նախորդ տարբերակները, որը կարող է ձեզ անսպասելի սխալ հաղորդագրություններ հաղորդել: + +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: + Applying blog.0001_initial... OK + + +Ուռա! Մեր Post մոդելը այժմ մեր տվյալների բազայում է: Ցանկալի կլիներ տեսնել դա, այնպես չէ՞: Անցեք հաջորդ գլխին ՝ տեսնելու, թե ձեր Post-ը ինչ տեսք ունի: \ No newline at end of file diff --git a/hy/django_orm/README.md b/hy/django_orm/README.md new file mode 100644 index 00000000000..e223fef2a4f --- /dev/null +++ b/hy/django_orm/README.md @@ -0,0 +1,221 @@ +# Django ORM և QuerySets + +Այս գլխում դուք կսովորեք, թե ինչպես է Django- ն միանում և պահում տեղեկատվությունը տվյալների բազայում: Եկեք սկսենք: + +## Ի՞նչ է QuerySet- ը: + +QuerySet- ը, ըստ էության, տվյալ Մոդելի օբյեկտների ցուցակն է: QuerySets- ը թույլ է տալիս կարդալ տվյալների բազան, զտել և փոխել դրանց կարգը: + +Օրինակով սովորելը ամենահեշտն է: Փորձենք սա, այնպես չէ՞: + +## Django shell + +Բացեք ձեր տեղական վահանակը (ոչ PythonAnywhere- ում) և մուտքագրեք այս հրամանը. + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py shell + + +Արդյունքն այսպիսին պետք է լինի. + +{% filename %}command-line{% endfilename %} + +```python +(InteractiveConsole) +>>> +``` + +Դուք այժմ Django- ի ինտերակտիվ վահանակում եք: Դա ճիշտ է Python- ի հուշման նման, բայց ինչ-որ լրացուցիչ Django մոգությամբ: :) Այստեղ կարող եք օգտագործել Python- ի բոլոր հրամանները: + +### Բոլոր օբյեկտները + +Փորձենք նախ ցուցադրել մեր բոլոր հաղորդագրությունները: Դա կարող եք անել հետևյալ հրահանգով. + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +Traceback (most recent call last): + File "", line 1, in +NameError: name 'Post' is not defined +``` + +Վայ Սխալ առաջացավ: Այն մեզ ասում է, որ Փոստ չկա: Եվ դա ճիշտ է. Մենք մոռացել ենք ներմուծել այն: + +{% filename %}command-line{% endfilename %} + +```python +>>> from blog.models import Post +``` + +Մենք ներմուծում ենք `Post` մոդելը `blog.models`-ից:Փորձենք կրկին ստանալ բլոգի բոլոր գրառումները. + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, ]> +``` + +Սա ավելի վաղ ստեղծած հաղորդագրությունների ցուցակն է: Մենք ստեղծեցինք այս հաղորդագրությունները Django ադմինիստրատորի ինտերֆեյսի միջոցով: Բայց հիմա մենք ուզում ենք ստեղծել նոր հաղորդագրություններ Python- ի միջոցով, ինչպե՞ս դա անել: + +### Ստեղծել օբյեկտ + +Ահա, թե ինչպես եք դուք ստեղծում նոր Post օբյեկտ տվյալների բազայում/database. + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') +``` + +Բայց այստեղ մենք ունենք մեկ պակասող բաղադրիչ ՝ `me/ես`: Մենք պետք է որպես հեղինակ փոխանցենք `User/Օգտագործող` մոդելի օրինակ: Ինչպե՞ս դա անել: + +Եկեք նախ ներմուծենք Օգտագործողի մոդելը/User model. + +{% filename %}command-line{% endfilename %} + +```python +>>> from django.contrib.auth.models import User +``` + +Ի՞նչ օգտվողներ ունենք մեր տվյալների բազայում/database: Փորձեք այս: + +{% filename %}command-line{% endfilename %} + +```python +>>> User.objects.all() +]> +``` + +Սա նույն գերշահագործողն է/superuser, որը մենք ստեղծել ենք ավելի վաղ: Այժմ եկեք ստեղծենք օգտագործողի օրինակ (այս տողը հարմարեցրեք ձեր սեփական օգտվողի անվանմանը). + +{% filename %}command-line{% endfilename %} + +```python +>>> me = User.objects.get(username='ola') +``` + +Ինչպես տեսնում եք, մենք այժմ ստանում ենք `get` a `User` `username`/օգտագործող անունով, որը համարժեք է «ola»-ին: Կոկիկ! + +Այժմ մենք վերջապես կարող ենք ստեղծել մեր գրառումը. + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') + +``` + +Ուռա! Ցանկանու՞մ եք ստուգել, ​​արդյո՞ք այն աշխատում է: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, , ]> +``` + +Ահա, ևս մեկ գրառում ցուցակում: + +### Ավելացրեք այլ հաղորդագրություններ + +Այժմ կարող եք մի փոքր զվարճանալ և ավելացնել նոր հաղորդագրություններ ՝ տեսնելու համար, թե ինչպես է դա աշխատում: Ավելացրեք ևս երկու-երեքը, ապա անցեք հաջորդ մասին: + +### Ֆիլտրեք օբյեկտները + +QuerySets- ի կարեւոր առանձնահատկությունը օբյեկտները զտելու հնարավորությունն է: Ասենք, որ ուզում ենք գտնել ola օգտվողի հեղինակած բոլոր գրառումնները: `Post.objects.all()` –ում `all/ամբողջի` փոխարեն մենք կօգտագործենք `filter/ֆիլտր ` : Փակագծերի մեջ մենք նշելու ենք այն պայմանները, որոնցով կկառուցվի գրառումների ընտրությունը: Մեր դեպքում պայմանն այն է, որ `author/հեղինակը` պետք է հավասար լինի `me/ինձ `: Django- ում այն կգրվի այսպես `author=me`: Մեր ծածկագիրն այժմ ունի այսպիսի տեսք. + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(author=me) +, , , ]> +``` + +Կամ գուցե `title/վերնագիր` դաշտում ուզում ենք տեսնել բոլոր գրառումները, որոնք պարունակում են «վերնագիր»/'title' բառը: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(title__contains='title') +, ]> +``` + +> **Նշում** որ `title/Վերնագրի` և `contains/պարունակության` միջև կա երկու ընդգծված նիշ (`_`): Django- ի ORM- ն այս կանոնն օգտագործում է դաշտերի անունները («վերնագիր»/"title") և գործողությունները կամ ֆիլտրերն առանձնացնելու համար («պարունակում է»/"contains"): Եթե ​​դուք օգտագործեք միայն մեկ ընդգծում, դուք կստանաք սխալ ՝ "FieldError: Cannot resolve keyword title_contains". + +Կարող եք նաև ստանալ բոլոր հրապարակված հաղորդագրությունների ցուցակը: Մենք դա անում ենք ՝ զտելով անցյալում տեղադրված `published_date/հրապարակված_ամսաթերթը` բոլոր հաղորդագրությունները: + +{% filename %}command-line{% endfilename %} + +```python +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) + +``` + +Ցավոք, գրառումը, որը մենք ավելացրել ենք Python կոնսոլից, դեռ հրապարակված չէ: Բայց մենք կարող ենք դա փոխել: Նախ ընտրենք այն գրառումը, որը մենք ցանկանում ենք հրապարակել. + +{% filename %}command-line{% endfilename %} + +```python +>>> post = Post.objects.get(title="Sample title") +``` + +Եվ այնուհետև հրապարակեք այն մեր `publish/հրապարակել ` եղանակով: + +{% filename %}command-line{% endfilename %} + +```python +>>> post.publish() +``` + +Այժմ կրկին փորձեք ստանալ հրապարակված հաղորդագրությունների ցուցակը (3 անգամ սեղմեք վեր սլաքը և ապա `enter`). + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +]> +``` + +### Օբյեկտների կարգավորում + +QuerySets- ը թույլ է տալիս տեսակավորել օբյեկտները: Փորձենք տեսակավորել ըստ `created_date/ստեղծման_ամսաթիվ` դաշտի. + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.order_by('created_date') +, , , ]> +``` + +Կարող ենք նաև հակադարձել հրամանը ՝ սկզբում ավելացնելով սա `-` + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.order_by('-created_date') +, , , ]> +``` + +### Բարդ հարցումներ մեթոդի շղթայացման միջոցով + +Ինչպես տեսնում եք, `Post.objects` - ի որոշ մեթոդներ վերադարձնում են QuerySet- ը: Նույն մեթոդները կարելի է կրկին կանչել QuerySet- ում, և նրանք կվերադարձնեն նոր QuerySet: Այս կերպ Դուք կարող եք շղթայել դրանց ազդեցությունը ՝ դրանք միմյանց **chaining/կապակցելով**: + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> +``` + +Սա իսկապես հզոր է և թույլ է տալիս գրել բավականին բարդ հարցումներ: + +Գերազանց է! Այժմ դուք պատրաստ եք հաջորդ մասի: Ինտերակտիվ վահանակը/shell փակելու համար մուտքագրեք ՝ + +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` \ No newline at end of file diff --git a/hy/django_start_project/README.md b/hy/django_start_project/README.md new file mode 100644 index 00000000000..42f1a697951 --- /dev/null +++ b/hy/django_start_project/README.md @@ -0,0 +1,260 @@ +# Ձեր առաջին Django նախագիծը: + +> Այս գլխի մի մասը հիմնված է Geek Girls Carrots- ի ձեռնարկների վրա (https://github.com/ggcarrots/django-carrots): +> +> Այս գլխի մասերը հիմնված են django-marcador ձեռնարկի վրա, որը լիցենզավորված է Creative Commons Attribution-ShareAlike 4.0 միջազգային լիցենզիայի կողմից: Django-marcador ձեռնարկի հեղինակային իրավունքները պաշտպանված են Markus Zapke-Gründemann- ի և այլոց կողմից: + +Մենք պատրաստվում ենք ստեղծել փոքրիկ բլոգ: + +Առաջին քայլը նոր Django նախագիծ սկսելն է: Ըստ էության, սա նշանակում է, որ մենք գործարկելու ենք մի քանի ստանդարտ սցենարներ Django բաշխումից, որոնք կստեղծեն նախագծի կմախք մեզ համար: Սա ընդամենը գրացուցակների և ֆայլերի մի խումբ է, որոնք մենք կօգտագործենք ավելի ուշ: + +Որոշ ֆայլերի և գրացուցակների անունները շատ կարևոր են Django- ի համար: Դուք չպետք է վերանվանեք այն ֆայլերը, որոնք մենք պատրաստվում ենք ստեղծել: Նրանց այլ տեղ տեղափոխելը նույնպես լավ գաղափար չէ: Django- ն պետք է որոշակի կառուցվածք պահպանի, որպեսզի կարողանա գտնել կարևոր բաներ: + +> Մի մոռացեք. Դուք պետք է գործադրեք բոլոր հրամանները virtualenv- ով: Եթե ​​հրամանի տողում չեք տեսնում `(myvenv)` նախածանցը, ապա ձեզ հարկավոր է ակտիվացնել virtualenv- ը: Մենք բացատրեցինք, թե ինչպես դա անել, **Django installation/Django տեղադրում** գլխի **Working with virtualenv/ Աշխատանք virtualenv-ի հետ ** բաժնում: Դա անելու համար մուտքագրեք `myvenv\Scripts\activate` Windows- ում կամ `source myvenv/bin/activate` Mac OS / Linux- ում: + + + +Mac OS- ի կամ Linux- ի վահանակի վրա գործարկեք հետևյալ հրամանը. **մի մոռացեք կետ ավելացնել ` ` at the end!/վերջում** + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ django-admin startproject mysite . + + +> `.` կետը կարևոր է, քանի որ այն ասում է, որ սցենարը Django- ն տեղադրի ձեր ընթացիկ գրացուցակում (որի համար `.` կետը կարճ հղում է): +> +> **Նշում** Վերը նշված հրամանը մուտքագրելիս հիշեք, որ դուք մուտքագրում եք միայն այն հատվածը, որը սկսվում է `django-admin` - ի կողմից: Այս `(myvenv) ~/djangogirls$` հատվածը, որը ցույց է տրված այստեղ, ուղղակի հուշման օրինակ է ՝ հետագա հրամանի մուտքագրման համար: + + + + + +Windows- ում պետք է գործարկել հետևյալ հրամանը: ** (Մի մոռացեք վերջում ավելացնել կետը) `. `) **: + +{% filename %}command-line{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . + + +> `.` կետը կարևոր է, քանի որ այն ասում է, որ սցենարը Django- ն տեղադրի ձեր ընթացիկ գրացուցակում (որի համար `.` կետը կարճ հղում է): +> +> ** Նշում ** Վերը նշված հրամանը մուտքագրելիս հիշեք, որ դուք մուտքագրում եք միայն այն մասը, որը սկսվում է `django-admin.exe` - ով: `(myvenv) C:\Users\Name\djangogirls>` սրանք ընդամենը տերմինալային արագ տողերի օրինակներ են ՝ հետագա հրամանի մուտքագրման համար: + + + +`django-admin.py` սա սցենար է, որը կստեղծի գրացուցակի անհրաժեշտ կառուցվածքը և ֆայլերը մեզ համար: Այժմ դուք պետք է ունենաք ծրագրի հետևյալ կառուցվածքը. + + djangogirls + ├── manage.py + ├── mysite + │ ├── __init__.py + │ ├── settings.py + │ ├── urls.py + │ └── wsgi.py + ├── myvenv + │ └── ... + └── requirements.txt + + +> **Նշում**. Գրացուցակի կառուցվածքում կտեսնեք նաև ձեր ` myvenv ` գրացուցակը, որը մենք ավելի վաղ ստեղծել էինք: + +`manage.py` սա սցենար է, որն օգնում է կառավարել կայքը: Դրանով մենք կկարողանանք վեբ սերվեր գործարկել ձեր համակարգչում ՝ առանց լրացուցիչ ծրագրեր տեղադրելու: + +` settings.py ` ֆայլը պարունակում է ձեր կայքի կարգավորումները: + +Հիշո՞ւմ եք փոստատարի հետ մեր անալոգիան, որը ստուգում է, թե որտեղ պետք է նամակ առաքել: ` urls.py ` ֆայլը պարունակում է ` urlresolver ` - ի կողմից օգտագործված օրինաչափությունների ցուցակ: + +Եկեք առայժմ մոռանանք մնացած ֆայլերի մասին , քանի որ դրանք չենք փոխելու: Միակ բանը, որ պետք է հիշել, դրանք պատահաբար չջնջելն է: + +## Փոխել կարգավորումները + +Եկեք որոշ փոփոխություններ կատարենք `mysite/settings.py` - ում: Բացեք ֆայլը ՝ ավելի վաղ տեղադրած կոդերի խմբագրիչի/code editor-ի միջոցով: + +**Նշում**. Հիշեք, որ `settings.py`- ը սովորական ֆայլ է, ինչպես ցանկացած այլ: Կարող եք այն բացել ձեր կոդերի խմբագրից `օգտագործելով "file -> open" /«ֆայլ-> բաց » գործողությունների ընտրացանկը: Սա ձեզ կտա սովորական պատուհանը, որում կարող եք անցնել ձեր `settings.py` ֆայլը և ընտրել այն: Այլապես, ֆայլը կարող եք բացել ՝ անցնելով ձեր աշխատասեղանի djangogirls պանակը և սեղմել աջ քլիք ֆայլի վրա: Ապա, ցուցակից ընտրեք ձեր կոդի խմբագիրը: Խմբագրի ընտրությունը կարևոր է, քանի որ կարող եք տեղադրել այլ ծրագրեր, որոնք կարող են բացել ֆայլը, բայց թույլ չեն տալիս խմբագրել այն: + +Լավ կլինի մեր կայքում ճիշտ ժամային գոտի սահմանել: Գնացեք [Wikipedia's list of time zones/Վիքիպեդիայի ժամային գոտիների ցուցակ](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) և պատճենեք ձեր համապատասխան ժամային գոտին (TZ) (օրինակ `Europe/Berlin`): + +`settings.py` ֆայլում գտեք `TIME_ZONE` պարունակող տողը և փոփոխեք այն ըստ ձեր ժամային գոտու: Օրինակ. + +{% filename %}mysite/settings.py{% endfilename %} + +```python +TIME_ZONE = 'Europe/Berlin' +``` + +Լեզվի կոդը կազմված է մի լեզվով, օրինակ ``en` անգլերենի համար կամ `de` գերմաներենի համար, և երկրի կոդ, ինչպիսիք են `de`- ն Գերմանիայի համար կամ `ch`-ն Շվեյցարիայի համար: Եթե ​​անգլերենը ձեր մայրենի լեզուն չէ, կարող եք լեզու ավելացնել ՝ սկզբնադիր կոճակները և ծանուցումները Django- ից ձեր մայրենի լեզվով փոխելու համար: Այսպիսով, դուք կունենաք "Cancel"/«Չեղարկել» կոճակը թարգմանված այն լեզվով, որը դուք ընտրել եք այստեղ: [Django comes with a lot of prepared translations/ Django- ն տրամադրում է բազմաթիվ թարգմանություններ:](https://docs.djangoproject.com/en/2.2/ref/settings/#language-code): + +Եթե ​​այլ լեզվի կարիք ունեք, փոխեք լեզվի կոդը `փոխելով հետևյալ տողը. + +{% filename %}mysite/settings.py{% endfilename %} + +```python +LANGUAGE_CODE = 'de-ch' +``` + +Անհրաժեշտ է նաև ավելացնել ուղի/path ստատիկ ֆայլերի/static files համար: (Ստատիկ ֆայլերի և CSS- ի մասին ամեն ինչ կիմանանք ավելի ուշ ձեռնարկի ընթացքում): Իջեք ֆայլի *end/վերջը* և անմիջապես `STATIC_URL` գրառման տակ, ավելացրեք նորը ՝ `STATIC_ROOT`. + +{% filename %}mysite/settings.py{% endfilename %} + +```python +STATIC_URL = '/static/' +STATIC_ROOT = BASE_DIR / 'static' +``` + +Երբ `DEBUG`- ը `True/ճիշտ է`ճիշտ է, և `ALLOWED_HOSTS`- ը սահմանված չէ, ընդունիչը գտնվում է ընդդեմ `['localhost', '127.0.0.1', '[::1]']` . Մեր դիմումը գործադրելուց հետո սա չի համապատասխանում PythonAnywhere-ում մեր hostname-ին (հյուրընկալող անունին ), այնպես որ մենք կփոխենք հետևյալ կարգավորումները: + +{% 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 ` կայքում, եկեք պաշտպանենք 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 +> # Here, inside the single quotes, you can cut and paste the random key generated above +> SECRET='3!0k#7ds5mp^-x$lqs2%le6v97h#@xopab&oj5y7d=hxe511jl' +> ``` +> +> - Դրանից հետո թարմացրեք Django- ի կարգավորումների ֆայլը `այս գաղտնի արժեքը ներարկելու համար և տեղադրելով Django կայքի անունը` +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> SECRET_KEY = os.getenv('SECRET') +> ``` +> +> - Եվ նույն ֆայլում մի փոքր ներքև, մենք ներարկում ենք ձեր նոր Glitch կայքի անունը (website-ը). +> +> {% 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': BASE_DIR / 'db.sqlite3', + } +} +``` + +Մեր բլոգի համար տվյալների շտեմարան ստեղծելու համար եկեք վահանակում գործարկենք հետևյալը.`python manage.py migrate` (մենք պետք է լինենք `djangogirls` գրացուցակում, որը պարունակում է `manage.py` ֆայլը) Եթե ​​ամեն բան լավ է, դուք պետք է տեսնեք նման մի բան. + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py migrate + Operations to perform: + Apply all migrations: auth, admin, 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 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 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 %} + + $ refresh + + + +Եթե ​​դուք Windows- ում եք, և դա չի հաջողվում ` UnicodeDecodeError ` - ի հետ, փոխարենը օգտագործեք այս հրամանը. + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + + +Այժմ դուք պետք է ստուգեք, արդյո՞ք ձեր կայքը գործում է: Բացեք ձեր բրաուզերը (Firefox, Chrome, Safari, Internet Explorer կամ այլ ինչ որ օգտագործում եք) և մուտքագրեք այս հասցեն. + +{% filename %}browser{% endfilename %} + + http://127.0.0.1:8000/ + + +Եթե ​​օգտագործում եք Chromebook և Cloud9, փոխարենը կտտացրեք ելնող պատուհանի URL- ին, որը պետք է որ հայտնվեր հրամանի պատուհանի վերևի աջ անկյունում, որտեղ վեբ սերվերն է աշխատում: URL- ն այսպիսի տեսք կունենա. + +{% filename %}browser{% endfilename %} + + https://.vfs.cloud9.us-west-2.amazonaws.com + + +or on Glitch: + + https://name-of-your-glitch-project.glitch.me + + +Շնորհավորում եմ Դուք պարզապես ստեղծել եք ձեր առաջին վեբ կայքը և այն վարում եք վեբ սերվերի միջոցով: Դա հիանալի, այնպես չէ՞: + +![Տեղադրեք աշխատանքը!](images/install_worked.png) + +Նկատի ունեցեք, որ հրամանի պատուհանը միանգամից կարող է գործարկել միայն մեկ բան, իսկ ավելի վաղ ձեր բացած հրամանի պատուհանը վեբ սերվերն է գործարկում: Քանի դեռ վեբ սերվերը աշխատում է և սպասում է լրացուցիչ մուտքային հարցումների, տերմինալը կընդունի նոր տեքստ, բայց չի կատարի նոր հրամաններ: + +> Մենք ստուգեցինք, թե ինչպես են աշխատում վեբ սերվերները ** Ինչպես է աշխատում ինտերնետը/How the Internet works ** գլխում: + +Վեբ սերվերի գործարկման ժամանակ լրացուցիչ հրամաններ մուտքագրելու համար բացեք նոր տերմինալի պատուհան և ակտիվացրեք ձեր virtualenv-ը. երկրորդ տերմինալի պատուհանը բացելու վերաբերյալ հրահանգները վերանայելու համար տե՛ս [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/hy/django_start_project/images/install_worked.png b/hy/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..4354c634ddb Binary files /dev/null and b/hy/django_start_project/images/install_worked.png differ diff --git a/hy/django_templates/README.md b/hy/django_templates/README.md new file mode 100644 index 00000000000..f32c320a7ce --- /dev/null +++ b/hy/django_templates/README.md @@ -0,0 +1,108 @@ +# Django շաբլոններ + +Որոշ տվյալներ ցուցադրելու ժամանակն է: Դրա համար Django- ն մեզ տալիս է մի քանի օգտակար **template tags/ձևանմուշներ**: + +## Ի՞նչ են շաբլոնային պիտակները + +Ինչպես տեսնում եք, HTML- ում դուք իսկապես չեք կարող Python կոդ գրել, քանի որ բրաուզերները չեն հասկանում դա: Նրանք գիտեն միայն HTML: Մենք գիտենք, որ HTML- ը բավականին ստատիկ է, մինչդեռ Python- ը շատ ավելի դինամիկ է: + +**Django template tags/Django շաբլոնային պիտակները**-ը թույլ են տալիս մեզ Python-ը տեղափոխել HTML- ի մեջ, այնպես որ կարող եք ավելի արագ կառուցել դինամիկ կայքեր: Հիանալի է: + +## ցուցադրել հաղորդագրությունների ցուցակի ձևանմուշը + +Նախորդ գլխում մենք մեր ձևանմուշին/template-ին փոխանցեցինք հաղորդագրությունների ցանկը `posts/հաղորդագրությունների ` փոփոխականում: Այժմ այն ​​կներկայացնենք HTML- ով: + +Django ձևանմուշի/Django templates մեջ փոփոխական տեղադրելու համար հարկավոր է օգտագործել կրկնակի ձևավոր փակագծեր, որի ներսում փոփոխականի անունն է, ինչպես օրինակում. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{{ posts }} +``` + +Փորձեք սա ձեր ձևանմուշում/template `blog/templates/blog/post_list.html` : Բացեք այն կոդերի խմբագրում և փոխարինեք ամեն ինչ ՝ սկսած երկրորդ –ից`
` երրորդ-`
` - ով `{{ posts }}`. Պահեք ֆայլը և թարմացրեք էջը ՝ արդյունքները տեսնելու համար. + +![Նկար 13.1](images/step1.png) + +Ինչպես տեսնում եք, մենք ստացանք հետևյալ տողը. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +, ]> +``` + +Սա ցույց է տալիս, որ Django- ն փոփոխականը հասկանում էր որպես օբյեկտների ցուցակ: Հիշեք Python- ի **Introduction to Python** («Ներածությունից), թե ինչպես կարող ենք ցուցակներ ցուցադրել: Ճիշտ է, for հանգույցով: Django- ի ձևանմուշում դրանք կարող եք օգտագործել այսպես. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} + {{ post }} +{% endfor %} +``` + +Փորձեք սա ձեր ձևանմուշում: + +![Նկար 13.2](images/step2.png) + +Այն աշխատում է! Բայց մենք ուզում ենք, որ դրանք հայտնվեն որպես ստատիկ գրառումներ, որոնք մենք ստեղծել ենք **Introduction to HTML/ «HTML Ներածություն» ** գլխում: Դուք կարող եք խառնել HTML և ձևանմուշի պիտակները: Մեր `body`-ի տարրը կունենա այսպիսի տեսք. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+

Django Girls Blog

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

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` + +{% raw %} Այն ամենը, ինչ դնում եք `{% for %}` - ի և `{% endfor %}` - ի միջև, կկրկնվի ցուցակի յուրաքանչյուր կետի համար: Թարմացրեք էջը ՝ {% endraw %} + +![Նկար 13.3](images/step3.png) + +Նկատե՞լ եք, որ այս անգամ մենք մի փոքր այլ գրառում ենք օգտագործել (`{{ post.title }}` or `{{ post.text }}`)? Մենք մուտք ենք գործում տվյալների `Post` մոդելում սահմանված յուրաքանչյուր դաշտ: Նաև `|linebreaksbr` -ը տեքստը ֆիլտրում է զտիչի միջոցով ՝ տողերի ընդմիջումները/line-breaks/ պարբերությունների/paragraphs/ վերածելու համար: + +## Եվս մեկ բան + +Ժամանակն է մեկ անգամ ևս համոզվել, որ մեր կայքը կաշխատի հանրային ինտերնետում, այնպե՞ս չէ: Փորձենք կայքի նոր տարբերակը տեղակայել PythonAnywhere - ում: Ահա քայլերի ամփոփումը... + +* Նախ վերբեռնեք ձեր կոդը GitHub- ում + +{% filename %}command-line{% endfilename %} + + $ git status + [...] + $ git add . + $ git status + [...] + $ git commit -m "Modified templates to display posts from database." + [...] + $ git push + + +* Դրանից հետո անցեք [ PythonAnywhere ](https://www.pythonanywhere.com/consoles/), բացեք **Bash console** (կամ սկսեք նորը) և մուտքագրեք հրահանգը. + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd .pythonanywhere.com + $ git pull + [...] + + +(Հիշեք, որ `` - ը փոխարինեք ձեր PythonAnywhere օգտվողի անունով, առանց անկյունային փակագծերի:) + +* Վերջապես, անցեք ["Web" page/«Վեբ» էջ](https://www.pythonanywhere.com/web_app_setup/) և սեղմեք **Reload/Վերաբեռնում** ձեր վեբ հավելվածում: (Վահանակից PythonAnywhere- ի այլ էջեր հասնելու համար օգտագործեք վերևի աջ անկյունում գտնվող ընտրացանկի կոճակը): Ձեր թարմացումը պետք է հասանելի լինի https://subdomain.pythonanywhere.com- ստուգեք բրաուզերում: Եթե ​​PythonAnywhere կայքում բլոգի գրառումները չեն համընկնում տեղական սերվերում տեղակայված բլոգում հայտնվող գրառումների հետ, դա նորմալ է: Ձեր տեղական համակարգչի և PythonAnywhere- ի տվյալների բազան համապատասխանեցված չէ ձեր մնացած ֆայլերի հետ: + +Շնորհավորում ենք։ Այժմ շարունակեք և փորձեք նոր գրառում ավելացնել Django ադմինիստրատորին (չմեռանաք ավելացնել published_date!) Համոզվեք, որ դուք գտնվում եք Django ադմինիստրատորում ձեր pythonanywhere կայքի համար https://subdomain.pythonanywhere.com/admin: Դրանից հետո թարմացրեք ձեր էջը ՝ տեսնելու համար արդյոք գրառումը հայտնվում է այնտեղ: + +Զարմանալի՞ է աշխատում: Մենք հպարտ ենք ձեզանով: Մի փոքր հեռացեք համակարգչից. Դուք ընդմիջում եք վաստակել: + +![Նկար 13.4](images/donut.png) \ No newline at end of file diff --git a/hy/django_templates/images/donut.png b/hy/django_templates/images/donut.png new file mode 100644 index 00000000000..f31cebdc8a3 Binary files /dev/null and b/hy/django_templates/images/donut.png differ diff --git a/hy/django_templates/images/step1.png b/hy/django_templates/images/step1.png new file mode 100644 index 00000000000..cbf6420360a Binary files /dev/null and b/hy/django_templates/images/step1.png differ diff --git a/hy/django_templates/images/step2.png b/hy/django_templates/images/step2.png new file mode 100644 index 00000000000..fd6269c837c Binary files /dev/null and b/hy/django_templates/images/step2.png differ diff --git a/hy/django_templates/images/step3.png b/hy/django_templates/images/step3.png new file mode 100644 index 00000000000..b471fdd4d7b Binary files /dev/null and b/hy/django_templates/images/step3.png differ diff --git a/hy/django_urls/README.md b/hy/django_urls/README.md new file mode 100644 index 00000000000..1235171fbb0 --- /dev/null +++ b/hy/django_urls/README.md @@ -0,0 +1,103 @@ +# Django URL- ներ + +Մենք պատրաստվում ենք ստեղծել մեր առաջին վեբ էջը. Ձեր բլոգի գլխավոր էջը: Բայց նախ եկեք մի փոքր սովորենք Django URL- ների մասին: + +## Ի՞նչ է URL-ը: + +URL- ը վեբ հասցե է: Դուք կարող եք տեսնել URL ՝ ամեն անգամ կայք այցելելիս. Այն տեսանելի է ձեր զննարկչի հասցեի տողում: Այո `127.0.0.1:8000` URL է: Եվ `https://djangogirls.org` նույնպես URL է: + +![URL](images/url.png) + +Ինտերնետում յուրաքանչյուր էջ իր սեփական URL- ի կարիքն ունի: Այս կերպ ձեր հավելվածը գիտի, թե ինչ պետք է ցույց տա այդ URL- ը բացող օգտվողին: Django- ում մենք օգտագործում ենք `URLconf` անունով մի բան (URL configuration/URL կազմաձևում): URLconf- ը օրինաչափությունների ամբողջություն է, որոնք Django- ն կփորձի համապատասխանել ստացված URL- ի հետ `դիտման համար ճիշտ մեթոդ ընտրելու համար: + +## Ինչպե՞ս են աշխատում URL- ները Django- ում: + +Եկեք բացենք `mysite/urls.py` ֆայլը ձեր ընտրած կոդի խմբագրում և տեսնենք, թե ինչ տեսք ունի այն. + +{% filename %}mysite/urls.py{% endfilename %} + +```python +"""mysite URL Configuration + +[...] +""" +from django.contrib import admin +from django.urls import path + +urlpatterns = [ + path('admin/', admin.site.urls), +] +``` + +Ինչպես տեսնում եք, Django- ն այստեղ արդեն ինչ-որ բան է տեղադրել մեզ համար: + +Եռապատիկ չակերտների միջեւ տողերը(`'''` or `"""`) կոչվում են docstrings/փաստաթղթերի գծեր. դուք կարող եք դրանք գրել ֆայլի, դասի կամ մեթոդի վերևում `բացատրելու համար, թե ինչ է դա անում: Դրանք չեն գործարկվի Python- ի կողմից: + +Նախորդ գլխում այցելած ադմինիստրատորի URL- ն արդեն առկա է այստեղ ՝ + +{% filename %}mysite/urls.py{% endfilename %} + +```python + path('admin/', admin.site.urls), +``` + +Այս տողը նշանակում է, որ յուրաքանչյուր URL- ի համար, որը սկսվում է `admin/`, /ադմինիստրատորով Django- ն կգտնի համապատասխան *view* /տեսք: Այս դեպքում մենք ընդգրկում ենք մեծ թվով ադմինիստրատորի URL- ներ, որոնք հստակ գրված չեն այս փոքր ֆայլում. Սա շատ ավելի կոկիկ է և ավելի ընթեռնելի: + +## Ձեր առաջին Django URL- ը: + +Ժամանակն է ստեղծել ձեր առաջին URL- ը: Մենք ուզում ենք, որ «http://127.0.0.1:8000/» - ը լինի մեր բլոգի գլխավոր էջը `դրանում տեղադրված հաղորդագրությունների ցուցակով: + +Մենք նաև ուզում ենք մաքուր պահել ` mysite/urls.py ` ֆայլը, այնպես որ URL- ներ կներմուծենք մեր ` blog` ծրագրից հիմնական ` mysite/urls.py ` ֆայլ: + +Առաջ անցեք, տող ավելացրեք `blog.urls` - ը ներմուծելու համար: Նշենք, որ մենք այստեղ օգտագործում ենք `include/ներառման` գործառույթը/function, այնպես որ դուք ստիպված կլինեք այն ներմուծել `from django.urls…` տողում: + +Ձեր `mysite/urls.py` ֆայլը այժմ պետք է ունենա այսպիսի տեսք. + +{% filename %}mysite/urls.py{% endfilename %} + +```python +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('blog.urls')), +] +``` + +Django- ն այժմ «http://127.0.0.1:8000/» - ի բոլոր խնդրանքները կուղղորդի դեպի `blog.urls` և այնտեղ կփնտրի հետագա հրահանգները: + +## blog.urls + +`blog` գրացուցակում ստեղծեք նոր դատարկ ֆայլ `urls.py` անունով և բացեք այն ձեր կոդի խմբագրում: Շատ լավ! Ավելացրեք այս առաջին երկու տողերը. + +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views +``` + +Այստեղ մենք ներմուծում ենք Django- ի `path` գործառույթը և մեր բոլոր `views/դիտումները ` `blog` հավելվածից: (Մենք դեռ դրանք չունենք, բայց մի րոպեից նրանք կհայտնվեն): + +Դրանից հետո մենք կարող ենք ավելացնել մեր առաջին URL նմուշը. + +{% filename %}blog/urls.py{% endfilename %} + +```python +urlpatterns = [ + path('', views.post_list, name='post_list'), +] +``` + +Ինչպես տեսնում եք, մենք կապել ենք `post_list` անունով `view` -ն և արմատային url- ը: Այս URL- ի օրինակը համընկնում է դատարկ տողի հետ, և Django URL լուծիչը անտեսելու է տիրույթի անունը (այսինքն `http://127.0.0.1:8000/), որը նախածանցում է URL- ի ամբողջական ուղին: Այս օրինակը Django- ին կասի, որ ` views.post_list ` - ը ճիշտ տեղն է այցելելու, եթե ինչ-որ մեկը մուտք է գործում ձեր կայք «http://127.0.0.1:8000/» հասցեով: + +Վերջին մասը ՝`name='post_list'`, URL- ի անունն է, որն օգտագործվելու է դիտումը նույնացնելու համար: Դա կարող է նույնը լինել, ինչ view-ի անունն է, կամ կարող է լինել բոլորովին այլ բան: Ծրագրում մենք հետագայում կօգտագործենք անվանական URL- ներ, ուստի կարևոր է, որ դրանց անուններն այժմ ներառվեն ձեր դիմումի մեջ: Մեր URL- ների անունները յուրահատուկ և հեշտ հիշվող պետք է լինեն: + +Եթե ​​այժմ փորձեք այցելել http://127.0.0.1:8000/, ապա դուք պետք է տեսնեք այնպիսի հաղորդագրություն, որում ասվում է ՝ «ինտերնետային էջը հասանելի չէ»/'web page not available' : Դա այն պատճառով է, որ սերվերը (Հիշո՞ւմ եք մուտքագրեք `runserver`) այլևս չի աշխատում: Հայացք գցեք ձեր սերվերի վահանակի պատուհանից ՝ պարզելու պատճառը: + +![Սխալ](images/error1.png) + +Ձեր վահանակը սխալ է ցույց տալիս, բայց մի անհանգստացեք. Սա իրականում շատ օգտակար է. այն Ձեզ ասում են, որ **no attribute 'post_list'**("բացակայում է հատկությունը 'post_list'"-ում): Դա այն *view*-ի անունն է, որը Django- ն փորձում է գտնել և օգտագործել, բայց մենք այն դեռ չենք ստեղծել: Այս փուլում ձեր `/admin/`/ադմինիստրատորը նույնպես չի աշխատի: Մի անհանգստացեք. Մենք կհասնենք այնտեղ: Եթե ​​այլ սխալի հաղորդագրություն եք տեսնում, փորձեք վերագործարկել/restart ձեր վեբ սերվերը: Դա անելու համար վեբ սերվերը աշխատող վահանակի պատուհանում դադարեցրեք այն ՝ սեղմելով Ctrl + C (Control և C ստեղները միասին): Windows- ում գուցե ստիպված լինեք սեղմել Ctrl + Break: Ապա դուք պետք է վերագործարկեք վեբ սերվերը ՝ գործարկելով <`python manage.py runserver` հրամանը: + +> Եթե ​​ցանկանում եք ավելին իմանալ Django- ի ադմինիստրատորի մասին, տես պաշտոնական փաստաթղթերի այս բաժինը ՝ https://docs.djangoproject.com/en/2.2/topics/http/urls/ \ No newline at end of file diff --git a/hy/django_urls/images/error1.png b/hy/django_urls/images/error1.png new file mode 100644 index 00000000000..50618fca3fe Binary files /dev/null and b/hy/django_urls/images/error1.png differ diff --git a/hy/django_urls/images/url.png b/hy/django_urls/images/url.png new file mode 100644 index 00000000000..c22441e930e Binary files /dev/null and b/hy/django_urls/images/url.png differ diff --git a/hy/django_views/README.md b/hy/django_views/README.md new file mode 100644 index 00000000000..7658a117908 --- /dev/null +++ b/hy/django_views/README.md @@ -0,0 +1,44 @@ +# Django- ի դիտում. Ստեղծագործելու ժամանակն է: + +Ժամանակն է ազատվել այն սխալից, որի հետ մենք բախվեցինք վերջին գլխում: :) + +*view/տեսարանը * այն հատվածն է, որտեղ տեղադրում ենք մեր հավելվածի «տրամաբանությունը»: Այն տեղեկատվություն կխնդրի ձեր ստեղծած նախկին `model`-ից և կփոխանցի `template/ձևանմուշ`-ին: Հաջորդ գլխում շաբլոն/template կստեղծենք: Views/Դիտումները պարզապես Python գործառույթներ/ Python functions են, որոնք մի փոքր ավելի բարդ են, քան այն, ինչ մենք գրել ենք **Introduction to Python/Python- ի «Ներածություն»** գլխում: + +Դիտումները տեղակայված են ` views.py ` ֆայլում: Մենք կավելացնենք մեր *views/դիտումները * `blog/views.py`- ին: + +## blog/views.py + +Լավ, եկեք բացենք այս ֆայլը մեր կոդի խմբագրում/code editor և տեսնենք, թե ինչ կա այնտեղ: + +{% filename %}blog/views.py{% endfilename %} + +```python +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', {}) +``` + +Ինչպես տեսնում եք, մենք ստեղծել ենք `post_list` անունով մի (`def`) մեթոդ, որը `request/խնդրանք` -ը որպես փաստարկ է վերցնում և `return/վերադարձնում` է `render/մատուցման ` մեթոդի արդյունքը, որը հավաքելու է մեր `blog/post_list.html` էջի ձևանմուշը: + +Պահեք ֆայլը, անցեք այստեղ հղումով http://127.0.0.1:8000/ և տեսեք, թե ինչ ունենք: + +Եվս մեկ սխալ: Կարդացեք, թե ինչ է կատարվում հիմա ՝ + +![Սխալ](images/error.png) + +Սա ցույց է տալիս, որ սերվերը գոնե նորից է աշխատում, բայց նրա աշխատանքի ընթացքը դեռ սխալ է թվում, ճի՞շտ է: Մի անհանգստացեք, սա պարզապես սխալի էջ է, վախենալու ոչինչ չկա: Ինչպես և վահանակի սխալի հաղորդագրությունները, այս հաղորդագրությունները նույնպես օգտակար են: Կարող եք կարդալ, որ *TemplateDoesNotExist*: Եկեք շտկենք այս սխալը և ձևանմուշ/template ստեղծենք հաջորդ գլխում: + +> Իմացեք ավելին Django- ի տեսակետների/Django views-ի մասին `կարդալով պաշտոնական փաստաթղթերը. https://docs.djangoproject.com/en/2.2/topics/http/views/ \ No newline at end of file diff --git a/hy/django_views/images/error.png b/hy/django_views/images/error.png new file mode 100644 index 00000000000..1530c879cb5 Binary files /dev/null and b/hy/django_views/images/error.png differ diff --git a/hy/dynamic_data_in_templates/README.md b/hy/dynamic_data_in_templates/README.md new file mode 100644 index 00000000000..74e76af4f3a --- /dev/null +++ b/hy/dynamic_data_in_templates/README.md @@ -0,0 +1,84 @@ +# Տվյալների դինամիկ փոփոխություն ձևանմուշներում + +Մենք ունենք տարբեր կտորներ. `Post` մոդելը սահմանվում է `models.py`- ում, մենք ունենք `post_list`- ը `views.py` - ում և ավելացնում է ձևանմուշը: Բայց ինչպե՞ս ցուցադրել գրառումները HTML էջի ձևանմուշում: Ի վերջո, սա հենց այն է, ինչին մենք ուզում ենք հասնել. Վերցնել որոշակի բովանդակություն (շտեմարանում պահվող մոդելներ) և ճշգրիտ ցուցադրել դրանք մեր ձևանմուշում/ template, այնպես չէ՞: + +Դրան են ծառայում դիտումները/*views* ՝ մոդելներն ու ձևանմուշները/models and templates/ միացնելու համար: `post_list` *view*-ում մենք պետք է վերցնենք այն մոդելները, որոնք մենք ցանկանում ենք ցուցադրել, և այնուհետև դրանք փոխանցել ձևանմուշին: *view*-ից մենք որոշում ենք, թե ինչ (մոդել) կցուցադրվի ձևանմուշում: + +Լավ, բա ինչպե՞ս ենք դրան հասնելու: + +Մենք պետք է բացենք `blog/views.py` ֆայլը կոդի խմբագրում/code editor: Այսպիսով, `post_list` *view* այսպիսի տեսք ունի. + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render + +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` + +Հիշո՞ւմ եք, մենք խոսեցինք այլ ֆայլերից կոդ ներառելու մասին: Այժմ մենք պետք է ներառենք մեր սահմանած մոդելը `models.py` ֆայլում: Մենք կավելացնենք տողը `from .models import Post` - ից հետևյալ կերպ. + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from .models import Post +``` + +Մոդելներից առաջ կետը/dot նշանակում է *current directory/ընթացիկ գրացուցակ * կամ *current application/ընթացիկ ծրագիր*: Թե `views.py`- ը, թե `models.py` - ին գտնվում են նույն գրացուցակում: Սա նշանակում է, որ մենք կարող ենք օգտագործել կետ `.` և ֆայլի անունը (առանց `.py`-ի): Դրանից հետո մենք ներմուծում ենք մոդելի անվանումը (`Post`): + +Բայց ի՞նչ է հաջորդը: `Post` մոդելից իրական գրառում ստանալու համար մեզ պետք է այսպես կոչված `QuerySet`: + +## QuerySet + +Դուք արդեն պետք է ծանոթ լինեք, թե ինչպես է աշխատում QuerySets- ը: Մենք դրա մասին խոսեցինք [Django ORM (QuerySets) գլխում ](../django_orm/README.md): + +Այսպիսով, հիմա մենք ուզում ենք հրապարակված բլոգային հաղորդագրություններ/ published blog posts ՝ տեսակավորված ըստ published_date- ի, ճիշտ է: Մենք դա արդեն արեցինք QuerySets գլխում: + +{% filename %}blog/views.py{% endfilename %} + +```python +Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +``` + +Այսպիսով, եկեք բացենք `blog/views.py` ֆայլը կոդի խմբագրում և ավելացնենք կոդի այս կտորը `def post_list(request)`, բայց մի մոռացեք ֆայլի սկզբում ավելացնել `from django.utils import timezone`. + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from django.utils import timezone +from .models import Post + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {}) +``` + +Մնացել է ընդամենը երկու բան ՝ մեր QuerySet- ը բլոգի գրառումների ցուցակում ցուցադրելու համար. + +1. Փոխանցեք `posts` QuerySet-ը ձևանմուշի մեջ ՝ զանգը/call փոխելով `render` function-ի /մատուցման գործառույթի (մենք դա կանենք հենց հիմա): +2. Փոփոխեք ձևանմուշը ՝ QuerySet `posts`-ը ցուցադրելու համար: Մենք կանդրադառնանք դրան հաջորդ գլխում: + +Խնդրում ենք նկատի ունենալ, որ մենք QuerySet- ի համար *variable/փոփոխական* ենք ստեղծել. `posts/հաղորդագրություններ`: Դուք կարող եք դա համարել որպես անուն մեր QuerySet- ի համար: Այսուհետ մենք կարող ենք դրան անդրադառնալ այս անունով: + +`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 +from .models import Post + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {'posts': posts}) +``` + +Այսքանը: Հիմա ժամանակն է գնալ ձևանմուշ/template և ցուցադրել QuerySet- ը էջում: + +Ցանկանու՞մ եք մի փոքր ավելին իմանալ Django- ի QuerySets- ի մասին: Անցեք այս հղումով՝ https://docs.djangoproject.com/en/2.2/ref/models/querysets/ \ No newline at end of file diff --git a/hy/extend_your_application/README.md b/hy/extend_your_application/README.md new file mode 100644 index 00000000000..3198751efd4 --- /dev/null +++ b/hy/extend_your_application/README.md @@ -0,0 +1,214 @@ +{% set warning_icon = '' %} + +# Ընդլայնել հավելվածը. + +Մենք արդեն ավարտել ենք մեր կայքի ստեղծման համար անհրաժեշտ բոլոր տարբեր քայլերը. Մենք գիտենք, թե ինչպես գրել մոդել, URL, դիտում և ձևանմուշ: Մենք նաև գիտենք, թե ինչպես կարելի է գեղեցիկ դարձնել մեր կայքը: + +Պրակտիկայի ժամանակն է: + +Բլոգում առաջին բանը, որ մեզ պետք է, հատուկ գրառումներ բացելու էջն է, այնպես չէ՞: + +Մենք դեռ ունենք `Post` մոդել, ուստի հարկավոր չէ որևէ լրացուցիչ կոդ ավելացնել մեր `models.py` ֆայլին: + +## Ստեղծեք ձևանմուշի հղում դեպի գրառման մանրամասներ + +Մենք կսկսենք այս `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.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +{% raw %} Մենք կցանկանայինք ցուցակում գրառման վերնագրից (post's title in the post list) հղում ունենալ գրառման մանրամասների (post's detail) էջին: Եկեք փոխենք `

{{ post.title }}

` այնպես, որ այն հղվի հաղորդագրության մանրամասն էջին ՝ {% endraw %} + +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} + +```html +

{{ post.title }}

+``` + +{% raw %} toամանակն է բացատրել խորհրդավոր `{% url 'post_detail' pk=post.pk %}`: Ինչպես կարող եք ենթադրել, այս `{% %}`նշումը նշանակում է, որ մենք օգտագործում ենք Django ձևանմուշի պիտակները/ Django template tags.: Այս անգամ մենք կօգտագործենք այն մեկը, որը մեզ համար URL կստեղծի: {% endraw %} + +` post_detail ` մասը նշանակում է, որ Django- ն սպասում է URL- ի`blog/urls.py` անունով = post_detail + +Իսկ ինչ վերաբերում է `pk=post.pk`- ին: `pk`- ն կարճ բանալին է, որը եզակի նույնացուցիչ է տվյալների բազայում յուրաքանչյուր գրառման համար: Յուրաքանչյուր Django մոդել ունի մի դաշտ, որը ծառայում է որպես իր հիմնական բանալի, և նրա ցանկացած այլ անուն կարող է նաև անվանվել «pk»: Քանի որ մենք չենք սահմանել հատուկ առաջնային բանալի մեր `Post` մոդելի մեջ, Django- ն կստեղծի մեկը մեզ համար (անխոս, դա կլինի մի թիվ, որը յուրաքանչյուր հաղորդագրության համար ավելանում է մեկով, ինչպես 1, 2, 3) և այն ավելացնում է ` pk ` անունով դաշտին ՝ մեր յուրաքանչյուր գրառման համար: Մենք մուտք ենք գործում հիմնական բանալին ՝ մուտքագրելով ` post.pk `, նույն կերպ, ինչպես մուտք ենք գործում այլ դաշտեր (`title/վերնագիր`, `author/հեղինակ`, etc.) մեր `Post/Հրապարակել ` օբյեկտ: + +Այժմ, երբ մենք գնանք http://127.0.0.1:8000/, մենք կունենանք սխալ (ինչպես սպասվում էր, քանի որ մենք դեռ URL կամ *view/դիտում* չունենք `post_detail`- ի համար): Դա նման տեսք կունենա: + +![NoReverseMatch error](images/no_reverse_match2.png) + +## Ստեղծեք URL ՝ post's detail/գրառման մանրամասներ էջի համար + +Եկեք `urls.py`- ում ստեղծենք URL մեր `post_detail` *view* համար: + +Մենք ուզում ենք, որ մեր առաջին հաղորդագրության մանրամասները ցուցադրվեն այս **URL** - ում ՝ http://127.0.0.1:8000/post/1/ + +Եկեք `blog/urls.py` ֆայլում URL կազմենք ՝ Django- ին ուղղելու համար `post_detail`, անունով *view/դիտումը*-ն , որը ցույց կտա բլոգի մի ամբողջ գրառում: Բացեք `blog/urls.py` ֆայլը կոդերի խմբագրում և ավելացրեք այս տողը (`path('post//', views.post_detail, name='post_detail'),`), որպեսզի ֆայլն այսպիսի տեսք ունենա. + +{% filename %}{{ warning_icon }} blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), +] +``` + +Այս `post//` մասը նշում է URL- ի օրինակը. Մենք ձեզ կբացատրենք ստորև. + +- `post/` /գրառում նշանակում է, որ URL- ը պետք է սկսվի **post** բառով, որին կհաջորդի **/**: Առայժմ ամեն բան կարգին է: +- `` - այս հատվածը ավելի բարդ է: Դա նշանակում է, որ Django- ն ակնկալում է ամբողջ թվային արժեք և այն կփոխանցի view-ին որպես `pk` կոչվող փոփոխական: +- `/` - ապա մեզ պետք է կրկին այս նշանը **/**, մինչև url- ի ավարտը: + +Սա նշանակում է, որ եթե ձեր բրաուզերում մուտքագրեք սա `http://127.0.0.1:8000/post/5/` , Django- ն պետք է հասկանա, որ ձեզ հարկավոր է *view*-ն որը կոչվող է ` post_detail `, և և փոխանցել այն տեղեկատվությունը, որը ` pk ` *հավասար է ` 5 ` այս <1>view*-ում: + +Լավ, մենք URL- ի նոր օրինակ ենք ավելացրել `blog/urls.py`-ում: Եկեք թարմացնենք էջը ՝ http://127.0.0.1:8000/ Boom! Սերվերը կրկին դադարեցրել է աշխատանքը: Հայացք գցեք կոնսոլին. Ինչպես և սպասվում էր, ևս մեկ սխալ կա: + +![AttributeError](images/attribute_error2.png) + +Հիշու՞մ եք, թե որն է հաջորդ քայլը: Դա view-ի/տեսակետ է ավելացնում: + +## Ավելացնել հաղորդագրության մանրամասն տեսք/post's detail view + +Այս անգամ մեր *view*-ին/ տեսակետին տրվում է լրացուցիչ պարամետր, `pk`. Մեր *view*-ն պետք է որսա, այնպես չէ՞: Այսպիսով, մենք մեր գործառույթը կսահմանենք որպես `def post_detail(request, pk):`. Նկատի ունեցեք, որ այս պարամետրը պետք է ունենա ճիշտ նույն անունը, ինչ որ մենք նշեցինք `urls` (`pk`) ներսում. Նկատի ունեցեք նաև, որ այս փոփոխականը բաց թողնելը սխալ է և կհանգեցնի սխալի: + +Այժմ մենք ուզում ենք ստանալ մեկ և միայն մեկ բլոգային հաղորդագրություն: Դա անելու համար մենք կարող ենք օգտագործել հարցաթերթիկներ, ինչպես հետևյալը. + +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} + +```python +Post.objects.get(pk=pk) +``` + +Բայց այս ծածկագիրը խնդիր ունի: Եթե ​​`primary key` (`pk`) -ում (տրված առաջնային բանալում) `Post`/գրառում չկա, մենք կունենանք շատ տգեղ սխալ: + +![DoesNotExist error](images/does_not_exist2.png) + +Մենք դա չենք ուզում: Բայց բարեբախտաբար, Django- ն շրջանցելու միջոց ունի, որը կկարգավորի դա մեզ համար. `get_object_or_404`: Այն դեպքում, երբ չկա `Post`/Հաղորդագրություն տրված ` pk ` -ի համար, մենք կստանանք շատ ավելի լավ էջ, որը կոչվում է `Page Not Found 404`/ Էջը չի գտնվել): + +![Page not found](images/404_2.png) + +Լավ նորությունն այն է, որ դուք իրականում կարող եք ստեղծել ձեր սեփական `Page not found` / չգտնված էջը/ և այն դարձնել այնքան գեղեցիկ, որքան ցանկանում եք: Բայց դա հիմա այդքան էլ կարևոր չէ, ուստի մենք այն բաց կթողնենք: + +Լավ, ժամանակն է մեր `views.py` ֆայլին *view* /դիտում ավելացնել: + +`blog/urls.py`- ում մենք ստեղծեցինք URL կանոն `post_detail` անունով, որը վերաբերում է `views.post_detail` կոչվող դիտմանը: Սա նշանակում է, որ Django- ն `blog/views.py`- ի ներսում `post_detail` անունով գործառույթ կսպասարկի ներկայացնելու համար: + +Ժամանակն է բացել `blog/views.py` ֆայլը կոդի խմբագրում և տողերի կողքին ավելացնել `from` հետևյալ տողերը. + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render, get_object_or_404 +``` + +Եվ ֆայլի վերջում մենք կավելացնենք մեր *view* -ն: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) +``` + +Այո Էջը թարմացնելու ժամանակն է ՝ http://127.0.0.1:8000/ + +![Post list view](images/post_list2.png) + +Աշխատում է! Ի՞նչ է պատահում, եթե փորձեք հետևել հաղորդագրության վերնագրի հղմանը: + +![TemplateDoesNotExist error](images/template_does_not_exist2.png) + +Օ ոչ! Եվս մեկ սխալ! Բայց մենք արդեն գիտենք, թե ինչպես վարվել դրա հետ, ճիշտ է: Մենք պետք է ձևանմուշ/template ավելացնենք: + +## Ստեղծեք ձևանմուշի հղում գրառման մանրամասների համար + +Մենք `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.text|linebreaksbr }}

+
+{% endblock %} +``` + +Կրկին մենք երկարացնում ենք `base.html`- ը: `content` (բովանդակություն) բլոկում մենք ցուցադրում ենք հրապարակման ամսաթիվը (եթե գոյություն ունի հրապարակված_ թվականը), վերնագիրն ու տեքստը: Բայց մենք պետք է քննարկենք մի քանի կարևոր բաներ, ճիշտ է՞: + +No translations matched your search {% raw %}`{% if ... %} ... {% endif %}` - ը ձևանմուշի պիտակ է, որը մենք կարող ենք օգտագործել, եթե ինչ-որ բան փորձելու կարիք ունենանք: (Հիշո՞ւմ եք եթե ... `if... կառուցվածքը Python- ի «Ներածություն» գլխից:) Այս բաժնում մենք ուզում ենք ստուգել, ​​թե արդյոք մեր գրառման published_date` -ն /հրապարակված_թվականը պարունակում է տվյալներ, թե ոչ:{% endraw %} + +Լավ, մենք կարող ենք թարմացնել մեր էջը և տեսնել, թե արդյո՞ք `TemplateDoesNotExist` - ը այլևս չկա: + +![Post detail page](images/post_detail2.png) + +Այո դա աշխատում է: + +# Տեղակայման ժամանակն է: + +Լավ կլինի ստուգել, ​​որ կայքը դեռ աշխատում է PythonAnywhere- ում, ճիշտ չէ՞: Եկեք նորից կատարենք տեղակայումը: + +{% filename %}command-line{% endfilename %} + + $ 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 + + +Հետո, [PythonAnywhere Bash console](https://www.pythonanywhere.com/consoles/)-ում: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Հիշեք, որ `` - ը փոխարինեք ձեր PythonAnywhere օգտվողի անունով, առանց չակերտների (անկյունային փակագծերի:) + +## Ստատիկ ֆայլերի թարմացվումը սերվերում + +Python- ի նման սերվերները ցանկացած այլ վայրում սիրում են ստեղծել «ստատիկ ֆայլեր» (օրինակ ՝ CSS ֆայլեր) Python ֆայլերից առանձին, քանի որ դրանք կարող են օպտիմալացնել, որպեսզի դրանք ավելի արագ բեռնվեն: Արդյունքում, ամեն անգամ, երբ մենք փոփոխություններ ենք կատարում մեր CSS ֆայլերում, մենք պետք է սերվերի վրա գործադրենք լրացուցիչ հրաման ՝ ասելու, որ դրանք թարմացնի: Հրամանը կոչվում է `collectstatic`: + +Սկսեք ակտիվացնելով ձեր virtualenv- ը, եթե այն արդեն ակտիվ չէ (PythonAnywhere- ը դրա համար օգտագործում է `workon` կոչվող հրամանը, սա նույնն է, ինչ `source myenv/bin/activate` հրամանը, որը դուք օգտագործում եք ձեր սեփական համակարգչում ): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ workon .pythonanywhere.com + (ola.pythonanywhere.com)$ python manage.py collectstatic + [...] + + +`manage.py collectstatic` հրամանը փոքր-ինչ նման է < `manage.py migrate`-ին: Մենք որոշ փոփոխություններ ենք կատարում մեր կոդի մեջ, այնուհետև ասում ենք, որ Django- ն *apply* / <0>կիրառի այդ փոփոխությունները սերվերում կամ տվյալների բազայում ստատիկ ֆայլերի հավաքածուի մեջ: + +Ամեն դեպքում, մենք այժմ պատրաստ ենք անցնել ["Web" page](https://www.pythonanywhere.com/web_app_setup/) / <0>«Վեբ» էջ (վահանակի վերևի աջ անկյունում գտնվող կոճակի ընտրացանկից) և կտտացնել **Reload** / <1>Վերաբեռնել, և այնուհետև անցնել այս հղումով https: // page subdomain.pythonanywhere.com արդյունքը տեսնելու համար: + +Այսքանը: Դու արեցիր դա! \ No newline at end of file diff --git a/hy/extend_your_application/images/404_2.png b/hy/extend_your_application/images/404_2.png new file mode 100644 index 00000000000..0a6fdf3234e Binary files /dev/null and b/hy/extend_your_application/images/404_2.png differ diff --git a/hy/extend_your_application/images/attribute_error2.png b/hy/extend_your_application/images/attribute_error2.png new file mode 100644 index 00000000000..4b8262476d9 Binary files /dev/null and b/hy/extend_your_application/images/attribute_error2.png differ diff --git a/hy/extend_your_application/images/does_not_exist2.png b/hy/extend_your_application/images/does_not_exist2.png new file mode 100644 index 00000000000..e7015f2c80d Binary files /dev/null and b/hy/extend_your_application/images/does_not_exist2.png differ diff --git a/hy/extend_your_application/images/no_reverse_match2.png b/hy/extend_your_application/images/no_reverse_match2.png new file mode 100644 index 00000000000..aba1c9c8980 Binary files /dev/null and b/hy/extend_your_application/images/no_reverse_match2.png differ diff --git a/hy/extend_your_application/images/post_detail2.png b/hy/extend_your_application/images/post_detail2.png new file mode 100644 index 00000000000..b40c92efb8c Binary files /dev/null and b/hy/extend_your_application/images/post_detail2.png differ diff --git a/hy/extend_your_application/images/post_list2.png b/hy/extend_your_application/images/post_list2.png new file mode 100644 index 00000000000..dd0a0d67a6f Binary files /dev/null and b/hy/extend_your_application/images/post_list2.png differ diff --git a/hy/extend_your_application/images/template_does_not_exist2.png b/hy/extend_your_application/images/template_does_not_exist2.png new file mode 100644 index 00000000000..c856abeda31 Binary files /dev/null and b/hy/extend_your_application/images/template_does_not_exist2.png differ diff --git a/hy/how_the_internet_works/README.md b/hy/how_the_internet_works/README.md new file mode 100644 index 00000000000..9a9629bb60f --- /dev/null +++ b/hy/how_the_internet_works/README.md @@ -0,0 +1,47 @@ +# Ինչպես է աշխատում ինտերնետը + +> Ընթերցողների համար տանը. Այս գլուխն ընդգրկված է [How the Internet Works](https://www.youtube.com/watch?v=oM9yAA09wdc) տեսանյութում +> +> Այս գլուխը ներշնչված է Howեսիկա ՄաքՔելարի (http://web.mit.edu/jesstess/www/) "How the Internet works"(«Ինչպես է աշխատում ինտերնետը») զրույցից: + +Մենք գրազ ենք գալիս, որ դուք ամեն օր ինտերնետ եք օգտագործում: Բայց գիտե՞ք իրականում, թե ինչ է պատահում, երբ ձեր զննարկչի մեջ մուտքագրում եք https://djangogirls.org- ի նման հասցե և սեղմում ` enter `: + +Առաջին բանը, որ դուք պետք է հասկանաք, այն է, որ կայքը բաղկացած է կոշտ սկավառակի/ hard disk -ի վրա պահված մի շարք ֆայլերից, ինչպես ձեր ֆիլմերը, երաժշտությունը կամ նկարները: Այնուամենայնիվ, կա մեկ առանձնահատկություն, որը հատուկ է միայն կայքերին. Դրանք պարունակում են համակարգչային կոդ, որը կոչվում է HTML: + +Եթե ​​դուք ծանոթ չեք ծրագրավորմանը, սկզբում դժվար կլինի հասկանալ HTML- ը, բայց ձեր վեբ բրաուզերները (օրինակ ՝ Chrome, Safari, Firefox և այլն) սիրում են այն: Վեբ բրաուզերները նախատեսված են հասկանալու այս կոդը, հետևելու նրա հրահանգներին և ներկայացնելու այն ֆայլերը, որոնցից կազմված է ձեր կայքը, ճիշտ այնպես, ինչպես ցանկանում եք: + +Ինչպես ցանկացած ֆայլ, HTML ֆայլերը նույնպես պետք է պահենք ինչ-որ տեղ մեր կոշտ սկավառակի/hard disk-ի վրա: Ինտերնետի համար մենք օգտագործում ենք հատուկ հզոր համակարգիչներ, որոնք կոչվում են *servers/սերվերներ*: Նրանք չունեն էկրան, մկնիկ կամ ստեղնաշար, քանի որ նրանց հիմնական նպատակը տվյալների պահպանումն ու սպասարկումն է: Այդ պատճառով նրանց անվանում են *servers/սերվեր* , քանի որ դրանք ձեզ ծառայություն են *մատուցում*: + +Շատ լավ, բայց ուզում եք իմանալ, թե ինչ տեսք ունի ինտերնետը, ճի՞շտ է: + +Մենք նկարեցինք նկար ձեզ համար: Այն այսպիսի տեսք ունի. + +![Պատկեր 1.1](images/internet_1.png) + +Կարծես խառնաշփոթ է, չէ՞: Իրականում դա միացված մեքենաների ցանց է (վերոհիշյալ *servers/սերվերները*): Հարյուր հազարավոր մեքենաներ: Շատ ու շատ կիլոմետրեր ճոպաններ/cables ամբողջ աշխարհում: Կարող եք այցելել սուզանավերի մալուխային քարտեզի/Submarine Cable Map կայք (http://submarinecablemap.com/) ՝ տեսնելու, թե որքան բարդ է ցանցը: Ահա կայքի սքրինշոթը. + +![Պատկեր 1.2](images/internet_3.png) + +Դա զարմանալի է, այնպես չէ՞: Այնուամենայնիվ, հասկանալի է, որ հնարավոր չէ յուրաքանչյուր մեքենա մետաղալարով միացնել ինտերնետին: Այսպիսով, ցանկալի մեքենային հասնելու համար (օրինակ,մեկը https://djangogirls.org որտեղ պահպանվում է), մենք պետք է հարցումը փոխանցենք շատ այլ մեքենաների միջով: + +Այն պետք է ունենա նման տեսք: + +![Պատկեր 1.3](images/internet_2.png) + +Պատկերացրեք, որ երբ մուտքագրեք https://djangogirls.org, դուք նամակ եք ուղարկում, որում ասվում է. «Հարգելի Django Girls, ես ուզում եմ տեսնել djangogirls.org կայքը: Ուղարկեք այն ինձ, խնդրում եմ»: + +Ձեր նամակը գնում է ձեզ ամենամոտ փոստային բաժանմունք: Այնուհետև այն ուղարկվում է մեկ ուրիշին, որը մի փոքր ավելի մոտ է հասցեատիրոջը, իսկ հետո հաջորդին և այլն, մինչև այն հասցվի իր նպատակակետին: Միակ յուրահատկությունն այն է, որ շատ նամակներ (*data packets/տվյալների փաթեթներ *) մեկ հասցեով ուղարկելիս նրանցից յուրաքանչյուրը կարող է անցնել բոլորովին այլ փոստային բաժանմունքների (*routers/երթուղիչների*) միջով: Դա կախված է նրանից, թե ինչպես են դրանք բաշխվում յուրաքանչյուր գրասենյակում: + +![Պատկեր 1.4](images/internet_4.png) + +Ահա թե ինչպես է, այն աշխատում. Դուք հաղորդագրություններ եք ուղարկում և սպասում պատասխանի: Իհարկե, թղթի և գրիչի փոխարեն օգտագործվում են տվյալների բայթեր, բայց գաղափարը նույնն է: + +Փողոցի, քաղաքի, փոստային կոդի և երկրի անունների փոխարեն մենք օգտագործում ենք IP հասցեներ: Ձեր համակարգիչը նախ խնդրում է DNS- ին (Domain Name System/Դոմեյն անունների համակարգ) djangogirls.org- ը թարգմանել IP հասցեի: Սա գործում է հին հեռախոսների գրքերի նման, որտեղ դուք կարող եք փնտրել այն մարդու անունը, ում հետ ցանկանում եք կապվել, և գտնել նրա հեռախոսահամարը և հասցեն: + +Նամակ ուղարկելիս այն պետք է ունենա որոշակի բնութագրեր, որպեսզի այն ճիշտ առաքվի ՝ հասցե, կնիք և այլն: Դուք նաև օգտագործում եք լեզու, որը ստացողը հասկանում է, այնպես չէ՞: Նույնը վերաբերում է *data packets/տվյալների փաթեթներին*, որոնք դուք ուղարկում եք կայքը տեսնելու համար: Մենք օգտագործում ենք HTTP (Hypertext Transfer Protocol) կոչվող արձանագրություն: + +Հետեւաբար, հիմնականում, երբ կայք ունեք, պետք է ունենաք նաև սերվեր (մեքենա)/*server* (machine), որտեղ այն գտնվում է: Երբ *server/սերվերը* ստանում է մուտքային *request/հարցում* (նամակով), այն հետ է ուղարկում ձեր կայքը (մեկ այլ նամակով): + +Քանի որ սա Django ձեռնարկ է, կարող եք հարցնել, թե ինչ է անում Django- ն: Պատասխան ուղարկելիս միշտ չէ, որ ցանկանում եք նույն բանը ուղարկել բոլոր հասցեատերերին: Շատ ավելի լավ է, եթե ձեր նամակները անձնավորված լինեն, հատկապես այն մարդու համար, ով հենց նոր է գրել ձեզ, այնպես չէ՞: Django- ն օգնում է ձեզ ստեղծել այս անհատականացված, հետաքրքիր նամակները: :) + +Բավական է խոսելը ՝ ստեղծագործելու ժամանակն է: \ No newline at end of file diff --git a/hy/how_the_internet_works/images/internet_1.png b/hy/how_the_internet_works/images/internet_1.png new file mode 100644 index 00000000000..e289eac2b23 Binary files /dev/null and b/hy/how_the_internet_works/images/internet_1.png differ diff --git a/hy/how_the_internet_works/images/internet_2.png b/hy/how_the_internet_works/images/internet_2.png new file mode 100644 index 00000000000..e8cf8b77999 Binary files /dev/null and b/hy/how_the_internet_works/images/internet_2.png differ diff --git a/hy/how_the_internet_works/images/internet_3.png b/hy/how_the_internet_works/images/internet_3.png new file mode 100644 index 00000000000..6f5d95dec80 Binary files /dev/null and b/hy/how_the_internet_works/images/internet_3.png differ diff --git a/hy/how_the_internet_works/images/internet_4.png b/hy/how_the_internet_works/images/internet_4.png new file mode 100644 index 00000000000..d4748ac48ef Binary files /dev/null and b/hy/how_the_internet_works/images/internet_4.png differ diff --git a/hy/html/README.md b/hy/html/README.md new file mode 100644 index 00000000000..a6c7d8b77b2 --- /dev/null +++ b/hy/html/README.md @@ -0,0 +1,228 @@ +# HTML- ի ներածություն + +Կարո՞ղ եք հարցնել, թե ի՞նչ ձևանմուշ է: + +Կաղապարը ֆայլ է, որը մենք կարող ենք կրկին օգտագործել `տարբեր տեղեկատվություն կայուն ձևաչափով ներկայացնելու համար. Օրինակ, դուք կարող եք օգտագործել ձևանմուշ, որը կօգնի ձեզ նամակ գրել, քանի որ չնայած յուրաքանչյուր նամակ կարող է պարունակել տարբեր հաղորդագրություն և հասցեագրված լինել այլ անձի: , նրանք կկիսվեն նույն ձևաչափով: + +Django ձևանմուշի ձևաչափը նկարագրված է HTML կոչվող լեզվով (դա HTML- ն է, որը մենք նշել ենք առաջին գլխում ՝ ** How the Internet works (Ինչպես է աշխատում ինտերնետը) **): + +## Ի՞նչ է HTML- ը: + +HTML- ը ծածկագիր է, որը մեկնաբանվում է ձեր վեբ զննարկչի կողմից, ինչպիսիք են Chrome- ը, Firefox- ը կամ Safari- ն `օգտագործողի համար վեբ էջ ցուցադրելու համար: + +HTML- ը նշանակում է «HyperText Markup Language»: ** HyperText ** նշանակում է, որ դա տեքստի տեսակ է, որն աջակցում է էջերի միջև հիպերհղումները: ** Markup (Նշում) ** նշանակում է, որ մենք վերցրել ենք մի փաստաթուղթ և նշել այն կոդով, որպեսզի ինչ-որ բան ասենք (այս դեպքում ՝ զննարկիչ), թե ինչպես մեկնաբանել էջը: HTML կոդը կառուցված է ** tags (պիտակներով) **, յուրաքանչյուրը սկսվում է `<` - ով և ավարտվում `>` - ով: Այս tag-ները (պիտակները) ներկայացնում են markup (մակնշման) ** element-ներ(տարրեր) **: + +## Ձեր առաջին template-ը (ձևանմուշը): + +Կաղապար ստեղծել նշանակում է ձևանմուշի ֆայլ ստեղծել: Ամեն ինչ ֆայլ է, չէ՞: Դուք հավանաբար դա արդեն նկատել եք: + +Ձևանմուշները պահվում են ` blog/templates/blog` գրացուցակում: Այսպիսով, նախ ստեղծեք ` template-ներ (կաղապարներ) ` կոչվող գրացուցակ ձեր բլոգի գրացուցակի ներսում: Դրանից հետո ստեղծեք մեկ այլ գրացուցակ, որը կոչվում է ` blog` ձեր ձևանմուշների գրացուցակում. + + blog + └───templates + └───blog + + +(Կարող եք զարմանալ, թե ինչու են մեզ հարկավոր երկու գրացուցակներ, որոնք կոչվում են ` blog`, ինչպես կիմանաք ավելի ուշ, սա անվանակոչման օգտակար պայմանագիր է, որը կյանքն ավելի է հեշտացնում, երբ ամեն ինչ սկսում է բարդանալ: + +Եվ հիմա ստեղծեք ` post_list.html ` ֆայլ (պարզապես թողեք այն դատարկ) առայժմ `blog/templates/blog ` գրացուցակի ներսում: + +Տեսեք, թե ինչպես է ձեր կայքը այժմ նայում. Http://127.0.0.1:8000/ + +> Եթե ​​դեռ սխալ ունեք ` TemplateDoesNotExist ` - ը, փորձեք վերագործարկել ձեր սերվերը: Անցեք հրամանի տող, դադարեցրեք սերվերը ՝ Ctrl + C (Control և C ստեղները միասին) սեղմելով և այն նորից սկսեք ՝ գործարկելով ` python manage.py runserver ` command-ը (հրամանը): + +![Figure 11.1](images/step1.png) + +Այլևս ոչ մի սխալ: Շնորհավորում եմ :) Այնուամենայնիվ, ձեր կայքը իրականում ոչինչ չի հրապարակում, բացի դատարկ էջից, քանի որ ձեր ձևանմուշն էլ է դատարկ: Մենք պետք է դա շտկենք: + +Բացեք նոր ֆայլը ծածկագրի խմբագրում և ավելացրեք հետևյալը. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + +

Hi there!

+

It works!

+ + +``` + +Այսպիսով, ինչպես է ձեր կայքը այժմ նայում: Այցելեք այն ՝ պարզելու համար ՝ http://127.0.0.1:8000/ + +![Figure 11.2](images/step3.png) + +Դա աշխատեց. Հաճելի աշխատանք այնտեղ: :) + +* `` տողը HTML պիտակ չէ: Այն հայտարարում է միայն փաստաթղթի տեսակը: Այստեղ այն զննարկչին տեղեկացնում է, որ փաստաթղթի տեսակը [ HTML5 ](https://html.spec.whatwg.org/#the-doctype) է: Սա միշտ էլ ցանկացած HTML5 ֆայլի սկիզբ է: +* Ամենահիմնական թեգը ՝ ``, միշտ html բովանդակության սկիզբն է, և ` ` միշտ վերջը: Ինչպես տեսնում եք, կայքի ամբողջ բովանդակությունը անցնում է `` սկզբի և եզրափակիչ թեգի միջև`` +* `

` պիտակ է պարբերության տարրերի համար; `

` փակվում է յուրաքանչյուր պարբերություն + +## Գլուխը և մարմինը + +Յուրաքանչյուր HTML էջ բաժանվում է նաև երկու element-երի ** head ** և ** body ** + +* ** head-ը ** էլեմենտ է, որը պարունակում է տեղեկություններ էկրանին չներկայացվող փաստաթղթի մասին: + +* ** body-ին ** էլեմենտ է, որը պարունակում է այն ամենը, ինչ ցուցադրվում է որպես վեբ էջի մաս: + +Մենք օգտագործում ենք `` ՝ զննարկիչին էջի կազմաձևման մասին պատմելու համար, և `` ՝ պատմելու համար, թե իրականում որն է էջում: + +Օրինակ, `` - ի ներսում կարող եք տեղադրել վեբ էջի վերնագրի էլեմենտ, ինչպես հետևյալը. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + + Ola's blog + + +

Hi there!

+

It works!

+ + +``` + +Պահեք (save) ֆայլը և թարմացրեք ձեր էջը: + +![Figure 11.3](images/step4.png) + +Նկատեք, թե զննարկիչը ինչպե՞ս է հասկացել, որ "Ola's blog"( «Օլայի բլոգը») ձեր էջի վերնագիրն է: Այն մեկնաբանել է ` Օla's blog ` և տեքստը դրել ձեր զննարկչի վերնագրի տողում (այն կօգտագործվի նաև էջանիշների համար և այլն): + +Հավանաբար, դուք նաև նկատել եք, որ յուրաքանչյուր բացող պիտակ համընկնում է * closing tag (փակող պիտակ) * - ի հետ, ` / ` - ով, և որ էլեմենտ * nested (տեղադրված են) * (այսինքն ՝ կարող եք փակեք որոշակի tag (պիտակ), մինչև որ փակվեն բոլոր ներսում գտնվողները): + +Դա նման է իրերը տուփերի մեջ դնելուն: Դուք ունեք մեկ մեծ տուփ ՝ ` `; դրա ներսում կա ` `, և դա պարունակում է դեռ ավելի փոքր տուփեր. `

` + +Դուք պետք է պահպանեք պիտակների* closing (փակման) * և * nesting(բնադրման)* տարրերի այս կանոնները. Եթե դա չես անում, զննարկիչը չի կարողանա դրանք ճիշտ մեկնաբանել, և ձեր էջը կցուցադրվի սխալ + +## Անհատականացրեք ձեր ձևանմուշը + +Այժմ կարող եք մի փոքր զվարճանալ և փորձել հարմարեցնել ձեր ձևանմուշը: Ահա դրա համար մի քանի օգտակար tags (պիտակ): + +* `

A heading (Վերնագիր)

` ձեր ամենակարևոր վերնագրի համար +* `

sub-heading (ենթավերնագիր)

`Հաջորդ մակարդակի վերնագրի համար +* Նույնիսկ ավելի փոքր`

Ենթավերնագիր

`… և այլն, մինչև `
` +* ` +

Տեքստի մի պարբերություն

` +* ` տեքստը ` ընդգծում է ձեր տեքստը +* ` տեքստը ` խիստ ընդգծում է ձեր տեքստը +* `
` անցնում է մեկ այլ տողի (br- ի ներսում ոչինչ չես դնի, և փակիչ պիտակ չկա) +* ` link-ը (հղումը) ` ստեղծում է link-ը (հղումը) +* `
  • առաջին նյութը
  • երկրորդ կետը
` կազմում է ցուցակ, ինչպես այս մեկը: +* `
` սահմանում է էջի մի հատված +* `` սահմանում է նավիգացիոն հղումների շարք +* `
` սահմանում է անկախ, ինքնամփոփ բովանդակություն +* `
` փաստաթղթում բաժին է սահմանում +* `
` նշանակում է փաստաթղթի կամ բաժնի վերնագիր +* `
` սահմանում է փաստաթղթի հիմնական բովանդակությունը +* `` defines some content aside from the content it is placed in (like a sidebar) +* `
` սահմանում է փաստաթղթի կամ բաժնի տողատակ +* `` սահմանում է որոշակի ժամանակ (կամ տվյալների ժամանակը) + +Ահա ամբողջական ձևանմուշի օրինակ, պատճենեք և տեղադրեք այն ` blog/templates/blog/post_list.html`: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + + Django Girls blog + + +
+

Django Girls Blog

+
+ +
+ +

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.

+
+ +
+ +

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.

+
+ + +``` + +Մենք այստեղ ստեղծել ենք մեկ ` header (վերնագիր) ` և երկու ` artcicle (հոդված) ` բաժիններ: + +* ` header (վերնագիր) ` տարրը պարունակում է մեր բլոգի վերնագիրը. Դա վերնագիր է և link +* ` article-ի (հոդվածի) ` երկու տարրերը պարունակում են մեր բլոգի հաղորդագրությունները հրապարակված ամսաթվով ` ժամանակ ` տարրում, ` h2 ` տարրը `գրառման վերնագրով, որը սեղմված է և ` p ` (paragraph/ պարբերություն) տարր `մեր բլոգի գրառման տեքստի համար: + +Դա մեզ տալիս է այս էֆեկտը. + +![Figure 11.4](images/step6.png) + +Սա շատ լավ է! Բայց մինչ այժմ մեր ձևանմուշը ցուցադրում է միայն ** նույն տեղեկատվությունը ** մինչդեռ ավելի վաղ մենք խոսում էինք ձևանմուշների մասին, որոնք թույլ էին տալիս մեզ ** տարբեր ** տեղեկատվություն ցուցադրել ** նույն ձևաչափով ** + +Այն, ինչ մենք իսկապես ուզում ենք անել, մեր Django ադմինիստրատորի մեջ ավելացված իրական հաղորդագրությունների ցուցադրումն է, և ահա թե ուր ենք գնալու: + +## Եվս մեկ բան. Տեղակայել: + +Լավ կլիներ այս ամենը տեսնել և ապրել ինտերնետում, այնպես չէ՞: Եկեք կատարենք մեկ այլ PythonAnywhere տեղակայում. + +### Commit (Պարտավորվել) և push (ուղարկել) ձեր կոդը դեպի GitHub + +Նախ և առաջ, եկեք տեսնենք, թե ինչ ֆայլեր են փոխվել վերջին անգամ տեղակայելուց հետո (գործադրեք այս հրամանները տեղական, այլ ոչ թե PythonAnywhere- ում). + +{% filename %}command-line{% endfilename %} + + $ git status + + +Համոզվեք, որ գտնվում եք ` djangogirls ` գրացուցակում, և եկեք ասենք, որ ` git ` ներառի այս փոփոխությունների բոլոր փոփոխությունները. + +{% filename %}command-line{% endfilename %} + + $ 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." + + +> ** Նշում ** Համոզվեք, որ կրկնակի գնանշումներ եք օգտագործում կատարած հաղորդագրության շուրջ: + +Դա անելուց հետո մենք մեր փոփոխությունները վերբեռնում ենք (մղում) մինչև GitHub: + +{% filename %}command-line{% endfilename %} + + $ git push + + +### Քաշեք ձեր նոր կոդը PythonAnywhere վայր և ներքաշեք ձեր վեբ ծրագիրը + +* Բացեք [ PythonAnywhere console page(վահանակների էջը) ](https://www.pythonanywhere.com/consoles/) և անցեք ձեր ** Bash console (Բաշ կոնսոլ) ** (կամ սկսեք նորը): Հետո run (սկի). + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +Դուք պետք է փոխարինեք `` ձեր իրական PythonAnywhere ենթադոմեյն անունով ՝ առանց անկյունային փակագծերի ( < > ): Ձեր ենթատիրույթի անունը սովորաբար ձեր PythonAnywhere օգտագործողի անունն է, բայց որոշ դեպքերում այն ​​կարող է մի փոքր այլ լինել (օրինակ, եթե ձեր օգտագործողի անունը մեծատառեր է պարունակում): Այսպիսով, եթե այս հրամանը չի գործում, օգտագործեք ` ls ` list files(ցուցակի ֆայլեր) հրամանը ՝ գտնելու ձեր իրական ենթադոմեյնը / թղթապանակի անունը, ապա ` cd ` այնտեղ: + +Այժմ դիտեք ձեր կոդի ներբեռնումը: Եթե ​​ուզում եք ստուգել, ​​թե արդյոք այն տեղ է հասել, կարող եք անցնել ** "Files" («Ֆայլեր») էջը ** և ձեր կոդը դիտել PythonAnywhere- ում (վահանակի էջի ընտրացանկի կոճակից կարող եք հասնել PythonAnywhere- ի այլ էջերի): + +* Վերջապես, անցեք [ "Web" («Վեբ») էջ ](https://www.pythonanywhere.com/web_app_setup/) և սեղմեք ** Reload (Վերաբեռնում) ** ձեր վեբ հավելվածում: + +Ձեր թարմացումը պետք է ուղիղ եթերում լինի: Գնացեք և թարմացրեք ձեր կայքը զննարկչում: Փոփոխությունները պետք է տեսանելի լինեն: :) \ No newline at end of file diff --git a/hy/html/images/step1.png b/hy/html/images/step1.png new file mode 100644 index 00000000000..eb474aaeddd Binary files /dev/null and b/hy/html/images/step1.png differ diff --git a/hy/html/images/step3.png b/hy/html/images/step3.png new file mode 100644 index 00000000000..47ede3f9993 Binary files /dev/null and b/hy/html/images/step3.png differ diff --git a/hy/html/images/step4.png b/hy/html/images/step4.png new file mode 100644 index 00000000000..0e6b48ec4a5 Binary files /dev/null and b/hy/html/images/step4.png differ diff --git a/hy/html/images/step6.png b/hy/html/images/step6.png new file mode 100644 index 00000000000..f044389de53 Binary files /dev/null and b/hy/html/images/step6.png differ diff --git a/hy/images/application.png b/hy/images/application.png new file mode 100644 index 00000000000..79071fe8d1b Binary files /dev/null and b/hy/images/application.png differ diff --git a/hy/installation/README.md b/hy/installation/README.md new file mode 100644 index 00000000000..b33b29d26bb --- /dev/null +++ b/hy/installation/README.md @@ -0,0 +1,69 @@ +# Եթե ​​ձեռնարկը տանը եք անում + +Եթե ​​դուք աշխատում եք ձեռնարկի վրա տանը, այլ ոչ թե [Django Girls- ի միջոցառումներից մեկում](https://djangogirls.org/events/), այժմ կարող եք ամբողջությամբ բաց թողնել այս գլուխը և անցնել անմիջապես [Ինչպես է աշխատում ինտերնետը](../how_the_internet_works/README.md) գլուխ + +Դա պայմանավորված է նրանով, որ մենք լուսաբանում ենք բաների տեղադրումը, քանի որ դրանք անհրաժեշտ են ձեռնարկի մեջ. Սա պարզապես լրացուցիչ էջ է, որը հավաքում է տեղադրման բոլոր հրահանգները մեկ տեղում (ինչը օգտակար է որոշ սեմինարների ձևաչափերի համար): Եթե ցանկանում եք, կարող եք ընտրել այն ամենը, ինչ կա այս էջում: Բայց եթե ցանկանում եք սկսել բաներ սովորել նախքան ձեր համակարգչում մի շարք իրեր տեղադրելը, բաց թողեք այս գլուխը և մենք ձեզ հետագայում կբացատրենք տեղադրման մասերը, երբ դրանք անհրաժեշտ լինեն: + +Հաջողություն! + +# Եթե ​​սեմինարի եք մասնակցում + +Եթե ​​մասնակցում եք [Django Girls- ի միջոցառումներից մեկին](https://djangogirls.org/events/): + +* Ձեր սեմինարը կարող է ունենալ «տեղադրման երեկույթ»: Եթե ​​դուք տեղադրման երեկույթի եք, այս էջը ձեզ համար է: Հետևեք այստեղ տրված հրահանգներին ՝ ստանալու այն ամենը, ինչ անհրաժեշտ սեմինարը տեղադրելու համար, և անհրաժեշտության դեպքում դիմեք մարզիչների օգնությունը: Այնուհետև հիմնական սեմինարում կարող եք բաց թողնել տեղադրման հրահանգները. Դուք կստանաք դրանք նաև հիմնական ձեռնարկում: +* Գուցե ձեր սեմինարի կազմակերպիչները խնդրել են ձեզ նախքան սեմինարը սկսելը, փորձել տանը ` ամեն ինչ տեղադրել ձեր համակարգչում: Եթե ​​ձեզանից խնդրեցին դա անել, այս էջը ձեզ համար է: Հնարավորինս լավ հետեւեք այստեղ տրված հրահանգներին: Այնուհետև հիմնական սեմինարում, երբ դուք ստանում եք հիմնական ձեռնարկի տեղադրման քայլերը, եթե չկարողացաք տեղադրել որոշ էլեմենտներ, ապա կարող եք օգնություն ստանալ ձեր մարզչից: +* Եթե ​​ձեր արհեստանոցը չի կազմակերպում «տեղադրման երեկույթ» (կամ դուք ի վիճակի չէիք ներկա գտնվել), և եթե կազմակերպիչները ձեզ չեն խնդրել տեղադրել ամեն ինչ նախքան ժամանելը. բաց թողեք այս էջը և անմիջապես անցեք [How the Internet works/ Ինտերնետի աշխատանք ](../how_the_internet_works/README.md) գլուխը: Ձեռնարկի միջոցով աշխատելու ընթացքում դուք կտեղադրեք այն ամենը, ինչ ձեզ հարկավոր է: + +# Installation (Տեղադրում) + +Այս ձեռնարկում դուք բլոգ կստեղծեք: Դա անելու համար ձեռնարկի ընթացքում ձեզ հանձնարարվելու է տարբեր ծրագրեր տեղադրել ձեր համակարգչում և անհրաժեշտության դեպքում կարգավորել որոշ առցանց հաշիվներ: Այս էջը պարունակում է տեղադրման և գրանցման բոլոր հրահանգները (ինչը օգտակար է սեմինարի որոշ ձևաչափերի համար): + + {% include "/chromebook_setup/instructions.md" %} + + + +# Հրամանի տողի/ command line հակիրճ նկարագրություն {#command-line} + +Ստորև նշված քայլերից շատերը վերաբերում են "console"-ին, «տերմինալին»/"terminal", «հրամանի պատուհանին»"command window" կամ «հրամանի տողին»/ "command line" . Սրանք բոլորը նույն բանն են նշանակում. Ձեր համակարգչի վրա պատուհան, որտեղ կարող եք մուտքագրել հրամաններ: Երբ հասնեք հիմնական ձեռնարկին, դուք ավելին կսովորեք հրամանի տողի մասին: Այժմ հիմնական բանը, որ դուք պետք է իմանաք, այն է, թե ինչպես բացել հրամանի պատուհան և ինչպիսի տեսք ունի այն: +{% include "/intro_to_command_line/open_instructions.md" %} + +# Տեղադրեք Python- ը {#python} + +{% include "/python_installation/instructions.md" %} + +# Տեղադրեք կոդերի խմբագիր/code editor {#code-editor} + +{% include "/code_editor/instructions.md" %} + +# Կարգավորեք virtualenv- ը և տեղադրեք Django- ն {#virtualenv} + +{% include "/django_installation/instructions.md" %} + +# Տեղադրեք Git- ը {#git} + +{% include "/deploy/install_git.md" %} + +# Ստեղծեք GitHub հաշիվ/GitHub account {#github-account} + +Գնացեք [GitHub.com](https://www.github.com) և գրանցվեք նոր անվճար հաշվի համար: Համոզվեք, որ կհիշեք ձեր գաղտնաբառը (եթե այն օգտագործում եք, ավելացրեք գաղտնաբառերի կառավարչին): + +# Ստեղծեք PythonAnywhere հաշիվ {#pythonanywhere-account} + +{% include "/deploy/signup_pythonanywhere.md" %} + +# Սկսեք կարդալ + +Շնորհավորում եմ, ամեն ինչ պատրաստ է: Եթե ​​սեմինարին դեռ ազատ ժամանակ է մնացել, օգտակար կլինի կարդալ առաջին մի քանի գլուխները. + +* [Ինչպես է աշխատում ինտերնետը](../how_the_internet_works/README.md) + +* [ Command line-ի (Հրամանի տողի) ներածություն](../intro_to_command_line/README.md) + +* [ Python-ի ներածություն/ Introduction to Python](../python_introduction/README.md) + +* [Ի՞նչ է Django- ն](../django/README.md) + +# Վայելեք սեմինարը: + +Երբ սեմինարը սկսվի, դուք կկարողանաք անմիջապես անցնել [Your first Django project! /ձեր Առաջին Django նախագիծը](../django_start_project/README.md) գլխին: diff --git a/hy/intro_to_command_line/README.md b/hy/intro_to_command_line/README.md new file mode 100644 index 00000000000..6cd46c75e2e --- /dev/null +++ b/hy/intro_to_command_line/README.md @@ -0,0 +1,441 @@ +# Հրամանի տողի ինտերֆեյսի /command-line interface ներածություն + +> Նրանց համար, ովքեր ձեռնարկն անցնում են տանը. Ձեր նոր ընկերը ՝ [հրամանի տողը/ Command Line](https://www.youtube.com/watch?v=jvZLWhkzX-8), խոսում է այս գլխի նյութի մասին: + +Ցնցող է, չէ՞:Մի քանի րոպեից դուք կգրեք ձեր առաջին տողի ծածկագիրը: :) + +**Թույլ տվեք ներկայացնել ձեր առաջին նոր ընկերոջը. Հրամանի տող/command line:** + +Հաջորդ քայլերը ցույց կտան, թե ինչպես օգտագործել այն սև պատուհանը, որն օգտագործում են բոլոր հակերները: Սկզբում դա կարող է թվալ մի փոքր վախեցնող, բայց իրականում դա պարզապես պատուհան է, որը սպասում է ձեզանից հրահանգների: + +> **Նշում** Խնդրում ենք նկատի ունենալ, որ այս ձեռնարկում մենք օգտագործում ենք «գրացուցակ/'directory'» և «թղթապանակ/'folder'» տերմինները փոխադարձաբար. Այս բառերը միևնույն բանն են նշանակում: + +## Ի՞նչ է հրամանի տողը/command line: + +Պատուհանը, որը սովորաբար անվանում են **Հրամանի տող/ command line** կամ **«Հրամանի տողի միջերես»/command-line interface (CLI)** , տեքստի վրա հիմնված ծրագիր է ՝ ձեր համակարգչի վրա ֆայլերը դիտելու, մշակելու և շահարկելու համար: Դա անում է նույնը, ինչ Explorer- ը Windows- ում կամ Finder- ը macOS- ում, բայց այն չունի գրաֆիկական ինտերֆեյս: Հրամանի տողի այլ անուններն են ՝ *cmd*, *CLI*, *prompt*, *console* կամ *terminal*: + +## Բացեք հրամանի տողի միջերեսը/command-line interface + +Որոշ փորձեր սկսելու համար նախ պետք է բացենք հրամանի տողի միջերեսը/command-line interface: + +{% include "/intro_to_command_line/open_instructions.md" %} + +## Հուշում + +Այժմ դուք պետք է տեսնեք սպիտակ կամ սև պատուհան, որը սպասում է ձեր հրամաններին: + + + +Եթե ​​ունեք Mac կամ Linux, ամենայն հավանականությամբ տողի վերջում կտեսնեք այս `$` նշանը. + +{% filename %}command-line{% endfilename %} + + $ + + + + + + +Windows- ում, հավանաբար, տեսնում եք այս `>` նշանը. + +{% filename %}command-line{% endfilename %} + + > + + +Մի փոքր վերևում կարող եք աչքի անցկացնել Linux- ի օգտագործողների հրահանգները. Մենք նման բան կտեսնենք, երբ հասնենք ձեռնարկի PythonAnyplace- ին: + + + +Յուրաքանչյուր հրամանին նախորդելու է `$` կամ `>` նշանը և տարածությունը/space: Բայց ձեզ հարկավոր չէ դրանք տպել: Համակարգիչը դա կանի ձեր փոխարեն :) + +> Մի փոքր հուշում. Նման մի բան կարող է գրվել հրամանի տողի կուրսորի դիմաց `C:\Users\ola>` կամ `Olas-MacBook-Air:~ ola$` և դա 100% -ով նորմալ է: + +Ցանկացած հատված, ներառյալ այս `$` կամ այս `>` նշանները, հավաքականորեն կոչվում է *command line prompt/հրամանի տող հուշում * կամ ուղղակի *prompt/հուշում* : Սովորաբար, այն պարունակում է այն թղթապանակի հասցեն, որի մեջ դուք այժմ գտնվում եք: Այն հուշում է ձեզ հրաման մուտքագրել պատուհանի մեջ: + +Հետագայում ձեռնարկում, յուրաքանչյուր հրամանից առաջ, որը դուք պետք է մուտքագրեք, մենք կգրենք `$` կամ `>` խորհրդանիշ: Երբեմն դրա ձախ կողմում կավելացնենք ևս մի քանի տեքստ: Անտեսեք ձախ կողմը և պարզապես մուտքագրեք հրահանգը. Այն սկսվում է հուշումից հետո: + +## Ձեր առաջին հրամանը (YAY!) + +Սկսենք մուտքագրել այս հրամանը. + + + +{% filename %}command-line{% endfilename %} + + $ whoami + + + + + + +{% filename %}command-line{% endfilename %} + + > whoami + + + + +Եվ ապա սեղմեք `enter`: Սա է մեր արդյունքը. + +{% filename %}command-line{% endfilename %} + + $ whoami + olasitarska + + +Ինչպես տեսնում եք, համակարգիչը նոր է տպել ձեր օգտվողի անունը: Կոկիկ է, այնպես չէ՞: :) + +> Փորձեք մուտքագրել յուրաքանչյուր հրաման ձեռքով, այլ ոչ թե պատճենել և տեղադրել: Այսպիսով, դուք ավելի լավ կհիշեք: + +## Հիմունքներ + +Յուրաքանչյուր գործավար համակարգ ունի հրամանի տողի մի փոքր այլ հրամանների հավաքածու, այնպես որ համոզվեք, որ հետևում եք ձեր օպերացիոն համակարգի հրահանգներին: Փորձե՞նք սա: + +### Ընթացիկ գրացուցակ/Current directory + +Ցանկալի կլիներ իմանալ, թե որտեղ ենք մենք գտնվում, այնպես չէ՞: Եկեք տեսնենք: Մուտքագրեք այս հրամանը և սեղմեք `enter`. + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska + + +> Նշում. «Pwd» նշանակում է «տպել աշխատանքային գրացուցակ»/'print working directory: + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska + + +> Նշում. «Cd» նշանակում է «փոփոխել գրացուցակը»/'change directory': PowerShell- ի միջոցով դուք կարող եք օգտագործել pwd այնպես, ինչպես Linux- ում կամ macOS- ում: + + + +Նման բան, հավանաբար, ձեր համակարգչում կտեսնեք: Հրամանի տող/command line բացելիս սովորաբար գտնվում եք ընթացիկ օգտվողի տնային գրացուցակում/user's home directory: + +* * * + +### Իմացիր ավելին հրամանի/command մասին + +Հրամանի տողի շատ հրամաններ ներկառուցված օգնություն ունեն: Օրինակ ՝ ահա, թե ինչպես կարելի է ավելին իմանալ հրամանի մասին, որը ցույց է տալիս, թե որ թղթապանակում եք գտնվում ներկայումս. + + + +macOS- ը և Linux- ը ունեն `man` հրաման, որը ձեզ օգնում է հրամանների հարցում: Փորձեք `man pwd` -ը և տեսեք, թե ինչ է ասում, կամ `man` հրամանը այլ հրամանների առաջ դրեք, որպեսզի տեսնեք նրանց օգնությունը: Սովորաբար, `man`-ի էջերը ցուցադրվում են էջ առ էջ: Օգտագործեք space bar հաջորդ էջին անցնելու համար, և ` q ` - ը `օգնությունից դուրս գալու համար: + + + + + +Օգնություն ցուցադրելու համար գրեթե ցանկացած հրամանին կարող եք ավելացնել ` /? `: Գուցե հարկ լինի ոլորել ներքև ՝ ամբողջ Օգնությունը կարդալու համար: Փորձեք մուտքագրել `cd /?`: + + + +### Նշեք ֆայլերը և գրացուցակները/directories + +Այսպիսով ի՞նչ կա դրա մեջ: Լավ կլինի պարզել դա: Տեսնենք. + + + +{% filename %}command-line{% endfilename %} + + $ ls + Applications + Desktop + Downloads + Music + ... + + + + + + +{% filename %}command-line{% endfilename %} + + > dir + Directory of C:\Users\olasitarska + 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- ում և macOS- ում: + +* * * + +### Փոխել ընթացիկ գրացուցակը/current directory + +Հիմա եկեք գնանք մեր աշխատասեղանի գրացուցակին/Desktop directory. + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + +Նկատի ունեցեք, որ գրացուցակի անունը «Desktop» կարող է թարգմանվել ձեր Linux հաշվի լեզվով: Եթե ​​դա այդպես է, դուք պետք է `Desktop` փոխարինեք թարգմանված անունով. օրինակ ՝ `Schreibtisch` գերմաներենի համար: + + + + + +{% filename %}command-line{% endfilename %} + + > cd Desktop + + + + +Ստուգեք, արդյոք այն իսկապես փոխվել է. + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + + +Ահա այն! + +> PRO հուշում. Եթե ձեր ստեղնաշարի վրա մուտքագրեք ` cd D ` և այնուհետև սեղմեք ` tab (էջանիշը/ներդիրը) `, command line (հրամանի տողը) ավտոմատ կերպով լրացնում է անվան մնացած մասը, որպեսզի կարողանաք ավելի արագ նավարկել Եթե ​​«D» - ով սկսվող մեկից ավելի պանակներ կան, երկու անգամ սեղմեք ` tab (ներդիրը )` ստեղնին `ընտրանքների ցուցակ ստանալու համար: + +* * * + +### Ստեղծեք գրացուցակ + +Ի՞նչ կասեք ձեր աշխատասեղանի վրա պրակտիկ գրացուցակ ստեղծելու մասին: Դուք կարող եք դա անել այս կերպ. + + + +{% filename %}command-line{% endfilename %} + + $ mkdir practice + + + + + + +{% filename %}command-line{% endfilename %} + + > mkdir practice + + + + +Այս փոքրիկ հրահանգը կստեղծի ձեր աշխատասեղանի վրա `practice` անունով պանակ: Կարող եք ստուգել, ​​արդյոք այնտեղ կա ՝ նայելով ձեր աշխատասեղանին կամ գործարկելով `ls` կամ `dir` հրամանը: Փորձիր. :) + +> PRO հուշում. Եթե չեք ցանկանում անընդմեջ մուտքագրել նույն հրամանները, փորձեք սեղմել `վերին սլաքը/up arrow` և `ներքևի սլաքը/ down arrow` ձեր ստեղնաշարի վրա, որպեսզի շրջանցեք վերջերս օգտագործված հրամանները: + +* * * + +### Վարժություն + +Մի փոքր առաջադրանք. Նորաստեղծ `practice/պրակտիկայի` թղթապանակում ստեղծեք պանակ, որը կոչվում է `test`: (Օգտագործեք `cd` և `mkdir` հրահանգները): + +#### Լուծում. + + + +{% filename %}command-line{% endfilename %} + + $ cd practice + $ mkdir test + $ ls + test + + + + + + +{% filename %}command-line{% endfilename %} + + > cd practice + > mkdir test + > dir + 05/08/2020 07:28 PM test + + + + +Շնորհավորում ենք։ + +* * * + +### Մաքրել + +Մենք չենք ուզում խառնաշփոթ թողնել, ուստի եկեք ջնջենք այն ամենը, ինչ ստեղծել ենք մինչև այս պահը: + +Նախ, մենք պետք է վերադառնանք Desktop / աշխատասեղան. + + + +{% filename %}command-line{% endfilename %} + + $ cd .. + + + + + + +{% filename %}command-line{% endfilename %} + + > cd .. + + + + +Օգտագործելով ` .. `-ի և ` cd ` - ի հրամանները միասին դուք կարող եք փոխել ընթացիկ գրացուցակը/current directory ծնող գրացուցակի/parent directory (այսինքն ՝ գրացուցակը, որը պարունակում է ձեր ընթացիկ գրացուցակը) + +Ստուգեք, թե որտեղ եք դուք ՝ + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + + +Հիմա ժամանակն է ջնջել `practice` գրացուցակը. + +> ** Ուշադրություն **. `del`, `rmdir` կամ `rm`ֆայլերը ջնջելը անվերադարձ է, այսինքն ՝ *ջնջված ֆայլերը կվերանան ընդմիշտ*!: Այսպիսով, շատ զգույշ եղեք այս հրամանի հետ: + + + +{% filename %}command-line{% endfilename %} + + $ rm -r practice + + + + + + +{% filename %}command-line{% endfilename %} + + > rmdir /S practice + practice, Are you sure ? Y + + + + +Կատարած է! Համոզված լինելու համար, որ այն իրականում ջնջված է, եկեք ստուգենք այն. + + + +{% filename %}command-line{% endfilename %} + + $ ls + + + + + + +{% filename %}command-line{% endfilename %} + + > dir + + + + +### Ելք + +Առայժմ վերջ: Այժմ կարող եք ապահով կերպով փակել հրամանի տողը: Եկեք դա անենք հակերային եղանակով, լա՞վ: :) + + + +{% filename %}command-line{% endfilename %} + + $ exit + + + + + + +{% filename %}command-line{% endfilename %} + + > exit + + + + +Հերիք է, հա՞: :) + +## Ամփոփում + +Ահա մի քանի օգտակար հրամանների ամփոփ նկարագրություն. + +| Command (Windows) | Command (Mac OS / Linux) | Description | Example | +| ----------------- | ------------------------ | -------------------------- | -------------------------------------------------- | +| exit | exit | close the window | **exit** | +| cd | cd | change directory | **cd test** | +| cd | pwd | show the current directory | **cd** (Windows) or **pwd** (Mac OS / Linux) | +| dir | ls | list directories/files | **dir** | +| copy | cp | copy file | **copy c:\test\test.txt c:\windows\test.txt** | +| move | mv | move file | **move c:\test\test.txt c:\windows\test.txt** | +| mkdir | mkdir | create a new directory | **mkdir testdirectory** | +| rmdir (or del) | rm | delete a file | **del c:\test\test.txt** | +| rmdir /S | rm -r | delete a directory | **rm -r testdirectory** | +| [CMD] /? | man [CMD] | get help for a command | **cd /?** (Windows) or **man cd** (Mac OS / Linux) | + +Սրանք ընդամենը հրամաններից մի քանիսն են, որոնք կարող եք գործարկել ձեր հրամանի տողում/command line, բայց այսօր դրանից ավելին չեք օգտագործելու: + +Եթե ​​ձեզ հետաքրքրում է, [ss64.com](http://ss64.com) - ը պարունակում է հրամանի ամբողջական հղում բոլոր օպերացիոն համակարգերի համար: + +## Պատրա՞ստ եք + +Եկեք խորասուզվենք Python- ի մեջ: \ No newline at end of file diff --git a/hy/intro_to_command_line/open_instructions.md b/hy/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..c7d883218f4 --- /dev/null +++ b/hy/intro_to_command_line/open_instructions.md @@ -0,0 +1,29 @@ + + + +Կախված Windows- ի ձեր տարբերակից և ստեղնաշարից, հետևյալներից որևէ մեկը պետք է հրամանի պատուհան բացի (գուցե մի քիչ փորձեր կատարեք, բայց բոլոր տարբերակները փորձելու կարիք չկա). + +- Գնացեք Սկսել /Start բաժին ընտրացանկից (կամ Start էկրանից), և որոնման տողում մուտքագրեք «Command Prompt»: +- Անցեք Սկսելու ցանկը/Start menu→Windows System → Command Prompt/ հրամանի տող: +- Անցեք Start menu /Սկսելու ցանկը → All Programs / Բոլոր ծրագրերը → Accessories/Աքսեսուարներ → Command Prompt /Հրամանի տող: +- Անցեք Start screen, ձեր մկնիկը տարեք էկրանի ստորին ձախ անկյունի վրա և կտտացրեք այնտեղ հայտնվող դեպի ներքև ուղված սլաքին: (Եթե ունեք սենսորային էկրան, մատը սահեցրեք ներքևից վերև): Հավելվածների էջը պետք է բացվի: Windows համակարգի բաժնում/Windows System section ընտրեք Command Prompt-ը/ հրամանի տողը: +- Ձեր ստեղնաշարի վրա սեղմած պահելով Windows ստեղնը սեղմեք X: Հայտնվող ընտրացանկում ընտրեք «Command Prompt/Հրամանի տող»-ը: +- Ձեր ստեղնաշարի վրա սեղմած պահելով Windows ստեղնը սեղմեք "R" ՝ Run պատուհանը վեր հանելու համար: Տողում մուտքագրեք "cmd" և կտտացրեք OK: + +![Մուտքագրեք "cmd" "Run" պատուհանում](../python_installation/images/windows-plus-r.png) + +Ավելի ուշ այս ձեռնարկի շրջանակներոըմ ձեզ հարկավոր է լինելու ունենալ միևնույն ժամանակ երկու բաց հրամանի պատուհան: Այնուամենայնիվ, Windows- ի որոշ տարբերակների դեպքում, եթե դուք արդեն ունեք մեկ բաց հրամանի պատուհան/command window և փորձում եք բացել երկրորդը նույն մեթոդով, այն ձեզ կուղարկի դեպի արդեն բացված հրամանի պատուհանը: Փորձեք դա ձեր համակարգչի վրա և տեսեք, թե ինչ է կատարվում: Եթե ​​միայն մեկ հրամանի պատուհան եք ստանում, փորձեք վերը նշված ցուցակի մյուս մեթոդներից որևէ մեկը: Դրանցից գոնե մեկը պետք է հանգեցնի նոր հրամանի պատուհանի բացմանը: + + + + + +Գնացեք Applications → Utilities/Կոմունալ ծառայություններ → Terminal /Տերմինալ: + + + + + +Հրամանի տողը, հավանաբար, թաքնված է հետևյալում ՝ Applications → Accessories → Terminal, or Applications → System → Terminal, բայց դա կարող է կախված լինել ձեր համակարգից: Եթե ​​չկարողանաք գտնել, Google- ը կօգնի: :) + + diff --git a/hy/python_installation/README.md b/hy/python_installation/README.md new file mode 100644 index 00000000000..34cd91728f5 --- /dev/null +++ b/hy/python_installation/README.md @@ -0,0 +1,15 @@ +# Եկեք սկսենք Python- ից + +Վերջապես մենք այստեղ ենք: + +Բայց նախ ասենք, թե ինչ է Python- ը: Python- ը շատ սիրված ծրագրավորման լեզու է, որը կարող է օգտագործվել կայքեր, խաղեր, գիտական ​​ծրագրեր, գրաֆիկա և շատ ավելին ստեղծելու համար: + +Python- ն առաջացել է 1980-ականների վերջին, և դրա հիմնական նպատակն է ընթեռնելի լինել մարդկանց կողմից (ոչ միայն մեքենաների): Ահա թե ինչու այն ավելի պարզ թվում, քան ծրագրավորման այլ լեզուները, բայց մի անհանգստացեք. Python-ը իսկապես հզոր է: + +# Python- ի տեղադրում + +> **Նշում** Եթե Chromebook եք օգտագործում, բաց թողեք այս գլուխը և համոզվեք, որ հետևում եք [Chromebook Setup/Chromebook- ի կարգավորման](../chromebook_setup/README.md) հրահանգներին: +> +> **Նշում** Եթե դուք արդեն ավարտել եք տեղադրումը, ապա այլևս դա անելու կարիք չկա. Դուք կարող եք անմիջապես անցնել հաջորդ գլխին: + +{% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/hy/python_installation/images/python-installation-options.png b/hy/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..a0a6c65d81d Binary files /dev/null and b/hy/python_installation/images/python-installation-options.png differ diff --git a/hy/python_installation/images/windows-plus-r.png b/hy/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/hy/python_installation/images/windows-plus-r.png differ diff --git a/hy/python_installation/instructions.md b/hy/python_installation/instructions.md new file mode 100644 index 00000000000..019e179c4fe --- /dev/null +++ b/hy/python_installation/instructions.md @@ -0,0 +1,118 @@ +> Ընթերցողների համար տանը. Այս գլուխն ընդգրկված է [ Installing Python & Code Editor ](https://www.youtube.com/watch?v=pVTaqzKZCdA) տեսանյութ: +> +> Այս բաժինը հիմնված է Geek Girls Carrots- ի ձեռնարկի վրա (https://github.com/ggcarrots/django-carrots) + +Django- ն գրված է Python- ում: Մեզ պետք է Python- ը, որպեսզի Django- ում ինչ-որ բան անի: Եկեք սկսենք տեղադրելով այն: Մենք ուզում ենք, որ դուք տեղադրեք Python 3-ի վերջին տարբերակը, այնպես որ, եթե ունեք ավելի վաղ տարբերակ, ապա ձեզ հարկավոր է արդիականացնել այն: Եթե ​​արդեն ունեք {{ book.py_min_version }} կամ ավելի բարձր տարբերակ, ապա լավ կլինի: + +Խնդրում ենք տեղադրել սովորական Python– ը հետևյալ կերպ, նույնիսկ այն ժամանակ, երբ ձեր համակարգչում տեղադրված է Anaconda: + + + +Նախ ստուգեք, արդյոք ձեր համակարգիչը 32-բիթանոց տարբերակ է կամ 64-բիթանոց Windows տարբերակ, Համակարգի տեղեկատվության էջի «Համակարգի տեսակ» տողում: Այս էջին հասնելու համար փորձեք այս մեթոդներից մեկը. + +* Միաժամանակ սեղմեք Windows կոճակը և Pause / Break կոճակը +* Բացեք ձեր կառավարման վահանակը Windows ընտրացանկից, ապա անցեք Համակարգ և & amp; Անվտանգություն, ապա ՝ Համակարգ +* Սեղմեք Windows կոճակը, ապա անցեք Settings > System > About (Կարգավորումներ> Համակարգ> Մեր մասին) +* Որոնեք Windows Start ընտրացանկում "System Information" («Համակարգի տեղեկատվություն») բաժնում: Դա անելու համար կտտացրեք Start կոճակին կամ սեղմեք Windows ստեղնը, ապա սկսեք մուտքագրել ` System Information `: Այն մուտքագրելուն պես կսկսի առաջարկություններ անել: Դուք կարող եք ընտրել առաջարկը, երբ այն հայտնվի: + +Python- ը Windows- ի համար կարող եք ներբեռնել https://www.python.org/downloads/windows/ կայքից: Կտտացրեք «Վերջին Python 3 թողարկում - Python x.x.x» հղմանը: Եթե ​​ձեր համակարգիչը աշխատում է Windows- ի ** 64-բիթանոց ** տարբերակով, ներբեռնեք ** Windows x86-64 գործարկվող տեղադրիչը **: Հակառակ դեպքում ներբեռնեք ** Windows x86 գործարկվող տեղադրիչը **: Տեղադրիչը ներբեռնելուց հետո դուք պետք է այն գործարկեք (կրկնակի սեղմեք դրա վրա) և հետևեք այնտեղ տրված հրահանգներին: + +Մի բան, որին պետք է զգույշ լինել. Տեղադրման ընթացքում դուք կնկատեք "Setup"(«Կարգավորում») նշվող պատուհանը: Համոզվեք, որ նշեք «Ավելացնել Python {{book.py_version}} - ը PATH» - ին կամ «Python ավելացնել ձեր միջավայրի փոփոխականներին» վանդակը և կտտացրեք «Տեղադրել հիմա» -ին, ինչպես ցույց է տրված այստեղ (կարող է մի փոքր այլ տեսք ունենալ, եթե տեղադրեք այլ տարբերակ): + +![ +Մի մոռացեք Python- ին ավելացնել Path- ին](../python_installation/images/python-installation-options.png) + +Տեղադրումն ավարտելուց հետո դուք կարող եք տեսնել երկխոսության տուփ հղումով, որին կարող եք հետևել Python- ի կամ ձեր տեղադրած տարբերակի մասին ավելին իմանալու համար: Փակեք կամ չեղարկեք այդ երկխոսությունը. Այս ձեռնարկում դուք ավելին կսովորեք: + +Նշում. Եթե օգտագործում եք Windows- ի (7, Vista կամ որևէ հին տարբերակ) ավելի հին տարբերակ, և Python- ի {{ book.py_version }} տեղադրիչը սխալմամբ ձախողվեց, ապա տեղադրեք բոլոր Windows Updates- ը և փորձեք նորից տեղադրել Python- ը: Եթե ​​դեռ սխալ ունեք, փորձեք տեղադրել Python տարբերակը {{ book.py_min_release }} [ Python.org ](https://www.python.org/downloads/windows/) կայքից: + +> Django- ին {{ book.django_version }} անհրաժեշտ է Python {{ book.django_version }} կամ ավելի մեծ, որը չի ապահովում Windows XP կամ ավելի վաղ տարբերակներ: + + + + + +> ** Նշում ** Նախքան Python- ը macOS- ում տեղադրելը, պետք է համոզվեք, որ ձեր Mac- ի կարգավորումները թույլ են տալիս տեղադրել փաթեթներ, որոնք App Store- ից չեն: Գնացեք համակարգի նախապատվություններ, կտտացրեք "Security & Privacy," , ապա "General" («Ընդհանուր»)ներդիրին: Եթե ​​ձեր «Allow apps downloaded from:» դրված է որպես «Mac App Store,», ապա այն փոխեք «Mac App Store and identified developers.»: + +Դուք պետք է գնաք https://www.python.org/downloads/ կայք և ներբեռնեք Python- ի վերջին տեղադրիչը. + +* Ներբեռնեք * macOS 64-բիթ / 32-բիթանոց տեղադրիչ * ֆայլը, +* Տեղադրիչը գործարկելու համար կրկնակի կտտացրեք * պիթոն - {{ book.py_release }} - macos11.pkg *: + + + + + +Շատ հավանական է, որ Python- ն արդեն տեղադրված է տուփից դուրս: Ստուգելու համար, արդյոք այն տեղադրված է (և որ տարբերակն է), բացեք վահանակ և մուտքագրեք հետևյալ հրահանգը. + +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python {{ book.py_release }} + + +Եթե ​​Python- ի այլ տարբերակ ունեք տեղադրված, առնվազն {{ book.py_min_version }} (օրինակ ՝ {{ book.py_min_release }}), ապա ձեզ հարկավոր չէ արդիականացնել: Եթե ​​Python- ը տեղադրված չէ, կամ եթե այլ տարբերակ եք ուզում, նախ ստուգեք, թե Linux- ի ո՞ր բաշխումն եք օգտագործում հետևյալ հրահանգով. + +{% filename %}command-line{% endfilename %} + + $ grep '^NAME=' /etc/os-release + + +Դրանից հետո, կախված արդյունքից, հետևեք այս բաժնի ներքևում տեղադրված հետևյալ ուղեցույցներից մեկին: + + + + + +Մուտքագրեք այս հրամանը ձեր վահանակի մեջ. + +{% filename %}command-line{% endfilename %} + + $ sudo apt install python3 + + + + + + +Օգտագործեք այս հրամանը ձեր վահանակում. + +{% filename %}command-line{% endfilename %} + + $ sudo dnf install python3 + + +Եթե ​​Fedora- ի հին տարբերակներում եք, կարող է սխալվել, որ ` dnf ` հրամանը չի գտնվել: Այդ դեպքում փոխարենը պետք է օգտագործել ` yum `: + + + + + +Օգտագործեք այս հրամանը ձեր վահանակում. + +{% filename %}command-line{% endfilename %} + + $ sudo zypper install python3 + + + + +Հաստատեք, որ տեղադրումը հաջող է անցել ՝ հրամանի տող բացելով և գործարկելով ` python3 ` հրամանը. + +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python {{ book.py_release }} + + +Shownուցադրված տարբերակը կարող է տարբերվել {{ book.py_release }} - ից `այն պետք է համապատասխանի ձեր տեղադրած տարբերակին: + +**NOTE:** Եթե ​​Windows- ում եք և սխալ հաղորդագրություն եք ստանում, որ ` python3 ` չի գտնվել, փորձեք օգտագործել ` python ` (առանց ` 3 `) և ստուգեք եթե այն դեռ կարող է լինել Python- ի {{ book.py_min_version }} կամ ավելի բարձր տարբերակ: Եթե ​​դա նույնպես չի աշխատում, կարող եք բացել նոր հրամանի տող և նորից փորձել: դա տեղի է ունենում, եթե օգտագործում եք Python- ի տեղադրումից առաջ բացված հրամանի տողը: + +* * * + +Եթե ​​կասկածներ ունեք կամ ինչ-որ բան սխալ է տեղի ունեցել, և գաղափար չունեք հետագա անելիքների մասին, խնդրում ենք ձեր մարզչին հարցրեք: Երբեմն ամեն ինչ հարթ չի ընթանում, և ավելի լավ է օգնություն խնդրել ավելի մեծ փորձ ունեցող մեկից: \ No newline at end of file diff --git a/hy/python_introduction/README.md b/hy/python_introduction/README.md new file mode 100644 index 00000000000..4cada98e864 --- /dev/null +++ b/hy/python_introduction/README.md @@ -0,0 +1,1072 @@ +{% set warning_icon = '' %} + +# Ներածություն Python- ին + +> Այս գլխի մի մասը հիմնված է Geek Girls Carrots- ի (https://github.com/ggcarrots/django-carrots) ձեռնարկների վրա: + +Եկեք գրենք մի քանի ծրագրեր: + +## Python prompt (կահակալ) + +> Ընթերցողների համար տանը. Այս մասը ներառված է [ Python Basics: Integers, Strings, Lists, Variables and Errors (Python- ի հիմունքներ. Ամբողջ թվեր, տողեր, ցուցակներ, փոփոխականներ և սխալներ) ](https://www.youtube.com/watch?v=MO63L4s-20U) տեսանյութում: + +Python- ի հետ խաղալու համար մենք պետք է ձեր համակարգչում բացենք * command line (հրամանի տող)*: Դուք արդեն պետք է իմանաք, թե ինչպես դա անել. Դուք դա սովորել եք [ Intro to Command Line (Հրամանի տողի ներածություն) ](../intro_to_command_line/README.md) գլխում: + +Պատրաստ լինելուց հետո հետևեք ստորև ներկայացված հրահանգներին: + +Մենք ուզում ենք Python կոնսոլ բացել, այնպես որ Windows- ում մուտքագրեք ` python ` կամ Mac OS / Linux համակարգում ` python3 ` և սեղմեք ` enter `: + +{% filename %}command-line{% endfilename %} + + $ python3 + Python {{ book.py_release }} (...) + Type "help", "copyright", "credits" or "license" for more information. + >>> + + +## Ձեր առաջին Python command-ը (հրամանը): + +Python հրամանը գործարկելուց հետո հուշումը փոխվեց `>>>`. Մեզ համար սա նշանակում է, որ առայժմ մենք կարող ենք օգտագործել միայն Python լեզվով հրամաններ: Պետք չէ մուտքագրել `>>>` - Python- ը դա կանի ձեզ համար: + +Եթե ​​ցանկանում եք ցանկացած պահի դուրս գալ Python- ի վահանակից, մուտքագրեք ` ելք () ` կամ օգտագործեք դյուրանցում ` Ctrl + Z ` Windows- ի և ` Ctrl + D ` Mac / Linux- ի համար: Այդ դեպքում `>>>`այլևս չեք տեսնի: + +Առայժմ մենք չենք ցանկանում դուրս գալ Python կոնսոլից: Մենք ուզում ենք ավելին իմանալ դրա մասին: Եկեք սկսենք մուտքագրել մի քանի մաթեմատիկա, ինչպիսին է ` 2 + 3 ` և սեղմելով ` մուտքագրումը `: + +{% filename %}command-line{% endfilename %} + +```python +>>> 2 + 3 +5 +``` + +Հոյակապ. Տեսեք, թե ինչպես հայտնվեց պատասխանը: Python- ը գիտի մաթեմատիկա: Կարող եք փորձել այլ հրամաններ, ինչպիսիք են ՝ + +- `4 * 5` +- `5 - 1` +- `40 / 2` + +Էքսպոնենտալ հաշվարկ կատարելու համար ասենք 2 հզորության 3-ը ՝ մենք մուտքագրում ենք. {% filename %}command-line (հրամանի տող){% endfilename %} + +```python +>>> 2 ** 3 +8 +``` + +Մի փոքր զվարճացեք դրանով, ապա վերադառնաք այստեղ :) + +Ինչպես տեսնում եք, Python- ը հիանալի հաշվիչ է: Եթե ​​մտածում եք, թե էլ ինչ կարող եք անել ... + +## Strings (տողեր) + +Ինչ վերաբերում է ձեր անունին: Մուտքագրեք ձեր անունը այսպիսի մեջբերումներում. + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" +'Ola' +``` + +Դուք այժմ ստեղծել եք ձեր առաջին string-ը (տողը): Դա նիշերի հաջորդականություն է, որը կարող է մշակվել համակարգչի կողմից: String-ը միշտ պետք է սկսվի և ավարտվի նույն նիշով: Սա կարող է լինել միայնակ (` '`) կամ կրկնակի (` "`) մեջբերումներ (տարբերություն չկա:) Գնանշումները Python- ին ասում են, որ իրենց մեջ եղածը string է: + +String-երը կարելի է միասին դնել: Փորձեք այս: + +{% filename %}command-line{% endfilename %} + +```python +>>> "Hi there " + "Ola" +'Hi there Ola' +``` + +Դուք կարող եք նաև բազմապատկել տողերը մի թվով. + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` + +Եթե ​​ձեզ հարկավոր է ապոստերֆ դնել ձեր string-ի ներսում, ապա դա անելու երկու եղանակ ունեք: + +Օգտագործելով կրկնակի գնանշումներ. + +{% filename %}command-line{% endfilename %} + +```python +>>> "Runnin' down the hill" +"Runnin' down the hill" +``` + +կամ հետադարձ աղեղից խուսափելուց (`\`): + +{% filename %}command-line{% endfilename %} + +```python +>>> 'Runnin\' down the hill' +"Runnin' down the hill" +``` + +Հետաքրքիր է, ոչ: Ձեր անունը մեծատառով տեսնելու համար մուտքագրեք ՝ + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola".upper() +'OLA' +``` + +Դուք հենց ձեր string-ի (տողի) վրա օգտագործեցիք ` upper(վերին) ` ** method(մեթոդը)**: Մեթոդը (ինչպիսին է ` upper() (վերին ()) `) հրահանգների հաջորդականությունն է, որը Python- ը պետք է կատարի տվյալ օբյեկտի վրա (` «Օլա» `), երբ այն զանգահարեք: + +Եթե ​​ուզում եք իմանալ ձեր անվան մեջ պարունակվող տառերի քանակը, դրա համար կա **function ( գործառույթ) **: + +{% filename %}command-line{% endfilename %} + +```python +>>> len("Ola") +3 +``` + +Հետաքրքիր է, թե ինչու եք երբեմն function-ներ (ֆունկցիաներ) կանչում a `.` String-ի (տողի) վերջում (ինչպես ` "Ola".upper() `) և երբեմն նախ կանչում ես ֆունկցիա և string-ը դնում փակագծերում: Դե, որոշ դեպքերում function-ները (ֆունկցիաները) պատկանում են object-ների (օբյեկտների), ինչպես, օրինակ, ` վերին () `, որը կարող է կատարվել միայն տողերի վրա: Այս դեպքում մենք function (ֆունկցիան) անվանում ենք ** method (մեթոդ) **: Այլ ֆունկցիաներ, գործառույթները չեն պատկանում որևէ կոնկրետ բանի և կարող են օգտագործվել տարբեր տեսակի օբյեկտների վրա, ինչպես ` len () `: Այդ պատճառով մենք`"Ola"` որպես պարամետր ենք տալիս `len` գֆունկցիաին: + +### Ամփոփում + +Լավ, բավական է string-եր: Մինչ այժմ իմացել եք. + +- ** prompt-ը** - Python- ի մեջ հրահանգներ (code / կոդ) մուտքագրելը Python- ում տալիս է պատասխաններ +- **numbers and strings (թվերն ու տողերը) ** - Python- ի համարներում օգտագործվում են մաթեմատիկայի համար, իսկ string-երը `տեքստային object- ների (օբյեկտների) համար +- ** operators (օպերատորները) ** - ինչպիսիք են ` + ` և ` * `, միավորում են արժեքները ՝ նորը արտադրելու համար +- ** function-ներ ** - ինչպես ` upper() ` և ` len() `, գործողություններ կատարել օբյեկտների վրա: + +Սրանք յուրաքանչյուր սովորած ծրագրավորման լեզվի հիմունքներն են: Պատրա՞ստ եք ավելի դժվար բանի: + +## Errors (Սխալներ) + +Փորձենք մի նոր բան: Կարո՞ղ ենք համարի երկարությունը ստանալ նույն կերպ, ինչպես կարող էինք պարզել մեր անվան երկարությունը: Մուտքագրեք ` len(304023) ` և սեղմեք ` enter `: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` + +Մենք ստացանք մեր առաջին սխալը: {{ warning_icon }} icon-ը (պատկերակը) ձեզ նախապատվություն տալու այն ձևն է, որ այն կոդը, որը պատրաստվում եք գործարկել, չի աշխատի ինչպես սպասվում էր: Սխալներ թույլ տալը (նույնիսկ դիտավորյալները) ուսման կարևոր մասն է: + +Այն ասում է, որ «int» տեսակի object-ները (օբյեկտները) (integers/ ամբողջ թվեր) երկարություն չունեն: Այսպիսով, ի՞նչ կարող ենք անել հիմա: Միգուցե կարո՞ղ ենք մեր թիվը գրել որպես string: String-երն ունեն length (երկարություն), չէ՞: + +{% filename %}command-line{% endfilename %} + +```python +>>> len(str(304023)) +6 +``` + +Դա աշխատեց! Մենք ` str ` գործառույթի ներսում օգտագործեցինք ` str() ` function-ը: ` str() ` ամեն ինչ վերածում է string-երի: + +- ` str ` function (ֆունկցիան) իրերը վերափոխում է ** string-երի ** +- ` int ` function (ֆունկցիան) իրերը վերափոխում է ** integers ** + +> Կարևոր. Մենք կարող ենք թվերը վերածել տեքստի, բայց պարտադիր չէ, որ տեքստը վերածենք թվերի. Ի՞նչ կլինի ամեն դեպքում `int('hello') `: + +## Variables (Փոփոխականներ) + +Mingրագրավորման կարևոր հայեցակարգը variable- ներն (փոփոխականներն) են: Varaible-ը (Փոփոխականը) ոչ այլ ինչ է, քան ինչ-որ բանի անուն, այնպես որ այն հետագայում կարող եք օգտագործել: ծրագրավորողներ օգտագործում են այս փոփոխականները տվյալներ պահելու, իրենց կոդերն ավելի ընթեռնելի դարձնելու համար և ստիպված չեն անընդհատ հիշել, թե ինչ բաներ են: + +Ասենք, որ ուզում ենք ստեղծել նոր variable (փոփոխական), որը կոչվում է ` name (անուն) `: + +{% filename %}command-line{% endfilename %} + +```python +>>> name = "Ola" +``` + +Մենք մուտքագրում ենք name-ը (անունը) հավասար է Ola: + +Ինչպես նկատել եք, ձեր ծրագիրը չի վերադարձրել այլ բան, ինչպես նախկինում էր: Այսպիսով, ինչպե՞ս իմանանք, որ variable-ն (փոփոխականն) իրականում գոյություն ունի: Մուտքագրեք ` name (անունը) ` և սեղմեք ` enter (մուտքագրեք) ` + +{% filename %}command-line{% endfilename %} + +```python +>>> name +'Ola' +``` + +Ձեր առաջին variable-ը փոփոխականը! :) Դուք միշտ կարող եք փոխել այն, ինչին վերաբերում է. + +{% filename %}command-line{% endfilename %} + +```python +>>> name = "Sonja" +>>> name +'Sonja' +``` + +Այն կարող եք օգտագործել նաև function-ներում. + +{% filename %}command-line{% endfilename %} + +```python +>>> len(name) +5 +``` + +Հիանալի է, չէ՞: Այժմ variable-ները (փոփոխականները )կարող են լինել ցանկացած ՝ թվեր նույնպես: Փորձեք այս: + +{% filename %}command-line{% endfilename %} + +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` + +Բայց ի՞նչ կլինի, եթե մենք սխալ անուն օգտագործենք: Կարո՞ղ եք գուշակել, թե ինչ կլինի: Արի փորձենք! + +{% 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 +``` + +Սխալ! Ինչպես տեսնում եք, Python- ն ունի տարբեր տեսակի սխալներ, և այս մեկը կոչվում է ** NameError **: Python- ը ձեզ կտա այս սխալը, եթե փորձեք օգտագործել դեռ չսահմանված variable (փոփոխական): Եթե ​​ավելի ուշ այս սխալի եք բախվել, ստուգեք ձեր կոդը ՝ ստուգելու համար, արդյոք սխալ եք մուտքագրել որևէ անուն: + +Մի փոքր խաղացեք սրա հետ և տեսեք, թե ինչ կարող եք անել: + +## Print function (Տպման գործառույթը) + +Փորձեք այս: + +{% filename %}command-line{% endfilename %} + +```python +>>> name = 'Maria' +>>> name +'Maria' +>>> print(name) +Maria +``` + +Երբ դուք պարզապես մուտքագրում եք ` name (անուն)`, Python- ի թարգմանիչը պատասխանում է 'name' variable (փոփոխական) string-ի (տող) * ներկայացմամբ* , որը M-a-r-i-a տառերն են, որոնք շրջապատված են մեկ չակերտով, ": Երբ ասում եք ` տպել (անունը) `, Python- ը "print"-կանի («կտպագրի») variable-ի պարունակությունը էկրանին ՝ առանց չակերտների, որը ավելի կոկիկ է: + +Ինչպես կտեսնենք ավելի ուշ, ` print () ` - ը օգտակար է նաև այն ժամանակ, երբ մենք ուզում ենք գործերը ներսից function-ներ տպել, կամ երբ ուզում ենք իրեր տպել բազմաթիվ տողերի վրա: + +## Lists (ցուցակները) + +String-երի և integer-ի (թվերի) հետ մեկտեղ Python- ն ունի ամենատարբեր տեսակի object-ներ (օբյեկտներ): Այժմ մենք պատրաստվում ենք ներկայացնել մեկը, որը կոչվում է ** list (ցուցակ) **: Ծուցակները հենց այն են, ինչ դուք կարծում եք. օբյեկտներ, որոնք այլ օբյեկտների ցուցակներ են: :) + +Գնացեք և ստեղծեք ցուցակ. + +{% filename %}command-line{% endfilename %} + +```python +>>> [] +[] +``` + +Այո, այս ցուցակը դատարկ է: Շատ օգտակար չէ, չէ՞: Եկեք ստեղծենք վիճակախաղի համարների ցուցակ: Մենք չենք ուզում անընդհատ կրկնվել, այնպես որ այն նաև կդնենք փոփոխականի մեջ. + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery = [3, 42, 12, 19, 30, 59] +``` + +Լավ, մենք ցուցակ ունենք: Ի՞նչ կարող ենք անել դրա հետ: Տեսնենք, թե վիճակախաղի քանի համար կա ցուցակում: Դուք գաղափար ունե՞ք, թե որ function (ֆունկցիան) պետք է օգտագործեք դրա համար: Դուք դա արդեն գիտեք: + +{% filename %}command-line{% endfilename %} + +```python +>>> len(lottery) +6 +``` + +Այո՛ ` len()` - ը կարող է ձեզ ցուցակում մի շարք օբյեկտներ տալ: Հարմար է, չէ՞: Միգուցե հիմա տեսակավորենք. + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.sort() +``` + +Սա ոչինչ չի վերադարձնում, պարզապես փոխեց ցուցակի թվերը հայտնվելու հերթականությունը: Եկեք նորից տպենք և տեսնենք, թե ինչ է տեղի ունեցել: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery) +[3, 12, 19, 30, 42, 59] +``` + +Ինչպես տեսնում եք, ձեր ցուցակի թվերն այժմ տեսակավորված են ամենացածրից բարձրագույն արժեքից: Շնորհավորանքներ + +Միգուցե մենք ուզում ենք հետ շրջե՞լ այդ կարգը: Արի անենք դա! + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.reverse() +>>> print(lottery) +[59, 42, 30, 19, 12, 3] +``` + +Եթե ցանկանում եք ինչ-որ բան ավելացնել ձեր ցուցակին, կարող եք դա անել ՝ մուտքագրելով այս հրահանգը. + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.append(199) +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +``` + +Եթե ցանկանում եք ցույց տալ միայն առաջին համարը, ապա կարող եք դա անել ՝ օգտագործելով ** index (ինդեքսներ) **: Ինդեկսը այն թիվն է, որն ասում է, թե որտեղ է ցուցակում ինչ-որ իր տեղի ունենում: Ծրագրավորողները նախընտրում են սկսել հաշվել 0-ից, այնպես որ ձեր ցուցակում առաջին օբյեկտը 0 ինդեքսում է, հաջորդը 1-ի վրա և այլն: Փորձեք այս: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery[0]) +59 +>>> print(lottery[1]) +42 +``` + +Ինչպես տեսնում եք, ձեր ցուցակում կարող եք մուտք գործել տարբեր օբյեկտներ ՝ օգտագործելով ցուցակի անվանումը և քառակուսի փակագծերի ներսում գտնվող օբյեկտի ցուցիչը: + +Ձեր ցուցակից ինչ-որ բան ջնջելու համար հարկավոր է օգտագործել ** indexes (ինդեքսները) **, ինչպես սովորեցինք վերևում և ` pop() (փոփ()) ` մեթոդը: Եկեք փորձենք մի օրինակ և ամրապնդենք նախկինում սովորածը. մենք կջնջենք մեր ցուցակի առաջին համարը: + +{% filename %}command-line{% 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] +``` + +Դա հիանալի աշխատեց: + +Լրացուցիչ զվարճանքի համար փորձեք մի քանի այլ ցուցանիշներ. 6, 7, 1000, -1, -6 կամ -1000: Տեսեք, արդյոք կարող եք կանխատեսել արդյունքը ՝ նախքան հրամանը փորձելը: Արդյո՞ք արդյունքները իմաստ ունեն: + +Python- ի փաստաթղթավորման այս գլխում կարող եք գտնել ցուցակի բոլոր մատչելի մեթոդների ցուցակը. https://docs.python.org/3/tutorial/datastructures.html + +## Բառարաններ + +> Ընթերցողների համար տանը. Այս մասն ընդգրկված է [ Python Basics: Dictionaries (Python- ի հիմունքները: բառարաններ) ](https://www.youtube.com/watch?v=ZX1CVvZLE6c) տեսանյութում: + +Բառարանը նման է ցուցակին, բայց արժեքներին մուտք եք գործում թվային ցուցիչի փոխարեն ստեղ փնտրելով: Բանալին կարող է լինել ցանկացած string(տո) կամ համար: Դատարկ բառարան սահմանելու համար շարահյուսությունն է. + +{% filename %}command-line{% endfilename %} + +```python +>>> {} +{} +``` + +Սա ցույց է տալիս, որ դուք պարզապես ստեղծել եք դատարկ բառարան: Ուռա! + +Այժմ փորձեք գրել հետևյալ հրահանգը (փորձեք փոխարինել նաև ձեր սեփական տեղեկությունները). + +{% filename %}command-line{% endfilename %} + +```python +>>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} +``` + +Այս հրամանի միջոցով դուք պարզապես ստեղծեցիք ` participant (մասնակից) ` անունով փոփոխական `երեք առանցքային արժեքի զույգերով. + +- `name(անուն) ` ստեղնը մատնանշում է ` 'Ola' ` արժեքը (` string` օբյեկտ), +- ` country (երկիրը) ` մատնանշում է `'Poland' «Լեհաստան» ` (մեկ այլ ` string `) +- և ` favorite_numbers (սիրված_համարները) ` ցույց են տալիս ` [7, 42, 92] ` (` list (ցուցակ) `, որի մեջ կա երեք համար): + +Անհատական ստեղների բովանդակությունը կարող եք ստուգել այս syntax (շարահյուսությամբ). + +{% filename %}command-line{% endfilename %} + +```python +>>> print(participant['name']) +Ola +``` + +Տեսեք, դա նման է ցուցակին: Բայց հարկավոր չէ հիշել ինդեքսը, պարզապես անունը: + +Ի՞նչ է պատահում, եթե Python- ից հարցնենք գոյություն չունեցող ստեղնաշարի արժեքը: Դուք կարող եք կռահել? Եկեք փորձենք և տեսնենք: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> participant['age'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'age' +``` + +Տեսեք, մեկ այլ սխալ: Այս մեկը ** KeyError ** է: Python- ը օգտակար է և ասում է, որ `'age' («տարիքը») ` բանալին գոյություն չունի այս բառարանում: + +Ե՞րբ պետք է օգտագործեք բառարան կամ ցուցակ: Լավ, դա խորհելու լավ կետ է: Մտածեք պատասխանի մասին նախքան այն հաջորդ տողում դիտելը: + +- Ուղղակի պե՞տք է իրերի պատվիրված հաջորդականություն: Գնացեք ցուցակի համար: +- Ձեզ հարկավոր է արժեքները կապել բանալիների հետ, որպեսզի հետագայում դրանք արդյունավետ (բանալիներով) որոնեք: Օգտագործեք բառարան + +Բառարանները, ինչպես list-ները (ցուցակ)ները, * mutable (փոփոխական) են *, ինչը նշանակում է, որ դրանք կարող են փոփոխվել ստեղծվելուց հետո: Բառարանում կարող եք ավելացնել բանալի-արժեքի նոր զույգեր այն ստեղծվելուց հետո, ինչպես հետևյալը. + +{% filename %}command-line{% endfilename %} + +```python +>>> participant['favorite_language'] = 'Python' +``` + +Ծուցակների նման, բառարաններում օգտագործելով ` len () ` ֆունկցիան, վերադարձնում է բառարանում բանալի-արժեք զույգերի քանակը: Գնացեք և մուտքագրեք այս հրամանը. + +{% filename %}command-line{% endfilename %} + +```python +>>> len(participant) +4 +``` + +Հուսով եմ ՝ դա մինչ այժմ իմաստ ունի: :) Պատրա՞ստ եք բառարանների հետ զվարճանալու համար: Կարդացեք մի քանի զարմանալի բաների մասին: + +Կարող եք օգտագործել ` pop () ` method-(մեթոդ)ը ՝ բառարանում իրը ջնջելու համար: Ասեք, եթե ցանկանում եք ջնջել `'favorite_numebrs' «սիրված_համարները» ` բանալին համապատասխան գրառումը, մուտքագրեք հետևյալ հրամանը. + +{% filename %}command-line{% endfilename %} + +```python +>>> participant.pop('favorite_numbers') +[7, 42, 92] +>>> participant +{'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +Ինչպես տեսնում եք արդյունքից, 'favorite_numbers'(«սիրված_համարներ») ստեղնին համապատասխանող ստեղն-արժեք զույգը ջնջվել է: + +Բացի դրանից, դուք կարող եք նաև փոխել մի բառ, որը կապված է բառարանում արդեն իսկ ստեղծված բանալին: Մուտքագրեք սա ՝ + +{% filename %}command-line{% endfilename %} + +```python +>>> participant['country'] = 'Germany' +>>> participant +{'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +Ինչպես տեսնում եք, `'country' («երկիր») ` ստեղնի արժեքը փոխվել է ` 'Poland' («Լեհաստան») ` - ից ` 'Germany' («Գերմանիա»)`: :) Հուզիչ? Ուռա! Դուք պարզապես սովորեցիք մեկ այլ զարմանալի բան: + +### Ամփոփում + +Հոյակապ. Դուք հիմա շատ բան գիտեք ծրագրավորման մասին: Այս վերջին մասում իմացաք. + +- ** errors (սխալներ) ** - Դուք այժմ գիտեք, թե ինչպես կարդալ և հասկանալ սխալները, որոնք հայտնվում են, եթե Python- ը չի հասկանում ձեր կողմից տրված հրամանը +- ** variables (փոփոխականներ) ** - օբյեկտների անուններ, որոնք թույլ են տալիս ավելի հեշտ ծածկագրել և ձեր կոդն ավելի ընթեռնելի դարձնել +- ** lists (ցուցակներ) ** - որոշակի հերթականությամբ պահված օբյեկտների ցուցակներ +- ** disctionaries (բառարաններ) ** - օբյեկտներ, որոնք պահվում են որպես ստեղն-արժեք զույգեր + +Հիասթափվա՞ծ եք հաջորդ մասի համար: :) + +## Համեմատեք իրերը + +> Ընթերցողների համար տանը. Այս մասն ընդգրկված է [ Python Basics: Comparisons (Համեմատություններ )](https://www.youtube.com/watch?v=7bzxqIKYgf4) տեսանյութում: + +Ծրագրավորման մեծ մասը ներառում է իրերի համեմատություն: Ո՞րն է համեմատության մեջ ամենահեշտ բանը: Թվե՛ր: Տեսնենք, թե ինչպես է դա գործում. + +{% 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 +``` + +Մենք որոշ թվեր տվեցինք Python- ին `համեմատելու համար: Ինչպես տեսնում եք, Python- ը ոչ միայն կարող է համեմատել թվերը, այլ նաև կարող է համեմատել մաթեմատիկական արտահայտությունների արժեքները, ինչպիսիք են ` 2 * 2 ` և ֆունկցիայի արդյունքները, ինչպիսին է ` 2 ` վերադարձվածը ` len ([4, 5]) `: Հաճելի է, հա՞: + +Զարմանո՞ւմ եք, թե ինչու ենք իրար կողքի դնում երկու հավասար ` == ` նշաններ ՝ համեմատելու համար, եթե թվերը հավասար են: Մենք օգտագործում ենք մեկ ` = ` փոփոխականներին արժեքներ նշանակելու համար: Դուք միշտ, ** միշտ ** պետք է դնեք դրանցից երկուսը ՝ ` == ` - եթե ուզում եք ստուգել, արդյոք իրերը հավասար են միմյանց: Կարող ենք նաև փաստել, որ իրերն անհավասար են միմյանց համար: Դրա համար մենք օգտագործում ենք `!= ` խորհրդանիշը, ինչպես ցույց է տրված վերևում բերված օրինակում: + +Python- ին տվեք ևս երկու առաջադրանք. + +{% filename %}command-line{% endfilename %} + +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` + +Մենք տեսել ենք `>`և `<` բայց ի՞նչ են նշանակում `>=` և `<=`: Կարդացեք դրանք այսպես. + +- x `>` y նշանակում է ՝ x- ն y- ից մեծ է +- x `<` y նշանակում է `x- ը y- ից փոքր է +- x `<=` y նշանակում է `x- ը y- ից փոքր է +- x `>=` y նշանակում է. x- ը y- ից մեծ է կամ հավասար է դրան + +Հիանալի! ուզում ես մի հատ էլ անել? Փորձեք այս: + +{% filename %}command-line{% endfilename %} + +```python +>>> 6 > 2 and 2 < 3 +True +>>> 3 > 2 and 2 < 1 +False +>>> 3 > 2 or 2 < 1 +True +``` + +Կարող եք Python- ին տալ այնքան թվեր, որպեսզի համեմատես, որքան ուզում ես, և դա քեզ կպատասխանի: Բավականին խելացի, այդպես չէ՞: + +- ** and (և) ** - եթե օգտագործում եք ` and (և) ` օպերատորը, երկու համեմատություններն էլ պետք է լինեն Ճիշտ, որպեսզի ամբողջ հրամանը լինի Ճիշտ: +- ** or (կամ) ** - եթե օգտագործում եք ` or (կամ) ` օպերատոր, ապա համեմատություններից միայն մեկը պետք է լինի Ճիշտ, որպեսզի ամբողջ հրամանը լինի Ճիշտ + +Լսե՞լ եք «խնձորը նարինջի հետ համեմատելը» արտահայտության մասին: Փորձենք Python- ի համարժեքը. + +{% 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' +``` + +Այստեղ տեսնում եք, որ ինչպես արտահայտության մեջ, Python- ը ի վիճակի չէ համեմատել համարը (` int `) և տողը (` str `): Փոխարենը, այն ցույց է տալիս ** TypeError ** և մեզ ասում է, որ երկու տիպերը չեն կարող համեմատվել միասին: + +## Boolean + +Ի դեպ, դուք հենց նոր իմացաք Python- ի նոր տեսակի օբյեկտների մասին: Այն կոչվում է ** Boolean (Բուլյան) **: + +Boolean (Բուլյան) ընդամենը երկու օբյեկտ կա. + +- Ճիշտ +- Կեղծ + +Բայց որպեսզի Python- ը դա հասկանա, դուք պետք է այն միշտ գրեք որպես 'True' («Ճիշտ») (առաջին տառերը մեծատառով, մնացած տառերը փոքրատառերով): ** true, TRUE և tRUE չեն գործի. Միայն True- ն է ճիշտ: ** (Նույնը վերաբերում է նաև 'False' - ին): + +Booleans- ը նույնպես կարող է փոփոխական լինել: Տեսեք այստեղ ՝ + +{% filename %}command-line{% endfilename %} + +```python +>>> a = True +>>> a +True +``` + +Դուք կարող եք նաև դա անել այս կերպ. + +{% filename %}command-line{% endfilename %} + +```python +>>> a = 2 > 5 +>>> a +False +``` + +Պարապեք և զվարճացեք Booleans- ի հետ `փորձելով կատարել հետևյալ հրահանգները. + +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` + +Շնորհավորանքներ. Booleans- ը ծրագրավորման ամենաթեժ առանձնահատկություններից մեկն է, և դուք պարզապես սովորեցիք, թե ինչպես օգտագործել դրանք: + +# Պահպանել այն! + +> Ընթերցողների համար տանը. Այս մասը ներառված է [ Python Basics: Saving files and 'if' statement (Python- ի հիմունքներում. Ֆայլեր պահելը և «Եթե» հայտարարությունը) ](https://www.youtube.com/watch?v=dOAg6QVAxyk) տեսանյութում: + +Մինչ այժմ մենք թարգմանչի մեջ գրում էինք մեր պիթոնի բոլոր կոդերը, ինչը մեզ սահմանափակում է միանգամից մեկ տող կոդ մուտքագրելով: Նորմալ ծրագրերը պահվում են ֆայլերում և կատարվում են մեր ծրագրավորման լեզվի ** interpreter (թարգմանիչ) ** կամ ** compiler (կազմողի) ** կողմից: Մինչ այժմ մենք միանգամից տողեր ենք վարում մեր ծրագրերը Python- ի ** interpreter (թարգմանչի) ** մեջ: Հաջորդ մի քանի առաջադրանքների համար մեզ մեկից ավելի տող ծածկագիր է պետք, ուստի մեզ արագ անհրաժեշտ կլինի. + +- Ելք Python- ի թարգմանիչից +- Բացեք մեր ընտրած կոդերի խմբագրիչը +- Մի քանի կոդ պահեք պիթոնի նոր ֆայլում +- Սկսե՛ք (run the code) + +Մեզ համար օգտագործվող Python- ի interpreter (թարգմանիչից) դուրս գալու համար մուտքագրեք ` exit() (ելք())` ֆունկցիան + +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` + +Սա ձեզ կրկին կտեղադրի command-ի (հրամանի) տողի մեջ: + +Ավելի վաղ մենք [ code editor (կոդերի խմբագիր) ](../code_editor/README.md) բաժնից ընտրեցինք code editor (կոդի խմբագիր): Մենք հիմա պետք է բացենք editor-ը (խմբագիրը) և մի քանի կոդ գրենք նոր ֆայլի մեջ (կամ եթե օգտագործում եք Chromebook, ստեղծեք նոր ֆայլ ամպային IDE- ում և բացեք այն ֆայլ, որը կլինի ներառված ծածկագրերի խմբագրում). + +{% filename %}editor{% endfilename %} + +```python +print('Hello, Django girls!') +``` + +Ակնհայտ է, որ դուք այժմ Python- ի բավականին փորձառու մշակող եք, այնպես որ ազատորեն գրեք մի քանի կոդ, որոնք սովորել եք այսօր: + +Այժմ մենք պետք է պահենք ֆայլը և տալ այն նկարագրական անուն: Եկեք զանգահարենք ֆայլը ** python_intro.py ** և պահենք այն ձեր աշխատասեղանին: Մենք կարող ենք ֆայլը անվանել այն, ինչ ուզում ենք, բայց այստեղ կարևոր մասն այն է, որ ֆայլը վերջանա ** .py **: ** .py ** ընդլայնումը մեր օպերացիոն համակարգին ասում է, որ սա ** Python excutable file (գործարկվող ֆայլ) ** է, և Python- ը կարող է այն գործարկել: + +> ** Նշում ** Դուք պետք է նկատեք կոդերի խմբագիրների ամենաթեժ մեկը `գույները: Python կոնսոլում ամեն ինչ նույն գույնն էր. հիմա պետք է տեսնեք, որ ` print (տպել) ` function-ը (գործառույթը) string-ից տարբեր գույն է: Սա կոչվում է "syntax highlighting" («շարահյուսական լուսաբանում»), և դա իսկապես օգտակար հատկություն է կոդավորման ժամանակ: Իրերի գույնը ձեզ հուշումներ կտա, ինչպիսիք են չփակված string-երը կամ կարևոր բառի տառասխալը (ինչպես ֆունկցիաի ` def (անջատումը) `, որը կտեսնենք ստորև): Սա է պատճառը, որ մենք օգտագործում ենք code editor ( կոդերի խմբագիր): :) + +Ֆայլը պահված պահով ՝ այն գործարկելու ժամանակն է: Օգտագործելով command line (հրամանի տողի) բաժնում ձեր սովորած հմտությունները, օգտագործեք տերմինալը ** change directories (գրացուցակները փոխելու ) ** համար: + + + +Mac- ի վրա հրամանը նման կլինի հետևյալ կերպ. + +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop + + + + + + +Linux- ում դա կլինի այսպես. + +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop + + +(Հիշեք, որ "Desktop" («աշխատասեղան») բառը կարող է թարգմանվել ձեր տեղական լեզվով): + + + + + +Windows- ի հրամանի տողում սա կլինի այսպես. + +{% filename %}command-line{% endfilename %} + + > cd %HomePath%\Desktop + + + + + + +Եվ Windows Powershell- ում դա կլինի այսպես. + +{% filename %}command-line{% endfilename %} + + > cd $Home\Desktop + + + + +Եթե խրվել եք, օգնություն խնդրեք: Դա հենց այն է, ինչի համար այստեղ են մարզիչները: + +Այժմ օգտագործեք Python- ը ֆայլի ծածկագիրը այսպիսի կատարելու համար. + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hello, Django girls! + + +Նշում. Windows- ում 'python3' («python3») - ը չի ճանաչվում որպես հրաման: Փոխարենը, ֆայլը կատարելու համար օգտագործեք 'python' («python»). + +{% filename %}command-line{% endfilename %} + +```python +> python python_intro.py +``` + +Լավ! Դուք պարզապես գործարկել եք ձեր առաջին Python ծրագիրը, որը պահվել է ֆայլում: Ձեզ հիանալի՞ եք զգում: + +Այժմ կարող եք անցնել ծրագրավորման կարևոր գործիքի. + +## If … elif … else + +Կոդում պարունակվող շատ բաներ պետք է կատարվեն միայն տրված պայմանների բավարարման դեպքում: Այդ պատճառով Python- ն ունի **if statement (եթե հայտարարություններ) ** կոչվող մի բան: + +Փոխարինեք կոդը ձեր ** python_intro.py ** ֆայլում հետևյալով. + +{% filename %}python_intro.py{% endfilename %} + +```python +if 3 > 2: +``` + +Եթե մենք save/ փրկեինք և run / գործարկեինք սա, կտեսնեինք այսպիսի սխալ. + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + + $ python3 python_intro.py + File "python_intro.py", line 2 + ^ + SyntaxError: unexpected EOF while parsing + + +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-ը, որպեսզի ամեն ինչ կոկիկ տեսք ունենա: Մեկ ներդիրը նույնպես կհամարվի 4 տարածություն, քանի դեռ ձեր տեքստի խմբագրիչը պատրաստ է դա անել: Երբ դու կատարեցիր քո ընտրությունը, մի փոխիր այն: Եթե դուք արդեն կտրել եք 4 տարածություն, ապա կատարեք ցանկացած ապագա խորացում նաև 4 տարածության հետ, հակառակ դեպքում կարող եք խնդիրներ առաջանալ: + +Պահպանեք այն և նորից run /մեկնարկեք. + +{% filename %}command-line{% endfilename %} + +```python +$ python3 python_intro.py +It works! +``` + +Նշում. Հիշեք, որ Windows- ում «python3» - ը չի ճանաչվում որպես հրաման: Այսուհետ, ֆայլը կատարելու համար փոխարինեք «python3» - ը «python» - ով: + +### Ի՞նչ կլինի, եթե պայմանը True (ճիշտ) չէ: + +Նախորդ օրինակներում ծածկագիրը կատարվում էր միայն այն ժամանակ, երբ պայմանները True (ճշմարիտ) էին: Բայց Python- ը ունի նաև ` elif ` և ` else ` հայտարարություններ. + +{% filename %}python_intro.py{% endfilename %} + +```python +if 5 > 2: + print('5 is indeed greater than 2') +else: + print('5 is not greater than 2') +``` + +Երբ սա գործարկվի, այն կտպագրվի ՝ + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + 5 is indeed greater than 2 + + +Եթե 2-ը 5-ից մեծ թիվ լիներ, ապա երկրորդ հրամանը կկատարվեր: Տեսնենք, թե ինչպես է աշխատում ` elif `: + +{% filename %}python_intro.py{% endfilename %} + +```python +name = 'Sonja' +if name == 'Ola': + print('Hey Ola!') +elif name == 'Sonja': + print('Hey Sonja!') +else: + print('Hey anonymous!') +``` + +և սկսեց. + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hey Sonja! + + +Տեսեք, թե ինչ է տեղի ունեցել այնտեղ: `elif` Ձեզ հնարավորություն է տալիս ավելացնել լրացուցիչ պայմաններ, որոնք գործում են նախորդ պայմանների ձախողման դեպքում: + +Նախնական ` if (եթե) ` հայտարարությունից հետո կարող եք ավելացնել այնքան ` elif ` հայտարարություն, որքան ցանկանում եք: Օրինակ: + +{% filename %}python_intro.py{% endfilename %} + +```python +volume = 57 +if volume < 20: + print("It's kinda quiet.") +elif 20 <= volume < 40: + print("It's nice for background music") +elif 40 <= volume < 60: + print("Perfect, I can hear all the details") +elif 60 <= volume < 80: + print("Nice for parties") +elif 80 <= volume < 100: + print("A bit loud!") +else: + print("My ears are hurting! :(") +``` + +Python- ն անցնում է յուրաքանչյուր թեստի հաջորդականությամբ և տպում. + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Perfect, I can hear all the details + + +## Comments + +Մեկնաբանությունները տողեր են, որոնք սկսվում են ` # ` - ով: ` # ` - ից հետո կարող եք գրել այն ամենը, ինչ ուզում եք, և Python- ը անտեսելու է այն: Մեկնաբանությունները կարող են հեշտացնել ձեր ծածկագիրը այլ մարդկանց համար: + +Տեսնենք, թե ինչպես է դա թվում. + +{% 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!") +``` + +Կոդի յուրաքանչյուր տողի համար անհրաժեշտ չէ մեկնաբանություն գրել, բայց դրանք օգտակար են բացատրելու համար, թե ինչու է ձեր կոդն ինչ-որ բան անում, կամ ամփոփում է ներկայացնում, երբ այն ինչ-որ բարդ բան է անում: + +### Ամփոփում + +Վերջին մի քանի վարժություններում, որոնց մասին իմացաք. + +- ** comparing things (իրերի համեմատություն)** - Python- ում դուք կարող եք համեմատել իրերը ՝ օգտագործելով`>`, `>=`, `==`, `<=`, `<` և ` և `, ` or (կամ) ` օպերատորները +- ** Boolean ** - օբյեկտի տեսակ, որը կարող է ունենալ միայն երկու արժեքներից մեկը ՝ ` Ture (Ճիշտ) ` կամ ` False (Սխալ)` +- ** Saving files (Ֆայլեր պահելը)** - ֆայլերում կոդ է պահվում, որպեսզի կարողանաք ավելի մեծ ծրագրեր իրականացնել: +- ** if… elif… other ** - հայտարարություններ, որոնք թույլ են տալիս կատարել կոդ միայն որոշակի պայմանների բավարարման դեպքում: +- ** comments (մեկնաբանություններ) ** - տողեր, որոնք Python- ը չի գործարկի, որոնք թույլ են տալիս փաստաթղթավորել ձեր կոդը + +Ժամանակն է այս գլխի վերջին մասի: + +## Ձեր սեփական functions (ֆունկցիաները): + +> Ընթերցողների համար տանը. Այս մասն ընդգրկված է [ Python Basics: Functions ](https://www.youtube.com/watch?v=5owr-6suOl0) տեսանյութում: + +Հիշո՞ւմ եք ` len() ` - ի նման գֆունկցիաներ, որոնք կարող եք կատարել Python- ում: Դե, լավ նորություն. Դուք կսովորեք, թե ինչպես գրել ձեր սեփական ֆունկցիաները հիմա: + +Ֆունկցիան հրահանգների հաջորդականություն է, որը Python- ը պետք է կատարի: Python- ում յուրաքանչյուր ֆունկցիան սկսվում է ` def ` հիմնաբառից, տրվում է անուն և կարող է ունենալ որոշ պարամետրեր: Եկեք փորձենք: Փոխարինեք կոդը ** python_intro.py ** - ում հետևյալով. + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(): + print('Hi there!') + print('How are you?') + +hi() +``` + +Լավ, մեր առաջին ֆունկցիան պատրաստ է: + +Կարող եք զարմանալ, թե ինչու ենք ֆունկցիայի անունը գրել ֆայլի ներքևում: Երբ մենք գրում ենք ` def hi (): ` և հետևյալ խորշված տողերը, սա մենք ենք, որ հրահանգներ ենք գրում, թե ինչ պետք է անի ` hi () ` ֆունկցիան: Python- ը կկարդա և կհիշի այս հրահանգները, բայց ֆունկցիան դեռ չի գործարկի: Python- ին ասելու համար, որ մենք ուզում ենք ֆունկցիան գործարկել, մենք պետք է ֆունկցիան կանչենք ` hi () ` - ով: Python- ը կարդում է ֆայլը և կատարում այն վերից վար, այնպես որ մենք պետք է ֆայլում սահմանենք ֆունկցիան նախքան այն կանչելը: + +Եկեք վարենք սա հիմա և տեսնենք, թե ինչ է տեղի ունենում. + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi there! + How are you? + + +Նշում. Եթե չի հաջողվել, մի խուճապի մատնվեք: Արդյունքը կօգնի ձեզ հասկանալ, թե ինչու. + +- Եթե դուք ստանում եք ` NameError` դա, հավանաբար, նշանակում է, որ դուք սխալ եք մուտքագրել ինչ-որ բան, ուստի պետք է ստուգեք, որ նույն անունն օգտագործել եք ` def hi (): ` ֆունկցիան ստեղծելիս և այն ` hi () ` - ով զանգահարելիս , +- Եթե դուք ստանում եք ` IndentationError `, տողի սկզբում ստուգեք, որ ` print (տպագիր) ` տողերն էլ ունենան նույն սպիտակ տարածությունը. +- Եթե ընդհանրապես ելք չկա, ստուգեք, որ վերջին ` hi() ` * տրոհված չէ * - եթե այդպես է, այդ տողը նույնպես կդառնա գործառույթի մաս: Այն երբեք չի սկսվի: + +Եկեք կառուցենք մեր առաջին գործառույթը պարամետրերով: Մենք կփոխենք նախորդ օրինակը ՝ ֆունկցիան , որն ասում է "hi" («ողջույն») այն աշխատող անձին ՝ անունով. + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): +``` + +Ինչպես տեսնում եք, մենք հիմա մեր ֆունկցիան տվեցինք մի պարամետր, որը կոչեցինք `name ( անուն) `: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + if name == 'Ola': + print('Hi Ola!') + elif name == 'Sonja': + print('Hi Sonja!') + else: + print('Hi anonymous!') + +hi() +``` + +Հիշիր `print (տպել) ` գործառույթը կտրված է չորս տարածության մեջ `if (եթե) ` հայտարարության մեջ: Դա պայմանավորված է նրանով, որ ֆունկցիան աշխատում է պայմանը բավարարելիս: Տեսնենք, թե ինչպես է այն աշխատում այժմ. + +{% 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' + + +Սխալ: Բարեբախտաբար, Python- ը մեզ տալիս է օգտակար սխալի հաղորդագրություն: Այն մեզ ասում է, որ ` hi () ` ֆունկցիան (այն, ինչ մենք սահմանեցինք) ունի մեկ պահանջվող փաստարկ (կոչվում է ` name (անուն) `) և որ մենք մոռացանք փոխանցել այն գործառույթը ակտիվացնելիս Եկեք ֆիքսենք այն ֆայլի ներքևում. + +{% filename %}python_intro.py{% endfilename %} + +```python +hi("Ola") +``` + +Եվ նորից գործարկեք այն. + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Ola! + + +Իսկ եթե անունը փոխե՞նք: + +{% filename %}python_intro.py{% endfilename %} + +```python +hi("Sonja") +``` + +Եվ run/գործարկեք այն. + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Sonja! + + +Հիմա ի՞նչ եք կարծում, ի՞նչ կլինի, եթե այնտեղ մեկ այլ անուն գրեք: (Ոչ Ola/Օլան կամ Sonja/Սոնյան): Փորձեք և տեսեք, արդյոք ճիշտ եք: Այն պետք է տպագրի սա ՝ + +{% filename %}command-line{% endfilename %} + + Ողջույն անանուն: + + +Սա հիանալի է, չէ՞: Այս կերպ ձեզ հարկավոր չէ կրկնել ամեն անգամ, երբ ցանկանում եք փոխել այն անձի անունը, որը պետք է ողջունի ֆունկցիան: Եվ հենց այդ պատճառով մեզ ֆունկցիաներ են պետք. Դուք երբեք չեք ցանկանում կրկնել ձեր ծածկագիրը: + +Եկեք ավելի խելացի բան անենք. Անուններն ավելի շատ են, քան երկուսը, և յուրաքանչյուրի համար պայման գրելը դժվար կլինի, չէ՞: Ձեր ֆայլի պարունակությունը փոխարինեք հետևյալով. + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + print('Hi ' + name + '!') + +hi("Rachel") +``` + +կեք հիմա զանգահարենք ծածկագիրը. + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Rachel! + + +Շնորհավորում եմ Դուք պարզապես իմացաք, թե ինչպես գրել ֆունկցիաներ: :) + +## Loops ( Օղակներ ) + +> Ընթերցողների համար տանը. Այս մասը ընդգրկված է [ Python Basics: For Loop ](https://www.youtube.com/watch?v=aEA6Rc86HF0) տեսանյութում: + +Սա արդեն վերջին մասն է: Դա արագ էր, չէ՞: :) + +Ծրագրավորողների չեն սիրում կրկնել իրենց: Ծրագրավորում բոլոր մասին, automating բաներ, այնպես որ, մենք չենք ուզում, որպեսզի ողջունելու յուրաքանչյուր անձին իրենց անունով ձեռքով, ճիշտ է? Դա այն վայրն է, որտեղ օղակները հարմար են: + +Դեռ հիշու՞մ եք ցուցակները: Եկեք կատարենք աղջիկների ցուցակ. + +{% filename %}python_intro.py{% endfilename %} + +```python +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +``` + +Մենք ուզում ենք նրանց բոլորին ողջունել իրենց անունով: Դա անելու համար մենք ունենք ` hi ` function, ուստի եկեք օգտագործենք այն loop-ի (օղակի) մեջ. + +{% filename %}python_intro.py{% endfilename %} + +```python +for name in girls: +``` + +` for ` հայտարարությունը իրեն նույն կերպ է վերաբերվում ` if ` հայտարարությանը; Այս երկուսից էլ ներքևի ծածկագիրը պետք է փորված լինի չորս տարածության մեջ: + +Ահա ամբողջական կոդը, որը կլինի ֆայլում. + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + print('Hi ' + name + '!') + +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +for name in girls: + hi(name) + print('Next girl') +``` + +Եվ երբ մենք այն run/վարում ենք. + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Rachel! + Next girl + Hi Monica! + Next girl + Hi Phoebe! + Next girl + Hi Ola! + Next girl + Hi You! + Next girl + + +Ինչպես տեսնում եք, այն ամենը, ինչ դնում եք ` for (համար) ` հայտարարության ներդիրով, կկրկնվի ` girls (աղջիկների)` ցուցակի յուրաքանչյուր տարր: + +Դուք կարող եք նաեւ օգտագործել `for (համար) ` է թվերի օգտագործելով ` range (հեռահար) ` ֆունկցիան: + +{% filename %}python_intro.py{% endfilename %} + +```python +for i in range(1, 6): + print(i) +``` + +Որը կտպագրի. + +{% filename %}command-line{% endfilename %} + + 1 + 2 + 3 + 4 + 5 + + +` range (միջակայքը) ` ֆունկցիան է, որը ստեղծում է թվերի ցուցակը մեկը մյուսին հաջորդող (այս թվերը տրամադրվում են ձեր կողմից որպես պարամետրեր): + +Նկատի ունեցեք, որ այս երկու թվերից երկրորդը ներառված չէ Python- ի կողմից թողարկվող ցուցակում (նկատի ունի ` range(1, 6) ` հաշվում է 1-ից 5-ը, բայց չի ներառում 6 թիվը): Դա այն պատճառով է, որ "range"-ը («միջակայքը») կիսաբաց է, և դրանով մենք նկատի ունենք, որ այն ներառում է առաջին արժեքը, բայց ոչ վերջինը: + +## Ամփոփում + +Վերջ ** Դուք լիովին ռոք եք անում: ** Սա բարդ գլուխ էր, այնպես որ դուք պետք է հպարտանաք ինքներդ ձեզնով: Մենք անկասկած հպարտ ենք ձեզանով, որ հասել եք մինչ այժմ: + +Python- ի պաշտոնական և ամբողջական ձեռնարկի համար այցելեք https://docs.python.org/3/tutorial/: Սա ձեզ լեզվի ավելի մանրակրկիտ և ամբողջական ուսումնասիրություն կտա: Ողջույն :) + +Կարող եք համառոտ մեկ այլ բան անել ՝ ձգվել, մի փոքր շրջել, հանգստանալ ձեր աչքերով ՝ նախքան հաջորդ գլուխ անցնելը: :) + +![Cupcake](images/cupcake.png) \ No newline at end of file diff --git a/hy/python_introduction/images/cupcake.png b/hy/python_introduction/images/cupcake.png new file mode 100644 index 00000000000..8c1820adee8 Binary files /dev/null and b/hy/python_introduction/images/cupcake.png differ diff --git a/hy/template_extending/README.md b/hy/template_extending/README.md new file mode 100644 index 00000000000..6f6584aeeba --- /dev/null +++ b/hy/template_extending/README.md @@ -0,0 +1,151 @@ +# Ձևանմուշի ընդլայնում/Template extending + +Django- ի մեկ այլ օգտակար բան **template extending/ձևանմուշի ընդլայնումն է ** : Ինչ է դա նշանակում? Ձեր կայքի տարբեր էջերիի համար կարող եք օգտագործել HTML- ի նույն մասերը: + +Ձևանմուշներն/Templates օգնում են, երբ ուզում եք նույն տեղեկատվությունը կամ դասավորությունը օգտագործել մեկից ավելի վայրերում: Յուրաքանչյուր ֆայլում հարկավոր չէ կրկնել: Եվ եթե ուզում եք ինչ-որ բան փոխել, ապա հարկավոր չէ դա անել յուրաքանչյուր ձևանմուշում, այլ միայն մեկում: + +## Ստեղծեք բազային ձևանմուշ/ base template + +Բազային ձևանմուշը/base template ամենահիմնական ձևանմուշն է, որը դուք տարածում եք ձեր կայքի յուրաքանչյուր էջում: + +Եկեք ստեղծենք `base.html` ֆայլ `blog/templates/blog/`-ում: + + blog + └───templates + └───blog + base.html + post_list.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.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
+ + +``` + +Դրանից հետո `base.html`- ում փոխարինեք ձեր ամբողջ `` -ը (ամեն ինչ `` և ` ` - ի միջև) հետևյալով. + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ +``` + +{% raw%} Ինչպես նկատեցիք, մենք փոխարինեցինք ամեն ինչ ՝ սկսած `{% for post in posts %}`-ը, `{% endfor %}` - ով փոխարինելով ՝ {% endraw %} + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% block content %} +{% endblock %} +``` + +Բայց ինչու՞ Դուք հենց նոր `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.text|linebreaksbr }}

+
+{% endfor %} +``` + +Մենք ուզում ենք սա օգտագործել որպես մեր ձևանմուշի մի մաս ՝ բովանդակության բոլոր բլոկների համար: Ժամանակն է այս ֆայլին ավելացնել բլոկի պիտակները/block tags: + +{% raw %} Դուք ցանկանում եք, որ ձեր բլոկի թեգը համընկնի `base.html` ֆայլի պիտակի/ tag-ի հետ: Դուք նաև ցանկանում եք ներառել ամբողջ ծածկագիրը, որը պատկանում է բովանդակության բլոկներին/content blocks: Դա անելու համար ամեն ինչ տեղադրեք{% block content %} - ի և {% endblock %} - ի միջև: Սրա նման. {% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% block content %} + {% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +Մնում է միայն մեկ բան. Մենք պետք է այս երկու ձևանմուշները միացնենք միմյանց: Սա այն է, ինչ կոչվում է «ձևանմուշի ընդլայնում/extending templates»: Մենք դա կանենք ՝ ֆայլի սկզբին ընդլայնման պիտակ/ extends tag ավելացնելով: Սրա նման: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +Վերջ Պահեք ֆայլը և ստուգեք, արդյոք ձեր կայքը դեռ պատշաճ կերպով աշխատում է: :) + +> Եթե `TemplateDoesNotExist` սխալ եք ստանում, դա նշանակում է, որ `blog/base.html` ֆայլը բացակայում է, և դուք ունեք `runserver` վահանակում: Փորձեք դադարեցնել այն (միաժամանակ սեղմելով Ctrl + C - Control և C ստեղները) և վերագործարկեք սերվերը `python manage.py runserver` հրամանի միջոցով: \ No newline at end of file diff --git a/hy/whats_next/README.md b/hy/whats_next/README.md new file mode 100644 index 00000000000..a17cb8f59c3 --- /dev/null +++ b/hy/whats_next/README.md @@ -0,0 +1,43 @@ +# Ի՞նչ է հաջորդը + +Շնորհավորիր քեզ: ** Դուք հիանալի եք **: Մենք շատ հպարտ ենք <3 + +### Ի՞նչ անել հիմա: + +Ընդմիջեք և հանգստացեք: Դուք պարզապես հոյակապ աշխատանք եք ավարտել: + +Հետևեք Django Girls- ին [Facebook](http://facebook.com/djangogirls)- ում և [Twitter](https://twitter.com/djangogirls) - ում `նորությունների մասին տեղեկացված լինելու համար: + +### Կարո՞ղ եք առաջարկել ուսման լրացուցիչ ռեսուրսներ: + +Այո: Բոլոր տեսակի ծրագրավորման լեզուները սովորելու համար կան * բազմաթիվ * առցանց ռեսուրսներ. Հնարավոր է դժվար թվալ ընտրությունը, թե որ կողմ շարժվել հաջորդ փուլերում, բայց մենք կօգնենք ձեզ դա հասկանալ: Ինչպիսին էլ որ լինեին ձեր հետաքրքրությունները նախքան Django Girls- ին միանալը, և ինչ հետաքրքրություններ էլ որ դուք զարգացրել եք ամբողջ դասընթացի ժամանակ, ահա մի քանի անվճար ռեսուրսներ (կամ ռեսուրսներ ՝ շատ անվճար բաղադրիչներով), որոնք կարող եք օգտագործել ձեր նպատակներին հասնելու համար: + +#### Django + +- Մեր մեկ այլ գիրք ՝ [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org/) +- [Django- ի պաշտոնական ձեռնարկը](https://docs.djangoproject.com/en/2.2/intro/tutorial01/) +- [Սկսենք Django- ի վիդեո դասերից](http://www.gettingstartedwithdjango.com/) +- [ Django- ն բոլորի համար մասնագիտացման համար ](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 + +- [Codecademy-ի Python դասընթացը](https://www.codecademy.com/learn/learn-python) +- [ Google- ի Python դասընթաց](https://developers.google.com/edu/python/) +- [ Learn Python The Hard Way book (Իմացեք Python The Hard Way գիրքը) ](http://learnpythonthehardway.org/book/) - նախնական վարժություններն անվճար են +- [ New Coder tutorials (Կոդերի նոր ձեռնարկներ) ](http://newcoder.io/tutorials/) - սա մի շարք գործնական օրինակներ է, թե ինչպես կարող եք օգտագործել Python- ը +- [ edX ](https://www.edx.org/course?search_query=python) - Դուք կարող եք ստուգել դասընթացների մեծ մասը անվճար, բայց եթե ցանկանում եք բարձրագույն կրթության որակավորման վկայագիր կամ կրեդիտներ, ապա դա կարժենա գումար: +- [ Coursera's Python specialization (Coursera- ի Python մասնագիտացումը) ](https://www.coursera.org/specializations/python) - որոշ վիդեո դասախոսություններ կարող են անվճար աուդիտի ենթարկվել, և դուք կարող եք վաստակել Coursera սերտիֆիկատ ՝ անցնելով այս դասընթացները +- [ Python for Everybody (Python բոլորի համար) ](https://www.py4e.com/) - Coursera Python- ի բոլորի համար անվճար և բաց տարբերակ մասնագիտացման համար + +#### Տվյալների հետ աշխատելը + +- [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 diff --git a/it/README.md b/it/README.md index 40e85c34b2e..bbeb397c717 100644 --- a/it/README.md +++ b/it/README.md @@ -1,48 +1,51 @@ # Il tutorial di 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) +[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial) -> Questo lavoro è sotto la licenza internazionale di Creative Commons Attribution-ShareAlike 4.0. Per vedere una copia di questa licenza, visita https://creativecommons.org/licenses/by-sa/4.0/ +> Questo lavoro è concesso sotto la licenza Creative Commons Attribuzione-ShareAlike 4.0 internazionale. Per visualizzare una copia di questa licenza, visita https://creativecommons.org/licenses/by-sa/4.0/ + +## Benvenuta + +Benvenuta al tutorial Django Girls! Siamo felici di vederti qui. :) In questo tutorial, vi porteremo in un viaggio nella sfera delle tecnologie web, offrendovi uno sguardo di tutti i bit e pezzi che hanno bisogno di stare insieme per far funzionare il web così come lo conosciamo. + +Come per tutte le cose sconosciute, questa sarà un'avventura - ma non preoccupatevi, dal momento che hai già avuto il coraggio di arrivare fino a qui, andrà tutto bene :) ## Introduzione -Hai mai sentito che il mondo sta diventando sempre più tecnologico e sei in qualche modo rimasto indietro? ti sei mai chiesta come creare un sito web ma non hai mai avuto abbastanza motivazione per iniziare? Hai mai pensato che il mondo del software è troppo complicato per te persino per provare a fare qualcosa per conto tuo? +Hai mai avuto l'impressione che il mondo stia diventando sempre più tecnologico e di essere per così dire (temporaneamente) rimasta indietro? Ti sei mai chiesta come creare un sito web ma non hai mai avuto abbastanza motivazione per iniziare? Hai mai pensato che il mondo del software è troppo complicato per te persino per provare a fare qualcosa per conto tuo? -Beh, abbiamo buone notizie per te! La programmazione non è così complicata come sembra e vogliamo dimostrati quanto può essere divertente. +Beh, abbiamo buone notizie per te! La programmazione non è così complicata come sembra e vogliamo dimostrarti quanto può essere divertente. -Il tutorial non ti trasformerà magicamente in un programmatore. Se vuoi diventare bravo/a, ci vorranno mesi o addirittura anni di apprendimento e pratica. Ma ti vogliamo dimostrare che la programmazione o creare siti web non è complicato come sembra. Proveremo a spiegarti diversi argomenti come meglio possiamo, in modo che non ti senta più intimidito/a dalla tecnologia. +Questo tutorial non ti trasformerà magicamente in una programmatrice. Se vuoi diventare brava, ci vorranno mesi o addirittura anni di apprendimento e pratica. Ma ti vogliamo dimostrare che scrivere programmi o creare siti web non è complicato come sembra. Proveremo a spiegarti diversi argomenti come meglio possiamo, in modo che non ti senta più intimidita dalla tecnologia. -Speriamo di essere in grado di farti amare la tecnologia come lo facciamo noi! +Speriamo di riuscire a farti amare la tecnologia come la amiamo noi! ## Cosa imparerai durante questo tutorial? -Una volta che avrai terminato il tutorial, avrai a disposizione una semplice applicazione web: il tuo blog personale. Ti mostreremo come metterlo in linea, in modo che gli altri possano vedere il tuo lavoro! +Una volta terminato il tutorial, avrai creato una piccola applicazione web funzionante: il tuo blog personale. Ti mostreremo come metterlo online, in modo che gli altri possano vedere il tuo lavoro! Assomiglierà (più o meno) a questo: -![Figure 0.1][2] +![Figure 0.1](images/application.png) - [2]: images/application.png +> Se lavori da sola al tutorial e non hai un insegnante che ti possa aiutare nel caso avessi qualche problema, abbiamo una chat per te: [![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial). Abbiamo chiesto ai nostri coach e a coloro che hanno già partecipato di visitare la chat di tanto in tanto per aiutare gli altri con il tutorial! Non aver paura di fare domande! -> Se lavori da solo/a al tutorial e non hai un'insegnante che ti possa aiutare nel caso avessi qualche problema, abbiamo una chat per te: [![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). Abbiamo chiesto ai nostri insegnanti e partecipanti precedenti di esserci di volta in volta ed aiutare gli altri con il tutorial! Non aver paura di fare domande! +OK, [cominciamo dall'inizio...](./how_the_internet_works/README.md) -OK, [cominciamo dall'inizio...][3] +## Seguire il tutorial da casa - [3]: ./how_the_internet_works/README.md +È fantastico prendere parte a un workshop Django Girls, ma siamo consapevoli che non sempre è possibile essere presenti a un workshop. Questo è il motivo per cui ti invitiamo a provare a seguire il tutorial da casa. Per chi ci segue da casa, stiamo preparando alcuni video che renderanno più facile seguire il tutorial da sole. È un progetto ancora in corso, ma col tempo gli argomenti trattati sul nostro canale YouTube [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed) saranno sempre di più. -## Informazioni e contribuzioni +In ogni capitolo già trattato, c'è un link che punta al video corrispondente. -Questo tutorial è mantenuto da [DjangoGirls][4]. Se trovi errori o se vuoi aggiornare questo tutorial, [segui le linee guida per i collaboratori][5]. +## Informazioni e contribuzioni - [4]: https://djangogirls.org/ - [5]: https://github.com/DjangoGirls/tutorial/blob/master/README.md +Questo tutorial è mantenuto da [DjangoGirls](https://djangogirls.org/). Se trovi errori o se vuoi aggiornare questo tutorial, [segui le linee guida per i collaboratori](https://github.com/DjangoGirls/tutorial/blob/master/README.md). -## Vorresti aiutarci a tradurre il tutorial in un altra lingua? +## Vuoi aiutarci a tradurre il tutorial in altre lingue? -Attualmente, le traduzioni vengono mantenute sulla piattaforma crowdin.com in: +Attualmente le traduzioni vengono svolte sulla piattaforma crowdin.com all'indirizzo: https://crowdin.com/project/django-girls-tutorial -Se la tua lingua non è elencata su crowding, per favore [apri una nuova istanza][6] con la tua lingua in modo che possiamo aggiungerla. - - [6]: https://github.com/DjangoGirls/tutorial/issues/new \ No newline at end of file +Se la tua lingua non è elencata su [crowdin](https://crowdin.com/), puoi [aprire una nuova istanza](https://github.com/DjangoGirls/tutorial/issues/new) segnalando la tua lingua, in modo che possiamo aggiungerla. \ No newline at end of file diff --git a/it/SUMMARY.md b/it/SUMMARY.md index 694b07fd6b9..3dc4d708974 100644 --- a/it/SUMMARY.md +++ b/it/SUMMARY.md @@ -1,11 +1,20 @@ # Indice * [Introduzione](README.md) -* [Installazione](installation/README.md) +* [Installazione](installation/README.md) + * [Riga di Comando](installation/README.md#command-line) + * [Python](installation/README.md#python) + * [L'editor di codice](installation/README.md#code-editor) + * [Ambiente virtuale](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) +* [Installazione (chromebook)](chromebook_setup/README.md) * [Come funziona Internet](how_the_internet_works/README.md) -* [Introduzione al command line](intro_to_command_line/README.md) -* [Installazione di Python](python_installation/README.md) -* [Code Editor](code_editor/README.md) +* [Introduzione alla command line](intro_to_command_line/README.md) +* [Istallazione di Python](python_installation/README.md) +* [L'editor di codice](code_editor/README.md) * [Introduzione a Python](python_introduction/README.md) * [Che cos'è Django?](django/README.md) * [Installazione di Django](django_installation/README.md) @@ -14,13 +23,13 @@ * [L'admin di Django](django_admin/README.md) * [Deploy!](deploy/README.md) * [Django URL](django_urls/README.md) -* [Le views di Django - è arrivata l'ora di creare!](django_views/README.md) +* [Le views di Django – è l'ora di creare!](django_views/README.md) * [Introduzione all'HTML](html/README.md) * [ORM di Django (Querysets)](django_orm/README.md) -* [I dati dinamici in templates](dynamic_data_in_templates/README.md) -* [I templates di Django](django_templates/README.md) -* [CSS - dagli un bell'aspetto](css/README.md) +* [I dati dinamici nei template](dynamic_data_in_templates/README.md) +* [I template di Django](django_templates/README.md) +* [CSS - rendilo più carino](css/README.md) * [Estendere il template](template_extending/README.md) * [Estendi la tua applicazione](extend_your_application/README.md) -* [Form Django](django_forms/README.md) -* [Quali sono le prospettive?](whats_next/README.md) \ No newline at end of file +* [I Form Django](django_forms/README.md) +* [E dopo?](whats_next/README.md) \ No newline at end of file diff --git a/it/chromebook_setup/README.md b/it/chromebook_setup/README.md new file mode 100644 index 00000000000..4e4076369f1 --- /dev/null +++ b/it/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# Configurazione del Chromebook + +> **Nota** Se hai già completato il processo di installazione, non è necessario rifare tutto e puoi passare direttamente a [Introduzione a Python](../python_introduction/README.md). + +{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/it/chromebook_setup/instructions.md b/it/chromebook_setup/instructions.md new file mode 100644 index 00000000000..0ae49f31e45 --- /dev/null +++ b/it/chromebook_setup/instructions.md @@ -0,0 +1,158 @@ +Puoi [saltare questa sezione](http://tutorial.djangogirls.org/en/installation/#install-python) se non utilizzi un Chromebook. L'installazione su Chromebook segue una procedura un po' diversa. Il resto delle istruzioni di installazione può essere ignorato. + +### Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com) + +Cloud IDE è uno strumento che mette a disposizione un editor di codice e l'accesso ad un computer virtuale su cui installare, scrivere ed eseguire il software. In questo tutorial, Cloud IDE avrà la funzione di un *computer locale*. Digiterai i comandi sull'interfaccia di un terminale, come le tue compagne di corso che utilizzano macOS, Ubuntu o Windows, ma il tuo terminale sarà connesso a un computer remoto che Cloud IDE ha creato per te. Puoi trovare di seguito le istruzioni per i Cloud IDE (PaizaCloud IDE, AWS Cloud9, Glitch.com). Puoi selezionare uno dei Cloud IDE e seguire le relative istruzioni. + +#### PaizaCloud Cloud IDE + +1. Vai su [PaizaCloud Cloud IDE](https://paiza.cloud/) +2. Crea un account +3. Clicca su *Nuovo server* oppure <0>New Server e scegli l'app Django +4. Seleziona il pulsante Terminal (sul lato sinistro della pagina) + +Ora dovresti vedere un'interfaccia con una barra laterale e dei pulsanti sulla sinistra. Fai click sul pulante "Terminal" per aprire la finestra del terminale con il prompt, così: + +{% filename %}Terminal{% endfilename %} + + $ + + +Il terminale su PaizaCloud Cloud IDE è pronto a ricevere istruzioni. Puoi ridimensionare la finestra o renderla un po' più più grande. + +#### AWS Cloud9 + +Attualmente Cloud 9 richiede la registrazione con AWS e l'inserimento delle informazioni sulla carta di credito. + +1. Installa Cloud9 dal [Chrome web store](https://chrome.google.com/webstore/detail/cloud9/nbdmccoknlfggadpfkmcpnamfnbkmkcp) +2. Vai su [c9.io](https://c9.io) e clicca *Inizia con AWS Cloud9* +3. Registra un account AWS (richiede informazioni sulla carta di credito, ma puoi usarlo gratuitamente) +4. Nella Dashboard di AWS, inserisci *Cloud9* nella barra di ricerca e facci click +5. Nel cruscotto Cloud 9, clicca su *Crea ambiente* +6. Chiamalo *django-girls* +7. Durante la configurazione delle impostazioni, selezionare *Creare una nuova istanza per l'ambiente (EC2)* per "Tipo di Ambiente" e *t2.micro* "Tipo di Istanza" (dovrebbe essere "Free-tier."). L'impostazione di default per il risparmio dei costi va bene e puoi mantenere le altre impostazioni predefinite. +8. Clicca *Passo Successivo* +9. Fai click su *Create Environment* + +Ora dovresti vedere un'interfaccia con una barra laterale, una grossa finestra principale con del testo, ed una piccola finestra in basso che sembra questa: + +{% filename %}bash{% endfilename %} + + yourusername:~/workspace $ + + +Questa finestra in basso è il tuo terminale. Puoi usare il terminale per inviare istruzioni al computer remoto Cloud9. Puoi cambiare le dimensioni della finestra e renderla più grande. + +#### Glitch.com + +1. Vai su [Glitch.com](https://glitch.com/) +2. Crea un account (https://glitch.com/signup) o, se lo possiedi, usa il tuo account GitHub (di seguito puoi trovare le istruzioni su GitHub). +3. Seleziona *New Project* e scegli *hello-webpage* +4. Seleziona l'elenco a discesa "Strumenti" (Tools, nella sezione della pagina in basso a sinistra), poi premi sul pulsante Terminale (Terminal) per aprire una scheda terminale con un prompt come il seguente: + +{% filename %}Terminal{% endfilename %} + + app@name-of-your-glitch-project:~ + + +Quando utilizzi Glitch.com come il tuo Cloud IDE, non è necessario creare un ambiente virtuale. Puoi invece creare manualmente i seguenti file: + +{% 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 +``` + +Una volta creati i file, vai al Terminale ed esegui i comandi seguenti per creare il tuo primo progetto Django: + +{% filename %}Terminal{% endfilename %} + + django-admin.py startproject mysite . + refresh + + +Per poter vedere dettagliatamente i messaggi di errore, puoi attivare i log di debug di Django per la tua applicazione Glitch. Aggiungi semplicemente questa dicitura alla fine del file `mysite/settings.py`. + +{% 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, + }, + }, +} +``` + +Questo procedimento creerà un file `debug.log` con i dettagli sulle operazioni effettuate da Django e su eventuali messaggi di errore che potrebbero apparire, rendendone più semplice la correzione se il tuo sito web non funzionasse. + +Il riavvio iniziale del progetto Glitch potrebbe fallire. (Se selezioni il pulsante a discesa in alto `Show` e poi `In a New Window`, riceverai il messaggio di errore `DisallowedHost`) Non devi preoccupartene in questa fase, il tutorial lo correggerà non appena aggiorni le impostazioni del tuo progetto di Django nel file `mysite/settings.py`. + +### Ambiente virtuale + +Un ambiente virtuale (virtual environment, spesso abbreviato in virtualenv) è una specie di scatola privata in cui si può inserire un codice informatico per un progetto su cui si sta lavorando. Si usa per mantenere separati i numerosi pezzi di codice dei vari progetti, in modo da non creare confusione tra i progetti stessi. + +Esegui: + +{% filename %}Cloud 9{% endfilename %} + + mkdir djangogirls + cd djangogirls + python3 -m venv myvenv + source myvenv/bin/activate + pip install django~={{ book.django_version }} + + +(N.B. nell'ultima riga abbiamo usato una tilde seguita dal segno uguale: `~=`). + +### GitHub + +Crea un account [GitHub](https://github.com). + +### PythonAnywhere + +Il tutorial di Django Girls include una sezione su ciò che viene definito Deployment, ovvero il processo durante il quale si estrae il codice che alimenta la tua nuova applicazione web e lo si sposta su un computer accessibile al pubblico (chiamato server), in modo che altre persone possano vedere il tuo lavoro. + +Questa parte del tutorial è un po' insolita se lo si segue su un Chromebook, siccome stiamo usando un computer che è già su internet (al contrario di un laptop, per esempio). È comunque utile, se consideriamo il nostro Cloud 9 come uno spazio per il nostro lavoro "in corso" e Python Anywhere come uno spazio per mostrare il nostro materiale quando è più completo. + +Quindi, registra il tuo nuovo account Python Anywhere su [www.pythonanywhere.com](https://www.pythonanywhere.com). \ No newline at end of file diff --git a/it/code_editor/README.md b/it/code_editor/README.md index 8261e76f6cb..13c4af12926 100644 --- a/it/code_editor/README.md +++ b/it/code_editor/README.md @@ -1,7 +1,11 @@ -# Code Editor +# L'editor di codice + +> Per i lettori a casa: questo capitolo è trattato nel video [Installing Python & Code Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s). Stai per scrivere la tua prima riga di codice, per cui è il momento di scaricare il tuo editor! -> **Nota** Potresti aver già affrontato questo passaggio nel capitolo Installazione - se è così, puoi saltare direttamente al prossimo capitolo! +> **Nota** Se utilizzi un Chromebook, salta questo capitolo e segui le istruzioni in [Configurazione di Chromebook](../chromebook_setup/README.md). L'IDE cloud che sceglierai (PaizaCloud Cloud IDE o AWS Cloud9) include un editor di codice, e quando aprirai un file nel tuo IDE dal menu File, utilizzerai automaticamente l'editor. +> +> **Nota** Potresti aver già effettuato questo passaggio nel capitolo sull'installazione. Se così fosse, puoi passare al prossimo capitolo! -{% include "/code_editor/instructions.md" %} +{% include "/code_editor/instructions.md" %} \ No newline at end of file diff --git a/it/code_editor/instructions.md b/it/code_editor/instructions.md index bd6ab5614c2..60c63fd4415 100644 --- a/it/code_editor/instructions.md +++ b/it/code_editor/instructions.md @@ -1,6 +1,12 @@ -Sono disponibili diversi editor e la scelta di uno piuttosto che un altro dipende principalmente dal gusto personale. La maggior parte dei programmatori Python usa complessi ma estremamente potenti IDE (ambienti di sviluppo integrati), come PyCharm. Tuttavia, dal momento che sei ancora agli inizi non è l'editor più appropriato; quelli che ti suggeriremo noi sono ugualmente potenti ma molto più semplici da utilizzare. +Ci sono moltissimi editor diversi e la scelta dipende in gran parte dalle proprie preferenze. La maggior parte dei programmatori Python usa IDE (in inglese Integrated Development Environments, ambienti di sviluppo integrati) complessi ma estremamente potenti, come PyCharm. Tuttavia questo non è l'editor più appropriato per una principiante; quelli che ti suggeriremo noi sono ugualmente potenti, ma molto più semplici. -I nostri suggerimenti sono riportati qui di seguito, ma sentiti libero/a di chiedere al tuo coach quali sono le sue preferenze in materia di editor, in questo modo sarà più semplice per il tuo coach aiutarti. +Qui di seguito te ne consigliamo alcuni, ma puoi chiedere al tuo coach quali editor preferisce - in modo che possa aiutarti più facilmente. + +## Codice Studio Visual + +Visual Studio Code è un editor di codice sorgente sviluppato da Microsoft per Windows, Linux e macOS. Include il supporto per il debug, il controllo Git incorporato, l'evidenziazione della sintassi, il completamento intelligente del codice, gli snippet e il refactoring del codice. + +[Scaricalo qui](https://code.visualstudio.com/) ## Gedit @@ -8,24 +14,24 @@ Gedit è un editor open-source e gratuito, disponibile per tutti i sistemi opera [Scaricalo qui](https://wiki.gnome.org/Apps/Gedit#Download) -## Sublime Text 3 +## Sublime Text -Sublime Text è uno tra gli editor più utilizzati. Ha un periodo di prova gratuito. È molto facile da installare e da utilizzare ed è disponibile per tutti i sistemi operativi. +Sublime Text è tra gli editor più utilizzati. Ha un periodo di prova gratuito ed è disponibile per tutti i sistemi operativi. -[Scaricalo qui](https://www.sublimetext.com/3) +[Scaricalo qui](https://www.sublimetext.com/) ## Atom -Atom è un nuovo editor di codice creato da [GitHub](https://github.com/). È gratuito, open-source, facile da installare e da usare. È disponibile per Windows, OSX e Linux. +Atom è un altro editor molto diffuso. È gratuito, open-source e disponibile per Windows, macOS e Linux. Atom è sviluppato da [GitHub](https://github.com/). [Scaricalo qui](https://atom.io/) -## Perché installiamo un editor di codice? +## Perché installare un editor di codice? -Forse ti stai chiedendo per quale motivo installiamo questo editor di codice invece di usare un applicazione come Word or Blocco Note. +Forse ti stai chiedendo per quale motivo installiamo questo editor di codice, invece di usare un'applicazione come Word o Blocco Note. -Il primo motivo è che il codice deve essere **testo semplice**, e il problema con programmi come Word e Textedit è che in realtà non producono testo semplice. Producono testo RTF (con caratteri e formattazione), utilizzando formati personalizzati come [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format). +La prima ragione è che il codice deve essere **testo semplice**, e programmi come Word e Textedit non producono questo tipo di testo, ma testo formattato (con font e formattazione), codificato in formati come l'[RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format). -La seconda ragione è che i code editor sono specializzati per programmare, perciò hanno molte funzionalità utili, ad esempio diversi colori per evidenziare frammenti di codice con diversi significati, o l'inserimento automatico del secondo paio di virgolette. +La seconda ragione è che gli editor sono specializzati nel modificare codice, e quindi mettono a disposizione utili funzionalità come l'evidenziazione della sintassi con colori legati al suo significato, o la chiusura automatica di parentesi e virgolette. -Vedremo tutto ciò più tardi. Il tuo fidato code editor sarà presto uno dei tuoi strumenti preferiti :) \ No newline at end of file +Vedremo tutto ciò più avanti. Presto, il tuo fidato editor di testo diventerà uno dei tuoi strumenti preferiti. :) diff --git a/it/css/README.md b/it/css/README.md index b7b87505dd2..e5be23e1df1 100644 --- a/it/css/README.md +++ b/it/css/README.md @@ -1,294 +1,330 @@ -# CSS - dagli un bel aspetto! +# CSS - rendilo carino! -Il nostro blog sembra ancora un pochino brutto, vero? È arrivato il momento di abbellirlo! Per fare ciò useremo CSS. +Il nostro blog sembra ancora bruttino, vero? È arrivato il momento di abbellirlo! Per fare ciò useremo i CSS. -## Che cos'è CSS? +## Che cosa sono i CSS? -Cascading Style Sheets (CSS) è un linguaggio usato per descrivere l'aspetto e la formattazione di un sito scritto in un linguaggio di markup (come HTML). Vedilo come il trucco del nostro sito ;). +I CSS (Cascading Style Sheet, fogli di stile a cascata) servono a descrivere l'aspetto e la formattazione di un sito web scritto in un linguaggio di Markup (come l'HTML). Vedilo come il make-up per la nostra pagina web. ;) -Ma non vogliamo ricominciare da capo, giusto? Ancora una volta useremo qualcosa preparato da altri programmatori disponibile su Internet gratuitamente per tutti. Si sa, re-inventare la ruota non è molto divertente. +Ma non vogliamo iniziare di nuovo dalle basi, vero? Ancora una volta, useremo qualcosa che i programmatori hanno rilasciato su internet gratuitamente. Reinventare la ruota non è divertente, come saprai. ## Usiamo Bootstrap! -Bootstrap è uno dei più popolari framework HTML e CSS per costruire bellissimi siti internet: https://getbootstrap.com/ +Bootstrap è uno dei framework HTML e CSS più poplari per sviluppare bellissimi siti web: https:/getbootstrap.com/ -È stato scritto da programmatori che lavoravano per Twitter ed è ora sviluppato da volontari da ogni parte del mondo. +È stato scritto dai programmatori che lavoravano per Twitter. Adesso è sviluppato da volontari provenienti da tutto il mondo! -## Installa Bootstrap +## Installare Bootstrap -Per installare Bootstrap, avrai bisogno di aggiungere questo nel tag `` del tuo file `.html` (`blog/templates/blog/post_list.html`): +Per installare Bootstrap, apri il tuo file `.html` nell'editor di codice e aggiungi la riga seguente alla sezione ``: + +{% filename %}blog/templates/blog/post_list{% endfilename %} ```html - - + ``` -Le due linee sopra riportate non aggiungono nessun file al tuo progetto. Stanno solo reindirizzando ad alcuni files the esistono in internet. Ma non ti preoccupare troppo, vai avanti e apri la tua pagina web e ricarica la pagina. Eccolo qui! - -![Figura 14.1][1] +Queste righe non aggiungono nessun file al tuo progetto. Puntano solo ad altri file già esistenti siu Internet. Quindi avanti, apri il tuo sito e ricarica la pagina. Ecco qua! - [1]: images/bootstrap1.png +![Figura 14.1](images/bootstrap1.png) Sembra già più carino! ## File statici in Django -Infine, daremo uno sguardo più approfondito a quelli che abbiamo chiamato **file statici**. I file statici sono tutti i tuoi CSS e le immagini -- file che non sono dinamici, il loro contenuto non dipende dal contesto della richiesta e sarà lo stesso per ogni utente. +Infine, daremo uno sguardo più approfondito a quelli che abbiamo chiamato **file statici**. I file statici sono tutti i tuoi CSS e le tue immagini. Il loro contenuto non dipende dal contesto richiesto e sarà lo stesso per tutti gli utenti. ### Dove mettere i file statici in Django -Come hai visto quando abbiamo eseguito `collectstatic` sul server, Django sa già dove trovare i file statici per l'app built-in "admin". Ora dobbiamo solo aggiungere alcuni file statici per la nostra app, `blog`. +Django sa già dove trovare file statici per l'app integrata "admin". Ora dobbiamo aggiungere alcuni file statici per la nostra app, `blog`. Lo facciamo creando una cartella denominata `static` all'interno dela nostra app blog: djangogirls ├── blog - │ ├── migrations - │ └── static + |     ├── migrations + |     ├── static + |     └── templates └── mysite + - -Django troverà automaticamente tutte le cartelle chiamate "static" dentro le cartelle delle tua app, e sarà in grado di utilizzare il loro contenuto come file statici. +Django trova automaticamente ogni cartella chiamata ''static'' all'interno di qualsiasi cartella della tua app. Quindi potrà usarne il contenuto come file statici. ## Il tuo primo file CSS! -Ora, creiamo un file CSS, per poter aggiungere il tuo stile personale al tuo sito. Crea una nuova cartella dal nome `css` all'interno della tua cartella `static`. Poi, crea un nuovo file all'interno della tua cartella `css` e chiamalo `blog.css`. Fatto? +Creiamo un file CSS, per aggiungere uno stile alla tua pagina web. Crea una nuova cartella dal nome `css` all'interno della tua cartella `static`. Poi, crea un nuovo file all'interno della tua cartella `css` e chiamalo `blog.css`. Fatto? djangogirls └─── blog └─── static └─── css └─── blog.css + +È il giunto il momento di scrivere un po' di CSS! Apri il file `static/css/blog.css` nel tuo editor di codice. -È giunto il momento di scrivere un po' di CSS! Apri il file `static/css/blog.css` nel tuo editor di codice. - -Non ci dilungheremo troppo sul come personalizzare e imparare CSS in questo momento, dal momento che è abbastanza facile e puoi impararlo da solo/a alla fine di questo workshop. Ti raccomandiamo caldamente di seguire questo corso [Codeacademy HTML & CSS course][2] per imparare tutto quello che serve sapere per poter rendere più bello un sito internet con CSS. +Non approfondiremo l'apprendimento dei CSS in questa sede. Se vuoi saperne di più, in fondo a questa pagina ti consigliamo un corso gratuito. - [2]: https://www.codecademy.com/tracks/web - -Facciamo comunque un esempio. Perchè non cambiare il colore del nostro header? Per decifrare i colori, i computer usano dei codici speciali. Questi codici cominciano con `#` a cui fanno seguito 6 caratteri, sia lettere (A-F) che numeri (0-9). Puoi trovare vari esempi di codici colore qui: http://www.colorpicker.com/. Puoi anche usare [colori predefiniti][3] come ad esempio `red` e `green`. - - [3]: http://www.w3schools.com/cssref/css_colornames.asp +Facciamo comunque un esempio. Vogliamo cambiare il colore del nostro header? Per decifrare i colori, i computer usano dei codici speciali. Questi codici iniziano con `#` seguiti da 6 lettere (A–F) e numeri (0–9). Per esempio, questo è il codice per il blu `#0000FF`. Puoi trovare i codici per molti colori qui: http://www.colorpicker.com/. Puoi anche usare [colori predefiniti](http://www.w3schools.com/colors/colors_names.asp) come ad esempio `red` e `green`. Aggiungi il seguente codice nel tuo file `static/css/blog.css`: +{% filename %}blog/static/css/blog.css{% endfilename %} + ```css -h1 a { -    color: #FCA205; +h1 a, h2 a { + color: #C25100; } + ``` -`h1 a` è un esempio di selettore CSS. Questo significa che stiamo cercando di cambiare lo stile su tutti gli elementi `a` all'interno di un elemento `h1` (in questo caso, abbiamo una linea di codice così strutturata: `

link

`). In questo caso, stiamo cercando di cambiare il colore con `#FCA205`, che corrisponde all'arancione. Ovviamente puoi mettere il codice di qualsiasi altro colore tu preferisca! +`h1 a` è un esempio di selettore CSS. Significa che stiamo applicando i nostri fogli di stile ad ogni elemento `a` all'interno di un elemento `h1`; il selettore `h2 a` si comporta allo stesso modo con gli elementi `h2`. Quindi quando si ha qualcosa come `

link

`, lo stile `h1 a` verrà applicato. In questo caso stiamo impostando il colore `#C25100`, che corrisponde all'arancione scuro. Puoi inserire il colore che preferisci, ma assicurati che ci sia un buon contrasto con lo sfondo bianco! -In un file CSS definiamo lo stile degli elementi presenti nel file HTML. Gli elementi in questione vengono identificati con il nome (ad esempio `a`, `h1`, `body`) oppure con l'attributo `class` o l'attributo `id`. Class e id sono i nomi che assegni agli elementi. Le classi definiscono gruppi di elementi mentre gli id indicano uno specifico elemento. Ad esempio, il seguente elemento può essere identificato nel CSS utilizzando il nome del tag `a`, la classe `external_link` oppure l'id ` link_to_wiki_page`: +In un file CSS definiamo lo stile degli elementi presenti nel file HTML. Il primo modo per identificare gli elementi è attraverso il loro nome. Potresti ricordarli come tags dalla sezione sull'HTML. Cose come `a`, `h1` e `body` sono tutti esempi di nomi di elementi. Possiamo identificare anche con l'attributo `class` o l'attributo `id`. Class e id sono i nomi che assegni agli elementi. Le classi definiscono gruppi di elementi mentre gli id indicano uno specifico elemento. Per esempio, potresti identificare il seguente elemento utilizzando il nome dell'elemento `a`, la classe `external_link`, o l'ID`link_to_wiki_page`: ```html ``` -Per saperne di più puoi leggere [CSS Selectors in w3schools][4]. +Puoi leggere di più su i [Selettori CSS su w3schools](http://www.w3schools.com/cssref/css_selectors.asp). - [4]: http://www.w3schools.com/cssref/css_selectors.asp +Inoltre dobbiamo dire al nostro template HTML che abbiamo aggiunto del codice CSS. Apri il file `blog/templates/blog/post_list.html` nell'editor di codice e aggiungi questa riga all'inizio: -Infine, dobbiamo anche far sapere al nostro template in HTML che abbiamo effettivamente aggiunto un po' di CSS. Apri il file `blog/templates/blog/post_list.html` e aggiungi la seguente riga di testo: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} ``` -Per ora stiamo solamente caricando tutti i nostri static files :). Aggiungi questa riga di testo tra `` e ``, subito dopo il link al file CSS di Bootstrap (il browser legge i file nell'ordine in cui sono dati, per cui il codice nei nostri files può sovrascrivere il codice presente nei files di Bootstrap): +Qui stiamo semplicemente caricando file statici. :) Tra i tag `` e ``, dopo il link ai file CSS di Bootstrap, aggiungi la riga seguente: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html ``` -Stiamo dicendo al nostro template dove trovare i nostri file CSS. +Il browser legge i file nell'ordine in cui sono messi, quindi dobbiamo essere sicuri che sia nel posto giusto. Altrimenti il codice del nostro file potrebbe essere sovrascritto dal codice dei file di Bootstrap. Stiamo dicendo al nostro template dove trovare i nostri file CSS. Il tuo file dovrebbe avere questo aspetto: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html -{% load staticfiles %} +{% load static %} + -     -        Django Girls blog -         -         -         -     -     -         - -        {% for post in posts %} -            
-                

published: {{ post.published_date }}

-                

{{ post.title }}

-                

{{ post.text|linebreaksbr }}

-            
-        {% endfor %} -     + + Django Girls blog + + + + +
+

Django Girls Blog

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

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} + ``` OK, salviamo il file e ricarichiamo la pagina web! -![Figura 14.2][5] - - [5]: images/color2.png +![Figura 14.2](images/color2.png) Ben fatto! Adesso potremmo dare un po' più d'aria alla nostra pagina web e aumentare il margine nella parte sinistra. Proviamo! +{% filename %}blog/static/css/blog.css{% endfilename %} + ```css body { -    padding-left: 15px; + padding-left: 15px; } ``` -Aggiungi questo al tuo CSS, salva il file e guarda il risultato! +Aggiungi queste righe al tuo CSS, salva il file e guarda il risultato! -![Figura 14.3][6] - - [6]: images/margin2.png +![Figura 14.3](images/margin2.png) Potremmo anche personalizzare lo stile calligrafico nel nostro header. Incolla quanto segue all'interno del tag `` che si trova nel file `blog/templates/blog/post_list.html`: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html - + ``` -Questa riga consente di importare un font chiamato *Lobster* da Google Fonts (https://www.google.com/fonts). +Come prima, controlla l'ordine e la posizione prima del link a `blog/static/css/blog.css`. Questa riga di codice importerà un carattere chiamato *Lobster* da Google Fonts (https://www.google.com/fonts). + +Trova il blocco `h1 a` (il codice tra parentesi `{` e `}`) nel file CSS `blog/static/css/blog.css`. Ora aggiungi la riga `font-family: 'Lobster';` tra le parentesi e ricarica la pagina: -Ora aggiungi `font-family: 'Lobster';` nel file CSS `static/css/blog.css` all'interno del blocco `h1 a` (il codice tra le due parentesi graffe, `{` e `}`) e ricarica la pagina: +{% filename %}blog/static/css/blog.css{% endfilename %} ```css -h1 a { -    color: #FCA205; -    font-family: 'Lobster'; +h1 a, h2 a { + color: #C25100; + font-family: 'Lobster'; } ``` -![Figura 14.3][7] - - [7]: images/font.png +![Figura 14.3](images/font.png) Grandioso! -Come già accennato, il CSS utilizza il concetto di 'classe' che in pratica ti permette di assegnare uno specifico nome ad una parte del tuo documento HTML e di applicare uno stile solo a questa parte senza cambiare il resto. È di grande aiuto quando hai due div che hanno funzioni differenti (ad esempio uno è un header e l'altro un post), e non vuoi che appaiano uguali. +Come già detto in precedenza, CSS possiede il concetto di classi. Questo ti permette identificare una parte del codice HTML e applicare lo stile solo su quella parte, senza modificare le altre. Questo è utilissimo! Potresti avere due div che hanno qualcosa di differente (come il tuo header e il tuo post). Una classe ti aiuta a renderli differenti. + +Vai avanti e chiama alcune parti del codice HTML. Sostituisci l'`intestazione` che contiene l'intestazione con quanto segue: -Prova a dare dei nomi ad alcune parti dell'HTML. Aggiungi una classe chiamta `page-header` al tuo `div` che contiene l'intestazione così: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - + ``` -E ora aggiungi una classe `post` al tuo `div` che contiene un articolo del blog. +E ora aggiungi una classe `post` al tuo `articolo` che contiene un post del blog. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -
-    

published: {{ post.published_date }}

-    

{{ post.title }}

-    

{{ post.text|linebreaksbr }}

-
+
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
``` -Ora aggiungiamo dei blocchi di codice ai nostri nuovi selettori. I selettori che iniziano con `.` indicano una classe. Online ci sono molti tutorial e spiegazioni sul CSS che possono aiutarti a comprendere il codice che stiamo per scrivere. Per ora, copia e incolla quanto segue nel tuo file `mysite/static/css/blog.css`: +Ora aggiungiamo dei blocchi di codice ai nostri nuovi selettori. I selettori che iniziano con `.` indicano una classe. Sul Web ci sono diversi ottimi tutorial e spiegazioni sui CSS che possono aiutarti a capire il codice che stiamo per scrivere. Per ora, copia e incolla quanto segue nel tuo file `blog/static/css/blog.css`: + +{% filename %}blog/static/css/blog.css{% endfilename %} ```css .page-header { -    background-color: #ff9400; -    margin-top: 0; -    padding: 20px 20px 20px 40px; + 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 { -    color: #ffffff; -    font-size: 36pt; -    text-decoration: none; +.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 { -    font-family: 'Lobster', cursive; +h1, +h2, +h3, +h4 { + font-family: 'Lobster', cursive; } .date { -    float: right; -    color: #828282; + color: #828282; } .save { -    float: right; + float: right; } -.post-form textarea, .post-form input { -    width: 100%; +.post-form textarea, +.post-form input { + width: 100%; } -.top-menu, .top-menu:hover, .top-menu:visited { -    color: #ffffff; -    float: right; -    font-size: 26pt; -    margin-right: 20px; +.top-menu, +.top-menu:hover, +.top-menu:visited { + color: #ffffff; + float: right; + font-size: 26pt; + margin-right: 20px; } .post { -    margin-bottom: 70px; + margin-bottom: 70px; +} + +.post h2 a, +.post h2 a:visited { + color: #000000; } -.post h1 a, .post h1 a:visited { -    color: #000000; +.post > .date, +.post > .actions { + float: right; +} + +.btn-default, +.btn-default:visited { + color: #C25100; + background: none; + border-color: #C25100; +} + +.btn-default:hover { + color: #FFFFFF; + background-color: #C25100; } ``` Ora aggiungi all'esterno del codice HTML riguardante i posts all'interno del blog alcuni elementi con definizione di classi. Sostituisci questo: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html {% for post in posts %} -    
-        

published: {{ post.published_date }}

-        

{{ post.title }}

-        

{{ post.text|linebreaksbr }}

-    
+
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
{% endfor %} ``` nel file `blog/templates/blog/post_list.html` con quanto segue: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html -
-    
-        
-            {% for post in posts %} -                
-                    
-                        {{ post.published_date }} -                    
-                    

{{ post.title }}

-                    

{{ post.text|linebreaksbr }}

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

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
``` Salva entrambi i file e ricarica la pagina web. -![Figura 14.4][8] - - [8]: images/final.png +![Figura 14.4](images/final.png) -Woohoo! È fantastico, vero? Il codice che abbiamo appena inserito non è poi così difficile da comprendere, dovresti riuscire a capirne la maggior parte semplicemente leggendolo. +Woohoo! È fantastico, vero? Guarda il codice che abbiamo appena incollato, per trovare i punti dove abbiamo aggiunto le classi nell'HTML usate nel CSS. Dove dovremmo modificare se volessimo la data in azzurro? -Non farti spaventare, sperimenta con i CSS e prova a cambiare alcune cose. Se rompi qualcosa, non ti preoccupare, puoi sempre farlo tornare come era prima! +Non aver paura di fare qualche esperimento con i CSS, prova a fare qualche modifica. Giocare con i CSS può aiutarti a capire cosa fanno le varie cose. Se fai qualche errore, non preoccuparti - puoi sempre tornare indietro! -Compito per casa post-workshop: ti consigliamo caldamente di seguire [il corso su HTML & CSS di Codeacademy][2]. Così potrai imparare tutto ciò di cui hai bisogno per rendere i tuoi siti web più belli sfruttando il CSS. +Consigliamo vivamente di seguire i corsi online gratuiti di "Basic HTML & HTML 5" e "Basic CSS" su [freeCodeCamp](https://learn.freecodecamp.org/). Possono aiutarti ad imparare tutto sul creare siti web più carini in HTML e CSS. Pronta per il prossimo capitolo?! :) \ No newline at end of file diff --git a/it/css/images/bootstrap1.png b/it/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/it/css/images/bootstrap1.png and b/it/css/images/bootstrap1.png differ diff --git a/it/css/images/color2.png b/it/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/it/css/images/color2.png and b/it/css/images/color2.png differ diff --git a/it/css/images/final.png b/it/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/it/css/images/final.png and b/it/css/images/final.png differ diff --git a/it/css/images/font.png b/it/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/it/css/images/font.png and b/it/css/images/font.png differ diff --git a/it/css/images/margin2.png b/it/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/it/css/images/margin2.png and b/it/css/images/margin2.png differ diff --git a/it/deploy/README.md b/it/deploy/README.md index 7108b23f80e..3a2a7374401 100644 --- a/it/deploy/README.md +++ b/it/deploy/README.md @@ -1,26 +1,18 @@ -# Deploy! +# Pubblica Online! -> **Nota** Il seguente capitolo è abbastanza difficile da capire fino in fondo. Non mollare e cerca di portarlo a termine; deployment (termine abbastanza complicato da tradurre, ma indica tutto ciò che tu rendi LIVE, accessibile sul web e non più solo dal tuo computer) è una parte importante nel processo di costruzione di un sito web. Questo capitolo è inserito a metà del tutorial per far sì che il tuo tutor possa aiutarti con il processo leggermente più complesso di messa online del sito. Questo significa che puoi ancora finire il tutorial da sola se sei a corto di tempo. +> **Nota** Il seguente capitolo può essere un po' difficile da fare fino in fondo. Non mollare e cerca di portarlo a termine; la pubblicazione online è una parte importante nel processo di costruzione di un sito web. Questo capitolo è collocato a metà del tutorial in modo che il tuo coach ti possa aiutare con il processo leggermente più complicato di messa online del sito. Questo significa che puoi ancora finire il tutorial per conto tuo se sei a corto di tempo. -Fino ad ora il tuo sito è accessibile solo dal tuo computer, ma ora imparerai come metterlo online! Deploying è il processo di pubblicazione online del tuo progetto in modo tale che sia visibile anche da altre persone :). +Fino ad ora il tuo sito web è stato presente solo sul tuo computer. Adesso imparerai come implementarlo! L'implementazione è il processo di pubblicazione online del tuo progetto in modo tale che sia visibile anche da altre persone. :) -Come hai già visto, un sito internet ha sede in un server. Ci sono tantissimi server providers disponibili su internet. Noi ne useremo uno che ha un processo di deployment relativamente semplice: [PythonAnywere][1]. Questo provider è gratuito per piccole applicazioni che non hanno troppi visitatori. Sarà quindi perfetto per te al momento. +Come abbiamo imparato, un sito Web deve trovarsi su un server. Ci sono molti server provider disponibili su Internet, noi useremo [PythonAnywhere](https://www.pythonanywhere.com/). PythonAnywhere è gratuito per le piccole applicazioni che non hanno troppi visitatori, sarà quindi perfetto per te al momento. - [1]: https://pythonanywhere.com/ +L'altro servizio esterno che useremo è [GitHub](https://www.github.com), che è un servizio di hosting di codice. Ne esistono altri, ma oggigiorno quasi tutti i programmatori hanno un account GitHub e ora lo avrai anche tu! -L'altro servizio esterno che useremo è [GitHub][2], che è un servizio di hosting di codice. Ne esistono altri, ma di questi tempi quasi tutti i programmatori hanno un account GitHub e ora lo avrai anche tu! - - [2]: https://www.github.com - -Useremo GitHub come trampolino di lancio per importare ed esportare il nostro codice su PythonAnywhere. +Questi tre servizi saranno importantissimi per te. Userai il tuo computer locale per sviluppare e fare test. Quando sarai soddisfatto delle modifiche, caricherai una copia del tuo programma su GitHub. Il tuo sito Web sarà su PythonAnywhere e lo aggiornerai con una nuova copia del codice da GitHub. # Git -Git è un "sistema di controllo versione" utilizzato da un sacco di programmatori. Questo software può tracciare le modifiche nel corso del tempo ad i file, in questo modo puoi ripristinare successivamente una specifica versione. Un pò come l'opzione "traccia modifiche" in Microsoft Word, ma molto più potente. - -## Installare Git - -> **Nota** Se hai già fatto la procedura di installazione, non devi farlo di nuovo - si può passare alla sezione successiva e iniziare a creare il tuo repository Git. +> **Nota** Se hai già terminato il processo di installazione, non é necessario eseguire nuovamente questa operazione. Puoi passare alla sezione successiva e iniziare a creare il tuo repository Git. {% include "/deploy/install_git.md" %} @@ -28,7 +20,9 @@ Git è un "sistema di controllo versione" utilizzato da un sacco di programmator Git tiene traccia delle modifiche a un particolare insieme di file in quello che è chiamato repository di codice (o "repo" in breve). Iniziamone uno per il nostro progetto. Apri la console ed esegui questi comandi nella directory `djangogirls`: -> **Nota** controlla la directory su cui stai lavorando adesso con il comando `pwd`(OSX/Linux) oppure `cd`(Windows) prima di iniziare il repository. Dovresti essere nella cartella `djangogirls`. +> **Nota** Controlla la tua cartella di lavoro corrente con a`pwd`(macOS/Linux) o`cd` (Windows) comando prima di inizziare il repository. Dovresti essere nella cartella `djangogirls`. + +{% filename %}comando-linea{% endfilename %} $ git init Initialized empty Git repository in ~/djangogirls/.git/ @@ -36,23 +30,55 @@ Git tiene traccia delle modifiche a un particolare insieme di file in quello che $ git config --global user.email you@example.com -Dobbiamo inizializzare il repository git solo una volta per ogni progetto (e non dovrai più reinserire il nome utente e l'email). +L'inizializzazione del repository git é qualcosa che dobbiamo fare una sola volta per progetto (e non dovrai piú reinserire il nome utente e l'indirizzo email). Git memorizzerà le modifiche a tutti i file e le cartelle in questa directory, ma ci sono alcuni file che vogliamo ignorare. Si fa creando un file chiamato `.gitignore` nella directory di base. Apri il tuo editor e crea un nuovo file con questo contenuto: +{% filename %}.gitignore{% endfilename %} + + # Python *.pyc + *~ __pycache__ - myvenv + + # Env + .env + myvenv/ + venv/ + + # Database db.sqlite3 - /static + + # 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 E salvalo come `.gitignore` all'interno della cartella "djangogirls". -> **Nota** Il punto all'inizio del nome del file è importante! Se hai difficoltà nel crearlo (ad esempio, ai Mac non piace quando crei file che iniziano con un punto tramite il Finder), allora usa la funzionalità "Salva con nome" nel tuo editor, è a prova di bomba. +> **Nota** Il punto all'inizio del nome del file è importante! Se hai difficoltá a crearlo (per esempio, Mac non piacere creare file che iniziano con un punto attraverso il Finder), usa la funzione "salva con nome" nell'editor, é a prova di proiettile. E assicurati di non aggiungere `.txt`, `.py`, o qualsiasi altra estensione al nome del file -- sarà riconosciuto da Git solo se il nome è `.gitignore`. Linux e MacOS trattano i file con un nome che inizia con `.` (come `.gitignore`) come nascosti ed il comando `Is` normale non mostrerà questi file. Invece usa `Is - a` per vedere il file `.gitignore`. +> +> **Nota** Uno dei file che hai specificato nel tuo file `.ginignore` è `db.sqlite3`. Questo file è il tuo database locale, in cui sono archiviati i post e gli utenti. Seguiremo le pratiche standard di programmazione web, ovvero useremo due diversi database: uno per il sito con cui effettuarai i test locali, e uno per il sito online su PythonAnywhere. Come database PythonAnywhere potresti usare SQLite, ma ne userai più spesso uno che si chiama MySQL, che può gestire molti più vsitatori di SQLite. In entrambi i casi, ignorando il database SQLite per la copia di GitHub, vuol dire che tutti i post che hai creato finora saranno solo disponibili localmente, ma li aggiungeremo nuovamente in produzione. Dovresti pensare al database locale come un parco giochi dove si possono provare cose diverse e senza avere paura di eliminare i tuoi messaggi reali dal tuo blog. -È una buona idea usare il comando `git status` prima di `git add` oppure ogni volta che non sei sicuro di cosa sia cambiato. Questo aiuterà ad evitare eventuali brutte sorprese, come file sbagliati che vengono aggiunti o a cui viene fatto il commit. Il comando `git status` restituisce informazioni riguardanti qualsiasi file non tracciato/modificato/in staging, lo stato del branch e molto altro. L'output dovrebbe essere simile a: +È una buona idea usare il comando `git status` prima di `git add` oppure ogni volta che non sei sicuro di cosa sia cambiato. Questo aiuterà ad evitare eventuali brutte sorprese, come file sbagliati che vengono aggiunti o a cui viene fatto il commit. Il comando `git status` restituisce informazioni riguardanti qualsiasi file non tracciato/modificato/in staging, lo stato del branch e molto altro. L'output dovrebbe essere simile a quanto segue: + +{% filename %}command-line{% endfilename %} $ git status On branch master @@ -66,14 +92,17 @@ E salvalo come `.gitignore` all'interno della cartella "djangogirls". blog/ manage.py mysite/ + requirements.txt nothing added to commit but untracked files present (use "git add" to track) E finalmente salviamo le nostre modifiche. vai alla tua console ed esegui questi comandi: - $ git add --all . - $ git commit -m "La mia app Django Girls, primo commit" +{% filename %}command-line{% endfilename %} + + $ git add . + $ git commit -m "My Django Girls app, first commit" [...] 13 files changed, 200 insertions(+) create mode 100644 .gitignore @@ -81,233 +110,137 @@ E finalmente salviamo le nostre modifiche. vai alla tua console ed esegui questi create mode 100644 mysite/wsgi.py -## Pubblichiamo il nostro codice su GitHub - -Vai su [GitHub.com][2] e registrati per ottenere un nuovo account gratuito. (Se l'hai già fatto nella preparazione di laboratorio, è fantastico!) +## Pubblica il tuo codice su GitHub -Quindi, crea un nuovo repository, dandogli il nome "my-first-blog". Lascia deselezionata la casella di controllo "initialise with a README", lascia l'opzione di .gitignore vuota (lo abbiamo fatto manualmente) e License su None. +Vai su [GitHub.com](https://www.github.com) e crea un nuovo account gratuito. (Se lo hai già fatto nella preparazione al workshop, benissimo!) Assicurati di ricordare la tua password (aggiungila al tuo password manager, se ne usi uno). -![][3] +Quindi, crea un nuovo repository con il il nome "my-first-blog". Lascia deselezionata la casella di controllo "initialise with a README", lascia vuota l'opzione .gitignore (lo abbiamo già fatto manualmente) e lascia License su None. - [3]: images/new_github_repo.png +![](images/new_github_repo.png) -> **Nota** Il nome `my-first-blog` è importante -- potresti scegliere qualcos'altro, ma si ripeterà un sacco di volte nelle istruzioni qui sotto, e dovrai sostituirlo ogni volta. Probabilmente è più facile mantenere il nome `my-first-blog`. +> **Nota** Il nome `my-first-blog` è importante -- potresti sceglierne un altro, ma il nome verrà ripetuto un sacco di volte nelle istruzioni qui sotto, e dovresti sostituirlo ogni volta. Probabilmente è più facile mantenere il nome `my-first-blog`. -Nella schermata successiva, ti verrà mostrato l'URL per clonare il tuo repo: +Sulla prossima schermata, ti sarà mostrato il tuo clone URL ricopiato, che userai in alcuni dei comandi che seguono: -![][4] +![](images/github_get_repo_url_screenshot.png) - [4]: images/github_get_repo_url_screenshot.png +Ora dobbiamo collegare il repository Git sul tuo computer a quello su GitHub. -Ora abbiamo bisogno di collegare il repository Git sul tuo computer a quello su GitHub. +Digita quanto segue sulla tua console (sostituisci `` con il nome utente che hai inserito quando hai creato l'account GitHub, ma senza le parentesi angolari -- l'URL dovrebbe coincidere con L'URL clone che hai appena visto): -Digita quanto segue sulla tua console (Sostituisci `` con il nome utente che hai inserito quando hai creato il account GitHub, ma senza le parentesi angolari): +{% filename %}command-line{% endfilename %} $ git remote add origin https://github.com//my-first-blog.git $ git push -u origin master -Inserisci il tuo username e la tua password di GitHub. Dovresti vedere qualcosa di simile: +Quando si spinge su GitHub, ti verrà chiesto il tuo nome utente e password GitHub (o nella finestra di comando o in una finestra pop-up), e dopo aver inserito le credenziali si dovrebbe vedere qualcosa di simile a questo: + +{% 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 + To https://github.com/ola/my-first-blog.git + * [new branch] master -> master Branch master set up to track remote branch master from origin. - + -Adesso Il tuo codice è su GitHub. Ora controlla! Scoprirai che è in bella compagnia - [Django][5], il [Django Girls Tutorial][6] e molti altri grandi progetti open source software usano GitHub per ospitare il loro codice :) - - [5]: https://github.com/django/django - [6]: https://github.com/DjangoGirls/tutorial +Adesso Il tuo codice è su GitHub. Guarda! Lo troverai in buona compagnia - [Django](https://github.com/django/django), il [Django Girls Tutorial](https://github.com/DjangoGirls/tutorial) e molti grandi progetti di software open source caricano il proprio codice su GitHub. :) # Configurare il nostro blog su PythonAnywhere -> **Nota** Potresti aver già creato un account di PythonAnywhere precedentemente, durante i passaggi di installazione - se è così, non c'è bisogno di farlo nuovamente. +## Crea un account PythonAnywhere -{% include "/deploy/signup_pythonanywhere.md" %} +> **Nota** Potresti aver già creato un account PythonAnywhere prima, durante la fase di installazione - in questo caso, non c'è bisogno di crearlo di nuovo. -## Scaricare il nostro codice su PythonAnywhere - -Quando ti sarai registrata su PythonAnywhere, verrai portata alla tua dashboard o alla pagina «Console». Scegli l'opzione per iniziare una console "Bash" -- quella è la versione PythonAnywhere di una console, proprio come quella sul tuo computer. +{% include "/deploy/signup_pythonanywhere.md" %} -> **Nota** PythonAnywhere è basato su Linux, quindi se sei su Windows, la console apparirà un po' diversa da quella sul tuo computer. +## Configurare il nostro sito su PythonAnywhere -Scarichiamo il nostro codice da GitHub e su PythonAnywhere creando un "clone" del nostro repo. Digita quanto segue nella console su PythonAnywhere ( non dimenticare di usare il tuo nome utente di GitHub al posto di ``): +Torna alla [PythonAnywhere Dashboard](https://www.pythonanywhere.com/) principale cliccando sul logo e scegli l'opzione per avviare una console "Bash” - questa è la versione PythonAnywhere di una riga di comando, proprio come quella sul tuo computer. - $ git clone https://github.com//my-first-blog.git - +![La sezione 'Nuova Console' sull'interfaccia web PythonAnywhere, con un pulsante per 'bash'](images/pythonanywhere_bash_console.png) -Questo scaricherà una copia del tuo codice su PythonAnywhere. Dai un'occhiata digitando `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 - +> **Nota** PythonAnywhere si basa su Linux, quindi se sei su Windows, la console apparirà un po' diversa da quella del tuo computer. -### Creare un virtualenv su PythonAnywhere +Per implementare un'applicazione web su PythonAnywhere devi prendere il codice da GitHub, e configurare PythonAnywhere in modo che lo riconosca come un'applicazione web. Puoi farlo manualmente, ma PythonAnywhere ti fornisce uno strumento che farà tutto il lavoro al posto tuo. Prima di tutto installiamolo: -Proprio come hai fatto sul tuo computer, puoi creare un virtualenv su PythonAnywhere. Nella console di Bash, digita: +{% filename %}PythonAnywhere command-line{% endfilename %} - 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==1.8 whitenoise==2.0 - Collecting django - [...] - Successfully installed django-1.8.2 whitenoise-2.0 + $ pip install --user pythonanywhere -> **Nota** Il passaggio `pip install` può richiedere un paio di minuti. Sii paziente! Ma se richiede più di 5 minuti, c'è qualcosa di sbagliato. Chiedi al tuo coach. - - - -### Raccogliere file statici. - -Ti stavi chiedendo cos'è quel "whitenoise"? È uno strumento per fornire i cosiddetti "file statici". I file statici sono i file che di solito non cambiano o non eseguono codice di programmazione, come i file HTML o CSS. Funzionano in modo diverso sui server e abbiamo bisogno di uno strumento come "whitenoise" per fornirli. +Ora dovresti leggere: `Collecting pythonanywhere` e un'eventuale riga finale che dice `Successfully installed (...) pythonanywhere- (...)`. -Scopriremo un po' di più sui file statici più tardi nell'esercitazione, quando modificheremo il CSS per il nostro sito. +Ora eseguiamo l'helper per configurare automaticamente la nostra applicazione da GitHub. Digita quanto segue nella console su PythonAnywhere (non dimenticare di usare il tuo nome utente di GitHub al posto di ``) in modo che l'URL corrisponda all'URL clone di GitHub: -Per ora abbiamo solo bisogno di eseguire un comando supplementare chiamato `collectstatic`, sul server. Dice a Django di raccogliere tutti i file statici di cui ha bisogno sul server. Al momento questi sono per lo più file che fanno apparire carino il sito di amministrazione. +{% filename %}PythonAnywhere command-line{% endfilename %} - (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 + $ pa_autoconfigure_django.py --python=3.10 https://github.com//my-first-blog.git -Digita "yes" e si parte! Non ti piace far stampare al computer pagine e pagine di testo incomprensibile? Faccio sempre piccoli versi per accompagnarlo. Brp, brp brp... +Guardando l'esecuzione, potrai vedere cosa sta facendo: - 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'. - +- Scaricare il tuo codice da GitHub +- Creare un virtualenv su PythonAnywhere, come quello sul tuo computer +- Aggiornare il file di impostazioni con alcune impostazioni di implementazione +- Configurare un database su PythonAnywhere utilizzando il comando `manage.py migrate` +- Configurare i tuoi file statici (di cui parlaremo più avanti) +- E configurare PythonAnywhere per servire la tua app web tramite la sua API -### Creare il database su PythonAnywhere +Su PythonAnywhere tutti questi passaggi sono automatizzati, ma sono gli stessi passaggi che dovresti effettuare con qualsiasi altro server provider. -Ecco un'altra differenza tra il tuo computer ed il server: usa un database diverso. Quindi gli account utente ed i post possono essere diversi sul server rispetto a come appaiono sul tuo computer. +La cosa principale da notare ora è che il tuo database su PythonAnywhere è completamente separato dal database sul tuo computer, e quindi può avere post e account di amministrazione differenti. Di conseguenza, come abbiamo fatto sul computer, dobbiamo inizializzare l'account di amministrazione con `createsuperuser`. PythonAnywhere ha attivato automaticamente il tuo virtualenv, quindi ora devi solo eseguire il codice seguente: -Possiamo inizializzare il database sul server proprio come abbiamo fatto sul tuo computer, con `migrate` e `createsuperuser`: +{% filename %}PythonAnywhere command-line{% endfilename %} - (mvenv) $ python manage.py migrate - Operations to perform: - [...] - Applying sessions.0001_initial... OK - - - (mvenv) $ python manage.py createsuperuser + (ola.pythonanywhere.com) $ python manage.py createsuperuser -## Pubblicare il nostro blog come una web app - -Ora il nostro codice è su PythonAnywhere, il nostro virutualenv è pronto, i file statici sono stati raccolti, ed il database è stato inizializzato. Siamo pronti a pubblicarlo come una web app! - -Torna alla dashboard di PythonAnywhere cliccando sul suo logo, e clicca sulla scheda **Web**. Infine, premi **Add a new web app**. - -Dopo aver confermato il nome del dominio, scegli **manual configuration** (NB *non* l'opzione "Django") nella finestra di dialogo. Successivamente, scegli **Python 3.4** e clicca su Avanti per completare la procedura guidata. - -> **Nota** assicurati di aver scelto l'opzione "Manual configuration", non l'opzione "Django". Siamo troppo cool per l'installazione di Django di PythonAnywhere di default;-) - -### Impostare il virtualenv - -Verrai portato alla schermata di configurazione PythonAnywhere per tua webapp, che è dove dovrai andare ogni volta che desideri apportare modifiche all'applicazione sul server. - -![][7] +Inserisci i dettagli per l'utente di amministrazione. È meglio utilizzare gli stessi che stai usando sul computer per evitare confusione, a meno che non desideri rendere la password su PythonAnywhere più sicura. - [7]: images/pythonanywhere_web_tab_virtualenv.png +Ora, se vuoi, puoi anche dare un'occhiata al tuo codice su PythonAnywhere utilizzando `ls`: -Nella sezione "Virtualenv", clicca sul testo rosso che dice "Enter the path to a virtualenv" ed immetti: `/home//my-first-blog/myvenv/`. Clicca sul riquadro blu con il segno di spunta per salvare il percorso prima di andare avanti. +{% filename %}PythonAnywhere command-line{% endfilename %} -> **Note** Sostituisci il tuo nome utente come appropriato. se commetti un errore, PythonAnywhere ti avvertirà. - -### Configurare il file WSGI - -Django funziona usando il "protocollo WSGI", uno standard per fornire siti Web utilizzando Python, che PythonAnywhere supporta. Il modo in cui configuriamo PythonAnywhere per riconoscere il nostro blog in Django è modificando un file di configurazione WSGI. - -Clicca sul link "WSGI configuration file" (nella sezione "Code" nella parte superiore della pagina -- avrà un nome tipo `/var/www/ _pythonanywhere_com_wsgi.py`), e accederai ad un editor. - -Elimina tutti i contenuti e sostituiscili con qualcosa di simile: - -```python -import os -import sys - -path = '/home//my-first-blog' # usa il tuo username qui -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()) -``` + (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 + -> **Nota** non dimenticare di mettere il tuo nome utente dove dice `` +Puoi anche andare alla pagina "File" e navigare in uso del browser di file integrato di PythonAnywhere. (Dalla pagina Console, puoi raggiungere altre pagine PythonAnywhere dal pulsante menu nell'angolo in alto a destra. Una volta che sei su una delle pagine, ci sono link agli altri vicini all'alto.) -Il compito di questo file è dire a PythonAnywhere dove si trova la nostra web app e qual è il nome del file che contiene le impostazioni Django. Inolte, configura lo strumento di file statici "whitenoise". +## Ora sei online! -Clicca **Save** e poi torna alla scheda **Web**. +Ora il tuo sito dovrebbe essere stato pubblicato online! Clicca sulla pagina PythonAnywhere per ottenere un link. Puoi condividerlo con chiunque tu voglia :) -Abbiamo finito! Premi il grande pulsante verde **Reload** e potrai vedere la tua applicazione. Troverai un link nella parte superiore della pagina. +> **Nota** Questo è un tutorial per principianti, e nel distribuire questo sito abbiamo preso alcune scorciatoie che non sono ideali dal punto di vista della sicurezza. Se e quando decidi di usare questo progetto in produzione, oppure di avviare un nuovo progetto, dovresti controllare la [Django deployment checklist](https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/) per alcuni consigli di sicurezza del tuo sito. ## Suggerimenti per il debug -Se vedi un errore quando provi a visitare il tuo sito, il primo posto dove cercare qualche info per il debugging è nel tuo **error log**. Troverai un link nella [ scheda Web][8] di PythonAnywhere. Vedi se ci sono messaggi di errore lì; i più recenti sono alla fine. I problemi comuni includono: - - [8]: https://www.pythonanywhere.com/web_app_setup/ - -* Dimenticare uno dei passi che abbiamo fatto nella console: creare il virtualenv, attivarlo, installarci Django, eseguire collecstatic, inizializzazione del database. +Se si osserva un errore durante l'esecuzione dello script `pa_autoconfigure_django.py`, ecco alcune cause comuni: -* Commettere un errore nel percorso del virtualenv sulla scheda Web -- di solito c'è un piccolo messaggio di errore in rosso, se c'è un problema. +- Dimenticare di creare il tuo token API PythonAnywhere. +- Errore nel tuo URL GitHub +- Se vedi un errore dicendo * "Non è stato possibile trovare le impostazioni.py"*, probabilmente perché non è riuscito ad aggiungere tutti i file a Git e/o non li hai spinti fino a GitHub con successo. Dai un altro sguardo alla sezione Git qui sopra +- Se ti sei registrato in precedenza con un account su PythonAnywhere e hai avuto un errore con il comando collectstatic, probabilmente, il tuo account ha una versione un po' vecchia di SQLite (es. 3..2). In tal caso, registrati per un nuovo account e prova i comandi nella sezione PythonAnywhere qui sopra. -* Commettere un errore nel file di configurazione WSGI -- il percorso che hai trovato per tua cartella my-first-blog è corretto? +Se vedi un errore quando provi a visitare il tuo sito, il primo posto dove cercare qualche info per il debugging è nel tuo **error log**. Troverai un link nella [ scheda Web](https://www.pythonanywhere.com/web_app_setup/) di PythonAnywhere. Vedi se ci sono messaggi di errore lì; i più recenti sono alla fine. -* Hai adottato la stessa versione di Python per il tuo virtualenv come hai fatto per la tua app web? entrambe dovrebbero essere 3.4. - -* Ci sono alcuni [consigli generali per il debugging sulla wiki di PythonAnywhere][9]. - - [9]: https://www.pythonanywhere.com/wiki/DebuggingImportError +Ci sono alcuni [consigli generali per il debugging sulla wiki di PythonAnywhere](http://help.pythonanywhere.com/pages/DebuggingImportError). E ricorda, il tuo coach è qui per aiutarti! -# Sei live! +# Scopri il tuo Elenco di Vita! + +La pagina predefinita per il tuo sito dovrebbe dire "Welcome to Django", esattamente come sul tuo Pc locale. Prova ad aggiungere `/admin/` alla fine della URL, e verrai portata al sito di amministrazione. Accedi con il nome utente e la password, e vedrai che puoi aggiungere nuovi post sul server -- ricorda che i post del database di test locale non sono stati inviati al tuo blog live. -La pagina predefinita per il tuo sito dovrebbe dire "Welcome to Django", esattamente come sul tuo Pc locale. Prova ad aggiungere `/admin/` alla fine della URL, e verrai portata al sito di amministrazione. Accedi con il tuo username e password, e vedrai che puoi aggiungere nuovi Post sul server. +Una volta che hai creato un paio di post, puoi tornare indietro alla copia locale (non PythonAnywhere). Da qui in poi, lavori sulla tua copia locale per fare le modifiche. Si tratta di un flusso di lavoro comune nello sviluppo Web (apportare modifiche localmente, inviare quei cambiamenti su GitHub, aggiornare le tue modifiche sul server Web. Questo consente di lavorare e fare esperimenti senza rompere il tuo sito Web. Bello, vero? -Dà a te stessa un' *ENORME* pacca sulla schiena! Il deploy dei server è tra le parti più complicate dello sviluppo web e di solito le persone ci impiegano svariati giorni prima di farli funzionare. Ma hai pubblicato il tuo sito su Internet senza sforzo! +Dà a te stessa un' *ENORME* pacca sulla schiena! Il deploy dei server è tra le parti più complicate dello sviluppo web e di solito le persone ci impiegano svariati giorni prima di farli funzionare. Ma hai pubblicato il tuo sito su Internet senza sforzo! \ No newline at end of file diff --git a/it/deploy/images/github_get_repo_url_screenshot.png b/it/deploy/images/github_get_repo_url_screenshot.png index 62a29f5f8d7..ee1560b1e85 100644 Binary files a/it/deploy/images/github_get_repo_url_screenshot.png and b/it/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/it/deploy/images/new_github_repo.png b/it/deploy/images/new_github_repo.png index 64011e59a52..d1f82e5d863 100644 Binary files a/it/deploy/images/new_github_repo.png and b/it/deploy/images/new_github_repo.png differ diff --git a/it/deploy/images/pythonanywhere_account.png b/it/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/it/deploy/images/pythonanywhere_account.png differ diff --git a/it/deploy/images/pythonanywhere_bash_console.png b/it/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..68eb2a030e1 Binary files /dev/null and b/it/deploy/images/pythonanywhere_bash_console.png differ diff --git a/it/deploy/images/pythonanywhere_beginner_account_button.png b/it/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/it/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/it/deploy/images/pythonanywhere_create_api_token.png b/it/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..abae45ae37a Binary files /dev/null and b/it/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/it/deploy/images/pythonanywhere_web_tab_virtualenv.png b/it/deploy/images/pythonanywhere_web_tab_virtualenv.png deleted file mode 100644 index 97e87e7b07b..00000000000 Binary files a/it/deploy/images/pythonanywhere_web_tab_virtualenv.png and /dev/null differ diff --git a/it/deploy/install_git.md b/it/deploy/install_git.md index dac44912b60..f0d8884287c 100644 --- a/it/deploy/install_git.md +++ b/it/deploy/install_git.md @@ -1,17 +1,52 @@ -### Windows +Git è un "sistema di controllo versione" utilizzato da molti programmatori. Questo software può tracciare le modifiche ai file nel corso del tempo, così da poter ripristinare successivamente una specifica versione. Un po' come la funzione "revisioni" nei programmi di elaborazione di testi (come Microsoft Word o LibreOffice), ma molto più potente. -È possibile scaricare Git da [git-scm.com](https://git-scm.com/). Puoi saltare tutti i passaggi tranne uno. Nel quinto passaggio, dal titolo "Regolazione della variabile PATH di sistema", scegli "Esegui Git e gli strumenti Unix associati dalla riga di comando di Windows" (l'opzione in basso). A parte questo, i valori predefiniti vanno bene. 'Checkout Windows-style' e 'commit Unix-style line endings' vanno bene. +## Installare Git -### MacOS + + +È possibile scaricare Git da [git-scm.com](https://git-scm.com/). Puoi saltare tutti i passaggi tranne due: nel passaggio dove ti chiede di scegliere l'editor, dovrai selezionare Nano, e nel passaggio "Regolazione della variabile di ambiente PATH", seleziona "Esegui Git e gli strumenti Unix opzionali dal prompt dei comandi di Windows" (l'opzione in basso). A parte questo, i valori predefiniti vanno bene. 'Checkout Windows-style' e 'commit Unix-style line endings' vanno bene. + +Non dimenticare di riavviare il prompt dei comandi o la powershell dopo che l'installazione è terminata con successo. + + Scarica Git da [git-scm.com](https://git-scm.com/) e segui le istruzioni. -### Linux +> **Nota** Se stai usando OS X 10.6, 10.7 o 10.8, dovrai installare la versione di Git da qui: [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) + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo apt install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo dnf install git +``` + + + + + +{% filename %}command-line{% endfilename %} -Se non è già installato, git dovrebbe essere disponibile tramite il gestore di pacchetti, prova a cercare: +```bash +$ sudo zypper install git +``` - sudo apt-get install git - # oppure - sudo yum install git - # oppure - sudo zypper install git + \ No newline at end of file diff --git a/it/deploy/signup_pythonanywhere.md b/it/deploy/signup_pythonanywhere.md index d70701156de..4ba19117885 100644 --- a/it/deploy/signup_pythonanywhere.md +++ b/it/deploy/signup_pythonanywhere.md @@ -1,5 +1,19 @@ -Ora è il momento di registrarsi per un account gratuito "Beginner" su PythonAnywhere. +PythonAnywhere è un servizio che permette di eseguire il codice Python sui server "nel cloud". Lo useremo per ospitare il nostro sito, live e su Internet. - * [www.pythonanywhere.com](https://www.pythonanywhere.com/) +Caricheremo il blog che stiamo realizzando su PythonAnywhere. Crea un account "beginner" su PythonAnywhere (l'account gratuito va benissimo, non ti serve una carta di credito). -> **Nota** Quando scegli il tuo nome utente, tieni conto che l'URL del tuo blog diventerà `iltuousername.pythonanywhere.com`, quindi scegli il tuo nickname oppure un nome ispirato a ciò su cui si basa il tuo blog. \ No newline at end of file +* [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +![Nella pagina di iscrizione di PythonAnywhere c'è il tasto per creare un account 'Principiante' gratuito](../deploy/images/pythonanywhere_beginner_account_button.png) + +> **Nota** Quando scegli il tuo nome utente, tieni presente che l'URL del tuo blog assumerá la forma` tuonomeutente.pythonanywhere.com`, quindi scegli il tuo soprannome o un nome che riguardi l'argomento del blog. Inoltre, assicurati di ricordare la tua password (aggiungilo al tuo password manager, se ne usi uno). + +## Creazione di un token API PythonAnywhere + +Dovrai compiere questo passaggio solo una volta. Dopo aver creato un account su PythonAnywhere, verrai indirizzata alla tua dashboard. Trova il link in alto a destra nella pagina "Account": + +![Link account in alto a destra sulla pagina](../deploy/images/pythonanywhere_account.png) + +quindi seleziona la scheda chiamata "API token", e premi il pulsante che dice "Crea nuovo token API". + +![La scheda token API nella pagina Account](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/it/django/README.md b/it/django/README.md index 5bcc3f74e2e..d9af20a3413 100644 --- a/it/django/README.md +++ b/it/django/README.md @@ -1,27 +1,27 @@ # Che cos'è Django? -Django (*/ˈdʒæŋɡoʊ/ jang-goh*) è un framework per applicazioni web gratuito e open source, scritto in Python. Un web framework è un insieme di componenti che ti aiuta a sviluppare siti web più velocemente e facilmente. +Django (/ˈdʒæŋɡoʊ/ *jang-goh*) è un framework per applicazioni web gratuito e open source, scritto in Python. Un web framework è un insieme di componenti che ti aiuta a sviluppare siti web più velocemente e facilmente. -Quando si costruisce un sito web, si ha sempre bisogno di un insieme di componenti simili: un sistema per gestire l'autenticazione dell'utente (registrazione, accesso, logout), un pannello di amministrazione per il tuo sito web, un sistema per caricare i file, ecc. +Per costruire un sito web ci vogliono sempre componenti molto simili: il sistema per gestire l'autenticazione dell'utente (registrazione, accesso, logout), il pannello di amministrazione del sito, il sistema per caricare i file, ecc. -Fortunatamente, alcune persone diverso tempo fa si sono rese conto che gli sviluppatori web incontrano problemi simili ogni volta che costruiscono un sito internet. Per questo motivo si sono uniti e hanno costruito dei framework (di cui Django fa parte) che offrono componenti già pronti per l'uso. +Non sei la prima e non sarai l'ultima persona ad affrontare questi problemi: altri programmatori prima di te li hanno affrontati e risolti, tanto spesso e tanto ripetitivamente da aver distillato varie *web framework* (Django è una delle tante) che mettono a disposizione tutti gli elementi necessari, pronti per l'uso. -I frameworks esistono per evitare che tu debba reinventare la ruota e ti semplificano il lavoro quando crei un nuovo sito. +La funzione dei *framework* è evitare di dover reinventare l'acqua calda, e risparmiar tempo nel mettere in piedi un nuovo progetto. ## Perché ho bisogno di un framework? -Per capire Django, abbiamo bisogno di dare un'occhiata più da vicino ai server. La prima cosa che il server deve sapere è che vuoi che ti fornisca una pagina web. +Per capire bene cosa è Django, a cosa serve davvero, diamo uno sguardo più da vicino ai server. Tanto per incominciare, bisogna che il server sappia che gli si sta chiedendo qualcosa, per esempio una pagina web. -Immagina una cassetta delle lettere che monitora tutte le lettere in entrata (richieste). Questo è ciò che fa un web server. Il web server legge le lettere, e invia una risposta con una pagina web. Ma quando vuoi inviare qualcosa, hai bisogno di avere qualche contenuto. E Django è ciò che ti aiuta a creare questo contenuto. +Immagina una cassetta delle lettere (port), che venga continuamente tenuta d'occhio, nel caso arrivino lettere (request). Questo è ciò che fa un server: tiene d'occhio un *port* e sbriga le *request* in arrivo. Un server web legge il contenuto della richiesta ed invia una risposta, sotto forma di pagina web. Ma quando vuoi inviare qualcosa, hai bisogno di avere qualche contenuto. E Django è ciò che ti aiuta a creare questo contenuto. ## Cosa succede quando qualcuno richiede un sito Web dal tuo server? -Quando una richiesta arriva al web server, viene passata a Django che prova a capire che cosa é stato veramente richiesto. Django prende l'indirizzo della pagina web e cerca di capire cosa deve fare. Questa parte viene svolta da Django **urlresolver** (nota che l'indirizzo di una pagina web si chiama URL - Uniform Resource Locator -per cui il nome *urlresolver* acquista significato). Non é molto intelligente -ha bisogno di una serie di schemi e in seguito prova a far corrispondere l'URL. Django controlla questi modelli o schemi da cima a fondo e se qualcosa corrisponde a quel punto Django passa la richiesta alla funzione associata (che si chiama *view*). +Quando una richiesta arriva ad un server web, questi lo passa a Django, che la interpreta, per capire cosa si stia richiedendo precisamente. Django esamina prima di tutto l'indirizzo della pagina web richiesta, e decide come proseguire. Di questa parte si occupa lo **urlresolver** di Django, (nota che un indirizzo di una pagina web si chiama URL, che sta per Localizzatore Uniforme di Risorse, cosa che spiega il nome *urlresolver*). Questo urlresolver non è nulla di trascendentale, non fa che raccogliere una serie di schemi e prova a trovare la corrispondenza per lo URL. Django passa in rassegna gli schemi disponibili, ed al primo che si adatti, passa la richiesta alla funzione associata (che si chiama *view*). Immagina un postino con una lettera. Sta camminando per la strada e controlla ogni numero civico mettendolo a confronto con quello sulla lettera. Se corrisponde, mette lì la lettera. Questo è il modo in cui l'urlresolver funziona! -Nella funzione *view* avvengono tutte le cose più interessanti: possiamo consultare un database alla ricerca di qualche informazione. Forse l'utente ha richiesto di cambiare qualcosa all'interno dei suoi dati? È come una lettera che dice "Per favore cambia la descrizione del mio lavoro". La *view* può controllare se sei autorizzata a farlo, poi aggiorna la descrizione del lavoro per te e manda un messaggio: "Fatto!". In seguito, la *view* genera una risposta e Django la può inviare al browser dell'utente. +Nella funzione *view*, è lì che avviene il vero lavoro: per esempio cercare in una base dati l'informazione richiesta. Forse l'utente ha richiesto di cambiare qualcosa all'interno dei suoi dati? Come se una lettera (la richiesta) dicesse: "aggiorna la descrizione del mio lavoro". La *view* verifica se hai autorizzazione a farlo, se sì, accetta il valore ricevuto come nuova descrizione, lo invia al database, e se il database le risponde "ok", la *view* costruisce la risposta alla richiesta iniziale, in modo che Django la possa servire al navigatore web dell'utente. -Naturalmente, la descrizione qui sopra é molto semplificata, ma per il momento non hai bisogno di sapere nel dettaglio tutti gli aspetti tecnici. Avere il senso generale per il momento è abbastanza. +La descrizione precedente è un tantinello semplificata, ma non c'è ancora bisogno di entrare nei dettagli tecnici. Serve bene per farsi un'idea corretta della interazione. -Per cui invece di perderci troppo nei dettagli, creeremo semplicemente qualcosa usando Django e apprenderemo i concetti fondamentali lungo la strada! \ No newline at end of file +A questo punto, lasciamo perdere i dettagli, che c'è tempo per impararli, e iniziamo piuttosto ad usare Django per costruire qualcosa. Strada facendo impareremo quello che manca, poco per volta. \ No newline at end of file diff --git a/it/django_admin/README.md b/it/django_admin/README.md index de3fcc57f64..aebd21f7712 100644 --- a/it/django_admin/README.md +++ b/it/django_admin/README.md @@ -1,47 +1,57 @@ -# Django admin +# L'interfaccia admin di Django -Per aggiungere, modificare e cancellare i post che abbiamo appena strutturato useremo Django admin. +Per aggiungere, modificare ed eliminare le pubblicazioni che abbiamo appena modellato, useremo l'amministratore di Django. -Apri il file `blog/admin.py` e sostituisci il suo contenuto con: +Apriamo `blog/admin.py` nell'editore testi e cambiamo il contenuto così: - from django.contrib import admin - from .models import Post - - admin.site.register(Post) - +{% filename %}blog/admin.py{% endfilename %} + +```python +from django.contrib import admin +from .models import Post + +admin.site.register(Post) +``` Come puoi vedere, stiamo importando (include) il modello di Post che abbiamo definito nel capitolo precedente. Per far si che il nostro modello sia visibile nella pagina di admin, dobbiamo registrare questo modello con `admin.site.register(Post)`. -OK, è tempo di guardare il nostro modello Post. Ricorda di eseguire `python manage.py runserver` nella console per avviare il web server. Vai nel browser e scrivi l'indirizzo http://127.0.0.1:8000/admin/ Vedrai una pagina di login come questa: +OK, è tempo di guardare il nostro Post. Ricorda di eseguire `python manage.py runserver` nella console per avviare il web server. Vai al tuo browser e digita l'indirizzo http://127.0.0.1:8000/admin/. Vedrai una pagina login simile a questa: -![Login page][1] +![Login page](images/login_page2.png) - [1]: images/login_page2.png +Per accedere, devi creare un *superuser* - un utente che ha pieno controllo di tutto quello che c'è sul sito. Torna alla riga di comando, digita `python manage.py createsuperuser`, e premi invio. -Per accedere, devi creare un *superuser* - un utente che ha il controllo su tutto nel sito. Torna alla command-line e digita `python manage.py createsuperuser`, e premi invio. Quando richiesto, digita il tuo username (minuscole, senza spazi), indirizzo e-mail e password. Non ti preoccupare se non riesci a vedere la password che stai digitando - è così che dovrebbe essere. Basta digitarlo e premere `invio` per continuare. L'output dovrebbe essere così (dove il nome utente e l'email dovrebbero essere i tuoi): +> Ricorda, per eseguire comandi lasciando in esecuzione il server web, apri una nuova finestra di terminale e attiva il tuo virtualenv. Abbiamo presentato come scrivere nuovi comandi nel capitolo **Il tuo primo progetto Django!**, nella sezione **Avvio del server web**. + +{% filename %}macOS o 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 + + +Quando te lo richiede, digita il tuo username (minuscole, senza spazi), il indirizzo email, e la password che vorrai utilizzare. **Non allarmarti se non vedi la password mentre scrivi, così funziona.** Digitala, premi `enter`, e continua. Il risultato dovrebbe assomigliare a questo (dove il nome utente e l'email saranno quelli che hai inserito): + + Username: ola + Email address: ola@example.com Password: Password (again): Superuser created successfully. -Torna nel tuo browser e fai il log in con le credenziali di superuser che hai scelto, dovresti vedere la dashboard d'amministrazione di Django. - -![L'admin di Django][2] - - [2]: images/django_admin3.png +Torna al navigatore web. Fai log in con le credenziali di superuser che hai appena definito, dovresti vedere il pannello di amministrazione di Django. -Vai su Post ed sperimenta un po'. Aggiungi cinque o sei post. Non preoccuparti del contenuto - puoi semplicemente fare il copia-incolla di parti di testo da questo tutorial per risparmiare tempo :). +![Django admin](images/django_admin3.png) -Assicurati che almeno due o tre post (ma non tutti) abbiano la data in cui sono stati pubblicati. Ti sarà utile più tardi. +Vai su Posts e giocaci un po', per capire come funziona. Aggiungi cinque o sei post. Non preoccuparti del contenuto — questo è visibile solo a te sul tuo computer personale — puoi fare copia-incolla di parti di questo tutorial per far presto. :) -![L'admin di Django][3] +Fa in modo di avere per lo meno un paio di post (non tutti però) con data di pubblicazione. Ci tornerà utile poi. - [3]: images/edit_post3.png +![Django admin](images/edit_post3.png) -Se vuoi sapere di più riguardo l'admin di Django, dovresti dare un'occhiata alla documentazione di Django: https://docs.djangoproject.com/en/1.8/ref/contrib/admin/ +Se vuoi sapere di più su Django admin, puoi controllare la documentazione ufficiale di Django: https://docs.djangoproject.com/en/2.2/ref/contrib/admin/ -Questo è un buon momento per andare a prendere un caffè (o tè) o qualcosa da mangiare per riprendere le forze. Hai creato il tuo primo modello Django - ti meriti una piccola pausa! \ No newline at end of file +Arrivati a questo punto, wow, mi sembra proprio il caso di prendersi un buon caffè ri-energizzante, una frutta (o magari una camomilla). Hai appena creato il tuo primo modello Django — ti meriti una pausa! diff --git a/it/django_admin/images/django_admin3.png b/it/django_admin/images/django_admin3.png index a450b4f9630..fb221bd18e1 100644 Binary files a/it/django_admin/images/django_admin3.png and b/it/django_admin/images/django_admin3.png differ diff --git a/it/django_admin/images/edit_post3.png b/it/django_admin/images/edit_post3.png index c8572a73e7d..57299b6f5af 100644 Binary files a/it/django_admin/images/edit_post3.png and b/it/django_admin/images/edit_post3.png differ diff --git a/it/django_admin/images/login_page2.png b/it/django_admin/images/login_page2.png index 47153ef6960..c16d1aa4289 100644 Binary files a/it/django_admin/images/login_page2.png and b/it/django_admin/images/login_page2.png differ diff --git a/it/django_forms/README.md b/it/django_forms/README.md index c3b4a73ee65..86240bbb18a 100644 --- a/it/django_forms/README.md +++ b/it/django_forms/README.md @@ -1,6 +1,6 @@ -# I form di Django +# Form Django -Infine vogliamo creare un bel modo per poter aggiungere e cambiare in nostri blog posts. Django `admin` è bello, ma è alquanto difficile da personalizzare e rendere carino. Con i `forms` avremo il potere assoluto sull'aspetto della nostra pagina web-possiamo fare praticamente qualsiasi cosa vogliamo! +Infine vogliamo creare un bel modo per poter aggiungere e cambiare in nostri blog posts. Django `admin` è bello, ma è alquanto difficile da personalizzare e rendere carino. Con `forms` avremo il controllo totale sulla nostra interfaccia - possiamo fare praticamente tutto quello ce vogliamo! La bella cosa dei Django forms è che possiamo sia inventare un nuovo form da zero che creare un `ModelForm` che salverà il risultato del form sul nostro modello. @@ -12,9 +12,11 @@ Dobbiamo creare un file con questo nome all'interno della cartella `blog`. blog └── forms.py + +Ok, apriamolo nell'editor di codice e digitiamo quanto segue: -OK, apriamo questo file e inseriamo: +{% filename %}blog/forms.py{% endfilename %} ```python from django import forms @@ -23,96 +25,120 @@ from .models import Post class PostForm(forms.ModelForm): - class Meta: - model = Post - fields = ('title', 'text',) +    class Meta: +        model = Post +        fields = ('title', 'text',) ``` Dobbiamo importare prima di tutto i Django Forms (`from django import forms`) e, ovviamente, il nostro `Post` model (`from .models import Post`). -`PostForm`, come probabilmente hai intuito, è il nome del nostro form. Dobbiamo ora dire a Django che questa form é una `ModelForm` (così Django farà qualche magia per noi)- `forms.ModelForm` è il comando per farlo. +`PostForm`, come probabilmente hai intuito, è nome del nostro form. Dobbiamo ora dire a Django che questa form é una `ModelForm` (così Django farà qualche magia per noi)- `forms.ModelForm` è il comando per farlo. Successivamente, abbiamo `class Meta`, con cui diciamo a Django quale model utilizzare per creare questo form (`model = Post`). -Finalmente possiamo indicare uno o più campi che il nostro form deve avere. In questo caso vogliamo che solamente `title` e `text` siano visibili -`author` è la persona attualmente connessa (tu!) e `created_date` dovrebbe generarsi da sola ogni volta che creiamo un post (cioè nel nostro programma), giusto? +Finalmente, possiamo indicare uno o più campi che il nostro form deve avere. In questo caso vogliamo che solamente `title` e `text` siano visibili -`author` è la persona attualmente connessa (tu!) e `created_date` dovrebbe generarsi da sola ogni volta che creiamo un post (cioè nel nostro programma), giusto? E questo è tutto! Tutto quello che dobbiamo fare ora é usare il form nella nostra *view* e visualizzarlo nel template. -Ricapitolando, creeremo: link che punti alla pagina, una URL, una view e un model. +Quindi creeremo di nuovo un link alla pagina, un URL, una view e un template. ## Link ad una pagina usando il form -È tempo di aprire `blog/templates/blog/base.html`. Aggiungeremo un link nel `div` chiamato `page-header`: +Prima di aggiungere il link, abbiamo bisogno di alcune icone da usare come pulsanti per il link. Per questo tutorial, scarica [file-earmark-plus.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/file-earmark-plus.svg) e salvalo nella cartella `blog/templates/blog/icons/` + +> Nota: Per scaricare l'immagine SVG, aprire il menu contestuale sul link (di solito facendo clic destro su di essa) e selezionare "Salva collegamento come". Nella finestra di dialogo che ti chiede dove salvare il file, vai alla directory `djangogirls` del tuo progetto Django, e all'interno di questo fino alla sottodirectory `blog/templates/blog/icons/`, e salvare il file lì. + +È ora di aprire `blog/templates/blog/base.html` nell'editor di codice. Ora possiamo usare questo file di icone all'interno del modello di base come segue. Nell'elemento `div` all'interno della sezione `header` , aggiungeremo un link prima dell'elemento `h1`: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + + {% include './icons/file-earmark-plus.svg' %} + ``` -Nota che vogliamo chiamare la nostra nuova view `post_new`. +Nota che vogliamo chiamare la nostra nuova view `post_new`. L'[icona SVG](https://icons.getbootstrap.com/icons/file-earmark-plus/) è fornita dal [Bootstrap Icons](https://icons.getbootstrap.com/) e mostrerà un'icona di pagina con il segno 'più'. Utilizziamo una direttiva sui modelli Django chiamata `include`. Questo immetterà il contenuto del file nel modello Django. Il browser web sa come gestire questo tipo di contenuto senza ulteriori elaborazioni. -Dopo aver aggiunto quanto detto, il tuo file html dovrebbe essere simile a questo: +> Puoi scaricare tutte le icone di Bootstrap [qui](https://github.com/twbs/icons/releases/download/v1.11.3/bootstrap-icons-1.11.3.zip). Scompattare il file e copiare tutti i file immagine SVG in una nuova cartella all'interno `blog/templates/blog/` chiamata `icone`. In questo modo è possibile accedere a un'icona come `pencil-fill.svg` utilizzando il percorso del file `blog/templates/blog/icons/pencil-fill.svg` + +Dopo aver modificato la riga, il file HTML dovrebbe ora assomigliare a questo: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} + Django Girls blog - - + - -
+ +
-
+
{% block content %} {% endblock %}
-
+
``` -Dopo aver salvato e aggiornato la pagina http://127.0.0.1:8000 vedrai ovviamente un errore familiare `NoReverseMatch`, giusto? +Dopo aver salvato e aggiornato la pagina http://127.0.0.1:8000 vedrai un errore che già conosci: `NoReverseMatch`. Lo vedi? Bene! ## URL -Apri il file `blog/urls.py` e aggiungi: +Apriamo `blog/urls.py` nell'editor di codice e aggiungiamo: + +{% filename %}blog/urls.py{% endfilename %} ```python -    url(r'^post/new/$', views.post_new, name='post_new'), +path('post/new/', views.post_new, name='post_new'), ``` -Il risultato finale sarà: +E il codice finale sarà così: + +{% 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'), ] ``` -Dopo aver aggiornato il sito, vedremo un `AttributeError` dal momento che non abbiamo ancora creato `post_new`. Aggiungiamolo adesso. +Dopo aver aggiornato il sito, vedremo un `AttributeError` dal momento che non abbiamo la view `post_new` implementata. Aggiungiamolo, adesso. ## post_new view -Apri il file `blog/views.py` e aggiungi quanto segue con il resto delle importazioni `from`: +È ora di aprire i `blog/views. y` file nell'editor di codice e aggiungere le seguenti righe con il resto delle `da` righe: + +{% filename %}blog/views.py{% endfilename %} ```python from .forms import PostForm ``` -e la nostra *view*: +E poi la nostra *view*: + +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): @@ -120,50 +146,50 @@ def post_new(request):     return render(request, 'blog/post_edit.html', {'form': form}) ``` -Per creare un nuovo `Post` form, dobbiamo chiamare il metodo `PostForm()` e passarlo nel nostro template. Torneremo poi sulla *view*, ma per ora creiamo un veloce template per il nostro form. +Per creare un nuovo modulo `Post`, dobbiamo richiamare `PostForm()` e passarlo nel nostro modello. Torneremo sulla *view* in seguito, ma per ora creiamo velocemente un modello per il modulo. ## Template -All'interno della cartella `blog/templates/blog` dobbiamo creare il file `post_edit.html`. Per far si che il nostro form funzioni abbiamo bisogno di diverse cose: +Dobbiamo creare un file `post_edit. tml` nella directory `blog/templates/blog` , e aprilo nell'editor di codice. Per far si che un modulo funzioni, abbiamo bisogno di diverse cose: -* dobbiamo rendere il form visibile. Per farlo possiamo usare semplicemente `{% raw %}{{ form.as_p }}{% endraw %}`. -* le righe scritte sopra hanno bisogno di 'essere avvolte' da un HTML tag: `...` -* ci serve un `Save` pulsante. Possiamo fare ciò con HTML button: `` -* infine, subito dopo l'apertura del tag `
`, dobbiamo aggiungere `{% raw %}{% csrf_token %}{% endraw %}`. Questo passaggio è molto importante dal momento che rende il nostro form sicuro! Django si lamenterà se ti dimentichi di inserire questa parte e provi comunque a salvare ciò che è contenuto nel form: +* Dobbiamo visualizzare il form. Possiamo farlo con (ad esempio) {% raw %}`{{ form.as_p }}`{% endraw %}. +* La riga sopra deve essere racchiuso con un elemento di forma HTML: `...
`. +* Ci serve un `Save` pulsante. Possiamo fare Ciò con HTML button: ``. +* E infine, subito dopo l'apertura `
` abbiamo bisogno di aggiungere {% raw %}`{% csrf_token %}`{% endraw %}. Questo passaggio è molto importante dal momento che rende il nostro form sicuro! Se dimentichi di questo bit, Django si lamenterà quando tenterai di salvare il modulo: -![CSFR Forbidden page][1] +![CSFR Forbidden page](images/csrf2.png) - [1]: images/csrf2.png +OK, quindi vediamo come dovrebbe apparire l'HTML in `post_edit.html`: -OK, il tuo HTML `post_edit.html` dovrebbe apparire così: +{% filename %}blog/templates/blog/post_edit.html{% endfilename %} ```html {% extends 'blog/base.html' %} {% block content %} -    

New post

-    {% csrf_token %} -        {{ form.as_p }} -         -    
+

New post

+
{% csrf_token %} + {{ form.as_p }} + +
{% endblock %} ``` -Ora aggiorna la pagina! Yeah! Puoi ora visualizzare il tuo form! - -![New form][2] +Aggiorna la pagina! Yay! Il tuo modulo è visualizzato! - [2]: images/new_form2.png +![Nuovo Modulo](images/new_form2.png) -Ma, aspetta un momento! Se provi a scrivere qualcosa in `title` e `text` e cerchi di salvare ciò che hai scritto, che cosa succede? +Ma, aspetta un momento! Se provi a scrivere qualcosa nei campi`titolo` e `testo` e cerchi di salvare ciò che hai scritto- che cosa succede? -Niente! Siamo di nuovo sulla stessa pagina di prima e il nostro testo é sparito...e non compare nessun nuovo post. Che cosa abbiamo sbagliato? +Nulla! Siamo ancora una volta nella stessa pagina e il nostro testo è andato perduto… e nessun nuovo post è stato aggiunto. Quindi cosa è andato storto? La risposta è: nulla. Dobbiamo solo fare un po' di lavoro in più nella nostra *view*. ## Salvare il form -Apri `blog/views.py` di nuovo. Attualmente tutto ciò che abbiamo nella view `post_new` é: +Apri ancora una volta `blog/views.py`. Attualmente tutto quello che abbiamo nella view `post_new` è: + +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): @@ -171,9 +197,11 @@ def post_new(request):     return render(request, 'blog/post_edit.html', {'form': form}) ``` -Quando inviamo il form, veniamo riportati alla stessa view, ma questa volta abbiamo più dati in `request`, in particolare in `request.POST` (il nome non ha nulla a che vedere con un blog "post", bensì con l'inglese "posting", ovvero inviare, in questo caso dati). Ti ricordi che nel nostro file HTML il nostro `
` aveva la variabile `method="POST"`? Per cui ora, tutto quello che l'utente ha inserito nel form è disponibile in `method="POST"`. Non è necessario rinominare `POST` in nessuna altra maniera (l'unico altro valore valido per `method` è `GET`, ma al momento non abbiamo abbastanza tempo per spiegare la differenza). +Quando inviamo il form, veniamo riportati alla stessa view, ma questa volta abbiamo più dati in `request`, in particolare in `request.POST` (il nome non ha nulla a che vedere con un blog "post", bensì con l'inglese "posting", ovvero inviare, in questo caso dati). Ricordate come nel file HTML, la nostra definizione `` aveva la variabile `method="POST"`? Tutti i campi dal modulo sono ora in `request.POST`. Non è necessario rinominare `POST` in nessuna altra maniera (l'unico altro valore valido per `method` è `GET`, ma al momento non abbiamo abbastanza tempo per spiegare la differenza). -Per cui nella nostra *view* abbiamo due diverse situazioni da gestire. Prima: quando accediamo alla pagina per la prima volta e vogliamo un form che sia vuoto. Seconda: quando torniamo alla *view* con tutti i dati appena inseriti nel form. Per cui dobbiamo aggiungere una condizione(useremo `if`). +Quindi, nella nostra *view* abbiamo due situazioni separate da gestire: prima, quando accediamo la pagina per la prima volta e vogliamo un modulo vuoto, e poi, quando torniamo alla *view* con tutti i dati del modulo che abbiamo appena digitato. Per cui dobbiamo aggiungere una condizione(useremo `if`): + +{% filename %}blog/views.py{% endfilename %} ```python if request.method == "POST": @@ -182,15 +210,19 @@ else:     form = PostForm() ``` -È ora di completare i puntini `[...]`. Se il `method` è `POST` allora vogliamo costruire il nostro `PostForm` con i dati appena inseriti dall'utente, giusto? Raggiungeremo questo risultato con: +È ora di riempire i punti `[...]`. Se `metodo` è `POST` allora vogliamo costruire il `PostForm` con dati dal modulo, giusto? Lo faremo come segue: + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(request.POST) ``` -Facile! Come prossima cosa dobbiamo controllare se il form è corretto (per cui che tutti i campi necessari siano stati impostati e che non ci siano valori sbagliati). Possiamo fare questo con `form.is_valid()`. +La cosa successiva è controllare se il modulo è corretto (tutti i campi obbligatori sono impostati e non sono stati inviati valori errati). Lo facciamo con `form.is_valid()`. + +Verifichiamo se il modulo è valido e se è così, possiamo salvarlo! -Se il form viene ritenuto valido verrà salvato! +{% filename %}blog/views.py{% endfilename %} ```python if form.is_valid(): @@ -200,23 +232,29 @@ if form.is_valid(): post.save() ``` -In pratica, ci sono due cose da fare: salviamo il form con `form.save` e aggiungiamo un autore (dal momento che non c'era nessun campo autore `author` nel form `PostForm` e questo campo non può essere lasciato bianco!). `commit=False` significa che non vogliamo salvare `Post` model per il momento-vogliamo prima assicurarci di aggiungere un autore. Per la maggior parte del tempo userai `form.save()`, senza `commit=False`, ma in questo caso abbiamo bisogno di questa extra specificazione. `post.save()` salverà le modifiche (aggiunta di autore) e il nuovo post del tuo blog è stato finalmente creato! +In pratica, ci sono due cose da fare: salviamo il modulo con `form.save` e aggiungiamo un autore(dal momento che non c'era nessun campo autore `author` nel modulo `PostForm` e questo campo non può essere lasciato bianco). `commit=False` significa che non vogliamo ancora salvare il modello `Post` - vogliamo aggiungere prima l'autore. La maggior parte del tempo userai `form.save()` senza `commit=False`, ma in questo caso dobbiamo fornirlo. `post.save()` manterrà le modifiche (aggiungendo l'autore) ed un nuovo post del blog è stato creato! -Infine, non sarebbe fantastico se potessimo immediatamente essere indirizzati alla pagina `post_detail` del nuovo blog post appena creato? Per fare ciò dobbiamo importare: +Infine, sarebbe fantastico se potessimo andare immediatamente alla pagina `post_detail` per il nostro post appena creato, giusto? Per fare questo abbiamo bisogno di un'altra importazione: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import redirect ``` -Aggiungilo all'inizio del file. E ora possiamo dire: vai alla pagina `post_detail` per il post appena creato. +Aggiungilo all'inizio del tuo file. E ora possiamo dire: "vai alla pagina `post_detail` per il post appena creato": + +{% filename %}blog/views.py{% endfilename %} ```python -return redirect('blog.views.post_detail', pk=post.pk) +return redirect('post_detail', pk=post.pk) ``` -`blog.views.post_detail` é il nome della view che vogliamo visitare. Ti ricordi che questa *view* ha bisogno della variabile `pk`? Per passarla alla nostre views utilizziamo `pk=post.pk`, dove `post` è il post appena creato! +`post_detail` è il nome della view su cui vogliamo andare. Ti ricordi che questa *view* ha bisogno della variabile `pk`? Per passare alle views, usiamo `pk=post.pk`, dove `post` è il post appena creato! + +OK, abbiamo parlato molto, ma probabilmente vogliamo vedere come appare l'intera *view* ora, giusto? -Ok, abbiamo parlato abbastanza ora e forse sei curioso/a di vedere l'aspetto della nostra *view*, giusto? +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): @@ -227,74 +265,88 @@ def post_new(request): post.author = request.user post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) ``` -Vediamo se funziona. Vai sulla pagina http://127.0.0.1:8000/post/new/, aggiungi un `title` e un `text`, salvalo... e voilà! Il tuo nuovo post è stato aggiunto e noi siamo stati reindirizzati automaticamente alla pagina `post_detail` ! +Vediamo se funziona. Vai alla pagina http://127.0.0.1:8000/post/new/, aggiungi un `titolo` e `testo`, salvalo… e voilà! Il nuovo post è stato aggiunto e siamo reindirizzati alla pagina `post_detail`! -Forse avrai notato che stiamo impostando una data di pubblicazione prima di salvare il post. Più tardi introdurremo l'uso del *publish button* in **Django Girls Tutorial: Extensions**. +Potresti aver notato che stiamo impostando la data di pubblicazione prima di salvare il post. Più tardi, introdurremo un *pulsante pubblcia* nel **Django Girls Tutorial: Estensioni**. Fantastico! -## Validazione del Form +> Poiché abbiamo recentemente utilizzato l'interfaccia di admin di Django, il sistema attualmente ritiene che siamo ancora loggati. Ci sono alcune situazioni che potrebbero portarci a disconnetterci (chiusura del browser, riavvio del DB, ecc.). Se, quando si crea un post, si scopre che si stanno ricevendo errori in riferimento alla mancanza di un utente loggato, vai alla pagina admin http://127.0.0.1:8000/admin e accedi di nuovo. Questo risolverà temporaneamente il problema. C'è una correzione permanente che ti aspetta nella sezione degli esercizi extra alla fine del tutorial principale **Compiti: aggiungi sicurezza al tuo sito web!**. -E adesso ti dimostreremo quanto siano belli i form di Django. Sappiamo che un post ha bisogno di `title` e `text`. Nel nostro `Post` model non abbiamo detto (al contrario di quello che abbiamo fatto per `published_date`) che questi campi non sono obbligatori, per cui Django si aspetta che vengano impostati. +![Registrato con un errore](images/post_create_error.png) -Prova a salvare il form senza `title` e `text`. Indovina che cosa accade! +## Validazione del form -![Validazione del form][3] +E adesso ti dimostreremo quanto siano belli i moduli di Django. Un post del blog deve avere dei campi per il `titolo` ed il `testo`. Nel nostro modello `Post` non abbiamo detto che questi campi (contrariamente a `published_date`) non sono richiesti, quindi Django, di default, si aspetta che siano impostati. - [3]: images/form_validation2.png +Prova a salvare il modulo senza `titolo` e `testo`. Indovina cosa accadrà! -Django si sta prendendo cura di controllare che tutti i campi nel nostro form siano corretti. Non è fantastico? +![Convalida del modulo](images/form_validation2.png) -> Dato che poco fa stavamo usando l'interfaccia di Django admin, Django pensa che siamo ancora connessi. Ci sono alcune situazioni che potrebbero portarci a fare un log out(chiudere il browser, riavviare il DB etc.). Se ti trovi nella situazione di avere errori, quando crei un post, relativi alla mancanza di un utente, vai alla admin page `http://127.0.0.1:8000/admin` ed effettua il log in di nuovo. Questo risolverà temporaneamente il problema. C'è una correzione permanente che ti aspetta nella sezione degli esercizi extra alla fine del tutorial principale **Compiti: aggiungi sicurezza al tuo sito web!**. +Django si incarica di verificare che tutti i campi nel nostro modulo siano corretti. Non è fantastico? -![Logged in error][4] +## Form di modifica - [4]: images/post_create_error.png +Ora sappiamo come aggiungere un nuovo post. Ma cosa succede se ne vogliamo cambiarne uno esistente? E' molto simile a quanto abbiamo appena fatto. Creiamo rapidamente alcune cose importanti. (Se non capisci qualcosa, dovresti chiedere al tuo coach o guardare i capitoli precedenti, poiché abbiamo già affrontato tutti questi passi.) -## Modifica il form +Innanzitutto, salviamo l'icona che rappresenta il pulsante di modifica. Scarica [pencil-fill.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/pencil-fill.svg) e salvalo nella posizione `blog/templates/blog/icons/`. -Ora sappiamo come aggiungere un form. Ma cosa succede se ne vogliamo cambiare uno esistente? È un processo abbastanza simile a quelli che abbiamo appena fatto. Creiamo alcune cose importanti rapidamente (se non capisci qualcosa, chiedi aiuto al tuo coach o guarda i capitoli precedenti, dal momento che abbiamo coperto tutti questi passaggi precedentemente). +Apri `blog/templates/blog/post_detail.html` nell'editor di codice e aggiungi il seguente codice all'interno dell'elemento `article`: -Apri `blog/templates/blog/post_detail.html` e aggiungi: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} -```python - +```html + ``` -per cui il tuo template sarà così: +così che il modello sarà così: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html {% extends 'blog/base.html' %} {% block content %} -
+
+ {% endblock %} ``` -In `blog/urls.py` aggiugi: +Apri `blog/urls.py` nell'editor del codice e aggiungi questa riga: + +{% 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'), ``` -Riutilizzeremo il model `blog/templates/blog/post_edit.html`, quindi l'ultima cosa che manca è una *view*. +Riutilizzeremo il modello `blog/templates/blog/post_edit.html`, quindi l'ultima cosa che manca è una *view*. + +Apriamo `blog/views.py` nell'editor del codice e aggiungiamolo alla fine del file: -Apriamo `blog/views.py` e aggiungiamo alla fine del file: +{% filename %}blog/views.py{% endfilename %} ```python def post_edit(request, pk): @@ -306,93 +358,122 @@ def post_edit(request, pk): post.author = request.user post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm(instance=post) return render(request, 'blog/post_edit.html', {'form': form}) ``` -Questo sembra quasi esattamente la view `post_new`, giusto? Ma non del tutto. Prima cosa: si passa un parametro supplementare `pk` dall'URL. Dopo di che: prendiamo il modello ` Post` che vogliamo modificare con `get_object_or_404(Post, pk=pk)` e in seguito, quando creeremo un form, passeremo questo post come `instance`, sia quando salviamo il form: +Questo sembra quasi esattamente la view `post_new`, giusto? Ma non del tutto. Per una, passiamo un parametro `pk` extra da `urls`. Successivamente, otteniamo il modello `Post` che vogliamo modificare con `get_object_or_404(Post, pk=pk)` e poi, quando creiamo un modulo, passiamo questo post come `istanza`, sia quando salviamo il modulo… + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(request.POST, instance=post) ``` -e quando abbiamo appena aperto un form con questo post da modificare: +…e quando abbiamo appena aperto un modulo con questo post per modificare: + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(instance=post) ``` -Ok, testiamo se funziona! Andiamo alla pagina `post_detail`. Dovrebbe esserci un pulsante modifica nell'angolo superiore destro: - -![Pulsante modifica][5] +OK, vedi se funziona! Vai alla pagina `post_detail` . Dovrebbe esserci un pulsante di modifica nell'angolo in alto a destra: - [5]: images/edit_button2.png +![Pulsante modifica](images/edit_button2.png) Quando ci clicchi, vedrai il modulo con i nostri post del blog: -![Modifica il form][6] +![Modificare il modulo](images/edit_form2.png) - [6]: images/edit_form2.png - -Sentiti libero di cambiare il titolo o il testo e salva le modifiche! +Sentiti libero di cambiare il titolo o il testo e salvare le modifiche! Complimenti! La tua application è sempre più completa! -Se ti servono altre informazioni sui forms di Django dovresti leggere la documentazione: https://docs.djangoproject.com/en/1.8/topics/forms/ +Se necessiti di altre informazioni sui moduli di Django, dovresti leggere la documentazione: https://docs.djangoproject.com/en/2.2/topics/forms/ ## Sicurezza -Riuscire a creare nuovi post semplicemente cliccando su un link è bellissimo! Ma, al momento, chiunque visiti il tuo sito potrebbe pubblicare un nuovo post nel tuo blog e probabilmente non vuoi che ciò accada. Facciamo in modo che questo tasto sia visibile solo per te e non per altri. +Riuscire a creare nuovi post semplicemente cliccando su un link è bellissimo! Ma in questo momento chiunque visiti il tuo sito potrà creare un nuovo post sul blog, e probabilmente non è qualcosa che vuoi. Facciamo spuntare il bottone solo per te e non per gli altri. + +Apri `blog/template/blog/base.html` nell'editor del codice, trova il nostro `div` all'interno dell'`intestazione` e il tag di ancoraggio che hai inserito in precedenza. Dovrebbe essere così: -Vai al tuo `blog/templates/blog/base.html` e trova il `page-header` `div` con il tag di tipo anchor che hai messo prima. Dovrebbe apparire così: +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + + {% include './icons/file-earmark-plus.svg' %} + ``` -Vogliamo aggiungere qui un altro tag del tipo `{% if %}` che farà comparire il link solo per gli utenti connessi come admin. Per ora, solo tu! Cambia il tag `` in modo che risulti così: +Aggiungeremo un altro tag `{% if %}` , che farà apparire il link solo per gli utenti che hanno effettuato l'accesso nell'admin. In questo momento, è solo voi! Cambia l'elemento `` per farlo assomigliare a questo: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% if user.is_authenticated %} - + + {% include './icons/file-earmark-plus.svg' %} + {% endif %} ``` -Grazie a questo `{% if %}`, il link verrà inviato al browser solo se l'utente che prova ad accedere alla pagina è connesso come admin. Con questa condizione non ci siamo protetti del tutto dalla creazione di nuovi post, ma abbiamo fatto un buon passo avanti. Nelle lezioni estensione ci occuperemo di più della sicurezza. +Questo `{% if %}` causerà l'invio del link al browser solo se l'utente che richiede la pagina è loggato. Questo non protegge completamente la creazione di nuovi post, ma è un buon primo passo. Ci occuperemo di più sicurezza nelle lezioni di estensione. -Ora, dato che probabilmente sei connessa/o, se aggiorni la pagina non troverai alcuna differenza. Ma prova a ricaricare la pagina in un altro browser o in una finestra di navigazione in incognito e vedrai che il link non c'è! +Ricordi l'icona modifica che abbiamo aggiunto sulla nostra pagina di dettaglio? Vogliamo faro la stessa cosa qui, così le altre persone non potranno editare i post esistenti. -## Ultima cosa: ora di fare il deploy! - -Vediamo se funziona su PythonAnywhere. È l'ora di un altro deploy! +Apri `blog/templates/blog/post_detail.html` nell'editor del codice e trova questa riga: -* Innanzitutto, fai un commit del tuo nuovo codice e fai il push per caricarlo su Github +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} -``` -$ git status -$ git add --all . -$ git status -$ git commit -m "Added views to create/edit blog post inside the site." -$ git push +```html + + {% include './icons/pencil-fill.svg' %} + ``` -* Poi, in una [console PythonAnywhere Bash][7]: +Cambialo in questo: - [7]: https://www.pythonanywhere.com/consoles/ +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} +```html +{% if user.is_authenticated %} + + {% include './icons/pencil-fill.svg' %} + +{% endif %} ``` -$ cd my-first-blog -$ source myvenv/bin/activate -(myvenv)$ git pull -[...] -(myvenv)$ python manage.py collectstatic -[...] -``` -* Infine, vai sulla [Web tab][8] e premi **Reload**. +Siccome probabilmente sei loggata, se ricarichi la pagina non vedrai differenze. Carica la pagina in un browser diverso o in una finestra incognita (chiamata "InPrivate" in Windows Edge), tuttavia, e vedrai che il link non viene mostrato in alto, e l'icona non viene visualizzata! + +## Ultima cosa: ora di fare il deploy! + +Vediamo se funziona su PythonAnywhere. È l'ora di ripartire! + +* Prima di tutto, esegui il tuo nuovo codice e push fino a GitHub: + +{% filename %}command-line{% endfilename %} + + $ git status + $ git add . + $ git status + $ git commit -m "Added views to create/edit blog post inside the site." + $ git push + + +* Poi, in una [console PythonAnywhere Bash](https://www.pythonanywhere.com/consoles/): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Ricordati di sostituire `` con il sottodominio di PythonAnywhere, senza le parentesi angolo.) - [8]: https://www.pythonanywhere.com/web_app_setup/ +* Infine, salta alla pagina [ "Web" ](https://www.pythonanywhere.com/web_app_setup/) (usa il pulsante menu in alto a destra della console) e premi **Ricarica**. Aggiorna il tuo blog https://subdomain.pythonanywhere.com per vedere le modifiche. -Fatto! Congratulazioni :) +Ecco fatto! Congratulazioni! \ No newline at end of file diff --git a/it/django_forms/images/csrf2.png b/it/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/it/django_forms/images/csrf2.png and b/it/django_forms/images/csrf2.png differ diff --git a/it/django_forms/images/drafts.png b/it/django_forms/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/it/django_forms/images/drafts.png and b/it/django_forms/images/drafts.png differ diff --git a/it/django_forms/images/edit_button2.png b/it/django_forms/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/it/django_forms/images/edit_button2.png and b/it/django_forms/images/edit_button2.png differ diff --git a/it/django_forms/images/edit_form2.png b/it/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/it/django_forms/images/edit_form2.png and b/it/django_forms/images/edit_form2.png differ diff --git a/it/django_forms/images/form_validation2.png b/it/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/it/django_forms/images/form_validation2.png and b/it/django_forms/images/form_validation2.png differ diff --git a/it/django_forms/images/new_form2.png b/it/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/it/django_forms/images/new_form2.png and b/it/django_forms/images/new_form2.png differ diff --git a/it/django_forms/images/post_create_error.png b/it/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/it/django_forms/images/post_create_error.png and b/it/django_forms/images/post_create_error.png differ diff --git a/it/django_installation/README.md b/it/django_installation/README.md index 15f3758fbdd..d8e3b0195a0 100644 --- a/it/django_installation/README.md +++ b/it/django_installation/README.md @@ -1,5 +1,7 @@ # Installazione di Django -> **Nota** Se hai già eseguito i passaggi per l'Installazione, allora hai già fatto quanto serve e puoi andare direttamente al prossimo capitolo! +> **Nota** Se utilizzi un Chromebook, salta questo capitolo e segui le istruzioni in [Configurazione di Chromebook](../chromebook_setup/README.md). +> +> Se hai terminato il processo di installazione, questo passaggio l'hai già completato e puoi passare direttamente al capitolo successivo! -{% include "/django_installation/instructions.md" %} +{% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/it/django_installation/instructions.md b/it/django_installation/instructions.md index 931be14224b..f91aa502a02 100644 --- a/it/django_installation/instructions.md +++ b/it/django_installation/instructions.md @@ -1,6 +1,6 @@ -> Una parte di questo capitolo si basa sui tutorial delle Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> Parte di questa sezione è basata sul tutorial delle Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). > -> Una parte di questo capitolo di basa sul [django-marcador tutorial](http://django-marcador.keimlink.de/) sotto licenza Creative Commons Attribution-ShareAlike 4.0 International License. Il tutorial di django-marcador è protetto da copyright di Markus Zapke-Gründemann et al. +> Una parte di questo capitolo di basa sul [django-marcador tutorial](http://django-marcador.keimlink.de/), con licenza Creative Commons Attribution-ShareAlike 4.0 International License. Il tutorial di django-marcador è protetto da copyright di Markus Zapke-Gründemann et al. ## Ambiente virtuale @@ -8,107 +8,222 @@ Prima di installare Django, ti vogliamo far installare uno strumento estremament Per cui, creiamo ora un **ambiente virtuale** (chiamato anche un *virtualenv*). Virtualenv isolerà la tua configurazione di Python/Django in base ai diversi progetti. Questo significa che qualunque modifica farai su un sito non avrà alcun effetto su tutti gli altri che stai sviluppando. Chiaro ora? -Tutto quello che devi fare è trovare una cartella in cui vuoi creare il `virtualenv`; la tua home directory, ad esempio. Su Windows potrebbe essere `C:\Users\Name` (dove `Name` è il nome del tuo login). +Tutto quello che devi fare è trovare una cartella in cui vuoi creare il `virtualenv`; la tua home directory, ad esempio. Su Windows potrebbe apparire come `C:\Users\Name` (dove `Name` è il nome del tuo login). + +> **Nota:** Su Windows, assicurati che la cartella non contenga caratteri accentati o speciali; se il tuo username contiene cartteri accentati, usa una cartella diversa, ad esempio `C:\djangogirls`. Per questo tutorial useremo una nuova directory `djangogirls` dalla tua home directory: - mkdir djangogirls - cd djangogirls +{% filename %}command-line{% endfilename %} + + $ mkdir djangogirls + $ cd djangogirls Ora creeremo un virtualenv dal nome `myvenv`. Questo è il formato del comando generale: - python3 -m venv myvenv +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv -### Windows + + +Per creare un nuovo `virtualenv` devi aprire il prompt dei comandi ed eseguire `python -m venv myvenv`. Apparirà così: -Per creare un nuovo `virtualenv` è necessario aprire la console (ti abbiamo spiegato come fare nei capitoli precedenti, ricordi?) ed esegui `C:\Python34\python -m venv myvenv`. Il risultato somiglierà a questo: +{% filename %}command-line{% endfilename %} - C:\Users\Name\djangogirls> C:\Python34\python -m venv myvenv + C:\Users\Name\djangogirls> python -m venv myvenv -dove `C:\Python34\python` è la directory in cui precedentemente hai installato Python e `myvenv` è il nome del tuo `virtualenv`. Puoi utilizzare qualsiasi altro nome, ma attieniti a utilizzare le minuscole, a non usare spazi, accenti o caratteri speciali. È meglio usare un nome breve dal momento che dovrai digitarlo spesso! +Qui `myvenv` è il nome del tuo `virtualenv`. Puoi utilizzare qualsiasi altro nome, ma attieniti a utilizzare le minuscole, a non usare spazi, accenti o caratteri speciali. Inoltre è meglio scegliere un nome breve, dato che dovrai digitarlo molte volte! -### Linux e OS X + -Creare un `virtualenv` su Linux e OS X è semplice, basta digitare: `python3 -m venv myvenv`. Il risultato sarà simile a questo: + - ~/djangogirls$ python3 -m venv myvenv +Possiamo creare un `virtualenv` sia su Linux che su macOS eseguendo `python3 -m myvenv`. Apparirà così: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv -`myvenv` è il nome del tuo `virtualenv`. Puoi usare qualsiasi altro nome, ma utilizza solo minuscole e niente spazi. Sarebbe meglio se il nome fosse corto perchè lo dovrai digitare molte volte! +`myvenv` è il nome del tuo `virtualenv`. Puoi usare qualsiasi altro nome, ma utilizza solo minuscole e niente spazi. Inoltre è meglio scegliere un nome breve, in quanto dovrai digitarlo molte volte! -> **NOTA:** Avviare il virtualenv su Ubuntu 14.04 in questa maniera al momento darà il seguente errore: +> **NOTA:** Su alcune versioni di Debian/Ubuntu potresti vedere il seguente errore: +> +> {% 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. +> +> +> In questo caso, segui le istruzioni sopra e installa il pacchetto `python3-venv`: {% filename %}riga di comando{% endfilename %} +> +> $ sudo apt install python3-venv +> +> +> **NOTA:** In alcune versioni di Debian/Ubuntu che iniziano l'ambiente virtuale come questo attualmente dà il seguente errore: +> +> {% filename %}command-line{% endfilename %} > > Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 > > > Per aggirare il problema utilizza, invece del precedente, il comando `virtualenv`. > -> ~/djangogirls$ sudo apt-get install python-virtualenv -> ~/djangogirls$ virtualenv --python=python3.4 myvenv +> {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python-virtualenv +> $ virtualenv --python=python{{ book.py_version }} myvenv +> +> +> **NOTA:** Se ottieni un errore come +> +> {% filename %}command-line{% endfilename %} +> +> E: Unable to locate package python3-venv +> +> +> allora esegui: +> +> {% filename %}command-line{% endfilename %} +> +> sudo apt install python{{ book.py_version }}-venv > + + ## Lavorare con virtualenv -Il comando sopra specificato, creerà una cartella dal nome `myvenv` (o col nome che hai scelto) che contiene il tuo virtual environment (ovvero un mucchio di files e cartelle). +Il comando sopra specificato, creerà una cartella dal nome `myenv` (o col nome che hai scelto) che contiene il tuo virtual environment (ovvero un mucchio di files e cartelle). -#### Windows + Avvia il tuo virtualenv digitando: +{% filename %}command-line{% endfilename %} + C:\Users\Name\djangogirls> myvenv\Scripts\activate +> **NOTA:** su Windows 10 potresti ottenere un errore in Windows PowerShell che dice `l'esecuzione degli script è disabilitata su questo sistema`. In questo caso, apri un'altra Windows PowerShell con l'opzione "Esegui come amministratore". Quindi prova a digitare il seguente comando prima di iniziare il tuo ambiente virtuale: +> +> {% 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 e OS X +> **NOTA:** Per gli utenti del popolare editor VS Code, che ha un terminale integrato basato su una powershell Windows, se vuoi rimanere con il terminale integrato, puoi eseguire il seguente comando per attivare il tuo ambiente virtuale: +> +> $ . myvenv\Scripts\activate.ps1 +> +> +> Il vantaggio è che non devi passare tra le finestre dell'editor e le finestre della linea di comando + + + + Avvia il tuo virtualenv digitando: - ~/djangogirls$ source myvenv/bin/activate +{% filename %}command-line{% endfilename %} + + $ source myvenv/bin/activate -Ricordati di sostituire `myvenv` con il nome `virtualenv` che hai scelto! +Ricordati di sostituire `myvenv` con il nome del `virtualenv` che hai scelto! > **Nota:** a volte il comando `source` potrebbe non essere disponibile. In quel caso prova ad usare questo: > -> ~/djangogirls$ . myvenv/bin/activate +> {% filename %}command-line{% endfilename %} +> +> $ myvenv/bin/activate > -Saprai con certezza che hai avviato `virtualenv` quando vedrai che il prompt dei comandi nella console si presenta così: + + +Sarai certo di aver avviato il `virtualenv` quando vedrai che il prompt nella tua console inizia con `(myvenv)`. + +Quando si lavora all'interno di un ambiente virtuale, `python` farà automaticamente riferimento alla versione corretta da utilizzare. Per cui puoi digitare `python` invece che `python3`. + +OK, abbiamo tutte le dipendenze importanti pronte. Finalmente possiamo installare Django! + +## Installare Django {#django} + +Ora che hai avviato il tuo `virtualenv`, puoi installare Django. - (myvenv) C:\Users\Name\djangogirls> +Prima però dobbiamo assicurarci di avere la versione più recente di `pip`, il software che useremo per installare Django: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~$ python -m pip install --upgrade pip -oppure: +### Installazione di pacchetti con requisiti + +Un file di requisiti mantiene un elenco di dipendenze da installare utilizzando `pip install`: + +Crea un file `requirements.txt` all'interno della cartella `djangogirls/` utilizzando l'editor di codice che hai installato prima. Lo fai aprendo un nuovo file nell'editor di codice e quindi salvarlo come `requirements.txt` nella cartella `djangogirls/` . La tua cartella assomiglierà a questo: - (myvenv) ~/djangogirls$ + djangogirls + ├── myvenv + │ └── ... + └───requirements.txt -Fai caso al prefisso `(myvenv)`! +Nel tuo file `djangogirls/requirements.txt` aggiungi il testo seguente: -Quando si lavora all'interno di un ambiente virtuale, `python` farà automaticamente riferimento alla versione corretta da utilizzare. Per cui puoi digitare `python` invece `python3`. +{% filename %}djangogirls/requirements.txt{% endfilename %} -OK, abbiamo tutte le dipendenze importanti pronte. Finalmente possiamo installare Django! + Django~={{ book.django_version }} + -## Installare Django +Ora, esegui `pip install -r requirements.txt` per installare Django. -Ora che hai iniziato ad utilizzare il tuo `virtualenv`, puoi installare Django usando `pip`. Nella console, esegui `pip install django==1.8` (nota che usiamo un doppio simbolo di uguale: `==`). +{% filename %}command-line{% endfilename %} - (myvenv) ~$ pip install django==1.8 - Downloading/unpacking django==1.8 - Installing collected packages: django - Successfully installed django - Cleaning up... + (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.1MB) + Installing collected packages: Django + Successfully installed Django-{{ book.django_version }} -Su Windows + + +> Se si verifica un errore durante la chiamata pip sulla piattaforma Windows, si prega di controllare se il tuo nome del progetto contiene spazi, accenti o caratteri speciali (ad esempio, `C:\Utenti\Nome utente\djangogirls`). Se lo fa, si prega di considerare l'utilizzo di un altro luogo senza spazi, accenti o caratteri speciali (suggerimento: `C:\djangogirls`). Crea un nuovo virtualenv nella nuova cartella, quindi cancellane uno vecchio e riprova il comando sopra. (Spostare la directory virtualenv non funzionerà perché virtualenv utilizza percorsi assoluti.) -> Se ottieni un errore quando chiami pip sulla piattaforma Windows controlla se il pathname del tuo progetto contiene spazi, accenti o caratteri speciali (i.e. `C:\Users\User Name\djangogirls`). Se è così ti conviene spostarlo in un altro path senza spazi, accenti o caratteri speciali (il suggerimento è: `C:\djangogirls`). Dopo averlo spostato, prova ad eseguire di nuovo il comando di cui sopra. + -su Linux + + +> La tua linea di comando potrebbe congelare dopo aver provato ad installare Django. Se ciò accade, invece del comando sopra utilizzato: +> +> {% filename %}command-line{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> + + + + > Se ottieni un errore quando esegui il comando pip su Ubuntu 12.04, prova ad eseguire `python -m pip install -U --force-reinstall pip` per risolvere il problema. -Questo è tutto! Sei (finalmente) pronto/a a creare un'applicazione Django! + + +Questo è tutto! Sei (finalmente) pronto/a a creare un'applicazione Django! \ No newline at end of file diff --git a/it/django_models/README.md b/it/django_models/README.md index 9c826a11556..fb96a3b7fb4 100644 --- a/it/django_models/README.md +++ b/it/django_models/README.md @@ -1,26 +1,31 @@ -# Modelli Django +# I modelli di Django Vogliamo creare un qualcosa che raccoglierà tutti i post del nostro blog. Per farlo, però, dobbiamo prima introdurre i cosiddetti `oggetti`. ## Oggetti -Esiste un concetto nella programmazione chiamato `programmazione orientata agli oggetti`. L'idea è che invece di scrivere tutto come una noiosa sequenza di istruzioni di programmazione, possiamo modellare le cose e definire come esse interagiscono fra di loro. +Esiste un concetto nella programmazione che è quello di `programmazione orientata agli oggetti`. L'idea di base è che invece di scrivere una noiosa sequenza di istruzioni di programmazione, possiamo modellare le cose e decidere come devono interagire l'una con l'altra. Quindi cos'è un oggetto? È un insieme di proprietà ed azioni. Suona strano, ma ti faremo un esempio. -Se vogliamo modellare un gatto creeremo un oggetto `Gatto` che ha qualche proprietà, i.e. `colore`, `età`, `umore` (i.e. bravo, cattivo, sonnolento ;)), `padrone` (che è un oggetto `Persona` oppure, nel caso di un gatto randagio, questa proprietà è vuota). +Se vogliamo il modello di un gatto creeremo un oggetto `Gatto` che possiede alcune proprietà come: `colore`, `età`, `umore` (come buono, cattivo, assonnato ;) ) e `padrone` (che è un oggetto `Persona` oppure, nel caso di un gatto randagio, la proprietà sarà vuota). -E poi il `Gatto` ha alcune azioni: `fusa`, `graffiare` oppure `alimentare` (nella quale daremo al gatto un po' di `Cibo per gatti`, che potrebbe essere un oggetto diverso con delle proprietà, i.e. `gusto`). +Quindi il `Gatto` possiede anche alcune azioni: `fare_le_fusa`, `graffiare` e `alimentare` (in quest'ultimo caso, daremo al gatto del `CiboPerGatti`, che sarà un altro oggetto con le sue proprietà, come `gusto`). - Gatto + Cat -------- - colore - età - umore - padrone - fare le fusa() - graffiare() - alimentare(cat_food) + color + age + mood + owner + purr() + scratch() + feed(cat_food) + + + CatFood + -------- + taste Quindi in pratica l'idea è quella di descrivere cose vere in codice con delle proprietà (chiamate `proprietà di oggetti`) e azioni (chiamate `metodi`). @@ -29,7 +34,7 @@ Quindi come faremo a modellare i post del blog? vogliamo costruire un blog, gius Dobbiamo rispondere alla domanda: cos'è un post? Quali proprietà dovrebbe avere? -Beh, sicuramente il nostro post ha bisogno di qualche testo con il suo contenuto ed un titolo, vero? Sarebbe bello sapere chi l'ha scritto - quindi abbiamo bisogno di un autore. Infine, vogliamo sapere quando il post è stato creato e pubblicato. +Beh, sicuramente il nostro post ha bisogno di qualche testo con il suo contenuto ed un titolo, vero? Sarebbe bello sapere anche chi l'ha scritto - quindi abbiamo bisogno di un autore. Infine, vogliamo sapere quando il post è stato creato e pubblicato. Post -------- @@ -56,42 +61,57 @@ Puoi pensare ad un modello nel database come ad un foglio elettronico con colonn ### Creazione di un'applicazione -Per mantenere tutto ordinato, creeremo un'applicazione diversa all'interno del nostro progetto. È molto bello avere tutto organizzato fin dall'inizio. Per creare un'applicazione abbiamo bisogno di eseguire il seguente comando nella console (dalla cartella `djangogirls` dove si trova il file `manage.py`): +Per mantenere tutto ordinato, creeremo un'applicazione diversa all'interno del nostro progetto. E' molto bello avere tutto organizzato fin dall'inizio. Per creare un'applicazione abbiamo bisogno di eseguire il seguente comando nella console (dalla cartella `djangogirls` dove si trova il file `manage.py`): + +{% filename %}macOS o Linux:{% endfilename %} (myvenv) ~/djangogirls$ python manage.py startapp blog +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + + Noterai che si è creata una nuova cartella `blog` e che ora contiene alcuni file. Le nostre cartelle ed i nostri file nel nostro progetto si dovrebbero vedere così: 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 + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + + +Dopo aver creato un'applicazione dobbiamo dire a Django che dovrebbe utilizzarla. Lo facciamo nel file `mysite/settings.py` -- aprilo nell'editor di codice. Dobbiamo scoprire `INSTALLED_APPS` ed aggiunge una riga contenente `'blog.apps.BlogConfig',` proprio sopra `]`. Il progetto dovrebbe assomigliare a questo: -Dopo aver creato un'applicazione dobbiamo dire a Django che dovrebbe utilizzarla. Lo facciamo nel file `mysite/settings.py`. Dobbiamo trovare `INSTALLED_APPS` ed aggiungere una riga che contenga `'blog',` appena sopra`)`. Quindi il prodotto finale dovrebbe assomigliare a questo: +{% filename %}mysite/settings.py{% endfilename %} ```python -INSTALLED_APPS = ( -    'django.contrib.admin', -    'django.contrib.auth', -    'django.contrib.contenttypes', -    'django.contrib.sessions', -    'django.contrib.messages', -    'django.contrib.staticfiles', -    'blog', -) +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog.apps.BlogConfig', +] ``` ### Creazione di un modello blog post @@ -100,73 +120,82 @@ Nel file `blog/models.py` definiamo tutti gli oggetti chiamati `Models` - Questo Apriamo `blog/models.py`, cancella tutto quello che è lì e scrivi un codice come questo: +{% filename %}blog/models.py{% endfilename %} + ```python -from django.db import models -from django.utils import timezone +from django.conf import settings +from django.db import models +from django.utils import timezone class Post(models.Model): - author = models.ForeignKey('auth.User') - title = models.CharField(max_length=200) - text = models.TextField() - created_date = models.DateTimeField( - default=timezone.now) - published_date = models.DateTimeField( - blank=True, null=True) - - def publish(self): - self.published_date = timezone.now() - self.save() - - def __str__(self): - return self.title + 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) + + def publish(self): + self.published_date = timezone.now() + self.save() + + def __str__(self): + return self.title ``` -> Ricontrolla se stai utilizzando due caratteri di sottolineatura (`_`) su ciascun lato di `str`. Questa convenzione viene utilizzata spesso in Python e a volte li chiamiamo anche "dunder" (abbreviazione di "doppio carattere di sottolineatura"). +> Assicurati di aver usato 2 underscore (`_`) da entrambi i lati di `str`. Questa convenzione viene utilizzata spesso in Python e a volte li chiamiamo anche "dunder" (abbreviazione di "doppio carattere di sottolineatura"). Sembra spaventoso, vero? ma non ti preoccupare, ti spiegheremo cosa significano queste righe! -Tutte le righe che iniziano con `from` oppure con `import` sono righe che aggiungono alcuni pezzi da altri file. Quindi invece di copiare e incollare le stesse cose in ogni file, possiamo includere alcune parti con `from ... import ...`. +Tutte le righe che iniziano con `from` oppure con `import` sono righe che aggiungono alcuni pezzi da altri file. Quindi invece di copiare e incollare le stesse cose in ogni file, possiamo includere alcune parti con `from ... importa ...`. `class Post(models.Model):` - questa riga definisce il nostro modello (è un `oggetto`). -* `class` è una parola chiave speciale che indica che stiamo definendo un oggetto. -* `Post` è il nome del nostro modello. Possiamo dargli un nome diverso (ma dobbiamo evitare caratteri speciali e spazi). Inizia sempre il nome di una classe con un lettera maiuscola. -* `models.Model` significa che il Post è un modello Django, quindi Django sa che dovrebbe essere salvato nel database. +- `class` è una parola chiave speciale che indica che stiamo definendo un oggetto. +- `Post` è il nome del nostro modello. Possiamo dargli un nome diverso (ma dobbiamo evitare caratteri speciali e spazi). Inizia sempre il nome di una classe con un lettera maiuscola. +- `models.Model` significa che il Post è un modello Django, quindi Django sa che dovrebbe essere salvato nel database. -Ora definiamo le proprietà di cui stavamo parlando: `titolo`, `testo`, `data_creazione`, `data_pubblicazione` e `autore`. Per fare ciò dobbiamo definire un tipo per ogni campo (è un testo? Un numero? Una data? Una relazione con un altro oggetto, i.e. un utente?). +Ora definiamo le proprietà di cui stavamo parlando: `titolo`, `testo`, `data_creazione`, `data_pubblicazione` e `autore`. Per fare ciò dobbiamo definire un tipo per ogni campo (è un testo? Un numero? Una data? Una relazione con un altro oggetto, come User?) -* `models.CharField` - così si definisce un testo con un numero limitato di lettere. -* `models.TextField` - questo è il codice per definire un testo senza un limite. Sembra l'ideale per i contenuti di un post, vero? -* `models.DateTimeField` - questo per la data ed l'ora. -* `models.ForeignKey` - questo è un link a un altro modello. +- `models.CharField` - così si definisce un testo con un numero limitato di lettere. +- `models.TextField` - questo è il codice per definire un testo senza un limite. Sembra l'ideale per i contenuti di un post, vero? +- `models.DateTimeField` - questo per la data ed l'ora. +- `models.ForeignKey` - questo è un link a un altro modello. -Non spiegheremo ogni pezzo di codice perchè ci vorrebbre troppo tempo. Dovresti dare un'occhiata alla documentazione di Django se vuoi saperne di più sui campi di un modello e come definire altre cose rispetto a quelle descritte sopra (https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-types). +Non spiegheremo ogni pezzo di codice perchè ci vorrebbre troppo tempo. Dovresti dare un'occhiata alla documentazione di Django se vuoi sapere di più sui campi del Modello e come definire le cose oltre che da quelli descritti sopra (https://docs.djangoproject.com/en/2.2/ref/models/fields/#field-types). Che dire di `def publish(self):`? È esattamente il metodo `pubblicare` di cui stavamo parlando prima. `def` significa che questa è una funzione/metodo e `publish` è il nome del metodo. Puoi modificare il nome del metodo, se vuoi. La regola per la denominazione è usare lettere minuscole e caratteri di sottolineatura al posto degli spazi. Per esempio, un metodo che calcola il prezzo medio potrebbe essere chiamato `calculate_average_price`. I metodi spesso `restituiscono` qualcosa. C'è un esempio nel metodo `__str__`. In questo caso, quando chiamiamo `__str__()` otterremo un testo (**stringa**) con il titolo del Post. +Nota anche che entrambe `def publish(self):` e `def __str__(self):` sono indentate all'interno della classe. Poiché Python è sensibile agli spazi, dobbiamo indentare i nostri metodi dentro alla classe. Altrimenti i metodi non apparterranno alla classe e potresti ottenere qualche comportamento inaspettato. + Se c'è qualcosa di poco chiaro sui modelli, sentiti libera/o di chiedere al tuo coach! Sappiamo che è complicato, soprattutto quando impari cosa sono gli oggetti e le funzioni allo stesso tempo. Ma speriamo che sembri un po' meno magico per te per adesso! ### Crea tabelle per i modelli nel tuo database -L'ultimo passo è quello di aggiungere un nuovo modello al nostro database. Prima dobbiamo far sapere a Django che ci sono alcuni cambiamenti nel nostro modello (l'abbiamo appena creato!). Digita `python manage.py makemigrations blog`. Il risultato somiglierà a questo: +L'ultimo passo è quello di aggiungere un nuovo modello al nostro database. Prima dobbiamo far sapere a Django che ci sono alcuni cambiamenti nel nostro modello (l'abbiamo appena creato. (Vai alla finestra della tua console e digita `python manage.py makemigrations blog`. Il risultato somiglierà a questo: + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py makemigrations blog Migrations for 'blog': - 0001_initial.py: + blog/migrations/0001_initial.py: + - Create model Post +**Nota:** Ricorda di salvare i file che modifica. Altrimenti, il computer eseguirà la versione precedente che potrebbe fornirti messaggi di errore inattesi. + Django ci ha preparato un file di migrazione che dobbiamo applicare nel nostro database. Digita `python manage.py migrate blog` e l'output dovrebbe essere: +{% 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 -Evviva! Il nostro modello Post ora è nel database! Sarebbe bello poterlo vedere, vero? Vai al prossimo capitolo per vedere com'è il tuo Post! +Evviva! Il nostro modello Post ora è nel database! Sarebbe bello poterlo vedere, vero? Vai al prossimo capitolo per vedere com'è il tuo Post! \ No newline at end of file diff --git a/it/django_orm/README.md b/it/django_orm/README.md index 4dfb21c3c89..c08695fcc90 100644 --- a/it/django_orm/README.md +++ b/it/django_orm/README.md @@ -1,10 +1,10 @@ -# Django ORM e i QuerySet +# Django ORM e QuerySets In questo capitolo imparerai come Django si collega al database e archivia i dati al suo interno. Tuffiamoci! ## Cos'è un QuerySet? -Un QuerySet, in sostanza, è una lista di oggetti di un determinato Modello. Il QuerySet ti permette di leggere il dato dal database, filtrarlo e ordinarlo. +Un QuerySet è in sostanza una lista di oggetti di un Model. Ti permettono di leggere i dati dal database, filtrarli e ordinarli. È più facile impararlo con un esempio. Proviamo, ti va? @@ -12,77 +12,110 @@ Un QuerySet, in sostanza, è una lista di oggetti di un determinato Modello. Il Apri la tua console locale (non su PythonAnywhere) e digita questo comando: - (myvenv) ~/djangogirls$ python manage.py shell +{% filename %}command-line{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py shell + L'effetto dovrebbe essere come questo: - (InteractiveConsole) - >>> +{% filename %}command-line{% endfilename %} +```python +(InteractiveConsole) +>>> +``` -Ora ti trovi nella consolle interattiva di Django. È come il prompt di python ma con un po' di magia di Django in più :). Qui puoi anche utilizzare tutti i comandi Python, ovviamente. +Ora ti trovi nella consolle interattiva di Django. E' come il prompt di python ma con un po' di magia di Django in più :). Qui puoi anche utilizzare tutti i comandi Python, ovviamente. ### Tutti gli oggetti Proviamo a rendere visibili tutti i nostri post prima. Puoi farlo con il seguente comando: - >>> 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 +``` Ops! È comparso un errore. Ci dice che non c'è nessun Post. È corretto -- ci siamo dimenticati di importarlo! - >>> from blog.models import Post +{% filename %}command-line{% endfilename %} +```python +>>> from blog.models import Post +``` È semplice: importiamo il modello `Post` da `blog.models`. Proviamo a rendere di nuovo visibili tutti i post: - >>> Post.objects.all() - [, ] +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.all() +, ]> +``` -È una lista di post che abbiamo creato prima! Abbiamo creato questi post usando l'interfaccia di ammisnistrazione di Django. Comunque sia, ora vogliamo creare nuovi post usando Python, quindi come lo facciamo? +È la lista dei post che abbiamo creato prima! Li abbiamo creati utilizzando l'interfaccia di amministrazione di Django. Se volessimo crearne uno con Python, come dovremmo fare? ### Creare oggetti Così si crea un nuovo oggetto Post nel database: - >>> 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') +``` Ma manca un ingrediente qui: `me`. Dobbiamo passare un'istanza del modello `User` come un autore. Come si fa? Importiamo il modello User prima: - >>> from django.contrib.auth.models import User +{% filename %}command-line{% endfilename %} +```python +>>> from django.contrib.auth.models import User +``` Quali utenti abbiamo nel nostro database? Prova questo: - >>> User.objects.all() - [] +{% filename %}command-line{% endfilename %} +```python +>>> User.objects.all() +]> +``` -È il superuser che abbiamo creato prima! Ora prendiamo un'istanza del user: +Questo è il superutente che abbiamo creato prima! Ora riceviamo un'istanza dell'utente (regolare questa linea per utilizzare il tuo nome utente): - me = User.objects.get(username='ola') +{% filename %}command-line{% endfilename %} +```python +>>> me = User.objects.get(username='ola') +``` -Come puoi vedere, ora prendiamo `(get)` un `User` con un `username` che è uguale a 'ola'. Ben fatto, devi cambiarlo con il tuo username. +Come puoi vedere, ora `riceviamo` un `Utente` con un `username` che equivale a 'ola'. Vicino! Adesso possiamo finalmente creare il nostro 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') + +``` Evviva! Vuoi controllare se funziona? - >>> Post.objects.all() - [, , ] +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.all() +, , ]> +``` Eccolo, un altro post nell'elenco! @@ -92,66 +125,97 @@ Ora puoi divertirti un po' ed aggiungere altri post per vedere come funziona. Ag ### Filtrare gli oggeti -Larga parte parte dei QuerySet consiste nell'abilità di filtrarli. Diciamo che vogliamo trovare tutti i post che hanno come autore l'Utente ola. Useremo `filter` invece di `all` in `Post.objects.all()`. Tra parentesi affermeremo le condizioni che un blog post deve soddisfare per finire nel nostro queryset. Nella nostra situazione è `autore` che è uguale a `me`. Il modo di scriverlo in Django è `autore=me`. Ora il nostro pezzo di codice ha questo aspetto: +Larga parte parte dei QuerySets consiste nell'abilità di filtrarli. Diciamo che vogliamo trovare tutti i post il cui autore è ola. Useremo `filter` invece di `all` in `Post.objects.all()`. Nelle parentesi andremo ad inserire tutte le condizioni che un Post deve avere per essere nel nostro queryset. Nella nostra situazione è `autore` che è uguale a `me`. Il modo di scriverlo in Django è `autore=me`. Ora il nostro pezzo di codice ha questo aspetto: - >>> Post.objects.filter(author=me) - [, , , ] +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.filter(author=me) +, , , ]> +``` O magari vogliamo vedere tutti i post che contengono la parola 'titolo' nel campo `titolo`? - >>> Post.objects.filter(title__contains='title') - [, ] +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.filter(title__contains='title') +, ]> +``` -> **Nota** ci sono due caratteri di sottolineatura (`_`) tra `titolo` e `contains`. L'ORM di Django usa questa sintassi per separare i nomi dei campi ("titolo") ed operazioni o filtri ("contiene"). Se usi solo un carattere di sottolineatura, otterrai un errore come "FieldError: non è possibile risolvere la parola chiave title_contains". +> **Nota** ci sono due caratteri di sottolineatura (`_`) tra `titolo` e `contains`. L'ORM di Django usa questa regola per separare i nomi dei field ("title") dalle operazioni e dai filtri ("contains"). Se usi solo un carattere di sottolineatura, otterrai un errore come "FieldError: non è possibile risolvere la parola chiave title_contains". Puoi anche ottenere una lista di tutti i post pubblicati. Lo facciamo filtrando tutti i post che hanno una `published_date` impostata in passato: - >>> from django.utils import timezone - >>> Post.objects.filter(published_date__lte=timezone.now()) - [] +{% filename %}command-line{% endfilename %} + +```python +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) + +``` Purtroppo, il post che abbiamo aggiunto dalla console Python non è ancora pubblicato. Possiamo modificarlo! In primo luogo ottenere un'istanza di un post che vogliamo pubblicare: - >>> post = Post.objects.get(title="Sample title") +{% filename %}command-line{% endfilename %} +```python +>>> post = Post.objects.get(title="Sample title") +``` -Ora pubblicalo con il nostro metodo `publish`! +Ora pubblicalo con il nostro metodo `publish`: - >>> post.publish() +{% filename %}command-line{% endfilename %} +```python +>>> post.publish() +``` Ora cerca di ottenere di nuovo l'elenco dei post pubblicati (premere il pulsante di freccia in su 3 volte e premere `invio`): - >>> Post.objects.filter(published_date__lte=timezone.now()) - [] +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +]> +``` ### Ordinare gli oggetti I QuerySet ti permettono anche di ordinare le liste di oggetti. Proviamo a ordinarli in base al campo `created_date`: - >>> Post.objects.order_by('created_date') - [, , , ] +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.order_by('created_date') +, , , ]> +``` Possiamo anche invertire l'ordine aggiungendo `-` all'inizio: - >>> Post.objects.order_by('-created_date') - [, , , ] +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.order_by('-created_date') +, , , ]> +``` -### QuerySet di concatenamento +### Query complesse attraverso la catena di metodo -Puoi anche combinare QuerySet ** concatenandole** insieme: - - >>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +Come hai visto, alcuni metodi su `Post.objects` restituiscono un QuerySet. Gli stessi metodi possono a loro volta essere chiamati su un QuerySet, e poi restituiranno un nuovo QuerySet. Puoi anche combinare QuerySets ** concatenandole** insieme: +```python +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> +``` È davvero potente e ti permette di scrivere query piuttosto complesse. Fantastico! Ora sei pronta per la prossima parte! Per chiudere la shell, digita questo: - >>> exit() - $ \ No newline at end of file +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` \ No newline at end of file diff --git a/it/django_start_project/README.md b/it/django_start_project/README.md index 02d16306558..b8481f0c665 100644 --- a/it/django_start_project/README.md +++ b/it/django_start_project/README.md @@ -1,45 +1,64 @@ # Il tuo primo progetto Django! -> Parte di questo capitolo è basato su esercitazioni di Geek Girls (https://github.com/ggcarrots/django-carrots). +> Parte di questo capitolo è tratto dal tutorial delle Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). > -> Parti di questo capitolo sono basate sul [django-marcador tutorial][1] sotto la licenza Creative Commons Attributions-ShareAlike 4.0 International License. Il tutorial di django-marcador è protetto da copyright di Markus Zapke-Gründemann et al. +> Parti di questo capitolo si basano sul [django-marcador tutorial](http://django-marcador.keimlink.de/) con licenza Creative Commons Attributions-ShareAlike 4.0 International License. Il tutorial di django-marcador è protetto da copyright di Markus Zapke-Gründemann et al. - [1]: http://django-marcador.keimlink.de/ - -Creeremo un semplice blog! +Creeremo un piccolo blog! Il primo passo è quello di iniziare un nuovo progetto di Django. Fondamentalmente, questo significa che eseguiremo alcuni script forniti da Django che creerà per noi lo scheletro di un progetto Django. Si tratta solo di un insieme di directory e file che verranno utilizzati dopo. I nomi di alcuni file e cartelle sono molto importanti per Django. Non dovresti modificare i nomi dei file che stiamo per creare. Neanche spostarli in un altro posto è una buona idea. Django deve mantenere una determinata struttura per essere in grado di trovare le cose importanti. -> Ricordati di eseguire tutto nel virtualenv. Se non vedi un prefisso `(myvenv)` nella tua console devi attivare il tuo virtualenv. Abbiamo spiegato come farlo nel capitolo **installazione Django** nella parte **Lavorando con virtualenv**. Digitando `myvenv\Scripts\activate` su Windows oppure `source myvenv/bin/activate` su Mac OS / Linux farà questo per te. +> Ricordati di eseguire tutto nel virtualenv. Se non vedi il prefisso `(myvenv)` nella tua console, devi attivare il tuo virtualenv. Abbiamo spiegato come farlo nel capitolo **installazione Django** nella parte **Lavorando con virtualenv**. Digitando `myvenv\Scripts\activate` su Windows oppure `source myvenv/bin/activate` su Mac OS / Linux farà questo per te. -Dovresti eseguire nella tua console MacOS o Linux il seguente comando; **non dimenticarti di aggiungere il punto `.` alla fine **: + + +Dovresti eseguire il seguente comando nella tua console MacmacOS o Linux; **non dimenticarti di aggiungere il punto `.` alla fine! ** + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ django-admin startproject mysite . -Su Windows; **non dimenticarti di aggiungere il punto `.` alla fine**: +> Il punto `.` è cruciale perché dice allo script d'installare Django nell'attuale directory (quindi il punto `.` è un riferimento di abbreviazione). +> +> **Nota** Quando digiti i comandi sopra, ricorda che si digita soltanto la parte che inizia con django-admin oppure ``. Le parti mostrate qui come (myvenv) ~/djangogirls$ e `(myvenv) C:\Users\Name\djangogirls` sono solo esempi del prompt che starà invitando il tuo input sulla tua command line. + + + + - (myvenv) C:\Users\Name\djangogirls> django-admin startproject mysite . +Dovresti eseguire nella tua console MacOS o Linux il seguente comando; **non dimenticarti di aggiungere il punto `.` alla fine **: + +{% filename %}command-line{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . -> Il punto `.` è cruciale perché dice allo script d'installare Django nell'attuale directory (quindi il punto `.` è un riferimento di abbreviazione) +> Il punto `.` è cruciale perché dice allo script d'installare Django nell'attuale directory (quindi il punto `.` è un riferimento di abbreviazione). > -> **Nota** Quando digiti i comandi sopra, ricorda che si digita soltanto la parte che inizia con `django-admin` oppure `django-admin.py`. Le parti mostrate qui come `(myvenv) ~/djangogirls$` e `(myvenv) C:\Users\Name\djangogirls>` sono solo esempi del prompt che starà invitando il tuo input sulla tua command line. +> **Nota** Quando digiti i comandi sopra, ricorda che si digita soltanto la parte che inizia con django-admin oppure ``. Le parti mostrate qui come (myvenv) ~/djangogirls$ e `(myvenv) C:\Users\Name\djangogirls` sono solo esempi del prompt che starà invitando il tuo input sulla tua command line. + + `django-admin.py` è uno script che creerà le cartelle ed i file per te. Adesso dovresti avere una struttura di directory simile a questa: djangogirls - ├───manage.py - └───mysite - settings.py - urls.py - wsgi.py - __init__.py + ├── manage.py + ├── mysite + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt -`manage.py` è uno script che aiuta a gestire il sito. Usandolo saremo in grado di avviare un web server sul nostro computer senza dover installare nient'altro, tra l'altro. +> **Nota**: nella struttura della directory, vedrai anche la tua cartella `myvenv` che abbiamo creato prima. + +`manage.py` è uno script che aiuta a gestire il sito. Usandolo saremo in grado di avviare un web server sul nostro computer senza dover istallare nient'altro, tra l'altro. Il file `settings.py` contiene la configurazione del tuo sito web. @@ -49,90 +68,193 @@ Ignoriamo gli altri file per ora dal momento che non li modificheremo. L'unica c ## Modificare le impostazioni -Facciamo qualche cambiamento in `mysite/settings.py`. Apri il file usando il code editor che hai installato prima. +Facciamo qualche cambiamento in `mysite/settings.py`. Apri il file usando il code editor che hai istallato prima. -Sarebbe bello avere l'ora corretta sul nostro sito Web. Vai alla [lista di fusi orari di wikipedia][2] e copia il tuo fuso orario (TZ). (es. `Europe/Berlin`) +**Nota**: Ricorda che `settings.py` è un file regolare, come qualsiasi altro. Puoi aprirlo all'interno dell'editor di codice, utilizzando le azioni di menu "file -> apri". Questo dovrebbe portarti la finestra abituale in cui puoi navigare nel file `settings.py` e selezionarlo. In alternativa, puoi aprire il file navigando nella cartella djangogirls sul tuo desktop e facendo clic destro su di esso. Quindi, seleziona l'editor di codice dall'elenco. La selezione dell'editor è importante perché potresti avere altri programmi installati che possono aprire il file ma non ti permetterà di modificarlo. - [2]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +Sarebbe bello avere l'ora corretta sul nostro sito Web. Vai alla lista delle zone orarie [Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) e copia la tua zona di tempo (TZ) (ad esempio. `Europa/Berlino`). In settings.py, trova la riga che contiene `TIME_ZONE` e modificala per scegliere il tuo fuso orario: +{% filename %}mysite/settings.py{% endfilename %} + ```python TIME_ZONE = 'Europe/Berlin' ``` -Modifica "Europe/Berlin" nel modo corretto +Un codice lingua è costituito dalla lingua, ad esempio`en` per l'inglese o `de` per il tedesco e il codice del paese, ad esempio`de` per la Germania o `ch` per la Svizzera. Se l'inglese non è la tua lingua nativa, puoi aggiungere questo per cambiare i pulsanti e le notifiche predefinite da Django per essere nella tua lingua. Quindi, il pulsante "Annulla" verrebbe tradotto nella lingua che hai definito qui. [Django arriva con molte traduzioni preparate](https://docs.djangoproject.com/en/2.2/ref/settings/#language-code). + +Se vuoi una lingua diversa, cambia il codice lingua modificando la seguente riga: -Avrai anche bisogno di aggiungere un percorso per i file statici (scopriremo tutto su file statici e CSS più avanti nell'esercitazione). Scendi fino alla *fine* del file e sotto la voce `STATIC_URL`, aggiungi un nuovo percorso chiamato `STATIC_ROOT`: +{% filename %}mysite/settings.py{% endfilename %} + +```python +LANGUAGE_CODE = 'de-ch' +``` + +Dovremo anche aggiungere un percorso per i file statici. (Più tardi scopriremo tutti i file statici e CSS nel tutorial.) Vai alla *end* del file, e appena sotto la voce `STATIC_URL` aggiungi un nuovo nome chiamato `STATIC_ROOT`: + +{% filename %}mysite/settings.py{% endfilename %} ```python STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') +STATIC_ROOT = BASE_DIR / 'static' ``` +Quando `DEBUG` è `Vero` e `ALLOWED_HOSTS` è vuoto, l'host è convalidato contro `['localhost', '127.0.0.1', '[::1]']`. Questo non abbina il nostro hostname su PythonAnywhere dopo aver distribuito la nostra applicazione in modo da modificare le seguenti impostazioni: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +ALLOWED_HOSTS = ['127.0.0.1', '.pythonanywhere.com'] +``` + +> **Nota**: se stai usando un Chromebook, aggiungi questa linea nella parte inferiore del file settings.py: `MESSAGE_STORAGE = 'django.contrib.storage.session.SessionStorage'` +> +> Aggiunge anche `.amazonaws.com` a `ALLOWED_HOSTS` se stai usando cloud9 +> +> Se stai presentando il tuo progetto su `Glitch.com`, bisogna proteggere la chiave segreta di Django, che deve rimanere confidenziale (altrimenti chiunque faccia un remix del tuo progetto potrebbe vederla): +> +> - Prima di tutto, si crea una chiave segreta casuale. Apri nuovamente il terminale Glitch e digita il comando seguente: +> +> {% filename %}command-line{% endfilename %} +> +> ```bash +> python -c 'from django.core.management.utils import get_random_secret_key; \ +> print(get_random_secret_key())' +> ``` +> +> Il comando dovrebbe mostrare una lunga stringa casuale, perfetta da usare come chiave segreta per il tuo nuovo sito web Django. Si incolla poi questa chiave in un file `.env` che Glitch mostrerà solamente se sei il proprietario del sito web. +> +> - Crea un file `.env` alla base del tuo progetto e aggiungi al suo interno la proprietà seguente: +> +> {% filename %}.env{% endfilename %} +> +> ```bash +> # Qui, all'interno delle virgolette, puoi tagliare e incollare la chiave casuale generata precedentemente +> SECRET='3!0k#7ds5mp^-x$lqs2%le6v97h#@xopab&oj5y7d=hxe511jl' +> ``` +> +> - Aggiorna poi il file delle impostazioni di Django per inserire questo valore segreto e impostare il nome del sito web: +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> SECRET_KEY = os.getenv('SECRET') +> ``` +> +> - Poco più avanti nello stesso file, inserisci il nome del tuo nuovo sito web Glitch: +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> ALLOWED_HOSTS = [os.getenv('PROJECT_DOMAIN') + ".glitch.me"] +> ``` +> +> Il valore `PROJECT_DOMAIN` è generato automaticamente da Glitch. Corrisponderà al nome del tuo progetto. + ## Imposta un database Ci sono un sacco di software di database diversi che possono immagazzinare dati per il tuo sito. Noi useremo quello di default, `sqlite3`. È già impostato in questa parte del file `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', } } ``` Per creare un database per il nostro blog, eseguiamo questo nella console: `python manage.py migrate` (abbiamo bisogno di essere nella directory `djangogirls` che contiene il file `manage.py`). Se funziona, dovresti vedere qualcosa di simile: +{% 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: auth, admin, 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 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 sessions.0001_initial... OK E abbiamo finito! Tempo di avviare il server web e vedere se il nostro sito Web funziona! +## Avvio del server web + Devi essere nella directory che contiene il file di `manage.py` (la directory `djangogirls`). Nella console, possiamo avviare il server web eseguendo `python manage.py runserver`: +{% filename %}command-line{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py runserver -Se sei su Windows e non funziona con `UnicodeDecodeError`, usa questo comando: +Se invece stai usando un Chromebook, digita questo comando: + +{% filename %}Cloud 9{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0.0.0.0:8080 + + +o questo se stai usando Glitch: + +{% filename %}Glitch.com terminal{% endfilename %} + + $ refresh + + + +Se usi Windows e il comando `UnicodeDecodeError` non funziona, puoi usare questo: + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 -Ora tutto quello che devi fare è controllare che il tuo sito sia in esecuzione. Apri il tuo browser (Firefox, Chrome, Safari, Internet Explorer o qualsiasi altro tu usi) e digita l'indirizzo: +Ora devi solo controllare se il tuo sito web è in esecuzione. Apri il tuo browser (Firefox, Chrome, Safari, Internet Explorer o quello che utilizzi di solito) e inserisci questo indirizzo: + +{% filename %}browser{% endfilename %} http://127.0.0.1:8000/ +Se stai utilizzando un Chromebook e Cloud9, seleziona invece l'URL nella finestra a comparsa che dovrebbe apparire nell'angolo in alto a destra della finestra di comando dove il server web è in esecuzione. L'URL sarà simile a questo: + +{% filename %}browser{% endfilename %} + + https://.vfs.cloud9.us-west-2.amazonaws.com + + +oppure su Glitch: + + https://name-of-your-glitch-project.glitch.me + + +Congratulazioni! Hai appena creato il tuo primo sito web e lo hai avviato usando un server web! Non è fantastico? -Il server web assumerà il controllo del command prompt finché non lo fermi. Per digitare più comandi mentre è in esecuzione apri una nuova finestra di terminale e attiva il tuo virtualenv. Per fermare il server web, torna alla finestra dove è in esecuzione e premi i pulsanti CTRL+C - Control e C insieme (su Windows, è probabile che tu deva premere Ctrl+Break). +![Installazione completata!](images/install_worked.png) -Congratulazioni! Hai appena creato il tuo primo sito e l'hai avviato usando un web server! Non è fantastico? +N.B. Una finestra di comando può eseguire solo una cosa alla volta e la finestra di comando che hai aperto in precedenza sta eseguendo il server web. Finché il server web è in esecuzione e in attesa di ulteriori richieste in arrivo, il terminale ammetterà del testo nuovo, ma non eseguirà nuovi comandi. -![Ha funzionato!][3] +> Abbiamo esaminato come funzionano i server web nel capitolo **Come funziona il capitolo** . - [3]: images/it_worked2.png +Per digitare ulteriori comandi mentre il server web è in esecuzione, puoi aprire una nuova finestra terminale e attivare il tuo virtualenv (per rivedere le istruzioni su come aprire una seconda finestra terminale, vedi [Introduction to the command line](../intro_to_command_line/README.md)). Per arrestare il server web, devi tornare alla finestra dove è in esecuzione e premere CTRL+C - ovvero i tasti Control e C insieme (su Windows potresti dover premere Ctrl+Break). -Pronto/a per il prossimo passo? È ora di creare un po' di contenuti! +Sei pronto per il prossimo passaggio? È ora di creare un po' di contenuti! \ No newline at end of file diff --git a/it/django_start_project/images/install_worked.png b/it/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..4354c634ddb Binary files /dev/null and b/it/django_start_project/images/install_worked.png differ diff --git a/it/django_start_project/images/it_worked2.png b/it/django_start_project/images/it_worked2.png deleted file mode 100644 index 4412ecfc49e..00000000000 Binary files a/it/django_start_project/images/it_worked2.png and /dev/null differ diff --git a/it/django_templates/README.md b/it/django_templates/README.md index cdf3d99ca3c..ae8a2beed24 100644 --- a/it/django_templates/README.md +++ b/it/django_templates/README.md @@ -14,68 +14,73 @@ Nel capitolo precedente abbiamo dato al nostro template una lista di posts nella Per stampare una variabile nel template Django, usiamo doppie parentesi graffe con il nome della variabile all'interno, così: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html {{ posts }} ``` -Prova questo nel tuo template `blog/templates/blog/post_list.html`. Sostituisci tutto dal secondo `
` al terzo `
` con `{{ posts }}`. Salva il file e aggiorna la pagina per vedere i risultati: - -![Figura 13.1][1] +Prova ad inserirlo nel tuo template `blog/templates/blog/post_list.html`. Sostituisci tutto dal secondo `
` al terzo `
` con `{{ posts }}`. Salva il file e aggiorna la pagina per vedere i risultati: - [1]: images/step1.png +![Figura 13.1](images/step1.png) Come vedi, quello che abbiamo è: - [, ] - +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +, ]> +``` Significa che Django lo vede come una lista di oggetti. Ricordi dalla **Introduzione a Python** come possiamo rendere visibili le liste? Sì, con for loops! In un template Django si fanno così: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html {% for post in posts %} - {{ post }} +    {{ post }} {% endfor %} ``` Prova ad inserirlo nel tuo template. -![Figura 13.2][2] - - [2]: images/step2.png +![Figura 13.2](images/step2.png) Funziona! Ma noi vogliamo che vengano mostrate come i post statici che abbiamo creato prima nel capitolo **Introduzione ad HTML**. Puoi mischiare i tag HTML con quelli di template. Il nostro `body` avrà questo aspetto: +{% 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 %}Tutto quello che hai messo tra `{% for %}` e `{% endfor %}` Sarà ripetuto per ciascun oggetto della lista. Aggiorna la tua pagina:{% endraw %} -![Figura 13.3][3] +![Figura 13.3](images/step3.png) - [3]: images/step3.png - -Ti sei accorto che abbiamo utilizzato una notazione leggermente diversa questa volta `{{ post.title }}` oppure `{{ post.text }}`? Stiamo introducendo i dati in ciascuno dei campi definiti nel nostro modello `Post`. Inoltre le `|linebreaksbr` stanno spingendo il testo dei post attraverso un filtro per trasformare le line-breaks in paragrafi. +Ti sei accorto che abbiamo utilizzato una notazione leggermente diversa questa volta `{{ post.title }}` oppure `{{ post.text }}`)? Stiamo introducendo i dati in ciascuno dei campi definiti nel nostro modello `Post`. Inoltre il comando `|linebreaks` introduce un filtro che traduce gli accapo (la pressione del tasto "invio" sulla tastiera) nel loro equivalente in HTML. ## Un' ultima cosa Sarebbe bello vedere se il tuo sito funziona ancora su Internet, giusto? Proviamo a fare il deploy su PythonAnywhere di nuovo. Ecco un riepilogo dei passaggi... -* Prima di tutto, fai il push del tuo codice verso Github +* Prima di tutto, fai il push del tuo codice verso Github + +{% filename %}command-line{% endfilename %} $ git status [...] - $ git add --all . + $ git add . $ git status [...] $ git commit -m "Modified templates to display posts from database." @@ -83,23 +88,21 @@ Sarebbe bello vedere se il tuo sito funziona ancora su Internet, giusto? Proviam $ git push -* Poi, ritorna su [PythonAnywhere][4] e vai alla tua **console di Bash** (o iniziane una nuova) ed esegui: +* Poi, ritorna su [PythonAnywhere](https://www.pythonanywhere.com/consoles/) e vai alla tua **console di Bash** (o iniziane una nuova) ed esegui: - [4]: https://www.pythonanywhere.com/consoles/ +{% filename %}PythonAnywhere command-line{% endfilename %} - $ cd my-first-blog + $ cd ~/.pythonanywhere.com $ git pull [...] -* Infine, vai sulla [Web tab][5] e premi **Reload** sulla tua web app. L'aggiornamento dovrebbe essere live! +(Ricordati di sostituire `` con il sottodominio di PythonAnywhere, senza le parentesi angolo.) - [5]: https://www.pythonanywhere.com/web_app_setup/ +* Infine, fai un salto alla [scheda Web](https://www.pythonanywhere.com/web_app_setup/) e premi **Reload** sulla tua web app. (Per raggiungere altre pagine PythonAnywhere dalla console, usa il pulsante menu nell'angolo in alto a destra.) Il tuo aggiornamento dovrebbe essere attivo su https://subdomain.pythonanywhere.com -- scoprilo nel browser! Se i post che hai sul computer non combaciano con quelli presenti su PythonAnywhere, va tutto bene. Il database su PythonAnywhere e quello sul tuo computer sono diversi a differenza degli altri file. -Congratulazioni! Ora vai avanti e prova ad aggiungere un nuovo post nel tuo Admin Django (ricorda di aggiungere una published_date!), sucessivamente aggiorna il tuo sito per vedere se il post compare. +Congratulazioni! Andiamo avanti e proviamo ad aggiungere nuovi post nel tuo admin di Django (ricordati di aggiungere published_date!). Assicurati di essere nell'admin del tuo sito su pythonanywhere, https://subdomain.pythonanywhere.com/admin. Quindi aggiorna la pagina per vedere se i post sono comparsi. Funziona come un incantesimo? Ne siamo fieri! Staccati dal computer per un po', ti sei guadagnato/a una pausa. :) -![Figura 13.4][6] - - [6]: images/donut.png \ No newline at end of file +![Figura 13.4](images/donut.png) \ No newline at end of file diff --git a/it/django_templates/images/donut.png b/it/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/it/django_templates/images/donut.png and b/it/django_templates/images/donut.png differ diff --git a/it/django_templates/images/step1.png b/it/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/it/django_templates/images/step1.png and b/it/django_templates/images/step1.png differ diff --git a/it/django_templates/images/step2.png b/it/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/it/django_templates/images/step2.png and b/it/django_templates/images/step2.png differ diff --git a/it/django_templates/images/step3.png b/it/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/it/django_templates/images/step3.png and b/it/django_templates/images/step3.png differ diff --git a/it/django_urls/README.md b/it/django_urls/README.md index b661a07a53a..626a37d85b0 100644 --- a/it/django_urls/README.md +++ b/it/django_urls/README.md @@ -4,11 +4,9 @@ Stiamo per costruire la nostra pagina web: una homepage per il tuo blog! Ma prim ## Che cos'è un URL? -Una URL è semplicemente un indirizzo web. Puoi vedere una URL ogni volta che visiti un sito web - si vede nella barra degli indirizzi del tuo browser. (sì! `127.0.0.1:8000` is a URL! Anche `https://djangogirls.org` è una URL): +Una URL è semplicemente un indirizzo web. Puoi vedere una URL ogni volta che visiti un sito web - si vede nella barra degli indirizzi del tuo browser. (sì. (Ma certo che sì! `127.0.0.1:8000` is a URL! Anche `https://djangogirls.org` è una URL.) -![Url][1] - - [1]: images/url.png +![URL](images/url.png) Ogni pagina internet ha bisogno della sua URL. In questo modo la tua applicazione sa cosa deve mostrare a un utente che visita una URL. In Django usiamo qualcosa chiamato `URLconf` ( configurazione dell'URL). URLconf è un insieme di modelli che Django cercherà di far corrispondere con l'URL ricevuta per trovare la view giusta. @@ -16,110 +14,90 @@ Ogni pagina internet ha bisogno della sua URL. In questo modo la tua applicazion Apriamo il file `mysite/urls.py` nel code editor che hai scelto e vediamo com'è: +{% filename %}mysite/urls.py{% endfilename %} + ```python -from django.conf.urls import include, url -from django.contrib import admin +"""mysite URL Configuration -urlpatterns = [ -    # Examples: -    # url(r'^$', 'mysite.views.home', name='home'), -    # url(r'^blog/', include('blog.urls')), +[...] +""" +from django.contrib import path, include +from django.urls import admin -    url(r'^admin/', include(admin.site.urls)), +urlpatterns = [ + path('admin/', admin.site.urls), ] ``` Come puoi vedere, Django ha già predisposto qualcosa per noi in questo file. -Le righe che iniziano con `#` sono commenti - questo significa che non verranno lette da Python. Comodo, non è vero? +Le line tra un triplo apice (`'''` o `"""`) sono chiamate docstrings - puoi scriverle all'inizio di file, classi o metodi per descrivere cosa fanno. Verranno ignorati da Python. L'admin URL , che hai visto nel capitolo precedente è già qui: +{% filename %}mysite/urls.py{% endfilename %} + ```python -    url(r'^admin/', include(admin.site.urls)), + path('admin/', admin.site.urls), ``` Questo significa che per ogni URL che comincia con `admin/` Django troverà la corrispondente *view*. In questo caso stiamo includendo un sacco di admin URL così che non sia tutto imballato in questo piccolo file - è più leggibile e più pulito. -## Regex - -Per caso ti stai chiedendo come fa Python a far corrispondere URL e view? Beh, questa parte è difficile. Django usa `regex`, abbreviazione di "espressioni regolari". Regex ha molte, (moltissime!) regole che costituiscono un modello di ricerca. Dal momento che i regex sono un argomento avanzato, non analizzeremo nel dettaglio come funzionano. - -Se vuoi capire come abbiamo creato i patterns, eccoti un esempio del procedimento - ci servirà solo un sottoinsieme limitato di regole per esprimere il modello che stiamo cercando, vale a dire: - - ^ per l'inizio del testo - $ per la fine del testo - \d per una cifra - + per indicare che l'elemento precedente dovrebbe essere ripetuto almeno una volta - () per catturare parte del pattern - - -Il resto nella definizione dell'url sarà preso alla lettera. +## Il tuo primo URL Django! -Ora immagina di avere un sito Web con un indirizzo così: `http://www.mysite.com/post/12345/`, dove `12345` è il numero del tuo post. - -Scrivere view separate per ogni numero del post sarebbe veramente noioso. Con l'espressione regolare possiamo creare un modello che corrisponde all'url ed estrae il numero per noi: `^ post/(\d+) / $`. Scomponiamo pezzo per pezzo per vedere che cosa stiamo facendo: - -* **^ post /** sta dicendo a Django di prendere tutto ciò che ha `post /` all'inizio dell'url (subito dopo `^`) -* **(\d+)** significa che ci sarà un numero (composto da una o più cifre) e che noi vogliamo che il numero venga catturato ed estratto -* **/** dice a django che ci dovrebbe essere un altro carattere a seguire `/` -* infine, **$** indica la fine dell'URL. Significa che solo le stringhe che terminano con `/` corrisponderanno a questo modello - -## La tua prima Url Django! - -È ora di creare la tua prima URL. Vogliamo usare http://127.0.0.1:8000/ come homepage per il nostro blog e visualizzare il nostro elenco di post. +E' ora di creare la tua prima URL. Vogliamo usare http://127.0.0.1:8000/ come homepage per il nostro blog e visualizzare il nostro elenco di post. Vogliamo anche mantenere il file di `mysite/urls.py` pulito, quindi importeremo le url dalla nostra applicazione `blog` sul file principale `mysite/urls.py`. -Vai avanti, elimina le righe commentate (che cominciano con `#`) e aggiungi una riga che importerà `blog.urls` nella url principale (`''`). +Vai avanti, aggiungi una linea che importerà `blog.urls`. Dovrai anche cambiare la riga `da django.urls…` perché stiamo usando la funzione `include` qui, quindi dovrai aggiungere questa importazione alla riga. Il tuo file `mysite/urls.py` ora dovrebbe avere questo aspetto: +{% 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 reindirizzerà ora tutto ciò che viene da 'http://127.0.0.1:8000/' verso `blog.urls` e cercherà ulteriori istruzioni in questo file. - -Quando si scrivono espressioni regolari in Python lo si fa sempre con `r` davanti alla stringa. Questo è un suggerimento utile per Python che la stringa possa contenere caratteri speciali che non sono destinati per lo stesso Python, ma per l'espressione regolare. +Ora Django reindirizzerà tutto ciò che viene da 'http://127.0.0.1:8000/' verso `blog.urls` e cercherà qui ulteriori istruzioni. ## blog.urls -Crea un nuovo file `blog/urls.py`. Perfetto! Ora aggiungi queste prime due righe: +Crea un nuovo file vuoto chiamato `urls.py` nella cartella `blog` e aprilo nell'editor di codice. Tutto a destra! Aggiungi queste prime due righe: + +{% filename %}blog/urls.py{% endfilename %} ```python -from django.conf.urls import url +from django.urls import path from . import views ``` -Stiamo solo importando metodi che appartengono a Django e tutte le nostre `views` dalla nostra app `blog` (non abbiamo ancora nulla all'interno, ma rimedieremo a questo in un minuto!) +Qui abbiamo importato la funzione `url` di Django e tutte le nostre `views` dalla applicazione `blog` (Non abbiamo ancora nulla, ma ci arriveremo fra un minuto!) Dopo di che, possiamo aggiungere il nostro primo modello di URL: +{% filename %}blog/urls.py{% endfilename %} + ```python urlpatterns = [ - url(r'^$', views.post_list, name='post_list'), + path('', views.post_list, name='post_list'), ] ``` -Come vedi, stiamo assegnando una `view` nominata `post_list` alla URL `^$`. Questa espressione regolare combinerà`^` (un inizio) seguito da `$` (una fine) - cosicché solo una stringa vuota possa combaciare. È giusto, perché nei resolver di URL di Django, ' http://127.0.0.1:8000 /' non è una parte dell'URL. Questo schema dirà a Django che `views.post_list` è il posto giusto dove andare se qualcuno entra nel tuo sito all'indirizzo 'http://127.0.0.1:8000/'. - -L'ultima parte `name='post_list'` è il nome dell'URL che verrà usata per identificare la view. Può avere lo stesso nome della view, ma può anche essere qualcosa di completamente diverso. Useremo le URL rinominate successivamente nel progetto quindi è importante dare un nome a ciascuna URL nell'app. Inoltre dovremmo cercare di mantenere i nomi delle URL unici e facili da ricordare. - -Tutto fatto? Apri http://127.0.0.1:8000 / nel tuo browser per vedere il risultato. +Come vedi, stiamo assegnando una `view` nominata `post_list` alla URL `^$`. Questo modello dell'URL corrisponderà ad una stringa vuota ed al risolutore URL di Django ignorerà il nome del dominio (es., http://127.0.0.1:8000/) che prefissa il percorso URL completo. Questo schema dirà a Django che `views.post_list` è il posto giusto dove andare se qualcuno entra nel tuo sito all'indirizzo 'http://127.0.0.1:8000/'. -![Errore][2] +L'ultima parte `name='post_list'` è il nome dell'URL che verrà usata per identificare la view. Può avere lo stesso del nome della view, ma può anche essere qualcosa di completamente diverso. Useremo le URL rinominate successivamente nel progetto quindi è importante dare un nome a ciascuna URL nell'app. Inoltre dovremmo cercare di mantenere i nomi delle URL unici e facili da ricordare. - [2]: images/error1.png +Se provi a guardare adesso http://127.0.0.1:8000/, troverai un qualche tipo di messaggio come 'pagina non disponibile'. Questo perché il server (ricordi quando hai digitato `runserver`?) non è più attivo. Per capirne il motivo dai un occhiata alla console del tuo server. -Non funziona, vero? Non ti preoccupare, è solo una pagina di errore, niente di cui spaventarsi! In realtà sono molto utili: +![Errore](images/error1.png) -Leggerai che **non c'è un attributo 'post_list**. il *post_list* ti ricorda qualcosa? Abbiamo chiamato la nostra view proprio così! Questo significa che è tutto a posto. Semplicemente non abbiamo ancora creato la nostra *view*. Non ti preoccupare, ci arriveremo. +La tua console sta mostrando un errore, ma non preoccuparti – è davvero molto utile: ti dice che c'è **nessun attributo 'post_list'**. È il nome della *view* che Django prova a cercare e usare, ma non l'abbiamo ancora creata. In questa fase, anche il tuo `/admin/` non funzionerà. Non ti preoccupare, ci arriveremo. Se vedi un altro messaggio di errore, prova a riavviare il server web. Per farlo, nella finestra della console che esegue il server web, interrompilo premendo Ctrl+C (i tasti Control e C insieme). Su Windows, potresti dover premere Ctrl+Break. Poi devi riavviare il server web eseguendo un comando `python manage.py runserver`. -> Se vuoi sapere di più sulla configurazione di URL Django, vai alla documentazione ufficiale: https://docs.djangoproject.com/en/1.8/topics/http/urls/ \ No newline at end of file +> Se vuoi sapere di più su URLconfs di Django, guarda alla documentazione ufficiale: https://docs.djangoproject.com/en/2.2/topics/http/urls/ \ No newline at end of file diff --git a/it/django_urls/images/error1.png b/it/django_urls/images/error1.png index cc17593d19d..50618fca3fe 100644 Binary files a/it/django_urls/images/error1.png and b/it/django_urls/images/error1.png differ diff --git a/it/django_urls/images/url.png b/it/django_urls/images/url.png index 6cd1bd96291..c22441e930e 100644 Binary files a/it/django_urls/images/url.png and b/it/django_urls/images/url.png differ diff --git a/it/django_views/README.md b/it/django_views/README.md index a65540fc789..0f76223f653 100644 --- a/it/django_views/README.md +++ b/it/django_views/README.md @@ -1,6 +1,6 @@ -# Le views di Django - è arrivata l'ora di creare! +# Le viste di Django – è arrivata l'ora di creare! -È ora di liberarsi di quel bug che abbiamo creato nel capitolo precedente :) +E' ora di liberarsi di quel bug che abbiamo creato nel capitolo precedente! :) Una *view* è un posto dove viene messa la "logica" della nostra applicazione. Essa richiederà informazioni dal `modello` che hai creato prima e lo passerà ad un `template`. Creeremo un template nel prossimo capitolo. Le views sono solo metodi di Python un po' più complicati di quelli che abbiamo descritto nel capitolo **Introduzione a Python**. @@ -10,29 +10,35 @@ Le views vengono collocate nel file `views.py`. Noi aggiungeremo le nostre *view OK, apriamo questo file e scopriamo cosa c'è dentro: +{% filename %}blog/views.py{% endfilename %} + ```python from django.shortcuts import render -# Create your views here. +# Crea le tue views qui. ``` -Non c'è molto per ora. La *view* più semplice può essere simile a questa. +Non c'è altro qui. + +Ricorda che le linee che iniziano con `#` sono commenti – questo significa che queste linee non saranno gestite da Python. + +Creiamo una *vista* come suggerisce il commento. Aggiungi la seguente vista minima qui sotto: + +{% filename %}blog/views.py{% endfilename %} ```python def post_list(request): -    return render(request, 'blog/post_list.html', {}) + return render(request, 'blog/post_list.html', {}) ``` -Come puoi vedere, abbiamo creato un metodo (`def`) chiamato `post_list` che prende `request` e `restituisce` un metodo `render` che ci fornirà (metterà insieme) il nostro template `blog/post_list.html`. +Come puoi vedere, abbiamo creato una funzione (`def`) chiamata `post_list` che prende `request` e restituisce `return` una funzione `render` che renderizza (mette insieme) il nostro template `blog/post_list.html`. Salva il file, vai su http://127.0.0.1:8000/ e guarda cosa abbiamo ottenuto. Un altro errore! Leggi cosa sta succedendo adesso: -![Error][1] - - [1]: images/error.png +![Errore](images/error.png) -Questo è facile: *TemplateDoesNotExist*. Sistemiamo il bug e creiamo un template nel prossimo capitolo! +Questo mostra che almeno il server è ancora attivo, ma ancora non sembra corretto, vero? Non preoccuparti, è solo una pagina di errore, nulla di cui aver paura! Come l messaggi di errore nella console, sono davvero utili. Puoi leggere il *TemplateDoesNotExist*. Correggiamo questo bug e creiamo un template nel capitolo successivo! -> Impara di più sulle views di Django leggendo la documentazione ufficiale: https://docs.djangoproject.com/en/1.8/topics/http/views/ \ No newline at end of file +> Scopri di più sulle visualizzazioni di Django leggendo la documentazione ufficiale: https://docs.djangoproject.com/en/2.2/topics/http/views/ \ No newline at end of file diff --git a/it/django_views/images/error.png b/it/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/it/django_views/images/error.png and b/it/django_views/images/error.png differ diff --git a/it/domain/README.md b/it/domain/README.md deleted file mode 100644 index e68b8a007e3..00000000000 --- a/it/domain/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# Dominio - -Heroku ti ha dato un dominio, ma è lungo, difficile da ricordare e brutto. Sarebbe fantastico avere un dominio che sia corto e facile da ricordare, non credi? - -in questo capitolo ti insegneremo come comprare un dominio e dirigerlo verso Heroku! - -## Dove registrare un dominio? - -un dominio costa circa 15 dollari all'anno. Ci sono opzioni più economiche e più costose, a seconda del fornitore. Ci sono tantissime aziende dalle quali puoi comprare un dominio: un semplice [google search][1] darà centinaia di opzioni. - - [1]: https://www.google.com/search?q=register%20domain - -Il nostro preferito è [I want my name][2]. Essi si promuovono come "gestione del dominio indolore" ed è veramente indolore. - - [2]: https://iwantmyname.com/ - -## Come registrare un dominio in IWantMyName? - -Vai su [iwantmyname][3] e digita un dominio che vuoi ottenere nella casella di ricerca. - - [3]: https://iwantmyname.com - -![][4] - - [4]: images/1.png - -Dovresti vedere una lista dei domini disponibili contenenti il termine che hai inserito nella casella di ricerca. Come vedi, una faccina sorridente indica che il dominio è disponibile e può essere comprato, mentre una faccina triste indica che è già stato preso. - -![][5] - - [5]: images/2.png - -Abbiamo deciso di comprare `djangogirls.in`: - -![][6] - - [6]: images/3.png - -Vai alla cassa. Dovresti iscriverti a iwantmyname se non hai ancora un'account. Poi fornisci le informazioni sulla tua carta di credito e compra un dominio! - -Poi clicca su `Domains` nel menù e scegli il tuo nuovo dominio. Infine individua e clicca sul link `manage DNS records`: - -![][7] - - [7]: images/4.png - -Ora devi individuare questo form: - -![][8] - - [8]: images/5.png - -E riempilo con i seguenti dati: - Hostname: www - Type: CNAME - Value: il tuo dominio da Heroku (per esempio djangogirls.herokuapp.com) - TTL: 3600 - -![][9] - - [9]: images/6.png - -Clicca il pulsante 'Aggiungi' e 'Salva' in fondo alla pagina per salvare cambiamenti. - -Perchè il tuo dominio cominci a funzionare potrebbero essere necessarie fino ad un paio di ore, quindi sii paziente! - -## Fai la configurazione del dominio su Heroku - -Devi dire a Heroku anche che vuoi utilizzare il tuo dominio personalizzato. - -Vai sulla [Heroku Dashboard][10], fai il login nel tuo account Heroku e scegli la tua app. Poi vai nelle impostazioni dell'app e aggiungi il tuo dominio nella sezione `Domini` e salva le tue modifiche. - - [10]: https://dashboard.heroku.com/apps - -Questo è tutto! \ No newline at end of file diff --git a/it/dynamic_data_in_templates/README.md b/it/dynamic_data_in_templates/README.md index b3479a7996f..91f554eb781 100644 --- a/it/dynamic_data_in_templates/README.md +++ b/it/dynamic_data_in_templates/README.md @@ -1,43 +1,50 @@ # I dati dinamici nei templates -Abbiamo diversi pezzi: il modello `Post` è definito in `models.py`, abbiamo `post_list` nel file `views.py` ed abbiamo aggiunto il template. Ma come faremo a far comparire i nostri post nel nostro template HTML? Perché questo è quello che vogliamo: prendere qualche contenuto (modelli salvati nel database) e farlo vedere in modo carino nel nostro template, giusto? +Abbiamo diversi pezzi: il modello `Post` è definito in `models.py`, abbiamo `post_list` nel file `views.py` ed abbiamo aggiunto il template. Ma come faremo a far comparire i nostri post nel nostro template HTML? Perché è quello che vogliamo: prendere qualche contenuto (modelli salvati nel database) e farlo vedere in modo carino nel nostro template, giusto? -Questo è esattamente quello che le *views* dovrebbero fare: collegare i modelli ed i template. Nella nostra `post_list` *view* avremo bisogno di prendere i modelli che vogliamo far vedere e passarli nel template. Quindi praticamente nella *view* decidiamo cosa (modello) renderemo visibile nel template. +Questo è esattamente quello che le *views* dovrebbero fare: collegare i modelli ed i template. Nella nostra `post_list` *view* avremo bisogno di prendere i modelli che vogliamo far vedere e passarli nel template. Nella *view* decidiamo cosa (modello) renderemo visibile nel template. OK, quindi come facciamo a farlo? Dobbiamo aprire il nostro `blog/views.py`. Per ora `post_list` *view* si vede così: +{% filename %}blog/views.py{% endfilename %} + ```python from django.shortcuts import render def post_list(request): - return render(request, 'blog/post_list.html', {}) +    return render(request, 'blog/post_list.html', {}) ``` Ricordi quando abbiamo parlato di includere codice scritto in diversi file? Ora è il momento di includere il model che abbiamo scritto in `models.py`. Aggiungeremo questa riga `from .models import Post` così: +{% filename %}blog/views.py{% endfilename %} + ```python from django.shortcuts import render from .models import Post ``` -Il punto dopo il `from` significa *directory attuale* oppure *applicazione attuale*. Dal momento che `views.py` e `models.py` sono nella stessa directory possiamo semplicemente utilizzare `.` ed il nome del file (senza `.py`). Allora importiamo il nome del modello (`Post`). +Il punto prima di `models` significa *directory attuale* oppure *applicazione attuale*. Sia `views.py` che `models.py` sono nella stessa cartella. Questo significa che possiamo usare `.` seguito dal nome del file (senza `.py`). Allora importiamo il nome del modello (`Post`). Cos'altro bisogna fare? Per poter prendere i post del blog dal modello`Post` ci serve una cosa chiamata `QuerySet`. ## QuerySet -Dovresti già sapere come funziona QuerySet. Ne abbiamo parlato nel capitolo [Django ORM (QuerySets) ][1]. +Dovresti già sapere come funziona QuerySet. Ne abbiamo parlato nel capitolo [Django ORM (QuerySets) ](../django_orm/README.md). - [1]: ../django_orm/README.md +Quindi ora vogliamo i post del blog che sono pubblicati ordinati per `published_date`, giusto? Lo abbiamo già fatto nel capitolo sulle QuerySet! -Quindi ora ci interessa una lista di post del blog che sono pubblicati e organizzati da `published_date`, giusto? Lo abbiamo già fatto nel capitolo sulle QuerySet! +{% 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') +``` +Quindi, apriamo il file `blog/views.py` nell'editor del codice, e aggiungiamo questo codice alla funzione `def post_list(request)` -- ma non dimenticare di aggiungere prima `da django.utils import timezone`: -Adesso mettiamo questo pezzo di codice nel file `blog/views.py` aggiungendolo alla funzione `def post_list(request)`: +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -49,15 +56,18 @@ def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -Nota che abbiamo creato una *variabile* per il nostro QuerySet: `posts`. Vedila come il nome del nostro QuerySet. Da qui in avanti possiamo riferirci ad esso con questo nome. +Per mostrare il nostro QuerySet sull'elenco dei post del nostro blog, ci sono rimaste due cose da fare: + +1. Passare il QuerySet dei `post` al contesto del modello, modificando la chiamata della funzione di `render`: Lo faremo adesso. +2. Modifica il modello per visualizzare il QuerySet dei `post`. Copriremo ciò in un capitolo successivo. -Il codice utilizza anche la funzione `timezone.now()`, quindi dobbiamo aggiungere un import per `timezone`. +Nota che abbiamo creato una *variabile* per il nostro QuerySet: `posts`. Vedila come il nome del nostro QuerySet. Da qui in avanti possiamo riferirci ad esso con questo nome. -L'ultima cosa che manca è passare la QuerySet `posts` nel template (ci occuperemo di come renderlo visibile nel prossimo capitolo). +Nella funzione `render` abbiamo già un parametro con `request` (quindi tutto quello che riceviamo dal nostro utente via internet) e un file template `'blog/post_list.html'`). Nell'ultimo parametro, che è simile a questo: `{}` possiamo aggiungere cose che il template possa utilizzare. Dobbiamo dargli un nome (ci atterremo a `'posts'` per il momento). :) Si vede così: `{'posts': posts}`. Ti preghiamo di notare che la parte prima di `:` è una stringa; devi metterla tra virgolette. -Nella funzione `render` abbiamo già un parametro con `request` (quindi tutto quello che riceviamo dal nostro utente via internet) e un file template `'blog/post_list.html'`. Nell'ultimo parametro, che è simile a questo: `{}` possiamo aggiungere cose che il template possa utilizzare. Dobbiamo dargli un nome (ci atterremo a `'posts'` per il momento :)). Si vede così: `{'posts': posts}`. Ti preghiamo di notare che la parte prima di `:` è una stringa; devi metterla tra virgolette `''`. +Finalmente il nostro file `blog/views.py` dovrebbe essere così: -Il nostro file `blog/views.py` dovrà risultare così: +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -65,10 +75,10 @@ from django.utils import timezone from .models import Post def post_list(request): - posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') - return render(request, 'blog/post_list.html', {'posts': posts}) +    posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +    return render(request, 'blog/post_list.html', {'posts': posts}) ``` -È tutto! Ora di tornare al nostro template e rendere visibile questo QuerySet! +E' tutto! Ora di tornare al nostro template e rendere visibile questo QuerySet! -Se vuoi leggere di più sui QuerySets in Django dovresti dare un'occhiata qui: https://docs.djangoproject.com/en/1.8/ref/models/querysets/ \ No newline at end of file +Vuoi leggere un poco di più su QuerySets in Django? Dovresti guardare qui: https://docs.djangoproject.com/en/2.2/ref/models/querysets/ \ No newline at end of file diff --git a/it/extend_your_application/README.md b/it/extend_your_application/README.md index be73b5469ec..fd4e75ba793 100644 --- a/it/extend_your_application/README.md +++ b/it/extend_your_application/README.md @@ -1,6 +1,8 @@ +{% set warning_icon = '' %} + # Estendi la tua applicazione -Abbiamo completato i passi necessari per la creazione del nostro sito: sappiamo come scrivere un modello, una url, una view ed un template. Sappiamo anche come far diventare carino il nostro sito. +Abbiamo già completato tutti i passaggi differenti necessari per la creazione del nostro sito web: sappiamo come scrivere un modello, un URL, una vista ed un modello. Sappiamo anche come rendere carino il nostro sito web. Ora di far pratica! @@ -10,40 +12,41 @@ Abbiamo già un modello dei `Post`, quindi non abbiamo bisogno di aggiungere nie ## Creare un link di template verso la pagina di dettaglio di un post -Cominceremo aggiungendo un link all'interno del file `blog/templates/blog/post_list.html`. Per ora dovrebbe avere questo aspetto: +Cominceremo aggiungendo un link all'interno del file `blog/templates/blog/post_list.html`. Per ora dovrebbe avere questo aspetto: Aprilo nell'editor di codice, e finora dovrebbe sembrare così: {% filename %}blog/template/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 content %} +{% endblock %} ``` +{% raw %}Vogliamo creare un link che dal titolo di un post facente parte dell'elenco di articoli porti alla pagina di dettaglio. Cambiamo `

{{ post.title }}

` così che linki alla pagina di dettaglio del post:{% endraw %} -{% raw %}Vogliamo creare un link che dal titolo di un post facente parte dell'elenco di articoli porti alla pagina di dettaglio. Cambiamo `

{{ post.title }}

` così che linki alla pagina di dettaglio del post:{% endraw %} +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} ```html -

{{ post.title }}

+

{{ post.title }}

``` {% raw %}È arrivata l'ora di spiegare il misterioso `{% url 'post_detail' pk=post.pk %}`. Come avrai capito, il simbolo `{% %}` significa che stiamo usando i tag del template di Django. Questa volta ne useremo uno che creerà una URL per noi!{% endraw %} -`blog.views.post_detail` è un percorso per arrivare alla `post_detail` *view* che vogliamo creare. Nota bene: `blog` è il nome della nostra applicazione (la directory `blog`), `views` viene dal nome del file `views.py` e l'ultima cosa - `post_detail` - è il nome della *view*. +La parte `post_detail` significa che Django si aspetta un URL in `blog/urls.py` con nome=post_detail -Adesso quando andremo all'indirizzo: http://127.0.0.1:8000/ avremo un errore (come sapevamo, dal momento che non abbiamo una URL oppure una *view* per `post_detail`). Avrà questo aspetto: +E come si può parlare di `pk=post.pk`? `pk` è breve per il tasto principale, che è un identificatore unico per ogni registro in un database. Ogni modello di Django ha un campo che serve come tasto principale, e qualsiasi altro nome ha, è anche referenziabile come "pk". Poiché non abbiamo specificato un tasto principale nel nostro modello `Post`, Django ne crea uno per noi (di default, un campo nominato "id" che mantiene un numero che aumenta per ogni registro, es. 1, 2, 3) e lo aggiunge come un campo per ognuno dei nostri post. Accediamo al tasto principale scrivendo `post.pk`, allo stesso modo in cui accediamo agli altri campi (`titolo`, `autore`, etc.) nel nostro oggetto del `Post`! -![Errore: nessuna corrispondenza inversa][1] +Adesso quando andremo all'indirizzo: http://127.0.0.1:8000/ avremo un errore (come sapevamo, dal momento che non abbiamo una URL oppure una *view* per `post_detail`). Avrà questo aspetto: - [1]: images/no_reverse_match2.png +![Errore: nessuna corrispondenza inversa](images/no_reverse_match2.png) ## Crea una URL per i dettagli di un post @@ -51,81 +54,85 @@ Creiamo una URL in `urls.py` per il nostro `post_detail` *view*! Vogliamo che il nostro primo post venga visualizzato a questo **URL **: http://127.0.0.1:8000/post/1/ -Facciamo sì che l'URL nel file `blog/urls.py` punti Django ad una *view* chiamata `post_detail`, che mostrerà un intero post. Aggiungi la riga `url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'),` al file `blog/urls.py`. Il file dovrebbe assomigliare a questo: +Facciamo sì che l'URL nel file `blog/urls.py` punti Django ad una *view* chiamata `post_detail`, che mostrerà un intero post. Apri il file `blog/urls.py` nell'editor del codice e aggiungi la riga `path('post//', view.post_detail, name='post_detail'),` così che il file assomiglia a questo: + +{% 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'), ] ``` -Questa parte `^post/(?P[0-9]+)/$` sembra spaventosa, ma non preoccuparti - te la spiegheremo: - inizia ancora con `^` -- "l'inizio" - `post/` semplicemente significa che dopo l'inizio, l'URL dovrebbe contenere la parola **post** e **/**. Fin qui tutto bene. - `(?P[0-9]+)` - questa parte è più complicata. Significa che Django prenderà tutto quello che hai messo qui e lo trasferirà ad una view come variabile denominata `pk`. `[0-9]` ci dice anche che la variabile può essere solo un numero, non una lettera (quindi tutto tra 0 e 9). `+` significa che ci devono essere una o più cifre. Quindi qualcosa di simile a `http://127.0.0.1:8000/post//` non è valido, ma `http://127.0.0.1:8000/post/1234567890/` è perfetto! - `/` Quindi ci serve **/** di nuovo - `$` - "fine"! - -Ciò significa che se digiti `http://127.0.0.1:8000/post/5/` nel tuo browser, Django capirà che stai cercando una *view* chiamata `post_detail` e trasferirà l'informazione che `pk` è uguale a `5` a quella *view*. +Questa parte `post//` specifica un modello URL – lo spiegheremo per te: -`pk` è un diminutivo di `primary key`. Questo nome viene frequentemente utilizzato nei progetti Django. Ma puoi chiamare la tua variabile come vuoi (ricorda: minuscole e `_` invece degli spazi!). Per esempio invece di `(?P[0-9]+)` potremmo avere la variabile `post_id`quindi questo pezzettino dovrebbe assomigliare a: `(?P[0-9]+)`. +- `post/` significa che l'URL deve iniziare con la parola **post** seguita da **/**. Fin qui tutto bene. +- `` – questa parte è più difficile. Significa che Django si aspetta un valore intero e lo trasferirà in una vista come variabile chiamata `pk`. +- `/` – abbiamo bisogno di un **/** di nuovo prima di completare l'URL. -Ok, abbiamo aggiunto un nuovo schema di URL a `blog/urls.py`! Aggiorniamo la pagina: http://127.0.0.1:8000/ Boom! Ancora un altro errore! Come previsto! +Ciò significa che se digiti `http://127.0.0.1:8000/post/5/` nel tuo browser, Django capirà che stai cercando una *view* chiamata `post_detail` e trasferirà l'informazione che `pk` è uguale a `5` a quella *view*. -![Errore attributo][2] +Ok, abbiamo aggiunto un nuovo pattern URL in `blog/urls.py`! Prova ad aggiornare la pagina: http://127.0.0.1:8000/ Boom! Il server ha smesso di funzionare di nuovo. Diamo un occhiata alla console - come previsto, c'è una altro errore! - [2]: images/attribute_error2.png +![Errore Attributo](images/attribute_error2.png) Ti ricordi di quale è il prossimo passo? Ma certo: aggiungere una view! ## Aggiungi una view del post -Questa volta alla nostra *view* viene data un altro parametro `pk`. La nostra *view* deve prenderlo, vero? Quindi definiremo la nostra funzione come `def post_detail(request, pk):`. Dobbiamo utilizzare esattamente lo stesso nome che abbiamo specificato in urls (`pk`). Omettere questa variabile è sbagliato e genererà un errore! +Questa volta alla nostra *view* viene data un altro parametro `pk`. La nostra *view* deve prenderlo, vero? Quindi definiremo la nostra funzione come `def post_detail(request, pk):`. Nota che questo parametro deve avere lo stesso esatto nome di quello specificato in `urls` (`pk`). Nota anche che omettere questa variabile è scorretto e risulterà in un errore! -Ora, noi vogliamo ottenere un unico post. Per farlo possiamo utilizzare le queryset così: +Ora, noi vogliamo ottenere un' unico post. Per farlo possiamo utilizzare le queryset così: - Post.objects.get(pk=pk) +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} +```python +Post.objects.get(pk=pk) +``` Ma questo codice presenta un problema. Se non c'è `Post` con `primary key` (`pk`) otterremo un errore bruttissimo! -![Errore: non esiste][3] - - [3]: images/does_not_exist2.png - -Noi non lo vogliamo! Ma, senza dubbio, Django ha qualcosa che si occuperà del problema per noi: `get_object_or_404`. Nel caso in cui non ci sia `Post` con la data `pk` mostrerà una pagina molto più carina (chiamata `Page Not Found 404`). +![Errore: non esiste](images/does_not_exist2.png) -![Pagina non trovata][4] +Noi non lo vogliamo! Ma, senza dubbio, Django ha qualcosa che si occuperà del problema per noi: `get_object_or_404`. Nel caso in cui non ci sia `Post` con la data `pk` mostrerà una pagina molto più carina (chiamata `Page Not Found 404`. - [4]: images/404_2.png +![Pagina non trovata](images/404_2.png) La buona notizia è che in realtà puoi creare la tua pagina `Page not found` modificarla come vuoi e darle un bell'aspetto. Ma non è importantissimo in questo momento, quindi salteremo questa parte. Ok, è arrivata l'ora di aggiungere una *view* al nostro file `views.py`! -Dovremo aprire `blog/views.py` ed aggiungere il seguente codice: +In `blog/urls.py` abbiamo creato una regola URL chiamata `post_detail` che si riferisce a una vista chiamata `views.post_detail`. Ciò significa che Django si aspetta una funzione di visualizzazione chiamata `post_detail` all'interno di `blog/views.py`. - from django.shortcuts import render, get_object_or_404 +Apri il file `blog/views.py` e aggiungi quanto segue con il resto delle importazioni `from`: - -Vicino ad altre righe `from` ed alla fine del file aggiungeremo la nostra *view*: +{% filename %}blog/views.py{% endfilename %} ```python - def post_detail(request, pk): - post = get_object_or_404(Post, pk=pk) - return render(request, 'blog/post_detail.html', {'post': post}) +from django.shortcuts import render, get_object_or_404 ``` -Si, è giunta l'ora di aggiornare la pagina: http://127.0.0.1:8000/ +E alla fine del file aggiungeremo la nostra *vista*: -![Visualizzazione elenco post][5] +{% filename %}blog/views.py{% endfilename %} - [5]: images/post_list2.png +```python +def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) +``` -Ha funzionato! Ma cosa succede se clicchi su un link nel titolo del post? +Sì. È ora di aggiornare la pagina: http://127.0.0.1:8000/ + +![Visualizzazione elenco post](images/post_list2.png) -![Errore: il template non esiste][6] +Ha funzionato! Ma cosa succede se clicchi su un link nel titolo del post? - [6]: images/template_does_not_exist2.png +![Errore: il template non esiste](images/template_does_not_exist2.png) Oh no! Un altro errore! Ma sappiamo già come occuparcene, giusto? Dobbiamo aggiungere un template! @@ -133,61 +140,75 @@ Oh no! Un altro errore! Ma sappiamo già come occuparcene, giusto? Dobbiamo aggi Creeremo un file in `blog/templates/blog` chiamato `post_detail.html`. -Il risultato somiglierà a questo: +Inserisci il codice seguente: + +{% 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 %} ``` Stiamo estendendo ancora una volta il template di base. `base.html`. Nel blocco `content` vogliamo mostrare una published_date del post (se esiste), un titolo ed il testo. Ma dovremmo discutere di alcune cose importanti, vero? -{% raw %}`{% if ... %} ... {% endif %}` è un tag di template che possiamo utilizzare quando vogliamo controllare qualcosa (ricordi `if ... else ..` dal capitolo **Introduzione a Python**?). In questo caso vogliamo controllare che la `published_date` di un post non sia vuota. {% endraw %} +{% raw %}`{% if ... %}... {% endif %}` è un tag di template che possiamo utilizzare quando vogliamo controllare qualcosa (ricordi if. (Ricorda `se... altro ...` da **Introduzione al capitolo Python** ?) In questo scenario vogliamo controllare se il post `published_date` non è vuoto.{% endraw %} -Ok, possiamo aggiornare la nostra pagina e vedere se `Page not found` non c'è più. +Ok, possiamo aggiornare la nostra pagina e vedere se `TemplateDoesNotExist` non c'è più. -![Pagina di dettaglio del post][7] - - [7]: images/post_detail2.png +![Pagina di dettaglio del post](images/post_detail2.png) Si! Ha funzionato! -## Ultima cosa: ora di fare il deploy! +# Tempo di Deploy! + +Sarebbe bello vedere se il tuo sito web funziona ancora su PythonAnywhere, giusto? Proviamo a fare nuovamente il deploy. -Sarebbe bello vedere se il tuo sito Web sarà ancora funzionante in PythonAnywhere, vero? Proviamo a fare un alrto deploy. +{% filename %}command-line{% endfilename %} $ git status - $ git add --all . + $ git add . $ git status $ git commit -m "Added view and template for detailed blog post as well as CSS for the site." $ git push + +Poi, in una [console PythonAnywhere Bash](https://www.pythonanywhere.com/consoles/): -* Poi, in una [console PythonAnywhere Bash][8]: - - [8]: https://www.pythonanywhere.com/consoles/ +{% filename %}PythonAnywhere command-line{% endfilename %} - $ cd my-first-blog - $ source myvenv/bin/activate - (myvenv)$ git pull - [...] - (myvenv)$ python manage.py collectstatic + $ cd ~/.pythonanywhere.com + $ git pull [...] + + +(Ricordati di sostituire `` con il sottodominio di PythonAnywhere, senza le parentesi angolo.) + +## Aggiornamento file statici sul server + +Server come PythonAnywhere amano trattare "file statici" (come file CSS) in modo diverso dai file Python, perché possono ottimizzare per essere caricati più velocemente. Di conseguenza, ogni volta che modifichiamo i nostri file CSS, dobbiamo eseguire un comando extra sul server per dirlo per aggiornarli. Il comando è chiamato `colleziona`. +Inizia attivando il tuo virtualenv se non è ancora attivo da prima (PythonAnywhere utilizza un comando chiamato `workon` per farlo, è proprio come il comando `sorgente myenv/bin/activate` che usi sul tuo computer): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ workon .pythonanywhere.com + (ola.pythonanywhere.com)$ python manage.py collectstatic + [...] + -* Infine, vai su il [Web tab][9] e premi **Reload**. +Il comando `manage.py collectstatic` è un po' come `manage.py migrate`. Facciamo alcune modifiche al nostro codice, e poi diciamo a Django a *applica* queste modifiche, sia alla collezione di file statici del server, sia al database. - [9]: https://www.pythonanywhere.com/web_app_setup/ +In ogni caso, siamo pronti a salire sulla pagina [ "Web"](https://www.pythonanywhere.com/web_app_setup/) (dal pulsante menu in alto a destra della console) e colpire **Ricarica**, e poi guarda la pagina https://subdomain.pythonanywhere.com per vedere il risultato. -Fatto! Congratulazioni :) +Ecco fatto! Congratulazioni! \ No newline at end of file diff --git a/it/extend_your_application/images/404_2.png b/it/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/it/extend_your_application/images/404_2.png and b/it/extend_your_application/images/404_2.png differ diff --git a/it/extend_your_application/images/attribute_error2.png b/it/extend_your_application/images/attribute_error2.png index 6edcd9933c3..4b8262476d9 100644 Binary files a/it/extend_your_application/images/attribute_error2.png and b/it/extend_your_application/images/attribute_error2.png differ diff --git a/it/extend_your_application/images/does_not_exist2.png b/it/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/it/extend_your_application/images/does_not_exist2.png and b/it/extend_your_application/images/does_not_exist2.png differ diff --git a/it/extend_your_application/images/no_reverse_match2.png b/it/extend_your_application/images/no_reverse_match2.png index 306926206f8..aba1c9c8980 100644 Binary files a/it/extend_your_application/images/no_reverse_match2.png and b/it/extend_your_application/images/no_reverse_match2.png differ diff --git a/it/extend_your_application/images/post_detail2.png b/it/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/it/extend_your_application/images/post_detail2.png and b/it/extend_your_application/images/post_detail2.png differ diff --git a/it/extend_your_application/images/post_list2.png b/it/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/it/extend_your_application/images/post_list2.png and b/it/extend_your_application/images/post_list2.png differ diff --git a/it/extend_your_application/images/template_does_not_exist2.png b/it/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/it/extend_your_application/images/template_does_not_exist2.png and b/it/extend_your_application/images/template_does_not_exist2.png differ diff --git a/it/how_the_internet_works/README.md b/it/how_the_internet_works/README.md index 13f02ddb34d..1669588aca9 100644 --- a/it/how_the_internet_works/README.md +++ b/it/how_the_internet_works/README.md @@ -1,53 +1,47 @@ # Come funziona Internet -> Questo capitolo è ispirato ad un discorso di Jessica McKellar "How the Internet Works" (http://web.mit.edu/jesstess/www/). +> Per le lettrici a casa: questo capitolo viene trattato nel video [Come funziona Internet](https://www.youtube.com/watch?v=oM9yAA09wdc). +> +> Questo capitolo trae ispirazione dal discorso di Jessica McKellar "Come funziona Internet" (http://web.mit.edu/jesstess/www/). -Scommettiamo che usi Internet tutti i giorni. Ma sai davvero che cosa succede quando digiti un indirizzo come https://djangogirls.org nel tuo browser e premi `invio`? +Scommettiamo che usi Internet tutti i giorni. Ma sai davvero cosa succede quando digiti un indirizzo come https://djangogirls.org nel tuo browser e premi `invio`? -La prima cosa da capire è che un sito è solo un gruppo di file salvati su un hard disk. Proprio come i tuoi film, la tua musica e le tue immagini. Tuttavia, c'è una caratteristica tipica dei siti web: includono un codice chiamato HTML. +La prima cosa da capire è che un sito è è composto da un gruppo di file salvati su un hard disk. Tuttavia, c'è una caratteristica tipica dei siti web: includono un codice chiamato HTML. -Se non hai familiarità con la programmazione, può essere difficile da capire l'HTML all'inizio, ma i tuoi web browser (come Chrome, Safari, Firefox, ecc) lo adorano. I browser sono progettati per capire questo codice, seguire le sue istruzioni e presentare questi file che costituiscono il tuo sito web esattamente nel modo desiderato. +Se non hai familiarità con la programmazione, può essere difficile da cogliere HTML all'inizio, ma i tuoi web browser (come Chrome, Safari, Firefox, ecc) lo adorano. I browser sono progettati per capire questo codice, seguire le sue istruzioni e presentare questi file che costituiscono il tuo sito web esattamente nel modo desiderato. -Come per tutti i file, dobbiamo archiviare i file HTML da qualche parte su un hard disk. Per l'Internet, utilizziamo computer speciali e potenti chiamati *servers*. Non hanno uno schermo, un mouse o una tastiera, perché il loro unico proposito è quello di archiviare i dati e fornirli. È per quello che vengono chiamati *servers* -- perché essi *servono* i tuoi dati. +Come per tutti i file, dobbiamo archiviare i file HTML da qualche parte su un hard disk. Per l'Internet, utilizziamo computer speciali e potenti chiamati *servers*. Non hanno uno schermo, un mouse o una tastiera, perché il loro unico proposito è quello di archiviare i dati e fornirli. Per questo vengono chiamati *server* -- perché *servono* i tuoi dati. -OK, ma tu vuoi sapere com'è internet, vero? +Ok, ma tu vuoi sapere com'è Internet, vero? -Abbiamo creato un'immagine! Ecco com'è: +Abbiamo creato un'immagine! Ecco: -![Figura 1.1][1] +![Figura 1.1](images/internet_1.png) - [1]: images/internet_1.png +Sembra complicato, vero? Infatti è una rete di macchine collegate (i *server* di cui parlavamo prima). Centinaia di migliaia di macchine! Molti, molti chilometri di cavi in tutto il mondo! Puoi visitare un sito di Submarine Cable Map (http://submarinecablemap.com) per vedere quanto è complicata la rete. Ecco uno screenshot dal sito web: -Sembra caotico, vero? Infatti è una rete di macchine collegate (i *servers* che abbiamo menzionato prima). Centinaia di migliaia di macchine! Molti, molti chilometri di cavi in tutto il mondo! Puoi visitare un sito di Submarine Cable Map (http://submarinecablemap.com) per vedere quanto è complicata la rete. Ecco uno screenshot dal sito web: +![Figura 1.2](images/internet_3.png) -![Figura 1.2][2] - - [2]: images/internet_3.png - -È affascinante, non è vero? Ma ovviamente, non è possibile avere un cavo fra ogni macchina collegata ad Internet. Quindi, per raggiungere una macchina (per esempio quella in cui è salvato https://djangogirls.org) dobbiamo far passare una richiesta attraverso a molte, molte macchine diverse. +E' affascinante, non è vero? Ma ovviamente, non è possibile avere un cavo fra ogni macchina collegata ad Internet. Quindi, per raggiungere una macchina (per esempio quella in cui è salvato https://djangogirls.org) dobbiamo far passare una richiesta attraverso a molte, molte macchine diverse. Assomiglia a questo: -![Figura 1.3][3] - - [3]: images/internet_2.png +![Figura 1.3](images/internet_2.png) Immagina che quando digiti https://djangogirls.org invii una lettera che dice: "Caro Django Girls, voglio vedere il sito djangogirls.org. inviamelo, per favore!" La tua lettera arriva nell'ufficio postale più vicino a te. Dopo di che va in un altro ufficio postale, che è un po' più vicino al tuo destinatario, poi in un altro ed in un altro ancora finché viene consegnato a destinazione. L'unica cosa è che se invii molte lettere (*pacchi di dati*) allo stesso posto, potrebbero attraversare uffici postali totalmente diversi (*routers*). Questo dipende da come vengono distribuiti presso ogni ufficio. -![Figura 1.4][4] - - [4]: images/internet_4.png +![Figura 1.4](images/internet_4.png) -Si, è esattamente così. Tu invii messaggi e ti aspetti una risposta. Certo, invece di carta e penna usi i bytes di dati, ma l'idea è la stessa! +Funziona così - invii un messaggio e aspetti una risposta. Solo che al posto di carta e penna usi byte di dati, ma il concetto è lo stesso! -Al posto di indirizzi fisici, ovvero del nome della via, della città, del Cap, e del nome del Paese, usiamo indirizzi IP. Il tuo computer prima chiede il DNS (Domain Name System) per tradurre djangogirls.org in un indirizzo IP. Funziona un po' come i vecchi elenchi telefonici, dove cercando il nome della persona che volevi contattare potevi trovare il numero telefonico e l'indirizzo. +Al posto di indirizzi fisici, ovvero del nome della via, della città, del Cap, e del nome del Paese, usiamo indirizzi IP. Il tuo computer prima chiede il DNS (Domain Name System) per tradurre djangogirls.org in un indirizzo IP. Funziona un po' come i vecchi elenchi telefonici, dove puoi cercare il nome della persona che vuoi contattare e trovare il numero telefonico e l'indirizzo. Quando invii una lettera, deve avere determinate caratteristiche per essere consegnata correttamente: un indirizzo, un timbro, ecc. Inoltre utilizzi un linguaggio che il destinatario è in grado di capire, vero? Lo stesso vale per i *pacchi di dati* che invii per vedere un sito Web. Usiamo un protocollo chiamato HTTP (Hypertext Transfer Protocol). Quindi, praticamente, quando hai un sito, devi avere un *server* (macchina) dove archiviarlo. Quando il *server* riceve una *richiesta* (in una lettera), restituisce il tuo sito (in un'altra lettera). -Dal momento che questo è il tutorial di Django, ti chiederai cosa fa Django. Quando invii una risposta, non vuoi inviare la stessa cosa a tutti. È molto meglio se le tue lettere son personalizzate, soprattutto per la persona che ti ha appena scritto, giusto? Django ti aiuta con la creazione di queste interessanti lettere personalizzate :). +Dal momento che questo è il tutorial di Django, ti starai chiedendo che cosa fa Django. Quando invii una risposta, non vuoi inviare la stessa cosa a tutti. E' molto meglio se le tue lettere son personalizzate, soprattutto per la persona che ti ha appena scritto, giusto? Django ti aiuta con la creazione di queste interessanti lettere personalizzate. :) Basta parlare, è arrivata l'ora di creare! \ No newline at end of file diff --git a/it/how_the_internet_works/images/internet_1.png b/it/how_the_internet_works/images/internet_1.png index 9c5bcf0b003..e289eac2b23 100644 Binary files a/it/how_the_internet_works/images/internet_1.png and b/it/how_the_internet_works/images/internet_1.png differ diff --git a/it/how_the_internet_works/images/internet_2.png b/it/how_the_internet_works/images/internet_2.png index dd5861f376f..e8cf8b77999 100644 Binary files a/it/how_the_internet_works/images/internet_2.png and b/it/how_the_internet_works/images/internet_2.png differ diff --git a/it/how_the_internet_works/images/internet_3.png b/it/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/it/how_the_internet_works/images/internet_3.png and b/it/how_the_internet_works/images/internet_3.png differ diff --git a/it/how_the_internet_works/images/internet_4.png b/it/how_the_internet_works/images/internet_4.png index 2661cec1b61..d4748ac48ef 100644 Binary files a/it/how_the_internet_works/images/internet_4.png and b/it/how_the_internet_works/images/internet_4.png differ diff --git a/it/html/README.md b/it/html/README.md index cd7287f49d8..8a413a18f81 100644 --- a/it/html/README.md +++ b/it/html/README.md @@ -21,55 +21,60 @@ I template vengono salvati in una cartella `blog/templates/blog`. Quindi prima c blog └───templates └───blog + - -(Ti chiederai perché abbiamo bisogno di due directory chiamate entrambe `blog` - come scoprirai più tardi, si tratta semplicemente di una denominazione convenzionale che serve a rendere la vita più facile.) +(Ti chiederai perché abbiamo bisogno di due directory chiamate entrambe `blog` - come scoprirai più tardi, si tratta semplicemente di una denominazione convenzionale che serve rendere la vita più facile.) E ora crea un file `post_list.html` nella directory `blog/templates/blog` (lascialo in bianco per adesso). Guarda che aspetto ha il tuo sito adesso: http://127.0.0.1:8000/ -> Se continui ad avere un errore `TemplateDoesNotExists`, prova a riavviare il server. Vai nella command line, arresta il server premendo Ctrl+C ( I tasti Control e C insieme) e riavvialo utilizzando il comando `python manage.py runserver`. +> Se hai ancora l'errore `TemplateDoesNotExist`, prova a riavviare il tuo server. Vai nella command line, arresta il server premendo Ctrl+C ( I tasti Control e C insieme) e riavvialo utilizzando il comando `python manage.py runserver`. -![Figura 11.1][1] +![Figura 11.1](images/step1.png) - [1]: images/step1.png +L'errore dovrebbe essere stato corretto! Congratulazioni :) Tuttavia, il tuo sito in realtà non sta pubblicando niente eccetto una pagina vuota, perché anche il tuo template è vuoto. Bisogna sistemarlo. -L'errore non c'è più! Congratulazioni :) Tuttavia, il tuo sito in realtà non sta pubblicando niente eccetto una pagina vuota, perché anche il tuo template è vuoto. Dobbiamo sistemarlo. +Apri il nuovo file nell'editor di codice e aggiungi quanto segue: -Aggiungi quanto segue nel tuo file template: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + +

Hi there!

It works!

+ ``` -Quindi come appare il tuo sito ora? Clicca per scoprirlo: http://127.0.0.1:8000/ - -![Figura 11.2][2] +Quindi come appare il tuo sito ora? clicca per scoprirlo: http://127.0.0.1:8000/ - [2]: images/step3.png +![Figura 11.2](images/step3.png) -Ha funzionato! Ottimo lavoro :) +Ha funzionato! Ottimo lavoro! :) -* Il comando più basico, ``, è sempre l'inizio di ogni pagina web e `` è sempre la fine. Come puoi vedere, l'intero contenuto del sito va tra il tag iniziale `` ed il tag conclusivo `` -* `

` è un tag per gli elementi paragrafo; `

` conclude ogni paragrafo +* La riga `` non è un tag HTML. Dichiara solo il tipo di documento. Qui, informa il browser che il tipo di documento è [HTML5](https://html.spec.whatwg.org/#the-doctype). Questo è sempre l'inizio di qualsiasi file HTML5. +* Il tag più semplice, ``, è sempre l'inizio del contenuto html e `` è sempre la fine. Come puoi vedere, l'intero contenuto del sito va tra il tag iniziale `` ed il tag conclusivo `` +* `

` è un tag per gli elementi paragrafo; `

` conclude ogni paragrafo -## Head & body +## Testa e corpo Ciascuna pagina HTML è a sua volta divisa in due elementi: **head** e **body**. -* **head** è un elemento che contiene informazioni sul documento non visibili sullo schermo. +* **head** è un elemento che contiene informazioni sul documento non visibili sullo schermo. -* **body** è l'elemento che contiene tutto ciò che invece viene visualizzato come parte della pagina web. +* **body** è l'elemento che contiene tutto ciò che invece viene visualizzato come parte della pagina web. Utilizziamo `` per dire al browser come interpretare la configurazione della pagina, e `` per dirgli in realtà cosa c'è nella pagina. Per esempio, puoi mettere un elemento di titolo all'interno di ``, così: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html + Ola's blog @@ -83,9 +88,7 @@ Per esempio, puoi mettere un elemento di titolo all'interno di ``, così: Salva il file e aggiorna la tua pagina. -![Figura 11.3][3] - - [3]: images/step4.png +![Figura 11.3](images/step4.png) Hai notato come il browser ha capito che "Il blog di Ola" è il titolo della tua pagina? Ha interpretato `Il blog di Ola` ed ha messo il testo nella barra del titolo sul tuo browser (sarà anche utilizzato per i segnalibri e così via). @@ -99,53 +102,63 @@ Devi seguire queste regole di tag *di chiusura*, e di elementi *annidati* - se n Ora puoi divertirti un po' e provare a personalizzare il tuo template! Qua ci sono un po' di tag utili per quello: -* `

Un'intestazione

` - per la tua intestazione più importante -* `

Un sottotitolo

` per un titolo di livello inferiore -* `

Un sottotitolo più piccolo

` ... e così via, fino a `
` -* `text` enfatizza il tuo testo -* `text` enfatizza fortemente il tuo testo -* `
` va in un'altra riga (puoi mettere qualsiasi cosa dentro br) -* `link` crea un link -* `
  • primo elemento
  • secondo elemento
` fa una lista, proprio come questa qui! -* `
` definisce una sezione della pagina - -Qui c'è un esempio di un template completo: +* `

A heading

` - per la tua intestazione più importante +* `

A sub-heading

` - per un titolo di livello inferiore +* `

A sub-sub-heading

` ... e così via, fino a `
` +* `

A paragraph of text

` +* `text` enfatizza il tuo testo +* `text` enfatizza fortemente il tuo testo +* `
` va in un'altra riga (puoi mettere qualsiasi cosa dentro br) +* `link` crea un link +* `
  • primo elemento
  • secondo elemento
` fa una lista, proprio come questa qui! +* `
` definisce una sezione della pagina +* `` definisce un insieme di collegamenti di navigazione +* `
` specifica il contenuto autonomo e indipendente +* `
` definisce una sezione in un documento +* `
` specifica un'intestazione per un documento o una sezione +* `
` specifica il contenuto principale di un documento +* `` definisce alcuni contenuti a parte il contenuto in cui è inserito (come una barra laterale) +* `
` definisce un piè di pagina per un documento o sezione +* `` definisce un'ora (o datetime) specifica + +Ecco un esempio di modello completo, copia e incolla in `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.

-
+

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.

-
+ ``` -Abbiamo creato tre sezioni `div` qui. +Abbiamo creato una sezione `intestazione` e due `articolo` sezione qui. -* Il primo elemento `div` contiene il titolo del nostro blog - è un'intestazione ed un link -* Altri tre elementi `div` contengono i nostri post con la loro data di pubblicazione, `h2` con il titolo di un post che è cliccabile e due `p` (paragrafi) di testo, uno per la data e l'altro per i nostri post. +* L'elemento `intestazione` contiene il titolo del nostro blog – è un'intestazione e un link +* I due elementi `articolo` contengono i nostri post sul blog con una data pubblicata in un elemento `ora` , un elemento `h2` con un titolo post cliccabile e un elemento `p` (paragrafo) per il testo del nostro post sul blog. Ci dà questo effetto: -![Figura 11.4][4] - - [4]: images/step6.png +![Figura 11.4](images/step6.png) Yaaay! Ma fino adesso, il nostro template mostra esattamente **la stessa informazione** - mentre prima stavamo dicendo che i template ci permettono di mostrare **diverse** informazioni nello **stesso formato**. @@ -159,51 +172,56 @@ Sarebbe bello vedere tutto questo live su Internet, giusto? Facciamo un altro de Prima di tutto, vediamo quali file sono cambiati dall'ultimo deploy (esegui questi comandi localmente, non su PythonAnywhere): - $ git status +{% filename %}command-line{% endfilename %} + $ git status + Assicurati di essere nella directory `djangogirls` e diciamo a `git` di includere tutte le modifiche in questa directory: - $ git add --all . +{% filename %}command-line{% endfilename %} - -> **Nota** `-A` (diminutivo di "all") significa che `git` riconoscerà anche il fatto che hai cancellato dei file (per impostazione predefinita, esso riconosce soltanto i file nuovi/modificati). Ricorda anche (dal capitolo 3) che il `.` significa la directory attuale. + $ git add . + Prima di caricare tutti i file, proviamo a controllare cosa caricherà `git` (tutti i file che caricherà `git` ora appariranno in verde): - $ git status +{% filename %}command-line{% endfilename %} + $ git status + Ci siamo quasi, ora è il momento di dirgli di salvare questa modifica nella cronologia. Gli daremo un "messaggio di commit" dove descriviamo ciò che abbiamo modificato. Puoi digitare tutto quello che vuoi a questo punto, sarebbe utile scrivere qualcosa di descrittivo in modo da ricordare in futuro cos'hai fatto. - $ git commit -m "Ho cambiato l'HTML per questo sito." +{% filename %}command-line{% endfilename %} + $ git commit -m "Ho cambiato l'HTML per questo sito." + -> **Nota** Assicurati di usare doppie virgolette attorno al messaggio di commit. +> **Nota** Assicurati di usare doppie virgolette prima e dopo il "messaggio di commit". Quando hai finito, caricheremo (push) le nostre modifiche su Github: - git push +{% filename %}command-line{% endfilename %} + $ git push + ### Scarica il tuo nuovo codice su PythonAnywhere, e ricarica la tua web app -* Apri la [pagina Console PythonAnywhere][5] e vai alla tua **Bash console** (o iniziane una nuova). Quindi, esegui: +* Apri la [pagina Console PythonAnywhere](https://www.pythonanywhere.com/consoles/) e vai alla tua **Bash console** (o iniziane una nuova). Quindi, esegui: - [5]: https://www.pythonanywhere.com/consoles/ +{% filename %}PythonAnywhere command-line{% endfilename %} - $ cd ~/my-first-blog - $ source myvenv/bin/activate - (myvenv)$ git pull - [...] - (myvenv)$ python manage.py collectstatic + $ cd ~/.pythonanywhere.com + $ git pull [...] + +Ricordati di sostituire `` con il sottodominio di PythonAnywhere, senza le parentesi angolo. Il tuo nome di sottodominio è normalmente il tuo nome utente PythonAnywhere, ma in alcuni casi potrebbe essere un po' diverso (come se il tuo nome utente contiene lettere capitali). Quindi, se questo comando non funziona, usa il comando `ls` (files list) per trovare il tuo nome di sottodominio/cartella reale e poi `cd` su di esso. -Ed osserva il tuo codice mentre viene scaricato. Se vuoi controllare che sia arrivato, puoi fare un salto alla scheda **Files** e vedere il tuo codice su PythonAnywhere. - -* Infine, fai un salto alla [scheda Web][6] e premi **Reload** sulla tua web app. +Ora guarda il tuo codice scaricato. Se vuoi controllare che sia arrivato, puoi saltare alla pagina **"Files** e visualizzare il tuo codice su PythonAnywhere (puoi raggiungere altre pagine PythonAnywhere dal pulsante menu sulla pagina della console). - [6]: https://www.pythonanywhere.com/web_app_setup/ +* Infine, fai un salto alla [scheda Web](https://www.pythonanywhere.com/web_app_setup/) e premi **Reload** sulla tua web app. -Il tuo aggiornamento dovrebbe essere applicato! Vai avanti ed aggiorna il tuo sito nel brower. Le modifiche dovrebbero essere visibili :) \ No newline at end of file +Il tuo aggiornamento dovrebbe essere applicato! Vai avanti ed aggiorna il tuo sito nel brower. Le modifiche dovrebbero essere visibili. :) \ No newline at end of file diff --git a/it/html/images/step1.png b/it/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/it/html/images/step1.png and b/it/html/images/step1.png differ diff --git a/it/html/images/step3.png b/it/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/it/html/images/step3.png and b/it/html/images/step3.png differ diff --git a/it/html/images/step4.png b/it/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/it/html/images/step4.png and b/it/html/images/step4.png differ diff --git a/it/html/images/step6.png b/it/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/it/html/images/step6.png and b/it/html/images/step6.png differ diff --git a/it/images/application.png b/it/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/it/images/application.png and b/it/images/application.png differ diff --git a/it/installation/README.md b/it/installation/README.md index 06f6a3085f9..20d759417ed 100644 --- a/it/installation/README.md +++ b/it/installation/README.md @@ -1,49 +1,69 @@ -# Se stai facendo il tutorial a casa +# Se stai seguendo il tutorial a casa -Se stai facendo il tutorial a casa e non durante uno degli [eventi Django Girls ](https://djangogirls.org/events/), puoi saltare questo capitolo e andare direttamente a [Come funziona Internet?](../how_the_internet_works/README.md). +Se stai seguendo il tutorial a casa, e non durante uno degli [eventi Django Girls](https://djangogirls.org/events/), puoi saltare completamente questo capitolo e andare direttamente al capitolo [Come funziona Internet](../how_the_internet_works/README.md). -Copriamo questi argomenti nel tutorial completo, e questa è una pagina aggiuntiva contenente tutte le istruzioni di installazione. L'evento Django Girls include una "serata dedicata all'installazione" in cui installiamo tutto, in modo da non preoccuparcene durante il workshop, quindi questo capitolo è utile per chi partecipa ad uno dei nostri workshop. - -Se lo trovi utile puoi seguire anche questo capitolo. Ma se vuoi iniziare a imparare prima di installare le cose sul tuo computer, salta questo capitolo. Ti spiegheremo l'installazione più avanti. +Questo perché nel tutorial spieghiamo come installare i programmi passo passo -- questa è una pagina aggiuntiva che raccoglie tutte le istruzioni di installazione (e che può tornare utile in alcuni workshop). Se vuoi puoi decidere di installare subito il materiale che trovi in questa pagina. Ma se vuoi imparare alcune nozioni prima di installare queste cose sul tuo computer, salta questo capitolo e ti spiegheremo come fare le installazioni più tardi, quando sarà necessario. Buona fortuna! +# Se stai partecipando a un workshop + +Se stai partecipando a uno degli [eventi Django Girls](https://djangogirls.org/events/): + +* Il tuo workshop potrebbe avere un "party di installazione" prima del workshop principale. Se sei in un party di installazione, questa pagina è per te! Segui le istruzioni qui per ottenere tutto quello che serve per il workshop installato, con l'aiuto degli autobus se necessario. Poi al workshop principale, sarai in grado di saltare le istruzioni di installazione che incontrerai nel tutorial principale quando li avrai ricevuti. +* Gli organizzatori del tuo workshop potrebbero aver chiesto di provare a casa per installare tutto sul tuo computer prima dell'inizio del workshop. Se ti è stato chiesto di farlo, questa pagina è per te! Segui le istruzioni qui, il meglio possibile. Poi al workshop principale, quando si arriva a un passo di installazione nel tutorial principale, se non si è riusciti a installare quel pezzo, si può ottenere aiuto dal tuo coach. +* Se il tuo workshop non ha un gruppo di installazione (o non hai potuto partecipare), e se gli organizzatori non ti hanno chiesto di provare a installare tutto prima di arrivare, salta questa pagina e vai direttamente al capitolo [Come funziona Internet](../how_the_internet_works/README.md) . Installerai tutto ciò di cui hai bisogno quando lavori il tutorial. + # Installazione -Nel workshop costruirai un blog, e ci sono alcuni task dedicati all'impostazione che sarebbe bello completare in anticipo, in modo che tu sia pronta a scrivere codice in giornata. +In questo tutorial costruirai un blog. Per farlo, mentre vai nel tutorial, sarai informato su come installare vari software sul tuo computer e impostare alcuni account online come sono necessari. Questa pagina raccoglie tutte le istruzioni di installazione e iscrizione in un unico luogo (che è utile per alcuni formati di workshop). -# Installare Python + {% include "/chromebook_setup/instructions.md" %} -{% include "/python_installation/instructions.md" %} + -# Preparare virtualenv e installare Django +# Breve introduzione alla linea di comando {#command-line} -{% include "/django_installation/instructions.md" %} +Molti dei passaggi qui sotto fanno riferimento alla "console", "terminal", "finestra di comando", o "linea di comando" - tutto questo significa la stessa cosa: una finestra sul tuo computer dove puoi inserire comandi. Quando arriverai al tutorial principale, imparerai di più sulla linea di comando. Per ora, la cosa principale che devi sapere è come aprire una finestra di comando e come sembra: +{% include "/intro_to_command_line/open_instructions.md" %} + +# Installa Python {#python} -# Installare un editor di codice +{% include "/python_installation/instructions.md" %} + +# Installa un editor del codice {#code-editor} {% include "/code_editor/instructions.md" %} -# Installare Git +# Imposta virtualenv e installa Django {#virtualenv} + +{% include "/django_installation/instructions.md" %} + +# Installa Git {#git} {% include "/deploy/install_git.md" %} -# Creare un account GitHub +# Crea un profilo di GitHub {#github-account} -Vai su [GitHub.com](https://www.github.com) e iscriviti per un nuovo account gratuito. +Vai su [GitHub.com](https://www.github.com) e crea un nuovo account gratuito. Assicurati di ricordare la tua password (aggiungila al tuo password manager, se ne usi uno). -# Creare un account PythonAnywhere +# Crea un profilo di PythonAnywhere {#pythonanywhere-account} {% include "/deploy/signup_pythonanywhere.md" %} # Inizia la lettura -Complimenti, ora sei pronta! Se hai un po' di tempo prima del workshop, potrebbe essere utile cominciare a leggere i capitoli iniziali: +Congratulazioni, sei pronta a partire! Se hai del tempo prima del workshop sarebbe magnifico se leggessi qualche capitolo iniziale: + +* [Come funziona Internet](../how_the_internet_works/README.md) + +* [Introduzione alla riga di comando](../intro_to_command_line/README.md) - * [Come funziona Internet](../how_the_internet_works/README.md) +* [Introduzione a Python](../python_introduction/README.md) - * [Introduzione alla riga di comando](../intro_to_command_line/README.md) +* [Che cos'è Django?](../django/README.md) - * [Introduzione a Python](../intro_to_command_line/README.md) +# Divertiti al workshop! - * [Che cos'è Django?](../django/README.md) +Quando inizierà il workshop, potrai andare direttamente a [il tuo primo progetto Django!](../django_start_project/README.md) dato che hai già coperto il materiale dei capitoli precedenti. diff --git a/it/intro_to_command_line/README.md b/it/intro_to_command_line/README.md index fd63b8bfca7..8ad96b96d7c 100644 --- a/it/intro_to_command_line/README.md +++ b/it/intro_to_command_line/README.md @@ -1,70 +1,91 @@ -# Introduzione alla linea di comando +# Introduzione all'interfaccia a riga di comando -Eccitante, vero? Scriverai la tua prima riga di codice in pochi minuti :) +> Messaggio per i lettori: questo capitolo si trova nel video [Your new friend: Command Line](https://www.youtube.com/watch?v=jvZLWhkzX-8). -**Ti presentiamo il tuo primo nuovo amico: la linea di comando!** +Non è grandioso? avete appena scritto la vostra prima linea di codice in pochi minuti! :) + +**Ti presentiamo il tuo primo nuovo amico: la riga di comando!** I prossimi passaggi ti mostreranno come utilizzare quella 'finestra nera' che tutti gli hacker utilizzano. Ti potrà sembrare un po' allarmante all'inizio, ma è solamente un prompt in attesa dei tuoi comandi. -> **Nota** Nota bene: in tutto questo tutorial usiamo sia il termine 'directory' che 'cartella' ma sono la stessa cosa. +> **Nota**: si prega di notare che in questo libro useremo il termine "directory" e "cartella" in maniera intercambiabile, ma sono la medesima cosa. -## Cos'è la command line? +## Cos'è la riga di comando? -La finestra solitamente chiamata **comand-line** o **interfaccia della command-line**, è un'applicazione basata su testo che ti permette di visualizzare, gestire e manipolare i file sul tuo computer. Molto simile a Windows Explorer o al Finder su Mac, ma senza l'interfaccia grafica. Altri nomi per la command line sono: *cmd*, *CLI*, *prompt*, *console* o *terminal*. +La finestra solitamente chiamata **riga di comando** o **interfaccia della riga di comando**, è un'applicazione basata su testo che ti permette di visualizzare, gestire e modificare i file sul tuo computer. È simile a Windows Explorer o Finder su Mac, ma senza interfaccia grafica. Altri nomi della riga di comando sono: *cmd*, *CLI*, *prompt*, *console* o *terminal*. -## Aprire l'interfaccia di command-line +## Aprire l'interfaccia della riga di comando -Per cominciare a sperimentare dobbiamo aprire l'interfaccia della nostra command-line. +Per cominciare a sperimentare, dobbiamo prima aprire la nostra interfaccia della riga di comando. -### Windows +{% include "/intro_to_command_line/open_instructions.md" %} -Vai a menù Start → tutti i programmi → accessori → prompt dei comandi. +## Prompt -### Mac OS X +Dovreste vedere ora una finestra nera o bianca in attesa dei vostri comandi. -Applicazioni → utilità → terminal. + -### Linux +Se state utilizzando un Mac o Linux, vedrete probabilmente un`$` come questo: -Probabilmente è sotto Applicazioni → Accessori → Terminal, ma quello potrebbe dipendere dal tuo sistema. Se non è lì cercalo su Google :) +{% filename %}riga di comando{% endfilename %} -## Prompt + $ + -Ora dovresti essere in grado di vedere una finestra bianca o nera che è in attesa di ricevere un comando. + -Se sei su Mac o Linux, probabilmente vedi `$`, proprio come questo: + - $ - +Su Windows, probebilmente vedrete un`>` come questo: -Su Windows, è un segno `>`, come questo: +{% filename %}riga di comando{% endfilename %} > -Ogni comando sarà preceduto da questo simbolo e da uno spazio, ma tu non hai bisogno di digitarlo. Il computer lo farà per te :) +Dai un'occhiata alla sezione Linux appena sopra -- vedrai qualcosa di più come quando arriverai a PythonAnywhere più tardi nel tutorial. -> Solo una piccola nota: nel tuo caso ci dovrebbe essere qualcosa come `C:\Users\ola>` oppure `Olas-MacBook-Air:~ ola$` prima del segno di prompt. È corretto al 100%. In questo tutorial lo semplificheremo al massimo. + + +Ogni comando sarà prepesso da un `$` o `>` e uno spazio, ma non dovresti digitarlo. Il tuo computer lo farà per te. :) + +> Solo una piccola nota: nel tuo caso ci dovrebbe essere qualcosa come `C:\Users\ola>` oppure `Olas-MacBook-Air:~ ola$` prima del segno di prompt. È corretto al 100%. + +La parte fino al `$` o al `>` inclusi, si chiama *prompt della linea di comando* o semplicemente *prompt*. Ti richiede di inserire qualcosa. + +Nel tutorial quando vorremo che tu scriva un comando, includeremo `$` o `>` e occasionalmente qualcosa in più a sinistra. Puoi ignorare la parte a sinistra e inserire solo il comando dopo il prompt. ## Il tuo primo comando (YAY!) -Cominciamo con qualcosa di veramente semplice. Digita questo comando: +Iniziamo digitando questo comando: + + + +{% filename %}command-line{% endfilename %} $ whoami -oppure + + + + +{% filename %}command-line{% endfilename %} > whoami + + Premi `invio`. Questo è il nostro risultato: - $ whoami - olasitarska +{% filename %}command-line{% endfilename %} + + $ whoami olasitarska -Come puoi vedere, il computer ha appena stampato il tuo nome utente. Bello, eh?:) +Come puoi vedere, il computer ha appena stampato il tuo nome utente. Bello, eh? :) > Prova a digitare ogni comando, non copiare ed incollare. Ti ricorderai di più in questo modo! @@ -74,28 +95,58 @@ Ogni sistema operativo ha un insieme di comandi leggermente diverso per la comma ### Cartella corrente -Sarebbe bello sapere dove siamo adesso, vero? Vediamo. Digita questo commando e premi `invio`: +Sarebbe bello sapere dove ci troviamo ora, giusto?Vediamo. Digita questo comando e premi Invio: - $ pwd - /Users/olasitarska + + +{% filename %}command-line{% endfilename %} + + $ pwd/utenti/olasitarska -Se sei su Windows: +> Nota: 'pwd' sta per 'stampa directory di lavoro'. + + - > cd - C:\Users\olasitarska + + +{% filename %}command-line{% endfilename %} + + > cd C:\Users\olasitarska -Probabilmente vedrai qualcosa di simile sul tuo computer. Quando apri la command-line normalmente inizi sulla tua directory home. +> Nota: 'cd' sta per 'modifica cartella'. Con la shell può usare pwd come su Linux o macOS. -> Nota: 'pwd' sta per 'stampa directory di lavoro'. + + +Probabilmente vedrai qualcosa di simile sul tuo computer. Quando apri la command-line normalmente inizi sulla tua directory home. * * * +### Guida Utente + +Molti comandi che puoi digitare al comando richiesto hanno un aiuto integrato che puoi visualizzare e leggere! Per esempio, per saperne di più sul comando della directory corrente: + + + +macOS e Linux hanno un comando `man` che ti dà aiuto sui comandi. Prova `man pwd` e vedi cosa dice, o mette `man` prima di altri comandi per vedere il loro aiuto. L'output di `man` è normalmente paginato. Usa la barra di spazio per passare alla pagina successiva, e `q` per smettere di guardare l'aiuto. + + + + + +Aggiungere un suffisso `/?` alla maggior parte dei comandi stamparà la pagina di aiuto. Potresti dover scorrere la finestra di comando per vederlo tutto. Prova `cd /?`. + + + ### Elenco di file e cartelle Cosa c'è dentro? Sarebbe bello scoprirlo. Vediamo come: + + +{% filename %}command-line{% endfilename %} + $ ls Applications Desktop @@ -104,46 +155,82 @@ Cosa c'è dentro? Sarebbe bello scoprirlo. Vediamo come: ... -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 +> Nota: In PowerShell è anche possibile utilizzare 'ls' come su Linux e macOS. + * * * ### Cambiare cartella corrente Ora, andiamo nella nostra directory Desktop: + + +{% filename %}command-line{% endfilename %} + $ cd Desktop -Windows: + + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + +Nota che il nome della directory "Desktop" potrebbe essere tradotto nella lingua del tuo account Linux. Se così è, dovrai sostituire `Desktop` con il nome tradotto; per esempio, `Schreibtisch` per il tedesco. + + + + + +{% filename %}command-line{% endfilename %} > cd Desktop + + Controlla ora se ti sei veramente spostato/a: + + +{% filename %}command-line{% endfilename %} + $ pwd /Users/olasitarska/Desktop -Windows: + + + + +{% filename %}command-line{% endfilename %} > cd C:\Users\olasitarska\Desktop + + Ecco fatto! -> Suggerimento PRO: se digiti `cd D` e poi premi `tab` sulla tastiera, la command-line completerà automaticamente il resto del nome per cui puoi navigare più velocemente. Se c'è più di una cartella che comincia con "D", premi `tab` due volte per ottenere la lista con tutte le opzioni. +> Suggerimento PRO:se digiti `cd D` e poi premi `tab` sulla tastiera, la command-line completerà automaticamente il resto del nome per cui puoi navigare più velocemente. Se c'è più di una cartella che comincia con "D", premi `tab` due volte per ottenere la lista con tutte le opzioni. * * * @@ -151,15 +238,25 @@ Ecco fatto! Che ne dici di creare una directory di pratica sul tuo desktop? Puoi farlo in questo modo: + + +{% filename %}command-line{% endfilename %} + $ mkdir practice -Windows: + + + + +{% filename %}command-line{% endfilename %} > mkdir practice -Questo breve comando creerà una cartella con il nome `practice` sul tuo desktop. Puoi controllare se è lì semplicemente guardando sul tuo desktop oppure eseguendo un commando `ls` oppure `dir`! Provalo :) + + +Questo breve comando creerà una cartella con il nome `practice` sul tuo desktop. Puoi controllare se è lì semplicemente guardando sul tuo desktop oppure eseguendo un commando `ls` oppure `dir`! Provalo. :) > Suggerimento PRO: se non vuoi digitare lo stesso comando tutte le volte, prova a premere ` freccia in su ` e `freccia in giù` sulla tua tastiera per scorrere tutti i comandi che hai usato fin ora. @@ -167,25 +264,35 @@ Questo breve comando creerà una cartella con il nome `practice` sul tuo desktop ### Esercizio! -Piccola sfida per te: nella tua directory appena creata `practice` crea una directory chiamata `test`. usa i comandi `cd` e `mkdir`. +Piccola sfida per te: nella tua directory appena creata `practice` crea una directory chiamata `test`. usa i comandi `cd` e `mkdir`.) #### Soluzione: + + +{% filename %}command-line{% endfilename %} + $ cd practice $ mkdir test $ ls test -Windows: + + + + +{% filename %}riga di comando{% endfilename %} > cd practice > mkdir test > dir - 05/08/2014 07:28 PM test + 05/08/2020 07:28 PM test -Congratulazioni! :) + + +Congratulazioni! * * * @@ -195,85 +302,136 @@ Non vogliamo lasciare un pasticcio, per cui rimuoviamo tutto quello che abbiamo Per prima cosa dobbiamo tornare al Desktop: + + +{% filename %}command-line{% endfilename %} + $ cd .. -Windows: + + + + +{% filename %}command-line{% endfilename %} > cd .. + + Usando `..` con il comando `cd` cambierai la tua directory attuale alla directory padre (si tratta della cartella che contiene la tua directory attuale). Controlla dove ti trovi ora: + + +{% filename %}command-line{% endfilename %} + $ pwd /Users/olasitarska/Desktop -Windows: + + + + +{% filename %}command-line{% endfilename %} > cd C:\Users\olasitarska\Desktop + + Adesso è l'ora di cancellare la directory `practice`: > **Attenzione**: cancellare un file usando `del`, `rmdir` o `rm` è irreversibile, *i file cancellati andranno perduti per sempre*! Per cui sii molto prudente nell'utilizzare questi comandi. + + +{% filename %}command-line{% endfilename %} + $ rm -r practice -Windows: + + + + +{% filename %}command-line{% endfilename %} > rmdir /S practice practice, Are you sure ? Y + + Fatto! Per essere sicuri che sia stato effettivamente cancellato, controlliamo: + + +{% filename %}command-line{% endfilename %} + $ ls -Windows: + + + + +{% filename %}command-line{% endfilename %} > dir + + ### Uscire dalla command line -Questo è tutto per ora! puoi tranquillamente chiudere la tua command line. Facciamolo alla maniera degli hacker, va bene?:) +Questo è tutto per ora! puoi tranquillamente chiudere la tua command line. facciamolo alla maniera degli hacker, va bene? :) + + + +{% filename %}command-line{% endfilename %} $ exit -Windows: + + + + +{% filename %}command-line{% endfilename %} > exit -Figo, eh?:) + + +Figo, eh? :) ## Indice Questo è un riepilogo di alcuni comandi utili: -| Comandi(Windows) | Comandi (Mac OS / Linux) | Descrizione | Esempio | -| ---------------- | ------------------------ | --------------------------- | ------------------------------------------------- | -| exit | exit | chiudi la finestra | **exit** | -| cd | cd | cambiare directory | **cd test** | -| dir | ls | elenco directory/file | **dir** | -| copy | cp | copia un file | **copy c:\test\test.txt c:\windows\test.txt** | -| move | mv | spostare un file | **move c:\test\test.txt c:\windows\test.txt** | -| mkdir | mkdir | creare una nuova directory | **mkdir testdirectory** | -| del | rm | eliminare un file/directory | **del c:\test\test.txt** | +| Comandi(Windows) | Comandi (Mac OS / Linux) | Descrizione | Esempio | +| ---------------- | ------------------------- | ------------------------------- | ------------------------------------------------- | +| esci | uscire dalla command line | chiudi la finestra | **uscire dalla command line** | +| cd | cd | cambiare directory | **cd test** | +| cd | pwd | Cambiare cartella corrente | **cd** (Windows) o **pwd** (Mac OS / Linux) | +| dir | ls | elenco directory/file | **dir** | +| copia | cp | copia un file | **copy c:\test\test.txt c:\windows\test.txt** | +| sposta | mv | spostare un file | **move c:\test\test.txt c:\windows\test.txt** | +| mkdir | mkdir | creare una nuova directory | **mkdir testdirectory** | +| rmdir (or del) | rm | Eliminare un file | **del c:\test\test.txt** | +| rmdir /S | rm -r | Seleziona una cartella | **mkdir testdirectory** | +| [CMD]/? | man [CMD] | Ottieni un aiuto per un comando | **cd** (Windows) o **pwd** (Mac OS / Linux) | Questi sono solo alcuni dei comandi che puoi eseguire sulla tua command line, ma non ne userai altri oltre a quelli spiegati oggi. -Se sei curioso/a, [ss64.com][1] contiene una guida completa ai comandi per tutti i sistemi operativi. - - [1]: http://ss64.com +Se sei curioso/a, [ss64.com](http://ss64.com) contiene una guida completa ai comandi per tutti i sistemi operativi. ## Fatto? -Tuffiamoci in Python! +Tuffiamoci in Python! \ No newline at end of file diff --git a/it/intro_to_command_line/open_instructions.md b/it/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..ba8021da133 --- /dev/null +++ b/it/intro_to_command_line/open_instructions.md @@ -0,0 +1,29 @@ + + + +A seconda della versione di Windows utilizzata e della propria tastiera, una delle azioni seguenti dovrebbe aprire una finestra di comando (probabilmente sarà necessario fare più prove, ma non è necessario provare tutti i suggerimenti proposti): + +- Andare al menù Start o alla schermata Start e digitare "Prompt dei comandi" nella barra di ricerca. +- Andare al menù Start-->Sistema Windows-->Prompt dei Comandi. +- Andare a menù Start-->Tutti i Programmi-->Accessori-->Prompt dei Comandi. +- Andare alla schermata Start, spostare il mouse nell'angolo in basso a sinistra dello schermo e cliccare sulla freccia in basso che comparirà (per i dispositivi touch screen, scorrere verso l'alto dal fondo dello schermo). La pagina App dovrebbe aprirsi. Cliccare su Prompt dei Comandi nella sezione Sistema Windows. +- Tenere premuto il tasto Windows e cliccare "X". Scegliere "Prompt dei Comandi" dal menù popup. +- Tenere premuto il tasto Windows e premere "R" per aprire la finestra "Esegui". Digitare "cmd" nella casella di testo e premere OK. + +![Type "cmd" in the "Run" window](../python_installation/images/windows-plus-r.png) + +Più avanti in questo tutorial, dovrete avere due finestre di comando aperte contemporaneamente. In ogni caso, in alcune versioni di Windows, se già si ha una finestra di comando aperta e si cerca di aprirne un'altra con lo stesso metodo, vi mostrerà la finestra di comando già aperta. Provate adesso sul vostro computer e vedete cosa accade! Se si riesce ad aprire solo una finestra di comando, provare un altro dei metodi sopra indicati. Almeno uno permetterà l'apertura di una nuova finestra di comando. + + + + + +Andare ad Launchpad → Altro → Terminal. + + + + + +Probabilmente si troverà in Applicazioni--> Funzionalità--> Terminal, ma dipende dal sistema operativo. Nel caso in cui non si trovasse, provare a fare una ricerca Google. :) + + diff --git a/it/python_installation/README.md b/it/python_installation/README.md index bb131b68683..4fc467a6976 100644 --- a/it/python_installation/README.md +++ b/it/python_installation/README.md @@ -2,12 +2,14 @@ Finalmente siamo qui! -Ma prima, permettici di introdurre brevemente cos'è Python. Python è un linguaggio di programmazione molto popolare che può essere utilizzato per creare siti web, giochi, sofware scientifici, grafici e molto, molto altro. +Ma prima, permettici di introdurre brevemente cos'è Python. Python è un linguaggio di programmazione molto popolare che può essere utilizzato per creare siti web, giochi, sofware scientifici, graffici e molto, molto altro. -Python ha avuto origine alla fine degli anni '80 ed il suo obiettivo principale è quello di essere leggibile dagli esseri umani (non solo dalle macchine!). Per questo motivo sembra molto più semplice di altri linguaggi di programmazione. Questo lo rende facile da imparare, ma non ti preoccupare, Python è anche molto potente! +Python è stato creato alla fine degli anni '80 ed il suo obiettivo principale è quello di essere leggibile dalle persone (e non solo dalle macchine!). Per questo motivo sembra più semplice di altri linguaggi di programmazione, ma non preoccuparti -- Python è anche molto potente! # Installazione di Python -> **Nota** Se hai fatto la procedura di installazione, non c'è bisogno di farlo di nuovo - puoi saltare dritto/a al prossimo capitolo! +> **Nota** Se utilizzi un Chromebook, salta questo capitolo e segui le istruzioni in [Configurazione di Chromebook](../chromebook_setup/README.md). +> +> Se hai terminato il processo di installazione, questo passaggio lo hai già completato e puoi passare direttamente al capitolo successivo! -{% include "/python_installation/instructions.md" %} +{% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/it/python_installation/images/add_python_to_windows_path.png b/it/python_installation/images/add_python_to_windows_path.png index 9510d6f2176..3266efb6177 100644 Binary files a/it/python_installation/images/add_python_to_windows_path.png and b/it/python_installation/images/add_python_to_windows_path.png differ diff --git a/it/python_installation/images/python-installation-options.png b/it/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..a0a6c65d81d Binary files /dev/null and b/it/python_installation/images/python-installation-options.png differ diff --git a/it/python_installation/images/windows-plus-r.png b/it/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/it/python_installation/images/windows-plus-r.png differ diff --git a/it/python_installation/instructions.md b/it/python_installation/instructions.md index c7db277b102..3937c630e90 100644 --- a/it/python_installation/instructions.md +++ b/it/python_installation/instructions.md @@ -1,66 +1,117 @@ -> Questa sezione si basa su un tutorial fatto da Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) +> Per le lettrici a casa: questo capitolo è trattato nel video [Installazione di Python & Editor di codice](https://www.youtube.com/watch?v=pVTaqzKZCdA). +> +> Questa sezione è basata sul tutorial delle Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) -Django è scritto in Python. Abbiamo bisogno di Python per fare qualsiasi cosa in Django. Iniziamo con l'installazione! Vogliamo che sul tuo pc sia installato Python 3.4 quindi se hai una versione precedente, dovrai aggiornarlo. +Django è scritto in Python. Python ci serve per fare qualunque cosa in Django. Iniziamo con l'installazione! Dovresti installare la versione più recente di Python 3, quindi se hai una versione precendente dovrai aggiornarla. Se possiedi già la versione {{ book.py_min_version }} o una versione successiva non servono aggiornamenti. -### Windows +Installa Python normale come segue, anche quando hai Anaconda installato sul tuo computer. -Puoi scaricare Python per Windows dal sito web https://www.python.org/downloads/release/python-343/. Dopo aver scaricato il file ***.msi**, lo dovresti eseguire (cliccaci sopra due volte) e segui le istruzioni. È importante ricordare il percorso (la directory) dove ha installato Python. Più tardi sarà necessario! + -Una cosa a cui fare attenzione: sulla seconda schermata dell'installazione guidata, contrassegnata "Customize", assicurati di scorrere verso il basso e di scegliere l'opzione "Add python.exe to the Path", come illustrato qui: +Prima verifica se il computer sta eseguendo una versione a 32 bit o una versione a 64 bit di Windows, sulla linea "Tipo di sistema" della pagina Info di sistema. Per raggiungere questa pagina, prova uno di questi metodi: -![Non dimenticare di aggiungere Python al Path](../python_installation/images/add_python_to_windows_path.png) +* Premi il tasto Windows e Pausa/Break contemporaneamente +* Apri il tuo Pannello di Controllo dal menu Windows, quindi naviga nel sistema & Sicurezza, quindi sistema +* Premi il pulsante Windows, quindi vai su Impostazioni > Sistema > Informazioni +* Cerca "System Information" nel menu Start di Windows. Per fare ciò, clicca sul pulsante Start o premi il tasto Windows, poi inizia a digitare `System Information`. Inizierà a dare suggerimenti non appena digiterai. Puoi selezionare la voce una volta che compare. -### Linux +Puoi scaricare Python per Windows dal sito web https://www.python.org/downloads/windows/. Clicca sul link "Ultimo Python 3 - Python x.x.x". Se il tuo computer sta eseguendo una versione **64-bit** di Windows, scarica il file **Windows x86-64 di installer eseguibile**. Altrimenti, scarica il file **Windows x86 eseguibile installer**. Dopo aver scaricato il file *.msi, lo dovresti eseguire (cliccaci sopra due volte) e segui le istruzioni. -È molto probabile che tu abbia Python già installato di default. Per controllare se ce l'hai già installato (e quale versione è), apri una console e digita il seguente comando: +Una cosa per cui guardare: durante l'installazione, si noti una finestra contrassegnata "Setup". Assicurati di selezionare la casellina "Add Python {{ book.py_version }} to PATH" o 'Aggiungi Python alle tue variabili ambientali" e clicca su "installa ora", come mostrato qui (potrebbe risultare leggermente diverso se stai installando una versione differente): + +![Non dimenticare di aggiungere Python al Path](../python_installation/images/python-installation-options.png) + +Quando l'installazione è completata, potresti vedere una finestra di dialogo con un link che puoi seguire per saperne di più su Python o sulla versione installata. Chiudi o annulla questa finestra -- imparerai molto di più in questo tutorial! + +Nota: Se si utilizza una versione precedente di Windows (7, Vista, o qualsiasi versione precedente) e l'installatore di Python {{ book.py_version }} non funziona per un errore, installare tutti gli aggiornamenti di Windows e provare a installare nuovamente Python. Se l'errore si ripresenta, prova ad installare la versione di Python {{ book.py_min_release }} da [Python.org](https://www.python.org/downloads/windows/). + +> Django {{ book.django_version }} ha bisogno di Python {{ book.py_min_version }} o maggiore, che non supporta Windows XP o versioni precedenti. + + + + + +> **Nota** Prima di installare Python su macOS, devi fare in modo/ verificare che le impostazioni Mac consentano l'installazione di pacchetti che non sono presenti nell'App Store. Vai alle Preferenze di sistema (è nella cartella Applicazioni), clicca "Sicurezza & Privacy," e poi la scheda "Generale". Se il tuo "Consenti le app scaricate da:" è impostato su "Mac App Store", cambialo in "Mac App Store e sviluppatori identificati". + +Devi andare sul sito https://www.python.org/downloads/ e scaricare il programma di installazione di Python più recente: + +* Scarica Python {{ book.py_release }} +* Fare doppio clic su *python-{{ book.py_release }}-macos11.pkg* per eseguire l'installer. + + + + + +È molto probabile che tu abbia già installato Python fuori dalla scatola. Per verificare se è installata (e quale versione è), aprire una console e digitare il seguente comando: + +{% filename %}command-line{% endfilename %} $ python3 --version - Python 3.4.3 + Python {{ book.py_release }} -Se non hai Python installato o se vuoi una versione diversa, puoi installarla come segue: - -#### Debian o Ubuntu +Se hai una versione diversa di Python installata, almeno {{ book.py_min_version }} (es. {{ book.py_min_release }}), allora non devi aggiornare. Se non hai Python installato, o se vuoi una versione diversa, controlla prima quale distribuzione Linux stai usando con il seguente comando: -Digita questo comando nella tua console: +{% filename %}command-line{% endfilename %} - $ sudo apt-get install python3.4 + $ grep '^NAME=' /etc/os-release -#### Fedora (fino a 21) +In seguito, a seconda del risultato, segui una delle seguenti guide di installazione sotto questa sezione. -Usa questo comando nella tua console: + + + + +Digita questo comando nella tua console: - $ sudo yum install python3.4 +{% filename %}command-line{% endfilename %} + + $ sudo apt install python3 -#### Fedora (22+) + + + Usa questo comando nella tua console: - $ sudo dnf install python3.4 +{% filename %}command-line{% endfilename %} + + $ sudo dnf install python3 -#### openSUSE +Se sei nelle vecchie versioni Fedora potresti ottenere un errore che il comando `dnf` non è stato trovato. In questo caso, devi utilizzare `yum` invece. -Usa questo comando nella tua console: + - $ sudo zypper install python3 + +Usa questo comando nella tua console: -### OS X +{% filename %}command-line{% endfilename %} -Devi andare sul sito https://www.python.org/downloads/release/python-343/ e scarica il programma d'installazione di Python: + $ sudo zypper install python3 + - * Scarica il file *Mac OS X 64-bit/32-bit installer* - * Fai doppio click su *python-3.4.3-macosx10.6.pkg* per eseguire il programma d'installazione. + Verifica che l'installazione si sia conclusa correttamente aprendo l'applicazione *Terminal* ed eseguendo il comando `python3`: +{% filename %}command-line{% endfilename %} + $ python3 --version - Python 3.4.3 + Python {{ book.py_release }} +La versione mostrata può essere diversa da {{ book.py_release }} -- dovrebbe corrispondere alla versione installata. + +**NOTA:** Se sei su Windows e ricevi un messaggio di errore che dice che `python3` non è stato trovato, prova ad utilizzare `python` (senza `3`), controlla sia la versione di Python che è {{ book.py_min_version }} o superiore. Se anche questo non funziona, puoi aprire un nuovo prompt dei comandi e riprovare; questo accade se usi un prompt dei comandi aperto da prima dell'installazione di Python. + * * * -Se hai dubbi o se qualcosa è andato storto e non hai idea di cosa fare dopo - chiedi al tuo insegnante! A volte le cose non vanno come dovrebbero ed è meglio chiedere aiuto a qualcuno con più esperienza. +Se hai dubbi o se qualcosa è andato storto e non hai idea di cosa fare dopo - chiedi al tuo coach! A volte le cose non vanno come dovrebbero ed è meglio chiedere aiuto a qualcuno con più esperienza. \ No newline at end of file diff --git a/it/python_introduction/README.md b/it/python_introduction/README.md index 90fb27d0cb0..224f55d4992 100644 --- a/it/python_introduction/README.md +++ b/it/python_introduction/README.md @@ -1,175 +1,240 @@ +{% set warning_icon = '' %} + # Introduzione a Python -> Parte di questo capitolo è basato su esercitazioni di Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> Parte di questo capitolo è tratto dal tutorial delle Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). -Scriviamo un pò codice! +Scriviamo un po' di codice! ## La linea di comando di Python -Per iniziare a giocare con Python, devi avviare sul tuo computer una *linea di comando*. Dovresti già sapere come farlo -- l'hai imparato nel capitolo [Introduzione a Command Line][1]. +> Per chi ci segue da casa: questa parte si trova nel video [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U). - [1]: ../intro_to_command_line/README.md +Per iniziare a giocare con Python, devi avviare sul tuo computer una *linea di comando*. Dovresti già sapere come farlo – l'hai imparato nel capitolo [Introduzione alla riga di comando](../intro_to_command_line/README.md). Una volta pronta, segui le istruzioni riportate di seguito. Vogliamo aprire una console Python, quindi digita `python` su Windows o `python3` su Mac OS/Linux e premi `invio`. +{% filename %}command-line{% endfilename %} + $ python3 - Python 3.4.3 (...) + Python {{ book.py_release }} (...) Type "help", "copyright", "credits" or "license" for more information. >>> ## Il tuo primo comando Python! -Dopo aver eseguito il comando Python, il prompt è cambiato in `>>>`. Significa che per ora dovremmo utilizzare comandi nel linguaggio Python. Non devi digitare `>>>` - Python lo farà per te. +Dopo aver eseguito il comando Python, il prompt è cambiato in `>>>`. Questo ci informa che ora dovremo utilizzare comandi propri del linguaggio Python. Non devi digitare `>>>` - Python lo farà per te. -Se ad un certo punto vuoi uscire dalla console di Python, digita `exit()` oppure usa la scorciatoia `Ctrl + Z` per Windows e `Ctrl + D` per Mac/Linux. Allora non vedrai più `>>>`. +Se ad un certo punto vuoi uscire dalla console di Python, digita `exit()` oppure usa la scorciatoia `Ctrl + Z` per Windows e `Ctrl + D` per Mac/Linux. Dopo non vedrai più `>>>`. -Per ora non vogliamo uscire dalla console Python. Vogliamo saperne di più. Cominciamo con qualcosa davvero semplice. Per esempio, prova un po' di matematica, come `2 + 3` e premi `invio`. +Per il momento, non vogliamo uscire dalla console di Python. Vogliamo saperne di più. Iniziamo digitando qualche espressione matematica, come `2 + 3` e premiamo `invio`. - >>> 2 + 3 - 5 - +{% filename %}command-line{% endfilename %} -Fantastico! Hai visto come è comparsa la risposta? Python conosce la matematica! potresti provare altri comandi come: - `4 * 5` - `5 - 1` - `40 / 2` +```python +>>> 2 + 3 +5 +``` + +Bello! Hai visto come le risposte spuntano fuori? Python conosce la matematica! Prova altri comandi come: -Divertiti con questo per un pò e dopo torna qui :). +- `4 * 5` +- `5 - 1` +- `40 / 2` -Come puoi vedere, Python è una buona calcolatrice. Ora ti starai sicuramente chiedendo cos'altro è capace di fare... +Per eseguire un calcolo esponenziale, per esempio 2 elevato alla potenza 3, digitiamo: {% filename %}command-line{% endfilename %} + +```python +>>> 2 ** 3 +8 +``` + +Giochicchia un po' con Python, e poi torna a leggere qui. :) + +Come puoi vedere, Python è una buona calcolatrice. Ora ti starai sicuramente chiedendo cos'altro è capace di fare… ## Stringhe Che ne dici di scrivere il tuo nome? Digitalo tra virgolette così: - >>> "Ola" - 'Ola' - +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" +'Ola' +``` Hai appena creato la tua prima stringa! Una stringa è una sequenza di caratteri che possono essere elaborati da un computer. La stringa deve sempre iniziare e finire con lo stesso carattere. Che può essere una virgoletta semplice (`'`) o doppia (`"`) (non c'è differenza!) Le virgolette dicono a Python che il contenuto al loro interno è una stringa. Le stringhe possono essere legate assieme. Prova questo: - >>> " Ciao " + "Ola" - 'Ciao Ola' - +{% filename %}command-line{% endfilename %} + +```python +>>> " Ciao " + "Ola" +'Ciao Ola' +``` Puoi anche moltiplicare le stringhe con un numero: - >>> "Ola" * 3 - 'OlaOlaOla' - +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` Se devi mettere un apostrofo nella tua stringa, hai due modi per farlo. Utilizzando le virgolette doppie: - >>> "Correre verso l'albero" - "Correre verso l'albero" - +{% filename %}command-line{% endfilename %} -o facendo l'escape dell'apostrofo (cioè trattandolo come un carattere qualunque) con una barra rovesciata ( \ ): +```python +>>> "L'ape Maja va" +"L'ape Maja va" +``` - >>> 'Correre verso l\'albero' - "Correre verso l'albero" - +o facendo l'escape dell'apostrofo (cioè evitando che concluda la stringa) con una barra rovesciata (`\`): + +{% filename %}command-line{% endfilename %} + +```python +>>> 'L\'ape Maja va' +"L'ape Maja va" +``` Bello, eh? Per vedere il tuo nome in maiuscolo, digita: - >>> "Ola".upper() - 'OLA' - +{% filename %}command-line{% endfilename %} -Hai appena usato la funzione `upper` sulla tua stringa! Una funzione (come `upper()`) è una sequenza di istruzioni che Python deve eseguire su un determinato oggetto (`"Ola"`). +```python +>>> "Ola".upper() +'OLA' +``` -Se vuoi sapere il numero delle lettere presenti nel tuo nome, c'è una funzione anche per quello! +Hai appena applicato il **metodo** `upper` sulla tua stringa! Un metodo (come `upper()`) è una sequenza di istruzioni che Python deve compiere su un oggetto dato (la stringa `"Ola"`) nel momento in cui viene applicato. - >>> len("Ola") - 3 - +Se vuoi sapere il numero di lettere nel tuo nome, per questo c'è una **funzione**! + +{% filename %}command-line{% endfilename %} + +```python +>>> len("Ola") +3 +``` -Ti stai chiedendo perché certe volte chiami una funzione con un `.` alla fine di una stringa (come `"Ola".upper()`) ed in altri casi chiami prima una funzione e poi metti la stringa tra parentesi? Beh, in alcuni casi, le funzioni appartengono ad oggetti, come `upper()`, che può essere eseguita solo su stringhe. In questo caso, chiamiamo la funzione **metodo**. Altre volte, le funzioni non appartengono a niente di specifico e possono essere utilizzate su diversi tipi di oggetti, proprio come `len()`. Ecco perché stiamo dando `"Ola"` come un parametro alla funzione `len`. +Ti stai chiedendo la differenza fra il chiamare una funzione con un `.` alla fine di una stringa (come `"Ola".upper()`) ed il chiamare prima la funzione e poi mettere la stringa tra parentesi? Beh, ci sono funzioni che appartengono ad oggetti, come `upper()`, che può essere eseguita solo su stringhe. In questo caso, chiamiamo la funzione **metodo**. Altre volte, le funzioni non appartengono a niente di specifico e possono essere utilizzate su diversi tipi di oggetti, proprio come `len()`. Ecco perché stiamo passando `"Ola"` come parametro alla funzione `len`. ### Indice OK, basta con le stringhe. Ecco fino ad ora quanto hai imparato: -* **il prompt** - digitare i comandi (codice) nel prompt di Python restituisce risposte in Python -* **numeri e stringhe** - in Python i numeri vengono utilizzati per la matematica e le stringhe per oggetti testuali -* **operatori** - come + e *, combinano i valori per produrne di nuovi -* **funzioni** - come upper() e len(), eseguono azioni su oggetti. +- Il **prompt** -- Digitare i comandi (codice) nel prompt di Python restituisce risposte in Python +- **Numeri e stringhe** -- In Python i numeri vengono utilizzati per la matematica e le stringhe per oggetti testuali +- Gli **operatori** -- come `+` e `*`, combinano più valori per produrne uno nuovo +- **funzioni** -- come `upper()` e `len()`, eseguono azioni su oggetti. -Queste sono le basi di ogni linguaggio di programmazione che impari. Pronta per qualcosa di più complicato? Scommetto che lo sei! +Fin qui le basi del linguaggio di programmazione che stiamo imparando. Pronta per qualcosa di più complicato? Scommetto di sì! ## Errori -Proviamo qualcosa di nuovo. Possiamo ottenere la lunghezza di un numero nella stessa forma in cui abbiamo potuto scoprire la lunghezza del nostro nome? Digita `len(304023)` e premi `Invio`: +Proviamo una cosa diversa. Possiamo ottenere la lunghezza di un numero nella stessa forma in cui abbiamo potuto scoprire la lunghezza del nostro nome? Digita `len(304023)` e premi `Invio`: - >>> 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 %} + +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` -Abbiamo ottenuto il nostro primo errore! Ci dice che gli oggetti di tipo "int" (integers, numeri interi) non hanno lunghezza. Quindi cosa possiamo fare? Forse possiamo scrivere il nostro numero come una stringa? Le stringhe hanno una lunghezza, vero? +Abbiamo ottenuto il nostro primo errore! L'icona {{ warning_icon }} è il nostro modo per suggerirti che il codice che stai per eseguire non funzionerà come ti aspetti. Fare errori (anche intenzionali) è un elemento importante dell'apprendimento! - >>> len(str(304023)) - 6 - +Il testo dice che gli oggetti di tipo "int" (interi, numeri interi) non hanno lunghezza. Quindi cosa possiamo fare ora? Forse possiamo scrivere il nostro numero come stringa? Le stringhe hanno una lunghezza, giusto? + +{% filename %}command-line{% endfilename %} + +```python +>>> len(str(304023)) +6 +``` -Ha funzionato! Usiamo la funzione `str` all'interno della funzione `len`. `str()` converte tutto in stringhe. +Ha funzionato! Abbiamo utilizzato la funzione `str` all'interno della funzione `len`. `str()` converte tutto in stringhe. -* La funzione `str` converte le cose in **stringhe** -* La funzione `int` converte le cose in **numeri interi** +- La funzione `str` converte le cose in **stringhe** +- La funzione `int` converte le cose in **numeri interi** > Importante: possiamo convertire i numeri in testo, ma non possiamo convertire il testo in numeri - cosa potrebbe essere `int('hello')`? ## Variabili -Un concetto importante nella programmazione è quello delle variabili. Una variabile è un nome per un qualcosa che deve essere utilizzato sucessivamente. I programmatori usano queste variabili per archiviare dati, rendere il loro codice più leggibile e per non dover tenere a mente cosa sono queste cose. +Un concetto importante nella programmazione è quello delle variabili. Una variabile non è altro che un nome per qualcosa, così puoi usarla più tardi. I programmatori usano le variabili per memorizzare dati, rendere il loro codice più leggibile in modo da non dover continuare a ricordare le cose. Diciamo che vogliamo creare una nuova variabile chiamata `nome`: - >>> nome = "Ola" - +{% filename %}command-line{% endfilename %} -Vedi? È facile! è semplicemente: nome è uguale a Ola. +```python +>>> nome = "Ola" +``` -Come avrai notato, il programma non ha ritornato nulla, diversamente da prima. Quindi come facciamo a sapere che la variabile esiste? Digita `nome` e premi `enter`: +Praticamente, poniamo il valore della variabile nome uguale alla stringa "Ola". - >>> nome - 'Ola' - +Come hai notato, il tuo programma non ha dato nessun risultato come ha fatto prima. Allora come facciamo a sapere che la variabile esiste veramente? semplicemente digita `nome` e premi `Invio`: -Evvai! La tua prima variabile :)! Puoi sempre modificare a cosa si riferisce: +{% filename %}command-line{% endfilename %} - >>> nome = "Sonja" - >>> nome - 'Sonja' - +```python +>>> nome +'Ola' +``` + +Urrà! La tua prima variabile! :) E puoi anche cambiare il valore a cui essa si riferisce: + +{% filename %}command-line{% endfilename %} + +```python +>>> nome = "Sonja" +>>> nome +'Sonja' +``` La puoi utilizzare anche nelle funzioni: - >>> len(nome) - 5 - +{% filename %}command-line{% endfilename %} -Fantastico, vero? Certo, le variabile possono essere qualsiasi cosa, così come i numeri! Prova questo: +```python +>>> len(nome) +5 +``` - >>> a = 4 - >>> b = 6 - >>> a * b - 24 - +Fantastico, vero? Naturalmente, le variabili possono essere qualsiasi cosa, così come i numeri! Prova questo: + +{% filename %}command-line{% endfilename %} + +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` Ma cosa succede se utilizziamo il nome sbagliato? Riesci a immaginare cosa succederebbe? Proviamo! - >>> city = "Tokyo" - >>> ctiy - Traceback (most recent call last): - File "", line 1, in - NameError: name 'ctiy' is not defined - +{% 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 +``` Un errore! Come puoi vedere, Python ha diversi tipi di errori e questo qui si chiama **NameError**. Python ti darà questo errore se provi ad utilizzare una variabile che non è stata ancora definita. Se incontri questo errore più tardi, controlla il tuo codice per vedere se hai digitato in modo errato i nomi. @@ -179,85 +244,116 @@ Giocaci per un po' e vedi cosa puoi fare! Prova questo: - >>> nome = 'Maria' - >>> nome - 'Maria' - >>> print(nome) - Maria - +{% filename %}command-line{% endfilename %} -Quando digiti `nome`, l'interprete di Python risponde con una stringa *rappresentazione* della variabile 'nome', che contiene le lettere M-a-r-i-a, circondate da singole virgolette, ''. Quando dici `print(nome)`, Python "stamperà" i contenuti della variabile sullo schermo, senza le virgolette, che è più pulito. +```python +>>> nome = 'Maria' +>>> nome +'Maria' +>>> print(name) +Maria +``` + +Quando digiti `name`, l'interprete di Python risponde con una stringa *rappresentazione* della variabile 'nome', che contiene le lettere M-a-r-i-a, circondate da singole virgolette, ''. Quando dici `print(nome)`, Python "stamperà" i contenuti della variabile sullo schermo, senza le virgolette, che è più pulito. Come vedremo dopo, `print()` è anche utile quando vogliamo stampare le cose dall'interno delle funzioni, oppure quando vogliamo stampare le cose in molteplici righe. ## Liste -Oltre alle stringhe ed ai numeri interi, Python ha tanti tipi di oggetti. Ora ne introdurremo uno chiamato **lista**. Le liste sono fatte proprio come immagini: sono oggetti che sono liste di altri oggetti :) +Oltre alle stringhe ed ai numeri interi, Python ha tanti tipi di oggetti. Ora ne introdurremo uno chiamato **lista**. Le liste sono fatte proprio come immagini: sono oggetti che sono liste di altri oggetti. :) Vai avanti e crea una lista: - >>> [] - [] - +{% filename %}command-line{% endfilename %} -Si, questa lista è vuota. Non serve a molto, giusto? Creiamo una lista di numeri della lotteria. Non vogliamo ripetere tutto ogni volta, quindi metteremo la lista in una variabile: +```python +>>> [] +[] +``` - >>> lotteria = [3, 42, 12, 19, 30, 59] - +Sì, questa lista è vuota. Abbastanza inutile, vero? Creiamo una lista di numeri della lotteria. Non vogliamo ripetere la sequenza ogni volta, quindi metteremo anche la lista in una variabile: -Abbiamo una lista! Cosa possiamo farne? Vediamo quanti numeri della lotteria ci sono nella lista. Hai idea di quale funzione potresti utilizzare per farlo? Lo abbiamo imparato insieme prima! +{% filename %}command-line{% endfilename %} - >>> len(lotteria) - 6 - +```python +>>> lotteria = [3, 42, 12, 19, 30, 59] +``` + +Bene, abbiamo una lista! Cosa possiamo farne? Vediamo quanti numeri della lotteria contiene. Quale funzione potresti utilizzare per questo compito? Lo hai già imparato! + +{% filename %}command-line{% endfilename %} + +```python +>>> len(lotteria) +8 +``` Si! `len()` può darti il numero di oggetti in una lista. Utile, vero? Forse abbiamo risolto: - >>> lotteria.sort() - +{% filename %}command-line{% endfilename %} + +```python +>>> lotteria.sort() +``` Questo comando non dà nessun risultato, ha semplicemente cambiato l'ordine in cui i numeri appaiono nella lista. Stampiamo di nuovo la lista per vedere cosa è successo: - >>> print(lotteria) - [3, 12, 19, 30, 42, 59] - +{% filename %}command-line{% endfilename %} + +```python +>>> print(lotteria) +[3, 12, 19, 30, 42, 59] +``` Come puoi vedere, adesso i numeri nella tua lista sono ordinati dal valore più basso a quello più alto. Congratulazioni! Vogliamo invertire quell'ordine? Facciamolo! - >>> lotteria.reverse() - >>> print(lotteria) - [59, 42, 30, 19, 12, 3] - +{% filename %}command-line{% endfilename %} + +```python +>>> lotteria.reverse() +>>> print(lotteria) +[59, 42, 30, 19, 12, 3] +``` Facile, vero? Se vuoi aggiungere qualcosa alla tua lista, puoi farlo digitando questo comando: - >>> lotteria.append(199) - >>> print(lotteria) - [59, 42, 30, 19, 12, 3, 199] - +{% filename %}command-line{% endfilename %} + +```python +>>> lotteria.append(199) +>>> print(lotteria) +[59, 42, 30, 19, 12, 3, 199] +``` Se vuoi mostrare solo il primo numero, puoi farlo usando gli **indici**. L'indice è il numero che dice la posizione esatta dell'elemento all'interno di una lista. I programmatori preferiscono iniziare a contare da 0, quindi il primo oggetto nella lista è all'indice 0, il successivo all'1, e così via. Prova questo: - >>> print(lotteria[0]) - 59 - >>> print(lotteria[1]) - 42 - +{% filename %}command-line{% endfilename %} + +```python +>>> print(lotteria[0]) +59 +>>> print(lotteria[1]) +42 +``` Come puoi vedere, puoi accedere a diversi oggetti nella tua lista usando il nome della lista e l'indice dell'oggetto all'interno delle parentesi quadre. -Per eliminare qualcosa dalla lista dovrai usare **indexes** come abbiamo visto sopra, e lo statement `pop()`. Proviamo a fare qualcosa per rafforzare quanto imparato prima; elimineremo il primo numero della lista. +Per eliminare qualcosa dalla lista dovrai usare gli **indici** come abbiamo visto sopra, e il metodo `pop()`. Proviamo a fare un esercizio per rafforzare quanto abbiamo imparato prima; elimineremo il primo numero della lista. - >>> print(lotteria) - [59, 42, 30, 19, 12, 3, 199] - >>> print(lotteria[0]) - 59 - >>> lotteria.pop(0) - >>> print(lotteria) - [42, 30, 19, 12, 3, 199] - +{% filename %}command-line{% 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] +``` Ha funzionato a meraviglia! @@ -267,76 +363,103 @@ Per saperne di più su i metodi disponibili per le liste puoi consultare questo ## Dizionari +> Per chi ci segue da casa: questa parte si trova nel video [Python Basics: Dictionaries](https://www.youtube.com/watch?v=ZX1CVvZLE6c). + Un dizionario (dictionary) è simile a una lista, ma accedi ai valori cercando una chiave invece di un indice. Una chiave può essere qualsiasi stringa o numero. La sintassi per definire un dizionario vuoto è: - >>> {} - {} - +{% filename %}command-line{% endfilename %} + +```python +>>> {} +{} +``` Questo dimostra che hai appena creato un dizionario vuoto. Evviva! Ora, prova a scrivere il seguente comando (prova a sostituirlo con le tue informazioni): - >>> partecipante = {'nome': 'Ola', 'paese': 'Polonia', 'numeri_preferiti': [7, 42, 92]} - +{% filename %}command-line{% endfilename %} + +```python +>>> partecipante = {'nome': 'Ola', 'paese': 'Polonia', 'numeri_preferiti': [7, 42, 92]} +``` Con questo comando hai appena creato una variabile chiamata `partecipante` con tre coppie di chiavi-valori: -* La chiave `nome` va a indicare il valore `'Ola'` (un oggetto `stringa`), -* `paese` indica `'Polonia'` (un'altra `stringa`), -* e `numeri_preferiti` indica `[7, 42, 92]` (una `lista` con tre numeri al suo interno). +- La chiave `nome` va a indicare il valore `'Ola'` (un oggetto `stringa`), +- `paese` indica `'Polonia'` (un'altra `stringa`), +- e `numeri_preferiti` indica `[7, 42, 92]` (una `lista` con tre numeri al suo interno). Puoi controllare il contenuto di chiavi individuali con questa sintassi: - >>> print(partecipante['nome']) - Ola - +{% filename %}command-line{% endfilename %} + +```python +>>> print(partecipante['nome']) +Ola +``` Vedi, assomiglia ad una lista. Ma non devi ricordare l'indice - solo il nome. Cosa succede se chiediamo a Python il valore di una chiave che non esiste? Riesci a indovinarlo? Proviamo! - >>> partecipante['età'] - Traceback (most recent call last): - File "", line 1, in - KeyError: 'età' - +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> partecipante['età'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'età' +``` Guarda, un altro errore! Questo qua è un **KeyError**. Python è utile e ti dice che la chiave `'età'` non esiste in questo dizionario. Quando usare un dizionario o una lista? Bella domanda. Prova a formulare una soluzione mentalmente prima di vedere la risposta nella prossima riga. -* Ha bisogno di una sequenza ordinata di elementi? Fai una lista. -* Hai bisogno di associare i valori alle chiavi, così che potrai cercarle agilmente (per chiave) dopo? Usa un dizionario. +- Ha bisogno di una sequenza ordinata di elementi? Fai una lista. +- Hai bisogno di associare i valori alle chiavi, così che potrai cercarle agilmente (per chiave) dopo? Usa un dizionario. I dizionari, come le liste, sono *mutable*, significa che possono essere cambiati dopo che sono stati creati. Si possono aggiugere nuove coppie chiave/valore ad un dizionario dopo averlo creato: - >>> partecipante['linguaggio_preferito'] = 'Python' - +{% filename %}command-line{% endfilename %} -Così come succede se applicato alle liste, il metodo `len()` restituisce il numero di coppie chiave/valore anche quando applicato a un dizionario. Vai e digita il comando: +```python +>>> partecipante['linguaggio_preferito'] = 'Python' +``` - >>> len(partecipante) - 4 - +Come le liste, usando la funzione `len()` sui dizionari restituisce il numero di coppie chiave-valore nel dizionario. Vai avanti e digita questo comando: + +{% filename %}command-line{% endfilename %} + +```python +>>> len(partecipante) +4 +``` Spero che abbia senso per te. :) Pronta per divertirti con i dizionari? Vai alla prossima riga per realizzare altre cose fantastiche. -Puoi usare il comando `pop()` per cancellare un elemento nella directory. Se vuoi cancellare la voce che corrisponde alla chiave `'numeri_preferiti'`, digita il seguente comando: +Puoi usare il comando `del` per cancellare un elemento nella directory. Se vuoi cancellare la voce che corrisponde al tasto `'numeri_preferiti'`, digita il seguente comando: - >>> partecipante.pop('numeri_preferiti') - >>> partecipante - {'paese': 'Polonia', 'linguaggio_preferito': 'Python', 'nome': 'Ola'} - +{% filename %}command-line{% endfilename %} + +```python +>>> participant.pop('favorite_numbers') +[7, 42, 92] +>>> participant +{'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +``` Come puoi vedere dall'output, la coppia chiave-valore corrispondente alla chiave 'numeri_preferiti' è stato cancellata. Puoi anche cambiare un valore associato ad una chiave già creata nel dizionario. Digita: - >>> partecipante['paese'] = 'Germania' - >>> partecipante - {'paese': 'Germania', 'linguaggio_preferito': 'Python', 'nome': 'Ola'} - +{% filename %}command-line{% endfilename %} + +```python +>>> partecipante['paese'] = 'Germania' +>>> partecipante +{'paese': 'Germania', 'linguaggio_preferito': 'Python', 'nome': 'Ola'} +``` Come puoi vedere, il valore della chiave `'paese'` è stato cambiato da `'Polonia'` a `'Germania'`. :) Eccitante, vero? Evviva! Hai già imparato un'altra cosa fantastica. @@ -344,178 +467,253 @@ Come puoi vedere, il valore della chiave `'paese'` è stato cambiato da `'Poloni Fantastico! ora sai molto sulla programmazione. In questa ultima parte hai imparato: -* **errori** - ora sai come leggere e capire gli errori che appaiono se Python non comprende un comando che gli hai dato -* **variabili** - nomi per oggetti. Ti permettono di scrivere codice più semplice e di renderlo più leggibile -* **liste** - liste di oggetti archiviati in un ordine particolare -* **dizionari** - oggetti archiviati come coppie di chiave-valore +- **errori** - ora sai come leggere e capire gli errori che appaiono se Python non comprende un comando che gli hai dato +- **variabili** - nomi per oggetti. Ti permettono di scrivere codice più semplice e di renderlo più leggibile +- **liste** - liste di oggetti archiviati in un ordine particolare +- **dizionari** - oggetti archiviati come coppie di chiave-valore Sei emozionato/a per la prossima parte? :) ## Confrontare le cose +> Per i lettori da casa: questa parte si trova nel video [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4). + Larga parte della programmazione include il confrontare le cose. Qual è la cosa più semplice da confrontare? I numeri, senza dubbio. Vediamo come funziona: - >>> 5 > 2 - True - >>> 3 < 1 - False - >>> 5 > 2 * 2 - True - >>> 1 == 1 - True - >>> 5 != 2 - True - +{% 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 +``` -Abbiamo dato a Python alcuni numeri da mettere a confronto. Come puoi vedere, Python può mettere a confronto non solo numeri, ma anche i risultati dei metodi. Forte, eh? +Abbiamo dato a Python dei numeri da confrontare. Come puoi vedere, non solo Python può confrontare i numeri, ma può anche confrontare i valori delle espressioni matematiche come `2 * 2` e i risultati delle funzioni come `2` restituiti da `len([4, 5])`. "Bello, eh?" Ti sei chiesta perché abbiamo messo due simboli di uguale `==` uno vicino all'altro per confrontare i numeri? Usiamo un singolo `=` per assegnare valori alle variabili. Sempre, **sempre** devi mettere due `==` se vuoi controllare se le cose sono uguali. Possiamo affermare anche che le cose sono diverse tra di loro. Per dirlo, usiamo il simbolo `!=`, come mostrato nell'esempio sopra. Dai a Python altri due compiti: - >>> 6 >= 12 / 2 - True - >>> 3 <= 2 - False - +{% filename %}command-line{% endfilename %} + +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` `>` e `<` sono facili, ma cosa significano `>=` e `<=`? Leggili così: -* x `>` y significa: x è maggiore di y -* x `<` y significa: x è minore di y -* x `<=` y significa: x è minore o uguale a y -* x `>=` y significa: x è maggiore o uguale a y +- x `>` y significa: x è maggiore di y +- x `<` y significa: x è minore di y +- x `<=` y significa: x è minore o uguale a y +- x `>=` y significa: x è maggiore o uguale a y Fantastico! Vuoi farne due o tre? prova questo: - >>> 6 > 2 and 2 < 3 - True - >>> 3 > 2 and 2 < 1 - False - >>> 3 > 2 or 2 < 1 - True - +{% filename %}command-line{% endfilename %} + +```python +>>> 6 > 2 and 2 < 3 +True +>>> 3 > 2 and 2 < 1 +False +>>> 3 > 2 or 2 < 1 +True +``` Puoi dare a Python tutti i numeri da confrontare che vuoi, ti darà sempre una risposta! Molto intelligente, vero? -* **and** - se usi l'operatore `e`, entrambe le cose confrontate devono essere True in modo tale che l'intero comando sia True -* **or** - se usi l'operatore `o`, solo una delle cose messe a confronto deve essere True in modo tale che l'intero comando sia True +- **and** - se usi l'operatore `e`, entrambe le cose confrontate devono essere True in modo tale che l'intero comando sia True +- **or** - se usi l'operatore `o`, solo una delle cose messe a confronto deve essere True in modo tale che l'intero comando sia True Hai sentito parlare dell'espressione "comparare mele e arance"? Proviamo l'equivalente in Python: - >>> 1 > 'django' - Traceback (most recent call last): - File "", line 1, in - TypeError: unorderable types: int() > str() - +{% 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' +``` Dall'espressione puoi capire che Python non è in grado di mettere a confronto un numero (`int`) e una stringa (`str`). Ci mostra invece un **TypeError** e ci dice che i due tipi non possono essere messi a confronto. ## Booleano -Accidentalmente, hai appena imparato un nuovo tipo di oggetto in Python. Si chiama **Boolean** e probabilmente è il tipo più facile che ci sia. +Tra parentesi, hai appena appreso di un nuovo tipo di oggetto in Python. Si chiama **Boolean**. + +Ci sono solo due oggetti Boolean:-True-False -Ci sono solo due oggetti Boolean: -- True -- False +- Vero +- Falso Ma perché Python possa capirlo, bisogna sempre scrivere True (prima lettera maiuscola, le altre minuscole). **true, TRUE, tRUE non funzionano -- solo True è corretto.** (Lo stesso vale per False, ovviamente.) I Boolean possono anche essere variabili! Guarda qui: - >>> a = True - >>> a - True - +{% filename %}command-line{% endfilename %} + +```python +>>> a = True +>>> a +True +``` Lo puoi fare anche in questa forma: - >>> a = 2 > 5 - >>> a - False - +{% filename %}command-line{% endfilename %} + +```python +>>> a = 2 > 5 +>>> a +False +``` -Fai pratica e divertiti con i Boolean provando ad eseguire i seguenti comandi: +Esercitati e divertiti con i valori booleani provando a eseguire i seguenti comandi: -* `True and True` -* `False and True` -* `True or 1 == 1` -* `1 != 2` +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` -Congratulazioni! I valori Boolean sono tra le cose più interessanti della programmazione e tu hai appena imparato ad utilizzarli! +Congratulazioni! I valori Booleani sono tra le cose più interessanti della programmazione e tu hai appena imparato ad utilizzarli! # Salvalo! -Finora abbiamo scritto il codice python nell'interprete, che ci permette di inserire una linea di codice per volta. I programmi vengono salvati in file ed eseguiti dall'**interpreter** del nostro linguaggio di programmazione o dal **compiler**. Fino ad ora abbiamo eseguito i nostri programmi una riga per volta nell' **interprete** di Python. Avremo bisogno di più di una riga di codice per i prossimi compiti, quindi dovremo fare queste cose velocemente: +> Per i lettori da casa: questa parte si trova nel video [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk). -* Uscire dall'interprete di Python -* Aprire l'editor di codice che abbiamo scelto -* Salvare un po' di codice in un file python -* Eseguirlo! +Fino ad ora abbiamo scritto tutto il nostro codice Python nell'interprete, il ché ci limita ad una riga di codice alla volta. I programmi vengono salvati in file ed eseguiti dall'**interpreter** del nostro linguaggio di programmazione o dal **compiler**. Fino ad ora abbiamo eseguito i nostri programmi una riga per volta nell' **interprete** di Python. Avremo bisogno di più di una riga di codice per i prossimi compiti, quindi dovremo fare queste cose velocemente: -Per uscire dall'interprete di Python che è quello che stavamo utilizzando, digita la funzione ```exit()``` : +- Uscire dall'interprete di Python +- Aprire l'editor di codice che abbiamo scelto +- Salvare un po' di codice in un file python +- Eseguirlo! - >>> exit() - $ - +Per uscire dall'interprete di Python che abbiamo utilizzato, digita la funzione `exit()` + +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` Questo ti immetterà nel prompt dei comandi. -Prima, abbiamo preso un editore di codice dalla sezione [code editor][2]. Dovremo aprire l'editor ora e scrivere un po' di codice in un nuovo file: +Prima abbiamo scelto un editor di codice dalla sezione [editor di codice](../code_editor/README.md) . Dobbiamo aprire l'editor ora e scrivere un codice in un nuovo file (o se stai usando un Chromebook, creare un nuovo file nell'IDE cloud e aprire il file, che sarà incluso nell'editor di codice): - [2]: ../code_editor/README.md +{% filename %}editor{% endfilename %} ```python print('Ciao, Django girls!') ``` -> **Nota** Dovresti notare una delle cose più belle degli editori di codice: i colori! Nella console Python ogni cosa era dello stesso colore, mentre ora dovresti visualizzare la funzione `print` di un colore differente rispetto alla stringa che la segue. Questa viene chiamata "sintassi evidenziata", ed è veramente utile quando si scrive codice. Il colore serve come suggerimento, ad esempio per una stringa che non è chiusa, o un errore di digitazione di una keyword (come la `def` per le funzioni, che vedremo più avanti). Questo è uno dei motivi per cui usiamo un editor di codice :) - Ovviamente a questo punto sei una programmatrice Python senior, quindi sentiti libera di scrivere un po' del codice che hai imparato oggi. Ora dobbiamo salvare il file e dargli un nome descrittivo. Chiama il file **python_intro.py** e salvalo sulla tua scrivania. Puoi chiamare il file come vuoi, ma è importante assicurarsi che finisca con **.py**. L'estensione **.py** dice al Sistema Operativo che questo è un **file eseguibile python** e che Python può eseguirlo. -È ora di eseguire il file! Usando le nozioni che hai imparato nella sezione command line, usa il terminal per **cambiare cartella** alla scrivania. +> **Nota** Dovresti notare una delle cose più belle degli editori di codice: i colori! Nella console Python ogni cosa era dello stesso colore, mentre ora dovresti visualizzare la funzione `print` di un colore differente rispetto alla stringa che la segue. Questa viene chiamata "sintassi evidenziata", ed è veramente utile quando si scrive codice. Il colore serve come suggerimento, ad esempio per una stringa che non è chiusa, o un errore di digitazione di una keyword (come la `def` per le funzioni, che vedremo più avanti). Questo è uno dei motivi per cui usiamo un editor di codice. :) + +E' ora di eseguire il file! Usando le nozioni che hai imparato nella sezione command line, usa il terminal per **cambiare cartella** alla scrivania. + + -Su un Mac, il comando assomiglierà a questo: +Su un Mac, il comando sarà più o meno così: + +{% filename %}command-line{% endfilename %} $ cd ~/Desktop -Su Linux, sarà come questo (la parola "Desktop" potrebbe essere tradotta nella tua lingua): + + + + +Su Linux, sarà così: + +{% filename %}command-line{% endfilename %} $ cd ~/Desktop -E su windows, sara come questo: +(Ricorda che la parola "Desktop" potrebbe essere tradotta nella tua lingua.) + + + + + +Nel prompt dei comandi di Windows, sarà così: + +{% filename %}command-line{% endfilename %} > cd %HomePath%\Desktop -Se rimani bloccata, chiedi aiuto. + + + + +E su windows, sara come questo: + +{% filename %}command-line{% endfilename %} + + > cd $Home\Desktop + + + + +Se sei bloccato, chiedi aiuto. Ecco esattamente per che cosa sono qui gli autobus! Ora usa Python per eseguire il codice nel file: +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Ciao, Django girls! +Nota: su Windows 'python3' non è riconosciuto come comando. Al contrario, usa 'python' per eseguire il file: + +{% filename %}command-line{% endfilename %} + +```python +> python python_intro.py +``` + Perfetto! Hai appena eseguito il tuo primo programma Python salvato su un file. Grande, no? Ora puoi continuare con uno strumento essenziale nella programmazione: -## If...elif...else +## If … elif … else -Molte cose dovrebbero essere eseguite soltanto quando si incontrano certe condizioni. È per questo che Python ha gli **if statements**. +Molte cose dovrebbero essere eseguite soltanto quando si incontrano certe condizioni. E' per questo che Python ha gli **if statements**. Sostituisci il codice nel file **python_intro.py** con questo: +{% filename %}python_intro.py{% endfilename %} + ```python if 3 > 2: ``` Se salviamo questo codice e lo eseguiamo, incontriamo un errore come questo: +{% filename %}{{ warning_icon }} command-line{% endfilename %} + $ python3 python_intro.py File "python_intro.py", line 2 ^ @@ -524,96 +722,137 @@ Se salviamo questo codice e lo eseguiamo, incontriamo un errore come questo: Python si aspetta che gli vengano fornite ulteriori istruzioni che saranno eseguite se la condizione `3 > 2` risulterà vera (o `True` se vogliamo). Proviamo a fare in modo che Python stampi "Funziona!". Modifica il tuo codice nel tuo file **python_intro.py** con questo: +{% filename %}python_intro.py{% endfilename %} + ```python if 3 > 2: - print('Funziona!') + print('It works!') ``` -Vedi come abbiamo indentato la riga successiva usando 4 spazi? Si deve fare così in modo tale che Python sappia quale codice eseguire se il risultato è True. Puoi fare uno spazio, ma circa tutti i programmatori di Python ne fanno 4 per far vedere le cose più ordinate. Anche un signolo `tab` conta come 4 spazi. +Vedi come abbiamo indentato la riga successiva usando 4 spazi? Si deve fare così in modo tale che Python sappia quale codice eseguire se il risultato è True. Puoi mettere uno spazio, ma la maggior parte dei programmatori di Python ne mettono 4 per rendere le cose più ordinate. Una singola scheda conterrà anche 4 spazi finché l'editor di testo è impostato per farlo. Quando hai fatto la tua scelta, non cambiarla! Se hai già indicizzato con 4 spazi, crea qualsiasi rientro futuro con 4 spazi - altrimenti potresti incorrere in problemi. Salvalo ed eseguilo di nuovo: - $ python3 python_intro.py - Funziona! - +{% filename %}command-line{% endfilename %} + +```python +$ python3 python_intro.py +Funziona! +``` + +Nota: Ricorda che su Windows, 'python3' non è riconosciuto come comando. Da ora in poi, sostituisci 'python3' con 'python' per eseguire il file. ### E se una condizione non è Vera? In esempi precedenti, il codice è stato eseguito solo quando le condizioni erano True. Ma Python ha anche gli `elif` e `else` statements: +{% filename %}python_intro.py{% endfilename %} + ```python if 5 > 2: - print('5 è infatti maggiore di 2') + print('5 è infatti maggiore di 2') else: - print('5 non è maggiore di 2') + print('5 non è maggiore di 2') ``` Quando viene lanciato, mostrerà: +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py 5 è infatti maggiore di 2 -Se 2 fosse un numero maggiore di 5, allora andrebbe in esecuzione il secondo comando. Facile, vero? Andiamo a vedere come funziona `elif`: +Se 2 fosse più grande di 5, allora andrebbe in esecuzione il secondo comando. Facile, vero? Andiamo a vedere come funziona `elif`: + +{% filename %}python_intro.py{% endfilename %} ```python nome = 'Sonja' if nome == 'Ola': - print('Ciao Ola!') + print('Hey Ola!') elif nome == 'Sonja': - print('Ciao Sonja!') + print('Hey Sonja!') else: - print('Ciao anonimo!') + print('Hey anonimo!') ``` ed eseguito: +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py - Ciao Sonja! + Hey Sonja! Hai visto cosa è successo? `elif` ti consente di aggiungere condizioni supplementari che verranno eseguite se nessuna delle condizioni precedenti viene soddisfatta. Allo statement iniziale `if` puoi far seguire tutti gli statement `elif` che vuoi. Per esempio: +{% filename %}python_intro.py{% endfilename %} + ```python volume = 57 if volume < 20: - print("Piuttosto basso.") + print("It's kinda quiet.") elif 20 <= volume < 40: - print("Adatto per musica di sottofondo") + print("It's nice for background music") elif 40 <= volume < 60: - print("Perfetto, posso apprezzare ogni dettaglio") + print("Perfect, I can hear all the details") elif 60 <= volume < 80: - print("Ideale per le feste") + print("Nice for parties") elif 80 <= volume < 100: - print("Un po' altino!") + print("A bit loud!") else: - print("Oddio, le mie orecchie! :(") + print("My ears are hurting! :(") ``` Python esegue ogni singolo test in sequenza e scrive: +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Perfetto, posso apprezzare ogni dettaglio +## Commenti + +I commenti sono linee che iniziano con `#`. Puoi scrivere tutto ciò che vuoi dopo `#` e Python lo ignorerà. I commenti possono rendere il tuo codice più facile da capire per gli altri. + +Vediamo come funziona + +{% 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!") +``` + +Non devi scrivere un commento per ogni riga di codice, ma sono utili per spiegare perché il tuo codice sta facendo qualcosa, o fornire un riepilogo quando sta facendo qualcosa di complesso. + ### Indice Nei tre esercizi precedenti hai imparato: -* come **confrontare le cose** - in Python puoi mettere a confronto le cose usando `>`, `>=`, `==`, `<=`, `<` e gli operatori `e`, `o` -* i **Boolean** - una tipologia di oggetto che può avere solo uno di questi due valori: `True` o `False` -* come **Salvare file** - archiviare codice nei file in modo da poter eseguire programmi più lunghi. -* **if...elif...else** - affermazioni che ti permettono di eseguire codice solo quando vengono incontrate certe condizioni. +- come **confrontare le cose** - in Python puoi mettere a confronto le cose usando `>`, `>=`, `==`, `<=`, `<` e gli operatori `e`, `o` +- i **Boolean** - una tipologia di oggetto che può avere solo uno di questi due valori: `True` o `False` +- come **Salvare file** - archiviare codice nei file in modo da poter eseguire programmi più lunghi. +- **if...elif...else** - affermazioni che ti permettono di eseguire codice solo quando vengono incontrate certe condizioni. +- **commenti** - linee che Python non verrà eseguito che ti permettono di documentare il tuo codice -È ora dell'ultima parte del capitolo! +E' ora dell'ultima parte del capitolo! ## Le funzioni personalizzate! +> Per i lettori da casa: questa parte si trova nel video [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0). + Ti ricordi quelle funzioni che puoi eseguire in Python come `len()`? Beh, buone notizie, ora imparerai a scrivere delle funzioni tutte tue! -Una funzione è una sequenza di istruzioni che Python dovrebbe eseguire. Ogni funzione in Python inizia con la parola chiave `def`, viene assegnato un nome e può avere alcuni parametri. Iniziamo con una facile. Sostituisci il codice nel file **python_intro.py** con il seguente: +Una funzione è una sequenza di istruzioni che Python dovrebbe eseguire. Ogni funzione in Python inizia con la parola chiave `def`, viene assegnato un nome e può avere alcuni parametri. Diamo un colpo. Sostituisci il codice nel file **python_intro.py** con il seguente: + +{% filename %}python_intro.py{% endfilename %} ```python def ciao(): @@ -625,16 +864,26 @@ ciao() Okay, la nostra prima funzione è pronta! -Ti starai chiedendo perché abbiamo scritto il nome della funzione alla fine del file. Perché Python legge il file e lo esegue dall'alto verso il basso. Quindi per poter utilizzare la nostra funzione, dobbiamo riscriverla alla fine. +Ti starai chiedendo perché abbiamo scritto il nome della funzione alla fine del file. Quando scriviamo `def hi():` e le seguenti linee indentate, questi siamo noi che scriviamo le istruzioni per cosa dovrebbe fare la funzione `hi()`. Python leggerà e ricorderà queste istruzioni, ma ancora non eseguirà la funzione. Per dire a Python che vogliamo eseguire la funzione, dobbiamo chiamare la funzione con `hi()`. Python legge il file e lo esegue dall'alto verso il basso, così che dobbiamo definire la funzione nel file prima di chiamarla. Eseguiamolo e vediamo cosa succede: +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Ciao! Come stai? -È stato facile! Costruiamo la nostra prima funzione con parametri. Useremo l'esempio precedente - una funzione che dice 'ciao' alla persona che lo esegue - aggiungendo il nome: +Nota: se non ha funzionato, non panicare! L'output ti aiuterà a capire perché: + +- Se ottieni un `NameError`, questo probabilmente significa che hai digitato qualcosa di sbagliato, quindi dovresti controllare che tu abbia usato lo stesso nome quando crei la funzione con `def hi():` e quando lo chiamate con `hi()`. +- Se ottieni un `IndentaionError`, controlla che entrambe le linee `print` abbiano lo stesso spazio bianco all'inizio di una linea: python vuole che tutto il codice all'interno della funzione sia allineato in modo adeguato. +- Se non c'è nessun output, controlla che l'ultima `hi()` *non sia indentato* se è così, questa linea diventerà parte della funzione, e non verrà mai eseguita. + +E' stato facile! Costruiamo la nostra prima funzione con parametri. Useremo l'esempio precedente - una funzione che dice 'ciao' alla persona che lo esegue - aggiungendo il nome: + +{% filename %}python_intro.py{% endfilename %} ```python def ciao(nome): @@ -642,6 +891,8 @@ def ciao(nome): Come puoi vedere, abbiamo dato alla nostra funzione un parametro chiamato `nome`: +{% filename %}python_intro.py{% endfilename %} + ```python def ciao(nome): if nome == 'Ola': @@ -656,45 +907,59 @@ ciao() Ricorda: La funzione `print` è rientrata di 4 spazi rispetto allo statement `if`. Infatti, la funzione viene eseguita quando la condizione viene soddisfatta. Vediamo ora come funziona: +{% filename %}{{ warning_icon }} command-line{% endfilename %} + $ python3 python_intro.py Traceback (most recent call last): File "python_intro.py", line 10, in - ciao() + hi() TypeError: ciao() missing 1 required positional argument: 'nome' Ops, un errore. Fortunatamente, Python ci fornisce un messaggio di errore che ci può servire. Ci dice che la funzione `ciao()` (quella che abbiamo definito) ha un argomento richiesto (chiamato `nome`) e che ci siamo dimenticati di metterlo quando abbiamo chiamato la funzione. Sistemiamolo alla fine del file: +{% filename %}python_intro.py{% endfilename %} + ```python ciao("Ola") ``` Ed eseguiamo di nuovo: +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Ciao Ola! E se cambiamo il nome? +{% filename %}python_intro.py{% endfilename %} + ```python ciao("Sonja") ``` Ed eseguilo: +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Ciao Sonja! Ora, cosa pensi che succederà se scrivi un altro nome? (non Ola o Sonja) Provaci e vedi se la tua ipotesi è giusta. Dovrebbe stampare questo: +{% filename %}command-line{% endfilename %} + Ciao anonimo! Fantastico, vero? In questo modo non devi ripetere tutto ogni volta che vuoi modificare il nome della persona che la funzione dovrebbe salutare. Ed è esattamente per questo che abbiamo bisogno delle funzioni - non vuoi ripetere il tuo codice! -Facciamo una cosa più intelligente -- ci sono più di due nomi, e scrivere una condizione per ognuno sarebbe complicato, vero? +Facciamo qualcosa di più intelligente – ci sono più nomi di due, e scrivere una condizione per ciascuno sarebbe difficile, giusto? Sostituisci il contenuto del tuo file con i seguenti: + +{% filename %}python_intro.py{% endfilename %} ```python def ciao(nome): @@ -705,46 +970,58 @@ ciao("Rachel") Ora chiamiamo il codice: +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Ciao Rachel! -Congratulazioni! Hai appena imparato a scrivere delle funzioni :) +Complimenti! Hai appena imparato a scrivere le funzioni! :) ## Loop +> Per i lettori da casa: questa parte si trova nel video [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0). + È l'ultima parte. Abbiamo fatto in fretta, vero? :) I programmatori non amano ripetere ciò che scrivono. La programmazione mira a automatizzare le cose, non vorremo mica salutare ognuno col suo nome manualmente? Ecco un caso in cui i loop ci tornano comodi. Ti ricordi ancora delle liste? Facciamo una lista di ragazze: +{% filename %}python_intro.py{% endfilename %} + ```python ragazze = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'Tu'] ``` Vogliamo salutare tutte loro per nome. Abbiamo la funzione `ciao` per farlo, quindi usiamola in loop: +{% filename %}python_intro.py{% endfilename %} + ```python -for nome in ragazze: +for name in girls: ``` -Lo statement `for` si comporta in modo simile allo statement `if`; il codice sottostante deve essere rientrato di quattro spazi. +Lo statement ~~~ for~~~ si comporta in modo simile allo statement ~~~ if~~~; il codice sottostante deve essere rientrato di quattro spazi. Qua c'è l'intero codice che sarà nel file: +{% filename %}python_intro.py{% endfilename %} + ```python def ciao(nome): - print('Ciao ' + nome + '!') + print('Ciao ' + nome + '!') -ragazze = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'Tu'] -for nome in ragazze: - ciao(nome) +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'Tu'] +for name in girls: + ciao(name) print('Prossima ragazza') ``` E quando lo eseguiamo: +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py Ciao Rachel! Prossima ragazza @@ -762,6 +1039,8 @@ Come puoi vedere, tutto quello che metti all'interno di un `for` statement con u Puoi anche utilizzare `for` su numeri usando la funzione `range`: +{% filename %}python_intro.py{% endfilename %} + ```python for i in range(1, 6): print(i) @@ -769,6 +1048,8 @@ for i in range(1, 6): Che stamperà: +{% filename %}command-line{% endfilename %} + 1 2 3 @@ -784,6 +1065,8 @@ Nota che il secondo di questi due numeri non è incluso nella lista prodotta da È tutto. **Sei grande!** Questo capitolo non era affatto facile, puoi essere orgogliosa di te stessa. Noi siamo fierissimi di te per avercela fatta fino a qui! +Per il tutorial ufficiale e completo di python visita https://docs.python.org/3/tutorial/. Questo ti darà uno studio più completo e completo della lingua. Saluti! :) + Potresti desiderare di fare brevemente qualcos'altro - stiracchiati, fai due passi, riposa gli occhi - prima di continuare con il prossimo capitolo. :) -![Cupcake](images/cupcake.png) +![Cupcake](images/cupcake.png) \ No newline at end of file diff --git a/it/python_introduction/images/cupcake.png b/it/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/it/python_introduction/images/cupcake.png and b/it/python_introduction/images/cupcake.png differ diff --git a/it/template_extending/README.md b/it/template_extending/README.md index 6ceef47e2db..5e06e2be4fd 100644 --- a/it/template_extending/README.md +++ b/it/template_extending/README.md @@ -2,11 +2,11 @@ Un'altra cosa bella di Django è l'**estensione del template**. Cosa significa? Significa che puoi usare le stesse parti del tuo HTML per pagine diverse del tuo sito. -Così non hai bisogno di ripetere le stesse informazioni/layout in ogni file. E se vuoi cambiare qualcosa, non devi cambiarlo in ogni templates, ma soltanto una volta! +I template ti aiutano quando vuoi usare le stesse informazioni o gli stessi layout in pagine diverse. Non devi ripetere lo stesso codice in ogni file. E se vuoi cambiare qualcosa, non lo devi fare in ogni template, ma solo in uno! -## Crea un template di base +## Creare un template di base -Un template base è il template più semplice. Lo puoi estendere su ogni pagina del tuo sito. +Un template di base è il template più semplice. Lo puoi estendere ad ogni pagina del tuo sito. Creiamo un file `base.html` in `blog/templates/blog/`: @@ -17,107 +17,135 @@ Creiamo un file `base.html` in `blog/templates/blog/`: post_list.html -Poi aprilo e copia tutto da `post_list.html` e incollalo sul file `base.html`, così: +Poi aprilo nell'editor di codice e copia tutto da `post_list.html` al file `base.html`, in questo modo: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} + Django Girls blog - - + - + -
+
-
+
{% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %}
-
+
``` Poi nel `base.html`, rimpiazza tutto il tuo `` (tutto quello che si trova tra `` e ``) con questo: +{% filename %}blog/templates/blog/base.html{% endfilename %} + ```html - -
+ +
-
+
{% block content %} {% endblock %}
-
+
``` -Abbiamo praticamente rimpiazzato tutto quello tra `{% for post in posts %}{% endfor %}` con: +{% raw %}Potresti aver notato che questo sostituisce tutto da `{% for post in posts %}` a `{% endfor %}` con: {% endraw %} + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% block content %} {% endblock %} ``` -Che cosa significa? Che hai appena creato un `blocco`, ovvero un tag di template che ti permette di inserire l'HTML presente in questo blocco all'interno di altri template che estendono `base.html`. Ti mostreremo come farlo tra un attimo. +Perchè? Hai appena creato un blocco! Hai appena usato un template tag `{% block %}` per creare un area che che avrà dell'HTML all'interno. Questo codice HTML verrà da altri template che estenderanno questo (`base.html`). Ti mostreremo come farlo tra un attimo. + +Ora salva `base.html` e apri di nuovo il tuo `blog/templates/blog/post_list.html` nell'editor di codice. {% raw %}Rimuovi tutto quello che c'è prima di `{% for post in posts %}` e dopo `{% endfor %}`. Quando hai finito, il file apparirà così:{% endraw %} -Ora salvalo, e apri il tuo `blog/templates/blog/post_list.html` di nuovo. Cancella tutto quello che non è all'interno del body e poi cancella anche ``, in modo che il file appaia così: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} ``` -Ed ora aggiungi questa riga all'inizio del file: +Vogliamo usare questa parte del nostro template per ogni blocco per i contenuti. Aggiungiamo un tag block in questo file! -```python -{% extends 'blog/base.html' %} +{% raw %}Dobbiamo fare in modo che il tuo tag block combaci con quello nel tuo file`base.html`. Dobbiamo anche includere tutto il codice del blocco dei contenuti. Per farlo, metti tutto tra `{% block content %}` e `{% endblock %}`. Come questo:{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% block content %} + {% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} ``` -{% raw %}Significa che stiamo estendendo il template `base.html` in `post_list.html`. Rimane solo una cosa da fare: metti tutto (tranne la riga che abbiamo appena aggiunto) tra `{% block content %}` e `{% endblock content %}`. Come questo:{% endraw %} +Un'ultima cosa. Dobbiamo collegare questi due template. È questo che vuol dire estendere i template! Lo faremo aggiungendo un tag extends all'inizio del file. Così: + +{% 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 content %} +{% endblock %} ``` -È tutto! Controlla se il tuo sito sta ancora funzionando correttamente :) +Ecco fatto! Salva il file e controlla se il tuo sito web funziona ancora correttamente. :) -> Se hai un errore `TemplateDoesNotExists` che dice che non c'è un file `blog/base.html` e hai `runserver` in esecuzione nella console, prova a fermarlo (premendo Ctrl+C - I tasti Control e C insieme) e riavvialo mettendo in esecuzione il comando `python manage.py runserver`. \ No newline at end of file +> Se ottieni l'errore `TemplateDoesNotExist`, significa che non c'è nessun file `blog/base.html` e `runserver` è in esecuzione nella console. Prova ad arrestarlo (premendo Ctrl+C, i tasti Control e C insieme) e riavvialo utilizzando il comando `python manage.py runserver`. \ No newline at end of file diff --git a/it/whats_next/README.md b/it/whats_next/README.md index 2a4ea36c1a6..4dcb13c2e48 100644 --- a/it/whats_next/README.md +++ b/it/whats_next/README.md @@ -1,39 +1,43 @@ # Quali sono le prospettive? -Complimenti! **Sei veramente incredibile**. Siamo orgogliosi! < 3 +Complimenti! **Sei veramente incredibile**. Siamo orgogliosi! <3 -### Cosa si fa ora? +### E ora cosa si fa? -Prenditi una pausa e rilassati. Hai veramente fatto un passo da gigante. +Per prima cosa: Pausa, Relax! Hai veramente appena fatto passi da gigante. -Dopo di che, assicurati di: +Dopodichè, assicurati di seguire Django Girls in [ Facebook ](http://facebook.com/djangogirls) o [ Twitter](https://twitter.com/djangogirls) per restare aggiornata. -* Seguire Django Girls su [Facebook][1] o [Twitter][2] per rimanere aggiornata +### Mi puoi consigliare ulteriori risorse? - [1]: http://facebook.com/djangogirls - [2]: https://twitter.com/djangogirls +Ma certo che sì! C'è una quantità *enorme* a dir poco, di risorse online per imparare i vari aspetti della programmazione — da farti perdere l'orientamento, tanto da impedirti di decidere in che direzione andare. Le Django Girls ti hanno preparato una selezione. Qualunque fosse il tuo interesse prima di iniziare questo tutorial, e qualunque sia l'interesse che questo tutorial ha maggiormente stimolato in te, qui ci sono un paio di risorse libere (o risorse con buona parte libera) per tornare ad orientarti, ed andare nella direzione che t'interessa. -### Mi puoi consigliare ulteriori risorse? +#### Django + +- Il nostro altro libro, [Django Girls Tutorial: Estensioni](https://tutorial-extensions.djangogirls.org/) +- [Il tutorial ufficiale di Django's](https://docs.djangoproject.com/en/2.2/intro/tutorial01/) +- [Le lezioni video su come incominciare con Django](http://www.gettingstartedwithdjango.com/) +- [Django for Everybody Specialization](https://www.coursera.org/specializations/django) – alcune lezioni a video possono essere viste gratuitamente e, seguendoli, puoi ottenere un Certificato Coursera + +#### HTML, CSS e JavaScript + +- [Corso di sviluppo web di Codecademy](https://www.codecademy.com/learn/paths/web-development) +- [freeCodeCamp](https://www.freecodecamp.org/) + +#### Python + +- [Corso Python di Codecademy](https://www.codecademy.com/learn/learn-python) +- [Corso Python di Google](https://developers.google.com/edu/python/) +- [Libro: Impara Python The Hard Way](http://learnpythonthehardway.org/book/) – gli esercizi iniziali sono gratuiti +- [Nuovi tutorial di Coder](http://newcoder.io/tutorials/) – Questo è una serie di esempi pratici di come utilizzare Python +- [edX](https://www.edx.org/course?search_query=python) – puoi controllare la maggior parte dei corsi gratuiti, ma se si desidera un certificato o crediti verso una qualifica di istruzione superiore, allora questo costerà denaro +- [specializzazione Python di questa persona](https://www.coursera.org/specializations/python) – alcune lezioni video possono essere revisionate gratuitamente e puoi ottenere un certificato di Coursera seguendo questi corsi +- [Python per tutti](https://www.py4e.com/) - una versione libera e aperta del Coursera Python per la specializzazione di tutti i corpi + +#### Lavorare con i dati + +- [Corso di informatica di Codecademy](https://www.codecademy.com/learn/paths/data-science) +- [edX](https://www.edx.org/course/?search_query=python&subject=Data%20Analysis%20%26%20Statistics) – puoi controllare la maggior parte dei corsi gratuiti, ma se si desidera un certificato o crediti verso una qualifica di istruzione superiore, allora questo costerà denaro +- [Dataquest](https://www.dataquest.io/) – le prime 30 "missioni" sono gratuite -Si! Vai avanti e prova il nostro libro dal titolo [Django Girls Tutorial: estensioni][3]. - - [3]: http://djangogirls.gitbooks.io/django-girls-tutorial-extensions/ - -Più avanti potrai provare le risorse elencate qui sotto. Sono tutte molto consigliate! -- [Django - tutorial ufficiale][4] -- [Tutorial per i nuovi Coder][5] -- [Corso Code Academy Python][6] -- [Corso Code Academy HTML & CSS][7] -- [Tutorial Django Carrots][8] -- [Il libro "Learn Python The Hard Way"][9] -- [Lezioni video "Inizia con Django"][10] -- [Il libro "Two Scoops of Django: Best Practices for Django 1.8 book"][11] - - [4]: https://docs.djangoproject.com/en/1.8/intro/tutorial01/ - [5]: http://newcoder.io/tutorials/ - [6]: https://www.codecademy.com/en/tracks/python - [7]: https://www.codecademy.com/tracks/web - [8]: https://github.com/ggcarrots/django-carrots - [9]: http://learnpythonthehardway.org/book/ - [10]: http://gettingstartedwithdjango.com/ - [11]: https://twoscoopspress.com/products/two-scoops-of-django-1-8 +Non possiamo aspettare di vedere cosa costruirai in seguito! \ No newline at end of file diff --git a/ja/GLOSSARY.md b/ja/GLOSSARY.md new file mode 100644 index 00000000000..591c8c621e7 --- /dev/null +++ b/ja/GLOSSARY.md @@ -0,0 +1,3 @@ +# コードエディタ + +コードエディタはコードを保存して後から戻ってこれるようにできるアプリケーションです。 [コードエディタの章](./code_editor/README.md)で、どこから入手できるか知ることができます。 \ No newline at end of file diff --git a/ja/README.md b/ja/README.md new file mode 100644 index 00000000000..165147d1c7e --- /dev/null +++ b/ja/README.md @@ -0,0 +1,51 @@ +# Django Girls のチュートリアル + +[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial) + +> これは、Creative Commons Attribution-ShareAlike 4.0 International License のライセンスの下で提供しています。ライセンスについてはこちらをご確認ください。 https://creativecommons.org/licenses/by-sa/4.0/ + +## ウェルカム! + +Django Girlsのチュートリアルにようこそ! お会いできて嬉しいです :) このチュートリアルでは、ウェブテクノロジーの中身を見て回る旅へあなたをお連れします。私たちが知っているようにウェブを動かすのに必要なものすべてを垣間見ることができるでしょう。 + +知らないことを学ぶことは冒険のようなものです - でも心配はいりません。あなたはすでに勇気を出してここにいらっしゃるのですから、きっとうまくいくでしょう :) + +## はじめに + +世界のますます色々なところに自分が(まだ)知らないテクノロジーが使われていると感じたことはありませんか? ウェブサイトはどうやって作るのだろうと興味をもちつつ、先延ばしにしていませんか? ソフトウェアの世界は複雑すぎて一人でなにかに取り組むことはできないと考えたことはありませんか? + +そんなあなたに朗報です!プログラミングはそれほど難しくありませんよ。楽しみかたをお教えします!! + +このチュートリアルは、魔法のようにあなたをプログラマーに変身させるものではありません。 上手くなりたかったら、何ヶ月あるいは何年もの勉強と練習を積まなければいけません。 しかし、プログラミングやウェブサイトを作成することは、あなたが思っているほど複雑ではないことを、このチュートリアルをとおして示したいと思います。 テクノロジーをコワイと感じないように、できるだけ細かく説明していきますね。 + +あなたがテクノロジーやプログラミングを楽しんでくれると嬉しいです!! + +## チュートリアルでは何を知ることができる? + +このチュートリアルを終わらせれば、実際に動作する、自分の小さなウェブアプリを1つ動かせるようになります。私たちは、アプリをインターネット上で動かす方法を教えます。インターネット上で動くようになれば、あなたが作ったアプリを世界中の誰でも見られるようになります! + +このようなサイトができあがります!: + +![図 0.1](images/application.png) + +> もしあなたがこのチュートリアルを1人ですすめていて、質問できるコーチが周りにいない時は、ここにチャットを用意しています:[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial) これまでにワークショップに参加したことがある方やコーチの皆さんが、このチャットで助けてくれることでしょう。 心配せずに、質問をなげかけてみてくださいね! + +それでは、[さっそく最初からやってみよう!](./how_the_internet_works/README.md) + +## 自分の家でチュートリアルを進める + +Django Girlsのワークショップに参加することはすばらしいことです。でも、いつも参加できるとは限らないですよね。 でしたら、ご自宅でこのチュートリアルに取り組むことをおすすめします。 ご自宅で取り組まれる方向けに、チュートリアルを一人で進めやすくする動画の準備を進めています。 動画の準備は進行中ですが、YouTubeチャンネル [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed) ですぐにますます多くのことがカバーされるでしょう。 + +動画がすでに準備された章には、動画へのリンクがあります。 + +## コントリビューションについて + +このチュートリアルは、[DjangoGirls](https://djangogirls.org/) がメンテナンスしています。 ミスを見つけたりチュートリアルを更新したくなった時は、[コントリビューション・ガイドライン](https://github.com/DjangoGirls/tutorial/blob/master/README.md)を読んでください。 + +## チュートリアルの翻訳をしたい方へ + +現在、翻訳は crowdin.com の次のプロジェクトで管理されています。 + +https://crowdin.com/project/django-girls-tutorial + +あなたが翻訳したい言語が [crowdin](https://crowdin.com/) にない時は、[新しい issue を立て](https://github.com/DjangoGirls/tutorial/issues/new)て、追加したい言語を私たちに教えてください。 \ No newline at end of file diff --git a/ja/SUMMARY.md b/ja/SUMMARY.md new file mode 100644 index 00000000000..8a92ce208be --- /dev/null +++ b/ja/SUMMARY.md @@ -0,0 +1,35 @@ +# 概要 + +* [はじめに](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) + * [PythonAnywhere](installation/README.md#pythonanywhere) +* [Chromebookのセットアップ](chromebook_setup/README.md) +* [インターネットのしくみ](how_the_internet_works/README.md) +* [コマンドラインを使ってみよう](intro_to_command_line/README.md) +* [Pythonのインストール](python_installation/README.md) +* [コードエディタ](code_editor/README.md) +* [Python入門](python_introduction/README.md) +* [Djangoってなに?](django/README.md) +* [Djangoのインストール](django_installation/README.md) +* [プロジェクトを作成しよう!](django_start_project/README.md) +* [Djangoモデル](django_models/README.md) +* [ログインページを作ろう(Django admin)](django_admin/README.md) +* [デプロイ!](deploy/README.md) +* [Django URL](django_urls/README.md) +* [Djangoビュー](django_views/README.md) +* [HTML 入門](html/README.md) +* [Django ORM(クエリセット)](django_orm/README.md) +* [テンプレート内の動的データ](dynamic_data_in_templates/README.md) +* [Djangoテンプレート](django_templates/README.md) +* [CSSでカワイくしよう](css/README.md) +* [テンプレートを拡張しよう](template_extending/README.md) +* [アプリケーションを拡張しよう](extend_your_application/README.md) +* [Djangoフォーム](django_forms/README.md) +* [次のステップは?](whats_next/README.md) \ No newline at end of file diff --git a/ja/chromebook_setup/README.md b/ja/chromebook_setup/README.md new file mode 100644 index 00000000000..ff6832e668e --- /dev/null +++ b/ja/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# Chromebook のセットアップ + +> **注意**既にインストール手順を実行している場合は、これをやり直す必要はありません。すぐにスキップして[ Python入門](../python_introduction/README.md)へ進んでください。 + +{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/ja/chromebook_setup/instructions.md b/ja/chromebook_setup/instructions.md new file mode 100644 index 00000000000..0cec44e70f1 --- /dev/null +++ b/ja/chromebook_setup/instructions.md @@ -0,0 +1,73 @@ +Chromebookを使わない場合は、このセクションを飛ばして、[Pythonのインストール](http://tutorial.djangogirls.org/en/installation/#install-python) に進んでください。 もし利用している場合は、普通のインストールの作業とは少し異なります。 インストール手順の残りの部分は無視できます。 + +### クラウドIDE (PaizaCloud Cloud IDE, AWS Cloud9) + +クラウドIDEはコードエディタと、インターネットにつながって動作し、ソフトウェアをインストールしたり、書いたり、実行したりできるコンピュータへのアクセスを提供するツールです。 チュートリアルを通して、クラウドIDEはまるであなたの*ローカルマシン*のように動作するでしょう。 みんながmacOSやUbuntuやWindowsでやるのと同じようにターミナルからコマンドを実行できますが、そのターミナルはクラウドIDEが準備したどこかのコンピュータに接続されています。 さて、いろいろなクラウドIDE(PaizaCloud Cloud IDE, AWS Cloud9)について見ていきましょう。 クラウドIDEのうちどれかを選んで、指示に従ってください。 + +#### PaizaCloud Cloud IDE + +1. [PaizaCloud Cloud IDE](https://paiza.cloud/) へ移動します。 +2. アカウントを登録します。 +3. *新規サーバ作成* をクリックして、Djangoを選択してください。 +4. (ウィンドウの左側にある)「ターミナル」をクリックします。 + +左側にサイドバーといくつかボタンのある画面が見えていると思います。 「ターミナル」ボタンをクリックして、下記のようなプロンプトが表示されたターミナルウィンドウを開いてください: + +{% filename %}Terminal{% endfilename %} + + $ + + +これでPaizaCloud Cloud IDEのターミナルは準備できました。 ウィンドウを大きくしたいときは、サイズを変えたり最大化したりできますよ。 + +#### AWS Cloud9 + +現在、Cloud 9 はAWSのアカウント作成とクレジットカード情報の登録が必須になっています。 + +1. [Chrome ウェブストア](https://chrome.google.com/webstore/detail/cloud9/nbdmccoknlfggadpfkmcpnamfnbkmkcp)から、Cloud 9 をインストールしてください。 +2. [c9.io](https://c9.io)に行って、*AWS Cloud9をはじめる* をクリックしてください。 +3. AWSアカウントを作成してください。(クレジットカード情報の登録が必要ですが、このチュートリアルは無料利用枠で進めることができます。) +4. AWSのダッシュボードを開き、検索ボックスで *Cloud9* と入力し選択してください。 +5. Cloud9のダッシュボードで、*Create environment (環境の作成)* を選択します。 +6. 名前は *django-girls* としておきましょう。 +7. ”Configure settings (設定の構成)”のステップでは、”Environment Type (環境タイプ)”に *Create a new instance for environment (EC2) (新しいインスタンスを作成する (EC2))* を、”Instance type (インスタンスタイプ)”に *t2.micro* を選択します("Free-tier eligible (無料利用枠で利用できる)" と書かれているはずです)。 ”Cost-saving setting (コスト削減の設定)”はデフォルトの選択のままにします。その他の設定もデフォルトにしておきましょう。 +8. *Next step (次のステップ)* を選択します。 +9. *Create environment (環境の作成)* を選択します。 + +サイドバー、文章が書かれた大きなメインウィンドウ、そして下部にはこのような小さなウィンドウが表示されています: + +{% filename %}bash{% endfilename %} + + yourusername:~/workspace $ + + +この下の部分が、あなたのターミナルです。このターミナルから、遠くにあるCloud 9のコンピュータに指示を送ることができます。ウィンドウのサイズを変更して少し大きくすることもできます。 + +### 仮想環境 + +仮想環境 (virtualenvとも呼ばれます) は、取り組んでいるプロジェクト用に、便利なコードを詰め込んでおけるプライベートボックスのようなものです。 様々なプロジェクトの様々なコードがプロジェクト間で混ざってしまわないように、仮想環境を使います。 + +以下を1行ずつ実行してください: + +{% filename %}Cloud 9{% endfilename %} + + mkdir djangogirls + cd djangogirls + python3.6 -mvenv myvenv + source myvenv/bin/activate + pip install django~={{ book.django_version }} + + +(最後の行は`~=`とチルダに続けてイコール記号をつけることに注意してください) + +### GitHub + +[GitHub](https://github.com)アカウントを作成してください。 + +### PythonAnywhere + +Django Girls チュートリアルには、デプロイと呼ばれるセクションが含まれています。これはあなたの新しいWebアプリケーションの原動力となるコードを取得して、それを公にアクセス可能なコンピュータ(サーバーと呼ばれます)に移動するプロセスです。これにより、あなたの作ったものを他の人が見られるようになります。 + +Chromebookでチュートリアルを行うとき、(例えばラップトップとは対照的に)インターネットに接続されているコンピュータをすでに使用しているので、この作業は少し変な感じがします。 しかし、Cloud 9のワークスペースを「開発中」の場所、PythonAnywhere をより完成したものを披露する場所として考えると役に立ちます。 + +したがって、[www.pythonanywhere.com](https://www.pythonanywhere.com) へ行って、PythonAnywhereの新規アカウントを作成してください。 \ No newline at end of file diff --git a/ja/code_editor/README.md b/ja/code_editor/README.md new file mode 100644 index 00000000000..39a5576f1c2 --- /dev/null +++ b/ja/code_editor/README.md @@ -0,0 +1,11 @@ +# コードエディタ + +> 家で1人でこのチャプターに挑戦している方へ:このチャプターは、動画(英語)もあるので参考にしてください。 [Your new friend: Command Line](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s) + +まさにこれから、はじめてのコードを書いていきます。コードエディタをダウンロードしましょう! + +> **補足:** Chromebookを使っている方は、このチャプターは飛ばして、 [Chromebookのセットアップ](../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/ja/code_editor/instructions.md b/ja/code_editor/instructions.md new file mode 100644 index 00000000000..7f961410224 --- /dev/null +++ b/ja/code_editor/instructions.md @@ -0,0 +1,37 @@ +本当にたくさんのエディタがありますが、どれを使うかは、結局は、ほとんど個人の好みの問題です。 ほとんどのPythonプログラマは、PyCharmなど、複雑ですが非常に強力なIDE(統合開発環境)というものを使っています。 しかし、初心者にとってはIDEはそれほど適していないかもしれないので、同じくらい強力で、もっとシンプルなものをオススメします。 + +オススメのエディタは下記に挙げますが、気軽にコーチに質問して好みや特徴ををきいてみてください。 + +## Visual Studio Code + +Visual Studio Codeは、マイクロソフトがWindowsとLinuxとmacOS向けに開発したソースコードエディタです。 デバッグのサポート、組み込まれたGit操作、シンタックスハイライト、かしこいコード補完、スニペット、リファクタリングなど多くの機能があります。 + +[ダウンロード](https://code.visualstudio.com/) + +## Gedit + +Gedit は、オープンソースの無料エディタで、全てのOSで利用可能です。 + +[ダウンロード](https://wiki.gnome.org/Apps/Gedit#Download) + +## Sublime Text + +Sublime Text はとても人気のあるエディタで、無料の試用期間があります。全てのOSに対応しています。  + +[ダウンロード](https://www.sublimetext.com/) + +## Atom + +Atomも人気のあるエディタで、無料でオープンソース、そしてWindows、macOS、Linuxで利用可能です。Atomは[GitHub](https://github.com/)が開発しています。 + +[ダウンロード](https://atom.io/) + +## なんでコードエディタをインストールするの? + +なぜWordやNotepadのようなものを使わず、特別なコードエディタをインストールする必要があるのかな、と思うかもしれません。 + +まずひとつ目の理由として、コードは**プレーンテキスト**という、何の装飾もない文字列でないといけません。問題は、WordやTexteditのようなプログラムが生成するのは、実は、プレーンテキストではないということなんです。WordやTexteditは、[RTF(リッチテキストフォーマット)](https://en.wikipedia.org/wiki/Rich_Text_Format)などのような独自の形式を使って、リッチテキスト(フォントや書式を持った文字列)を生成します。 + +2つ目の理由は、コードエディタは、コードを編集することに特化しているので、コードを意味によって色づけして強調したり、引用符を自動的に閉じたりするような、便利な機能があります。 + +あとで使ってみて、こういった機能が全てわかるようになります。すぐに、信頼できる使い慣れたコードエディタが、お気に入りのツールになると思いますよ^^ diff --git a/ja/css/README.md b/ja/css/README.md new file mode 100644 index 00000000000..34dfdf55505 --- /dev/null +++ b/ja/css/README.md @@ -0,0 +1,305 @@ +# CSSでカワイくしよう! + +ブログは作ったものの、まだなんかダサいですよね。かわいくしましょう! そのためにはCSSを使います。 + +## CSSとは? + +Cascading Style Sheets (CSS)とは、HTMLなどのマークアップ言語で書かれたWebサイトの見た目や書式を記述するための言語です。私達のWebページをメイクアップするものとして使います。 + +でも、またゼロから作りたくないですよね。プログラマーたちがすでに作って無料で公開しているツールを使いましょう。わざわざイチから作り直す必要はないですからね。 + +## Bootstrapを使いましょう! + +Bootstrap は美しいWebサイトを開発するためのHTMLとCSSのフレームワークとしてとても有名です: http://getbootstrap.com/ + +これは、もともとTwitterのプログラマーが作成したもので、今は、世界中の有志のボランティアで開発されています。 + +## Bootstrapのインストール + +Bootstrap をインストールするため、`.html` ファイル (blog/templates/blog/post_list.html) をコードエディタで開き `` の中にこれを追加しましょう: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + +``` + +これは、あなたのプロジェクトにファイルを追加しているわけではありません。インターネット上にあるファイルを指しているだけです。では、Webサイトを開いてページを再読み込みしてください。 + +![図 14.1](images/bootstrap1.png) + +これだけでずいぶん見た目が良くなりましたね! + +## Djangoの静的ファイル + +最後に、**静的ファイル**と呼ばれるものを詳しく見ていきましょう。 静的ファイルとは、CSSファイルや画像ファイルといった、動的な変更が発生しないファイルのことです。 そのため、これらのファイルはリクエストに依存せず、どのユーザに対しても中身は同じになります。 + +### 静的ファイルはプロジェクトのどこに置けばいいの? + +Djangoは、ビルトインの "admin" アプリにより、静的ファイルをどこで探せばいいのかわかっています。私たちがやることは、`blog` アプリのための静的ファイルを追加することだけです。 + +そのために、blogアプリの中に `static` というフォルダを作ります。 + + djangogirls + ├── blog + │ ├── migrations + │ ├── static + │ └── templates + └── mysite + + +Djangoは、全てのアプリのフォルダ内の "static" と名づけられた全てのフォルダを自動的に探して、その中身を静的ファイルとして使えるようにします。 + +## 最初のCSSファイル! + +CSSファイルを作って、Webサイトにあなたのスタイルを設定していきましょう。 `static` ディレクトリの中に `css` というディレクトリを作成しましょう。 そして、その `css` ディレクトリの中に `blog.css` という新規ファイルを作ります。 準備OK? + + djangogirls + └─── blog + └─── static + └─── css + └─── blog.css + + +ついにCSSを書くときが来ました! コードエディタで `blog/static/css/blog.css` ファイルを開きましょう。 + +ここではCSSのカスタマイズや学習方法については詳しく説明しません。さらに知りたい場合は、このページの最後に無料のCSSの学習コースを紹介していますので、そちらを参考にしてください。 + +ただ、せめて少しはここでやってみましょう。 ヘッダーの色を変えてみるのもいいかもしれませんね。 色を理解するために、コンピュータは特殊なコードを使います。 コードは、`#` で始まり、6種類のアルファベット(A-F)や数字(0-9)が続きます。 たとえば、青色のコードは `#0000FF` です。 カラーコードのサンプルはこのサイト http://www.colorpicker.com/ で確認できます。 `red` や `green` といった[定義済みの色](http://www.w3schools.com/colors/colors_names.asp)を利用することもできます. + +`blog/static/css/blog.css` ファイルに、次のコードを追加しましょう。 + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +h1 a, h2 a { + color: #C25100; +} + +``` + +`h1 a` はCSSセレクタと呼ばれるものです。 これは、`h1`要素内の`a`要素にスタイルを適用していることを意味します。 `h2 a`セレクタは、`h2`要素に対して同じことを行います。 よって `

link

`となっているとき、 `h1 a` スタイルが適用されます。 この場合、その要素を `#C25100` に、つまり濃いオレンジ色にしようとしています。 あるいは、あなたの好きな色を設定することができますが、それが白い背景に対して良いコントラストを持つことを確認しましょう! + +CSSファイルには、HTMLファイルの各要素のスタイルを指定していきます。 まずは要素名でもって、その要素を識別します。 HTMLのタグ名は覚えがあるでしょう。 例えば `a`, `h1`, `body` などが要素名の例です。 また、`class` 属性や、`id` 属性によって要素を識別することができます。 classやidは、あなたが自分で要素につけることができる名前です。 classは要素のグループを定義して、idは特定の要素を指定します。 例えば、次のタグは、タグ名 `a`、class名 `external_link`、id名 ` link_to_wiki_page`、どれを使ってもCSSによって識別されます。 + +```html + +``` + +CSSセレクタについては[CSS Selectors in w3schools](http://www.w3schools.com/cssref/css_selectors.asp)を見てください。 + +さて、CSSを追加したことをHTMLテンプレートに教えないといけません。`blog/templates/blog/post_list.html` を開いて、先頭にこの行を追加しましょう: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% load static %} +``` + +これで、このテンプレートに静的ファイルを読み込むことができました^^。そして、`` と `` の中にあるBootstrap CSSファイルのリンクの下に、この行を追加しましょう: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +ブラウザは上から書いた順番でファイルを読み込むので、記述する箇所はよく確かめる必要があります。 順番が逆になると、私たちが書いたファイルがBootstrapのファイルに上書きされてしまうかもしれません。 これで、テンプレートにCSSファイルがある場所を教えました。 + +ファイルは次のようになっているはずです: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% load static %} + + + Django Girls blog + + + + + + + + {% for post in posts %} +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} + + +``` + +保存して、サイトを更新してください。 + +![図 14.2](images/color2.png) + +素晴らしいですね!あとは、左サイドの余白幅を少し広げて、余裕を持たせてあげたらもっと良くなると思いませんか?やってみましょう! + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +body { + padding-left: 15px; +} +``` + +これをCSSに追加して、保存してください。どのように変化したか、さぁ見てみましょう! + +![図 14.3](images/margin2.png) + +ヘッダーのフォントを変えてみませんか?ファイル `blog/templates/blog/post_list.html` の `` タグの中に次の一行を貼り付けましょう。 + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +まずは、このリンクが `blog/static/css/blog.css` より前にあることを確かめましょう。この1行は *Lobster* というフォントをGoogle Fonts (https://www.google.com/fonts) から読み込むということを意味しています。 + +`blog/static/css/blog.css` ファイルの中の、 `h1 a` という宣言ブロックを見つけてください(コードは `{` と `}` で囲まれています)。 そして、そのカッコの中に `font-family: 'Lobster';` と1行追加して、webサイトを更新してみましょう: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +h1 a, h2 a { + color: #C25100; + font-family: 'Lobster'; +} +``` + +![図 14.3](images/font.png) + +素晴らしいです! + +前述のように、CSSはクラスの概念を持っています。 それにより、HTMLコードの一部に名前を指定し、他の部分に影響を与えずにこの部分にだけスタイルを適用することができます。 なんて便利なんでしょう! 例えば、2つのdiv要素(ヘッダーと記事など)があったとして、これらのそれぞれに違うスタイルを適用することができます。 クラスを利用すると、違う見た目にできるのです。 + +先に進んで、HTMLコードの一部に名前をつけましょう。ヘッダーを含む`div` 要素に、`page-header` というクラス名をつけましょう: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + +``` + +さらにブログ投稿を含む `div` 要素に `post` というクラス名をつけましょう。 + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+``` + +そして、さまざまなセレクタに宣言ブロックを追加します。 `.` で始まるセレクタはクラスに関連します。 Web上にはCSSに関する多くのチュートリアルがあり、それらは以下に示すコードを理解する手助けになるはずです。 今のところは、`blog/static/css/blog.css` のファイルに以下の内容をコピー&ペーストしましょう: + +{% filename %}blog/static/css/blog.css{% endfilename %} + +```css +.page-header { + background-color: #C25100; + margin-top: 0; + padding: 20px 20px 20px 40px; +} + +.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 { + font-family: 'Lobster', cursive; +} + +.date { + color: #828282; +} + +.save { + float: right; +} + +.post-form textarea, .post-form input { + width: 100%; +} + +.top-menu, .top-menu:hover, .top-menu:visited { + color: #ffffff; + float: right; + font-size: 26pt; + margin-right: 20px; +} + +.post { + margin-bottom: 70px; +} + +.post h2 a, .post h2 a:visited { + color: #000000; +} +``` + +では、投稿を表示しているHTMLコードをクラス宣言で囲みましょう。 `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.text|linebreaksbr }}

+
+{% endfor %} +``` + +これで置き換えて下さい: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+
+
+ {% for post in posts %} +
+
+

published: {{ post.published_date }}

+
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
+``` + +ファイルを保存してWebサイトを更新してみましょう。 + +![図 14.4](images/final.png) + +やったー! ほら凄いでしょ? 貼り付けたコードを見て、HTMLにクラスを追加した場所やそのクラスがCSSの中で使われている場所を探してみましょう。 日付の色をターコイズブルーにするには、どこを変更すればいいでしょうか? + +CSSをいじって表示が壊れることを恐れないで、どんどん変更を加えてみてください。 CSSで遊んでみることで、何がどうなっているかを理解できてきます。 たとえ何かを壊してしまっても、心配しないで!すぐに元に戻すことができます。 + +[freeCodeCamp](https://learn.freecodecamp.org/)で無料のオンラインコース「Basic HTML & HTML5」と「Basic CSS」を受講することをおすすめします。 これらで学ぶと、HTMLとCSSであなたのWebサイトをよりカワイくできるでしょう。 + +さて、次の章にいく準備はできましたか?^皿^ \ No newline at end of file diff --git a/ja/css/images/bootstrap1.png b/ja/css/images/bootstrap1.png new file mode 100644 index 00000000000..bd81cd14373 Binary files /dev/null and b/ja/css/images/bootstrap1.png differ diff --git a/ja/css/images/color2.png b/ja/css/images/color2.png new file mode 100644 index 00000000000..3f82e7d3922 Binary files /dev/null and b/ja/css/images/color2.png differ diff --git a/ja/css/images/final.png b/ja/css/images/final.png new file mode 100644 index 00000000000..067c83d36cc Binary files /dev/null and b/ja/css/images/final.png differ diff --git a/ja/css/images/font.png b/ja/css/images/font.png new file mode 100644 index 00000000000..310f9e85f18 Binary files /dev/null and b/ja/css/images/font.png differ diff --git a/ja/css/images/margin2.png b/ja/css/images/margin2.png new file mode 100644 index 00000000000..895828b688d Binary files /dev/null and b/ja/css/images/margin2.png differ diff --git a/ja/deploy/README.md b/ja/deploy/README.md new file mode 100644 index 00000000000..9a28af415e4 --- /dev/null +++ b/ja/deploy/README.md @@ -0,0 +1,222 @@ +# デプロイ! + +> **補足** このチャプターはちょっと難しいことが沢山書かれています。 頑張って最後までやりきってください。デプロイはウェブサイトを開発するプロセスの上で、とても重要な部分ですが、つまずきやすいポイントも多く含まれています。 チュートリアルの途中にこのチャプターを入れています。そういったつまずきやすい箇所はメンターに質問して、あなたが作っているウェブサイトをオンラインでみれるようにしてください。 言い換えれば、もし時間切れでワークショップ内でチュートリアルを終わらせることができなかったとしても、この後のチュートリアルはきっと自分で終わらせることができるでしょう。 + +今のところ、あなたが作ったサイトは、あなたのコンピューターでしかみることができません。 ここでは、デプロイの方法を学びましょう! デプロイとは、あなたが作っているアプリケーションをインターネットで公開することです。あなた以外の人もウェブサイトを見ることができるようになりますよ. :) + +これまでに学んだとおり、ウェブサイトはサーバーに置かれています。 インターネットで利用できる多くのサーバー プロバイダーがありますが、私達は [PythonAnywhere](https://www.pythonanywhere.com/) を使用します。 PythonAnywhere は、多くの人がアクセスするものではない小さいアプリケーションを無料で公開できますので今のあなたには最適でしょう。 + +使用するその他の外部サービスは [GitHub](https://www.github.com)、コードのホスティング サービスです。 他にも色々ありますが、ほとんどのプログラマはGitHubのアカウントを持っています。そしてあなたも今そうなります。 + +これら3つの場所が重要になります。 ローカルコンピューターは、開発およびテストを行う場所になります。 変更に満足したら、GitHub上にプログラムのコピーを配置します。 あなたのウェブサイトはPythonAnywhereで公開され、GitHub からコードの新しいコピーを取得することによって更新されます。 + +# Git + +> **注:**もし、すでにインストールしていた場合は再度行う必要はありません。次のセクションに進んであなたのGitリポジトリを作り始められます。 + +{% include "/deploy/install_git.md" %} + +## Gitリポジトリを始める + +Gitはコードリポジトリ(または略して「リポジトリ」)というものの中に置かれる特定のファイルへの変更を追跡します。 私たちのプロジェクトを開始しましょう。 あなたのコンソールを開き、`djangogirls` ディレクトリでこれらのコマンドを実行します。 + +> **備考:**リポジトリを初期化する前に `pwd` (OSX/Linux) または `cd` (Windows) コマンドで現在の作業ディレクトリを確認してください。 `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リポジトリを初期化することは、プロジェクトごとに1回だけ行う必要があります(ユーザー名と電子メールをもう一度入力する必要はありません)。 + +Git はこのディレクトリ内のすべてのファイルとフォルダの変更を追跡しますが、無視してほしいいくつかのファイルがあります。 ベースディレクトリ内で `.gitignore` という名前のファイルを作成することによってこれを行います。 あなたのエディターを開き、次の内容で新しいファイルを作成します。 + +{% filename %}.gitignore{% endfilename %} + + *.pyc + *~ + /.vscode + __pycache__ + myvenv + db.sqlite3 + /static + .DS_Store + + +これを "djangogirls" フォルダ内に `.gitignore` という名前で保存します。 + +> **備考:**ファイル名の先頭のドットは重要です! もしそのファイルを作るのが難しいなら、(Macをお使いの方はFinderからドット( . )で始まるファイルを作れません。)そういう時はエディタでSave Asから作成すれば問題ありません。 `.txt`や `.py`などの拡張子をファイル名に入れないように気をつけてください。 ファイル名が`.gitignore`でないとGitに認識されません。 +> +> **備考:** `.gitignore`ファイルで指定したファイルの1つが`db.sqlite3`です。 そのファイルはローカルデータベースで、すべてのユーザーと投稿が保存されます。 私達は標準的なウェブプログラミングの慣習に従います。つまり、ローカルのテストサイトとPythonAnywhere上の本番のウェブサイトでデータベースを分けるということです。 PythonAnywhereのデータベースは開発用のマシンと同じようにSQLiteにすることができますが、通常はMySQLというSQLiteよりもたくさんのサイト訪問者に対処できるデータベースを使用します。 どちらの方法でも、GitHubのコードのコピーではSQLiteデータベースを無視することで、これまでに作成したすべての投稿と管理者はそのままローカルで利用できますが、本番環境(ブログを公開するPythonAnywhereのことです)ではそれらを再び作成する必要があります。 ローカルデータベースは本当のブログ投稿をブログから削除してしまうことを心配せずに、さまざまなことをテストできるよい遊び場として考えるといいでしょう。 + +`git add` コマンドを実行する前や、どのような変更を加えたか定かでない時は、 `git status` コマンドを使用する事をおすすめします。 これは間違ったファイルを追加またはコミットなど思いもかけない事を止めるために役立ちます。 `git status` コマンドは、あらゆる追跡されていない/変更されている/ステージされている(untracked/modifed/staged)ファイルや、ブランチの状態などさまざまな情報を返します。 出力は次のようになります。 + +{% filename %}command-line{% endfilename %} + + $ git status + On branch master + + 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) + + +最後に、変更内容を保存します。コンソールに移動し、これらのコマンドを実行します。 + +{% filename %}command-line{% endfilename %} + + $ git add --all . + $ git commit -m "My Django Girls app, first commit" + [...] + 13 files changed, 200 insertions(+) + create mode 100644 .gitignore + [...] + create mode 100644 mysite/wsgi.py + + +## GitHubにコードをプッシュする + +[GitHub.com](https://www.github.com)にアクセスし、Sign upをクリックして無料の新規アカウントを作成してください。 (ワークショップの前にすでに作成していたら、それは素晴らしいです!) あなたのパスワードを忘れないようにしてください(使っていたら、パスワードマネージャーに入れておいてください) + +そして、新しいリポジトリに "my-first-blog"の名前で新しいリポジトリを作成します。 "READMEで初期化する"チェックボックスをオフのままにし、.gitignoreオプションを空白にして(手動で行っています)、ライセンスをNoneのままにしておきます。 + +![](images/new_github_repo.png) + +> **注** `my-first-blog`という名前は重要です。何か他のものを選択することもできますが、以下の手順では何度も繰り返す必要があります。他の名前を選択した場合は、 毎回それを置き換えてください。 できれば、`my-first-blog` の名前にしておきましょう。 + +次の画面では、リポジトリをクローンするためのURLが表示されます。これはこの後のコマンドで利用します。 + +![](images/github_get_repo_url_screenshot.png) + +そして自分のコンピューター上のGitリポジトリをGitHub上のGitリポジトリに結びつけてあげる必要があります。 + +コンソールに次のように入力します(``をGitHubアカウントの作成時に入力したユーザー名に置き換えます。山カッコ<>を残さないでください。このURLはさっき見たクローンURLと一致する必要があります)。 + +{% filename %}command-line{% endfilename %} + + $ git remote add origin https://github.com//my-first-blog.git + $ git push -u origin master + + +GitHubにプッシュするとき、GitHubのユーザー名とパスワードを聞かれます(コマンドライン上かポップアップウィンドウにて)。認証情報を入力したらこんな風に表示されます。 + +{% filename %}command-line{% endfilename %} + + 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/ola/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)や[ Django Girls Tutorial ](https://github.com/DjangoGirls/tutorial)、その他たくさんの素晴らしいオープンソースソフトウェアプロジェクトもGitHubでコードをホストしています。 :) + +# PythonAnywhereでブログを設定する + +## PythonAnywhere アカウントにサインアップする + +> **備考:**あなたがすでにPythonAnywhereのアカウントを以前に作成しインストールの手順をふんでいたら、再びそれを行う必要はありません。 + +{% include "/deploy/signup_pythonanywhere.md" %} + +## PythonAnywhere でサイトを設定する + +ロゴをクリックしてメインの[PythonAnywhere Dashboard](https://www.pythonanywhere.com/)に戻り、「Bash」コンソールを起動するボタンをクリックします。これはPythonAnywhereバージョンのコマンドラインで、ちょうどあなたのコンピューターのコマンドラインと同じようなものです。 + +![PythonAnywhereのウェブインターフェースの「New Console」、「bash」ボタン](images/pythonanywhere_bash_console.png) + +> **備考:**PythonAnywhere は Linuxベースなので、Windowsを使っている場合は、コンソールがあなたのものと少し違って見えるでしょう。 + +PythonAnywhereにWebアプリケーションをデプロイするには、コードをGitHubからプルし、PythonAnywhereがそれを認識してWebアプリケーションのサーバを動かし始めるように設定する必要があります。 それを手動で行う方法もありますが、PythonAnywhereはそれをすべて行うヘルパーツールを提供しています。 まず、インストールしてみましょう。 + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ pip3.6 install --user pythonanywhere + + +`Collecting pythonanywhere` のようなメッセージがいくつか出力され、最終的に`Successfully installed (...) pythonanywhere- (...)`という行で終わると思います。 + +GitHub からアプリを自動的に構成するためのヘルパーを実行します。 PythonAnywhereのコンソールに次のように入力します(GitHubからクローンするときのURLと一致するように、``の代わりにご自身のGitHubユーザー名を使用することを忘れないでください): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ pa_autoconfigure_django.py --python=3.6 https://github.com//my-first-blog.git + + +実行しているところを見れば、何をしているのかわかるでしょう。 + +- GitHubからコードをダウンロードする +- ちょうどあなたのPC上でやったように、PythonAnywhere上に仮想環境 を作成する +- 一部のデプロイメント設定で設定ファイルを更新する +- `manage.py migrate`コマンドを使ってPythonAnywhere上のデータベースをセットアップする +- 静的ファイルの設定(これについては後で学習します) +- APIを通じてPythonAnywhereがあなたのWebアプリケーションを提供するように設定する + +PythonAnywhereではこれらすべてのステップは自動化されていますが、他のサーバープロバイダーでは同じ手順を自分で実行しなければなりません。 + +今注目すべき重要な点は、PythonAnywhere上のデータベースが、自分のPC上のデータベースとはまったく別物であることです。つまり、異なる投稿と管理者アカウントを持つことができます。 その結果、自分のコンピュータで行ったように、`createsuperuser`で管理者アカウントを初期化する必要があります。 PythonAnywhereがあなたの代わりに仮想環境を自動的に起動したので、あなたがする必要があるのは以下の通りです: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + (ola.pythonanywhere.com) $ python manage.py createsuperuser + + +管理者の詳細を入力します。 PythonAnywhere上のパスワードをより安全にしたい場合を除き、混乱を避けるために自分のコンピュータで使用しているのと同じものを使用することをお勧めします。 + +PythonAnywhereのコードを`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 + + +また、Filesページに移動し、PythonAnywhereに組み込まれているファイルブラウザを使用して閲覧することもできます。 (ConsoleページからPythonAnywhereの他のページには、右上のメニューボタンからいけます。 一度いずれかのページに移動したら、他ページへのリンクは上部にあります。) + +## 動いています! + +あなたのサイトは現在、インターネット上で動作しているはずです! PythonAnywhereのWebページをクリックしてリンクを取得します。 あなたはあなたが望む誰とでもこれを共有することができます:) + +> **注** これは初心者向けのチュートリアルです。このサイトをデプロイする際にはセキュリティの観点からは理想的ではない、いくつかのショートカットをしました。 もしこのプロジェクトを利用すると決めたり、新しいプロジェクトを開始する場合は、あなたのサイトを安全にするいくつかのヒントについて、[Djangoデプロイチェックリスト](https://docs.djangoproject.com/ja/5.1/howto/deployment/checklist/)を注意深く読んでください。 + +## デバッギングのヒント + +`pa_autoconfigure_django.py`スクリプトの実行中にエラーが表示された場合は、次のような原因が考えられます。 + +- PythonAnywhere APIトークンの作成を忘れている +- あなたのGitHubのURLを間違えている +- *Could not find your settings.py*というエラーが表示された場合は、おそらくGitにすべてのファイルを追加できていなかったか、 GitHubにうまくプッシュできていなかった。 この場合はGitセクションをもう一度見てください +- PythonAnywhereのアカウントを以前に作成していてcollectstaticでエラーが起きたとしたら、あなたのアカウントで古いバージョンのSQLite(例えば、3.8.2)を使っている可能性があります。 その場合、新しいアカウントを作成して、上記のPythonAnywhereのセクションに記載しているコマンドを実行してください。 + +サイトにアクセスしようとするとエラーが表示された場合、最初にデバッグ情報を探す場所は**エラーログ**です。 PythonAnywhereの[ Webページ](https://www.pythonanywhere.com/web_app_setup/)には、エラーログへのリンクがあります。 そこにエラーメッセージがあるかどうかを確認してください。 最新のものは一番下にあります。 + +[ PythonAnywhereヘルプサイトの一般的なデバッグのヒント](http://help.pythonanywhere.com/pages/DebuggingImportError)もあります。 + +つまづいた時は、コーチに助けを求めましょう。 + +# あなたのサイトをチェック! + +サイトのデフォルトページでは、ローカルコンピュータと同じように「It worked!」と表示されます。 URLの最後に`/admin/`を追加すると、管理サイトに移動します。 ユーザー名とパスワードでログインしたら、Postsへのリンクからサーバーに新規投稿を追加できることがわかるでしょう。ローカルのテスト用データベースの投稿は本番環境のブログに送られていないことも忘れないてくださいね。 + +いくつかの投稿を作成したら、ローカル環境(PythonAnywhereではなく)に戻ることができます。 ここから、変更を加えるためにはあなたのローカル環境で作業する必要があります。 これがWeb開発の一般的なワークフローです。ローカルで変更し、それらの変更をGitHubにプッシュし、それからその変更を公開しているWebサーバーにプルしてきます。 これにより、公開しているWebサイトを壊すことなく作業したり試したりできます。 とってもクールでしょ? + +自分を*すっごく*褒めてあげてください! サーバーのデプロイはWeb開発の最も難しい部分の1つで、ちゃんと動くようになるまで数日かかることもよくあります。 しかし、あなたは実際のインターネット上で、あなたのサイトを動かす事ができました! diff --git a/ja/deploy/images/github_get_repo_url_screenshot.png b/ja/deploy/images/github_get_repo_url_screenshot.png new file mode 100644 index 00000000000..ee1560b1e85 Binary files /dev/null and b/ja/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/ja/deploy/images/new_github_repo.png b/ja/deploy/images/new_github_repo.png new file mode 100644 index 00000000000..d1f82e5d863 Binary files /dev/null and b/ja/deploy/images/new_github_repo.png differ diff --git a/ja/deploy/images/pythonanywhere_account.png b/ja/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/ja/deploy/images/pythonanywhere_account.png differ diff --git a/ja/deploy/images/pythonanywhere_bash_console.png b/ja/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..458b43f5d0d Binary files /dev/null and b/ja/deploy/images/pythonanywhere_bash_console.png differ diff --git a/ja/deploy/images/pythonanywhere_beginner_account_button.png b/ja/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/ja/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/ja/deploy/images/pythonanywhere_create_api_token.png b/ja/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..6e617d0a53e Binary files /dev/null and b/ja/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/ja/deploy/install_git.md b/ja/deploy/install_git.md new file mode 100644 index 00000000000..95089ffcc3a --- /dev/null +++ b/ja/deploy/install_git.md @@ -0,0 +1,52 @@ +Gitはたくさんのプログラマが利用する「バージョン管理システム」です。 このソフトウェアは、特定のバージョンを後で呼び出すことができるように、時間の経過とともにファイルへの変更を追跡することができます。 ワードプロセッサープログラム (例えば、Microsoft WordやLibreOffice Writer)の「変更履歴」機能をより強力にしたようなものです。 + +## Gitのインストール + + + +[git-scm.com](https://git-scm.com/) からGitをダウンロードすることができます。 2つのステップを除いて「次へ」を押して進んで大丈夫です。エディタを選ぶステップでは、Nanoを選んでください。「PATH環境を調整する(Adjusting your PATH environment)」というステップでは、「Use Git and optional Unix tools from the Windows Command Prompt(WindowsコマンドプロンプトからGitとオプションのUnixツールを使用する)」(一番下の選択肢)を選択します。 それ以外はデフォルトの設定値で構いません。 改行コードの変換(Configuring the line ending conversions)については、「Checkout Windows-style, commit Unix-style line endings」の選択で大丈夫です。 + +インストールが正常に終了した後、コマンドプロンプトまたはPowerShellを再起動することを忘れないでください。 + + + +[git-scm.com](https://git-scm.com/) からGitをダウンロードし、指示に従ってください。 + +> **注** OS X 10.6,10.7、または10.8を実行している場合は、ここからgitのバージョンをインストールする必要があります: [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) + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo apt install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo dnf install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo zypper install git +``` + + \ No newline at end of file diff --git a/ja/deploy/signup_pythonanywhere.md b/ja/deploy/signup_pythonanywhere.md new file mode 100644 index 00000000000..06f0a3ce5a3 --- /dev/null +++ b/ja/deploy/signup_pythonanywhere.md @@ -0,0 +1,19 @@ +PythonAnywhereはクラウド上のサーバーでPythonのコードを走らせるためのサービスです。私たちのサイトをホスティングして、インターネット上で動かし続けるために使います。 + +今までの章で作ったブログをPythonAnywhere上にホスティングします。PythonAnywhereの「Beginner」アカウントを作成しましょう(アカウントは無料枠で大丈夫です。クレジットカードは必要ありません)。 + +* [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +![PythonAnywhereの登録ページ。無料の「Beginner」アカウントを作るためのボタンがあります。](../deploy/images/pythonanywhere_beginner_account_button.png) + +> **注意** ユーザー名をつけるとき、ユーザー名が `yourusername.pythonanywhere.com` というようにブログのURLに反映されることに注意しましょう。なので、あなたのニックネームかブログの名前をユーザー名とするようにしてください。 パスワードは忘れないようにしてください。(パスワードマネージャーを使っているなら覚えさせておくのも良いでしょう。) + +## PythonAnywhere APIトークンの作成 + +トークンは一度だけ作ればよいです。PythonAnywhereの登録が終わるとダッシュボード画面に移動します。「Account」ページへのリンクはページ右上のバーの中にあります。 + +![ページ右上にあるAccountページへのリンク](../deploy/images/pythonanywhere_account.png) + +「Account」ページに移動したら、「API Token」というタブを選んで、「Create new API token」のボタンを押してください。 + +![Accountページの「API Token」のタブ](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/ja/django/README.md b/ja/django/README.md new file mode 100644 index 00000000000..23550b7b2bf --- /dev/null +++ b/ja/django/README.md @@ -0,0 +1,27 @@ +# Djangoってなに? + +Django (/ˈdʒæŋɡoʊ/ *jang-goh* ジャンゴ と読みます) は無料でオープンソースとして公開されているPythonを使用したWebアプリケーションフレームワークです。 Web フレームワークは、素早く、簡単にウェブサイトを開発するのに役立つコンポーネントの一式が含まれています。 + +ほら、Webサイトを構築する時、同じような構造が毎回必要になってきますよね。ユーザー認証(サインアップ、サインイン、サインアウト)、管理者用の画面、フォーム、ファイルのアップロードなど。 + +開発者たちはサイトを構築する度に同じ問題を抱えたため、みんなで力を合わせてフレームワークを開発しました。(Djangoはフレームワークのひとつです。)幸運なことに、私たちは、開発に必要な要素がすでに含まれているフレームワークを使って開発することができます。 + +フレームワークを使うことで、私たちは開発をイチから作り直して車輪の再発明をすることを避けられます。また、新しいサイトを構築する際にかかる最初の準備に必要なコストを軽減します。 + +## なぜフレームワークを必要とするか。 + +Djangoを本当に理解するために、サーバーの役割についてもう少し考えてみましょう。サーバーにWebページを配信してもらうようにするには、サーバーにその設定をする必要があります。 + +手紙が届くポストを想像してください。手紙はユーザからWebサーバーに送られるリクエストのことで、ポストはWebサーバーのポートのことです。 Webサーバーが行っています。 Webサーバーはこのポストを監視して、手紙が届くとそれを読み、Webページから返事を送ります。 返事を送ろうとする時、コンテンツが必要ですね。 Djangoは、あなたがそのコンテンツを作る手助けをするものです。 + +## 誰かがあなたのWEB サイトにリクエストを要求したときどうなりますか。 + +Webサーバーにリクエストがあると、Djangoに伝えられ、リクエストの内容を把握しようとします。 まずWebページのアドレスを調べ、リクエストに対して何をするか決めます。 これは、Djangoの**urlresolver**が行います。(WebサイトのアドレスはURLと呼ばれます。 Uniform Resource Locator の略です。-resolverとは「解決するもの」という意味ですので、*urlresolver* というのはうなずけますよね。)。 パターンのリストを受け取って、URLに一致するものを探します。あまり賢いとはいえません。 Djangoは上から下にURLパターンを順に調べていきます。そこで何かがマッチすると、Djangoは*ビュー*と呼ばれる関数にリクエストを送ります。 + +郵便配達員を思い浮かべてください。 配達員は、通りを歩き、ひとつひとつの家の番地と、手紙に書かれている番地を見比べて行きます。 マッチする番地があったら、手紙をそこに置いていきます。 urlresolverも同じ仕組みです。 + +*ビュー*関数では、面白いことが行われます。私たちは、データベースに情報を探しにいきます。 時に、ユーザーがデータを変更するよう求めてきますよね? 例えば、「私の仕事内容を変えて下さい」といった手紙のように。*ビュー*は、まずあなたにその権限があるか確認します。次に、仕事内容を書き換えて、「完了しました!」というメッセージをあなたに送り返します。そして、*ビュー*が反応を返して、DjangoがユーザーのWebブラウザに情報を送ります。 + +上記の説明は、多少簡略化して説明しています。しかし、今ここでは、技術的なことを完璧に理解する必要はありません。概念が分かれば十分です。 + +これ以上詳細について深く説明するより、きっと、Djangoを使って実際に手を動かして作ってみる方がいいでしょう。重要な事はすべてその過程で学べますよ! \ No newline at end of file diff --git a/ja/django_admin/README.md b/ja/django_admin/README.md new file mode 100644 index 00000000000..2af2c8e756e --- /dev/null +++ b/ja/django_admin/README.md @@ -0,0 +1,57 @@ +# Django admin + +今作成したポストを追加、編集、削除するのにDjango adminを使います。 + +`blog/admin.py`ファイルをエディタで開いて、内容をこのように変えて下さい: + +{% filename %}blog/admin.py{% endfilename %} + +```python +from django.contrib import admin +from .models import Post + +admin.site.register(Post) +``` + +見て分かる通り、前回定義したPostモデルをimportしています。 モデルをAdminページ(管理画面)上で見えるようにするため、`admin.site.register(Post)`でモデルを登録する必要があります。 + +ではPostモデルを見てみましょう。 Web サーバーを実行するコンソールで `python manage.py runserver` を実行してください。 ブラウザに行って http://127.0.0.1:8000/admin/ とアドレスバーにタイプします。 こんなログインページが出ますね。 + +![ログインページ](images/login_page2.png) + +ログインするには、*superuser *(サイトの全てを管理するユーザー)を作る必要があります。 コマンドラインに戻り、`python manage.py createsuperuser` と入力し、enter キーを押します。 + +> Webサーバーを実行しているときに新しいコマンドを入力したい場合は、新しいターミナルウィンドウを開き、仮想環境(virtualenv)を有効にすることを思い出してください。 **プロジェクトを作成しよう!**の**ウェブサーバを起動する**セクションでどうやって新しいコマンドを書くかというのを見直しました。 + +{% filename %}macOS または Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py createsuperuser + + +{% 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. + + +ブラウザに戻ってsuperuserでログインすると、Django admin ダッシュボードが見えるでしょう。 + +![Django admin](images/django_admin3.png) + +Postsをクリックして移動し、少し試してみましょう。 5つか6つほど記事を追加してみることにします。 内容は気にしなくて大丈夫です。ローカルコンピュータで、あなただけに見える記事ですので。また、時間を節約するため、このチュートリアルからテキストをコピー&ペーストしても構いません。 :) + +少なくとも 2 つまたは 3 つの記事 (すべてではない) は公開日がセットされているようにしてください。後ほど役に立ちます。 + +![Django admin](images/edit_post3.png) + +Django adminについてもっと知りたいときは、Djangoのドキュメントを見るとよいでしょう。https://docs.djangoproject.com/ja/5.1/ref/contrib/admin/ + +ここでそろそろコーヒー(または紅茶)か何か食べるものを摂って自分を元気づけるのにいいタイミングでしょう。最初のDjangoモデルを作ったのだから、少し休みをとっていいところです! diff --git a/ja/django_admin/images/django_admin3.png b/ja/django_admin/images/django_admin3.png new file mode 100644 index 00000000000..fb221bd18e1 Binary files /dev/null and b/ja/django_admin/images/django_admin3.png differ diff --git a/ja/django_admin/images/edit_post3.png b/ja/django_admin/images/edit_post3.png new file mode 100644 index 00000000000..57299b6f5af Binary files /dev/null and b/ja/django_admin/images/edit_post3.png differ diff --git a/ja/django_admin/images/login_page2.png b/ja/django_admin/images/login_page2.png new file mode 100644 index 00000000000..c16d1aa4289 Binary files /dev/null and b/ja/django_admin/images/login_page2.png differ diff --git a/ja/django_forms/README.md b/ja/django_forms/README.md new file mode 100644 index 00000000000..30c46581768 --- /dev/null +++ b/ja/django_forms/README.md @@ -0,0 +1,449 @@ +# Djangoフォーム + +私たちのWebサイトで最終的にやりたいことは、記事を追加したり編集したりするためのよい方法を作ることです。 `Django admin`はかなりいいですが、カスタマイズしたりかわいくいい感じにするのはちょっと大変です。 `フォーム` によってインターフェイスを完璧にコントロールできるようになります。想像するほとんど全てのことができます! + +Djangoフォームのよいところは、フォームをゼロから定義できたり、フォームの結果をモデルに保存できる`ModelForm`を作れたりするところです。 + +これはまさに私たちがやりたいことです:`Post`モデルのためのフォームを作ります。 + +Djangoの他の重要なパーツと同様に、フォームは自身のファイルがあります: `forms.py` + +これは`blog`ディレクトリの下にforms.pyの名前で作る必要があります。 + + blog + └── forms.py + + +このファイルをエディタで開き、次のコードを入力してください。 + +{% filename %}blog/forms.py{% endfilename %} + +```python +from django import forms + +from .models import Post + +class PostForm(forms.ModelForm): + + class Meta: + model = Post + fields = ('title', 'text',) +``` + +最初にDjangoのformsをインポート(`from django import forms`)し、`Post`モデルもインポート(`from .models import Post`)する必要があります。 + +`PostForm`とは何かと思うかもしれませんが、これはフォームの名前です。 このフォームが `ModelForm` の一種だとDjangoに伝える必要があります (Djangoが私たちのためにいくつか魔法をかけられるように)。`forms.ModelForm`がその役割を果たします。 + +次に`class Meta`ですが、ここでDjangoにフォームを作るときにどのモデルを使えばいいか (`model = Post`) を伝えます。 + +最後にフォームのフィールドに何を置くか書きます。 ここでは、私たちは`title`(タイトル)と `text`(本文)のみをフォームで使用します。 `author` は現在ログインしている人(あなた)です。 `created_date` は(コードによって)自動的に記事を書いた日時が設定されます。 + +ひとまずこれでおしまいです!あとはフォームを*ビュー*で使い、それをテンプレート内に表示しさえすればいいです。 + +もう一度、ページへのリンク、URL、ビューとテンプレートを作ります。 + +## フォームにおけるページへのリンク + +`blog/templates/blog/base.html` をエディタで開きましょう。`page-header` と名付けた `div` 中に次のリンクを追加します: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + +``` + +新しいビュー` post_new `を呼び出すことに注意してください。 ` "glyphicon glyphicon-plus" `クラスは、使用しているBootstrapテーマによって提供され、プラス記号を表示します。 + +行を追加すると、このような html ファイルになります。 + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% load static %} + + + Django Girls blog + + + + + + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ + +``` + +ファイルを保存して、ページ http://127.0.0.1:8000 をリロードすると見覚えのある `NoReverseMatch` エラーが表示されると思います。実際にそうなってますか?いいですね! + +## URL + +`blog/urls.py`をエディタで開き、次の行を追加します。 + +{% filename %}blog/urls.py{% endfilename %} + +```python +path('post/new/', views.post_new, name='post_new'), +``` + +すると最終的なコードは次のようになります: + +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views + +urlpatterns = [ + 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`ビューの実装がないからです。ファイルに追加してみましょう。 + +## post_new ビュー + +`blog/views.py`をエディタで開き、`from`の行の後に次の内容を追加してみましょう。 + +{% filename %}blog/views.py{% endfilename %} + +```python +from .forms import PostForm +``` + +その後に*ビュー*を追加します。 + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +`Post`フォームを新しく作るには、`PostForm()`を呼び出し、それをテンプレートに渡す必要があります。 あとでこの *ビュー* に戻ってきますが、今はフォームのためのテンプレートをすぐに作ってしまいましょう。 + +## テンプレート + +`blog/templates/blog`ディレクトリに`post_edit.html`ファイルを作り、エディタで開きましょう。フォームを動かすにはいくつかやることがあります。 + +* フォームを表示する必要があります。 私たちは(例えば){% raw %}`{{ form.as_p }}`{% endraw %} でこれを行うことができます。 +* 上記の行は HTMLのformタグでラップする必要があります:`...` +* `Save` ボタンが必要です。これをHTMLのbuttonタグで行います:`` +* 最後に`
` タグの開始直後に、 `{% raw %}{% csrf_token %}{% endraw %}`を追加する必要があります。 フォームをセキュアにするためこれは非常に重要です! これを忘れると、Djangoはフォームを保存しようとすると文句を言うでしょう: + +![CSFR 禁止のページ](images/csrf2.png) + +では、`post_edit.html` のHTMLがどのようになるか見てみましょう: + +{% filename %}blog/templates/blog/post_edit.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} +

New post

+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} +``` + +更新をしてみましょう。やった!フォームが表示されます。 + +![New form](images/new_form2.png) + +ちょっと待ってみて下さい。`title` と `text` フィールドに何か入力して保存するとどうなりますか? + +何も起きません!もう一度同じページに戻りテキストはどこかに行ってしまいました… そして新しい投稿は追加されていません。何がいけなかったのでしょうか? + +答えは: 何も間違ってない、です。*ビュー* でもう少し作業を行う必要があります. + +## フォームを保存する + +`blog/views.py` をもう一度エディタで開きます。現在の `post_new` ビューはこうなっています。 + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +フォームを送信したとき、同じビューに戻されていましたが、このとき`request`、もっと詳しくいうと `request.POST` にデータが追加されています (このPOSTという名前はブログ投稿 "post" とは関係ありません。このデータは送られてきたもの、というコトと関係しています) 。 HTMLファイルの `
` タグで、`method="POST"` という変数があったのを覚えていますか? これによってフォームのすべてのフィールドは今 `request.POST` にあります。 `POST` という名前を何か別のものに変えることはできません (他に唯一の有効な `method` の値は `GET` ですが、その違いを説明する時間がありません) 。 + +私たちの *ビュー* では、扱わなくてはならない2つの別々のシチュエーションがあります: 1つ目は、最初にページにアクセスしてきた時で空白のフォームが必要な場合。2つ目はすべてのフォームデータが入力された状態で*ビュー*に戻ってくる場合です。 したがって条件分岐を追加する必要があります(そのために`if`を使います): + +{% filename %}blog/views.py{% endfilename %} + +```python +if request.method == "POST": + [...] +else: + form = PostForm() +``` + +ドット `[...]` の部分を埋めていきましょう。 `method`が`POST`の場合、フォームのデータを使って`PostForm`を構築します。 私たちはそれを次のようにします: + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(request.POST) +``` + +次にフォームの値が正しいかどうかをチェックします(すべての必須フィールドが設定され、不正な値が送信されないこと)。 `form.is_valid()` で行います。 + +フォームをチェックして、フォームの値が有効であれば保存できます。 + +{% filename %}blog/views.py{% endfilename %} + +```python +if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() +``` + +基本的にここでは2つのことを行います。まず `form.save` でフォームを保存することと author を追加することです (`PostForm` 内に `author` フィールドがありませんし、このフィールドは必須です) 。 `commit=False` は `Post` モデルをまだ保存しないという意味です。保存前に author を追加したいので。 ほとんどの場合、`commit=False`なしで`form.save()`を使用しますが、この場合はそれを指定する必要があります。 `post.save()`は変更を保存し(作成者を追加しつつ)、新しいブログ投稿が作成されます! + +最後に、新しく作成された記事の `post_detail` ページを表示できれば良いですよね? そのために次のインポートを追加します: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import redirect +``` + +ファイルの先頭に追加します。これで新しく作成されたポストの `post_detail` ページに移動する処理を書けます。 + +{% filename %}blog/views.py{% endfilename %} + +```python +return redirect('post_detail', pk=post.pk) +``` + +`post_detail` は移動したいビューの名前です。 この *ビュー* では `pk` 変数が必須であることを覚えていますか? ビューにそれを渡すため、`pk=post.pk`を使います。この `post` は新しく作られたブログポストです! + +ふー、たくさんのことを話してきましたが、そろそろ *ビュー* の全体がどんな感じか見てみたい頃じゃないでしょうか? + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_new(request): + if request.method == "POST": + form = PostForm(request.POST) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +では動作確認してみましょう。 http://127.0.0.1:8000/post/new/ に行き、 `title` と `text` を追加し、保存すると…… じゃじゃーん! 新しいブログ記事が追加され、post_detail にリダイレクトされます! + +ブログ記事を保存する前に公開日をセットしていることに気づいたかもしれません。後ほど、**Django Girls Tutorial: Extensions**にて *公開ボタン* を導入します。 + +素晴らしい! + +> 最近までDjango adminを使ってきたので、システム上で今まだログイン状態かと思います。 いくつかの状況ではログアウト状態になることがあります(ブラウザを閉じる、DBを再起動するなど..)。 投稿を作成するときに、ログインユーザーがわからないというエラーが発生した場合は、管理ページhttp://127.0.0.1:8000/admin にアクセスして再度ログインしてください。 その問題は一時的に解決します。 メインチュートリアルの後 **Homework: add security to your website!** の章に恒久的な対策がありますので宿題として取り組んでみてください。 + +![ログインエラー](images/post_create_error.png) + +## フォームのバリデーション(検証) + +ここではDjangoのフォームのクールなところを紹介します。 ブログのポストは `title` と `text` のフィールドが必要です。 `Post` モデルではこれらのフィールドがなくてもよいとは書いておらず (`published_date` とは対照的に)、Djangoはその場合、それらのフィールドには何らかの値が設定されることを期待します。 + +`title` と `text` を入力せずに保存してみましょう。何が起こるでしょうか? + +![フォームのバリデーション(検証)](images/form_validation2.png) + +Djangoはフォームのすべてのフィールドが正しいことを検証してくれます。気が利くでしょう? + +## フォームの編集 + +今、私たちは新しいフォームを追加する方法を知っています。 しかし既存のデータを編集するためはどうすれば良いのでしょうか? それは先ほど行ったことと非常に似ています。 すぐにいくつかの重要なものを作成してみましょう。 (もしわからない場合、コーチに尋ねるか、もしくはすでに手順をカバーしているので、前の章を見てください) + +`blog/templates/blog/post_detail.html` をエディタで開いて次の行を追加します + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + +``` + +テンプレートは次のようになります: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} + +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endblock %} +``` + +`blog/urls.py`をエディタで開き、次の行を追加します。 + +{% filename %}blog/urls.py{% endfilename %} + +```python + path('post//edit/', views.post_edit, name='post_edit'), +``` + +テンプレート `blog/templates/blog/post_edit.html` を再利用します。そして残るは*ビュー*です。 + +`blog/views.py` をエディタで開いて次の内容をファイルの最後に追加します: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_edit(request, pk): + post = get_object_or_404(Post, pk=pk) + if request.method == "POST": + form = PostForm(request.POST, instance=post) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm(instance=post) + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +`post_new` とほとんど同じに見えますか? しかし完全に同じではありません。 まず `urls` から追加の `pk` パラメータを渡します。 次に編集したい`Post` モデルを `get_object_or_404(Post, pk=pk)` で取得し、フォームを作るときは以下の2つのケースのようにそのポストを`instance(インスタンス)`として渡します。フォームを保存するときは… + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(request.POST, instance=post) +``` + +…このポストを編集するためにただフォームを開く場合は: + +{% filename %}blog/views.py{% endfilename %} + +```python +form = PostForm(instance=post) +``` + +よし、ちゃんと動くか試してみましょう!`post_detail` ページにいきましょう。そこの右上に [編集] ボタンがあるはずです: + +![編集ボタン](images/edit_button2.png) + +クリックするとブログ記事のフォームが表示されると思います: + +![編集フォーム](images/edit_form2.png) + +あとはお気軽にタイトルやテキストを変更して保存してください! + +おめでとう!アプリケーションが完成しました。 + +Djangoのフォームについてもっと知りたい場合、Djangoのドキュメントを読んでください。https://docs.djangoproject.com/ja/5.1/topics/forms/ + +## セキュリティ + +リンクをクリックするだけで新しい投稿を作成できることは素晴らしいことです! しかし、今、あなたのサイトにアクセスした人は誰でも新しいブログ投稿を作成することができます。それはおそらくあなたが望むものではありません。 ボタンはあなたのためには表示されますが、他の人には表示されないようにしましょう。 + +`blog/templates/blog/base.html` をエディタで開き、`page-header` と名付けた `div` とそこに以前に入力したアンカータグを見つけます。 これは次のようになっています。 + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + +``` + +これに`{% if %}`タグを追加し、管理者でログインしているユーザーのみにリンクを表示します。 今は、あなただけです! `` タグを以下のように変更します: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% if user.is_authenticated %} + +{% endif %} +``` + +この`{% if %}`は、ページをリクエストしているユーザーがログインしている場合にのみ、リンクがブラウザに送信されるようにします。 これは新しい投稿の作成を完全に保護するものではありませんが、それは良い第一歩です。 私たちは拡張レッスンでより多くのセキュリティをカバーします。 + +詳細ページに追加した編集アイコンを覚えていますか? 他の人が既存の投稿を編集できないように、同じ変更を追加したいと思います。 + +`blog/templates/blog/post_detail.html` をエディタで開いて次の行を見つけてください: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + +``` + +以下のように変更してください: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% if user.is_authenticated %} + +{% endif %} +``` + +あなたはログインしている可能性が高いので、ページを更新しても、何も変わらないかもしれません。 ただし、別のブラウザやシークレットウィンドウ(Windows Edgeでは「InPrivate」と呼ばれます)でページを読み込むと、リンクが表示されず、アイコンも表示されないでしょう! + +## もう一つ: デプロイの時間です! + +ではPythonAnywhere上で動作するかを確認しましょう。再度デプロイします。 + +* まず、Githubにあなたの新しく書いたコードをCommitして、Pushしてみましょう。 + +{% filename %}command-line{% endfilename %} + + $ git status + $ git add --all . + $ git status + $ git commit -m "Added views to create/edit blog post inside the site." + $ git push + + +* それから、[PythonAnywhereのbashコンソール](https://www.pythonanywhere.com/consoles/)で: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(``の部分を、自分の実際のPythonAnywhereのサブドメイン名に山カッコをはずして置き換えることを忘れずに) + +* 最後に、[Webページ](https://www.pythonanywhere.com/web_app_setup/) に飛んで(コンソールの右上のメニューボタンを使ってもいいですね)それから **Reload** を押しましょう。 変更を見るためにあなたのブログ https://subdomain.pythonanywhere.com を再読み込みしましょう。 + +うまくいってるはずです!おめでとう :) diff --git a/ja/django_forms/images/csrf2.png b/ja/django_forms/images/csrf2.png new file mode 100644 index 00000000000..ee946324f92 Binary files /dev/null and b/ja/django_forms/images/csrf2.png differ diff --git a/ja/django_forms/images/drafts.png b/ja/django_forms/images/drafts.png new file mode 100644 index 00000000000..1d62f8866f4 Binary files /dev/null and b/ja/django_forms/images/drafts.png differ diff --git a/ja/django_forms/images/edit_button2.png b/ja/django_forms/images/edit_button2.png new file mode 100644 index 00000000000..804674f0965 Binary files /dev/null and b/ja/django_forms/images/edit_button2.png differ diff --git a/ja/django_forms/images/edit_form2.png b/ja/django_forms/images/edit_form2.png new file mode 100644 index 00000000000..3d4e525d5d0 Binary files /dev/null and b/ja/django_forms/images/edit_form2.png differ diff --git a/ja/django_forms/images/form_validation2.png b/ja/django_forms/images/form_validation2.png new file mode 100644 index 00000000000..6e333af3077 Binary files /dev/null and b/ja/django_forms/images/form_validation2.png differ diff --git a/ja/django_forms/images/new_form2.png b/ja/django_forms/images/new_form2.png new file mode 100644 index 00000000000..8f2a1088070 Binary files /dev/null and b/ja/django_forms/images/new_form2.png differ diff --git a/ja/django_forms/images/post_create_error.png b/ja/django_forms/images/post_create_error.png new file mode 100644 index 00000000000..d140e8e2419 Binary files /dev/null and b/ja/django_forms/images/post_create_error.png differ diff --git a/ja/django_installation/README.md b/ja/django_installation/README.md new file mode 100644 index 00000000000..d4eef511648 --- /dev/null +++ b/ja/django_installation/README.md @@ -0,0 +1,7 @@ +# Djangoのインストール + +> **補足:** Chromebookを使っている方は、このチャプターは飛ばして、 [Chromebook Setup](../chromebook_setup/README.md) の説明に従ってセットアップしてください。 +> +> **補足:**インストールのチャプターで既にインストール済みの方は、このチャプターは飛ばして次に進みましょう。 + +{% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/ja/django_installation/instructions.md b/ja/django_installation/instructions.md new file mode 100644 index 00000000000..ae37c63a423 --- /dev/null +++ b/ja/django_installation/instructions.md @@ -0,0 +1,230 @@ +> このチャプターの一部はGeek Girls Carrots (https://github.com/ggcarrots/django-carrots) のチュートリアルに基づいています。 +> +> このチャプターの一部はCreative Commons Attribution-ShareAlike 4.0 International License のライセンスによる[django-marcador tutorial](http://django-marcador.keimlink.de/)に基づいています. このdjango-marcador tutorialはMarkus Zapke-Gründemann らが著作権を保有しています。 + +## 仮想環境 + +Django をインストールする前に、あなたのコーディング環境を、きれいにしておく便利な道具をインストールしてもらいます。 このステップをとばすこともできますが、しかし、このステップをとばすことは全くお勧めしません。 可能な限りベストなセットアップで始めることは将来のたくさんのトラブルからあなたを救うはずですから! + +さあ、**仮想環境(virtual environment )**(*virtualenv*とも呼ばれています)を作成してみましょう。 仮想環境(virtual environment)ではプロジェクト単位であなたのPython/Djangoのセットアップを他から隔離します。 これは、あなたがひとつのウェブサイトにおこなったどんな変更も、あなたが開発している他のサイトに影響を及ぼさないということです。 便利でしょ? + +あなたがしなければならないのは、あなたが`仮想環境(virtual environment)`を作成したいディレクトリを見つけることです(たとえばホームディレクトリなどです)。 Windowsでは、ホームディレクトリは、`C:\Users\Name`と書かれているかもしれません (`Name`はあなたのログインネームです)。 + +> **補足:** Windowsの方は、ディレクトリ名に特殊文字やアクセント記号を含まないよう気をつけてください。もし、ユーザー名が特殊文字を含む場合は、`C:\djangogirls` のようなディレクトリを作成してください。 + +このチュートリアルのために、ホームディレクトリに新しいディレクトリ`djangogirls`を作成します。 + +{% filename %}command-line{% endfilename %} + + $ mkdir djangogirls + $ cd djangogirls + + +`myvenv`という仮想環境(virtual environment)を作成します。一般的なコマンドは以下のようになります: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + + + +新しい`virtualenv`を作成するために、コマンドプロンプトを開き(コマンドプロンプトについては何章か前にお話ししましたね。覚えてますか?)、`python -m venv myvenv`を実行して下さい。たとえばこのように入力します: + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls> python -m venv myvenv + + +`myvenv` というところが、あなたの`virtualenv(仮想環境)` の名前です。 どんな名前でも使うことができますが、必ず小文字で表記し、スペース・アクセント記号・特殊文字は入れないでください。 短い名前にしておくのもいいアイデアですーあなたはこの名前を何度も参照しますから! + + + + + +LinuxやmacOSで`virtualenv`を作るときは、`python3 -m venv myvenv`と実行するだけです。 たとえばこんな感じです: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + +`myvenv` は、あなたの `仮想環境(virtualenvironment)` の名前です。 どんな名前でも使うことができますが、必ず小文字で表記し、スペースは入れないでください。 短い名前にしておくのもいいアイデアですーあなたはこの名前を何度も参照しますから! + +> **補足:**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=python3.6 myvenv +> +> +> **補足:**もし以下のようなエラーがでたら、 +> +> {% filename %}command-line{% endfilename %} +> +> E: Unable to locate package python3-venv +> +> +> 代わりに次のコマンドを実行してください。 +> +> {% filename %}command-line{% endfilename %} +> +> sudo apt install python3.6-venv +> + + + +## 仮想環境の操作 + +上に示したコマンドは仮想環境(基本的には一連のディレクトリとファイル)を含む`myvenv` という名前(あるいはあなたが選んだ名前)のディレクトリを生成します。次に我々がしたいのは、仮想環境を起動することです。 + + + +実行して、仮想環境を起動します。 + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls > myvenv\Scripts\activate + + +> **補足:**Windows 10では、`execution of scripts is disabled on this system`というエラーが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 +> + + + +> **補足:** 人気のあるエディタであるVS Codeを使っている方は、VS CodeはWindows Powershellベースの統合ターミナルが一緒になっているので、統合ターミナルを使う場合、仮想環境を有効にするために下記のコマンドを実行してください: +> +> $ . myvenv\Scripts\activate.ps1 +> +> +> エディタのウィンドウとコマンドラインのウィンドウを行き来する必要がなくなるのが利点です。 + + + + + +実行して、仮想環境を起動します。 + +{% filename %}command-line{% endfilename %} + + $ source myvenv/bin/activate + + +`myvenv` のところを、あなたが選んだ `仮想環境(virtualenv)` の名前に置き換えることを忘れないで下さいね! + +> **備考:** `source` ではできない場合もあります。その場合は、代わりに以下のように入力してみてください: +> +> {% filename %}command-line{% endfilename %} +> +> $ . myvenv/bin/activate +> + + + +コンソールでプロンプトの行頭に `(myvenv)` が付いたら、`仮想環境(virtualenv)` を起動しています。 + +仮想環境の中で作業しているとき、`python` コマンドは自動的に正しいバージョンのPythonを参照するので、`python3` コマンドの代わりに `python` コマンドを使うことができます。 + +OK、これで依存関係の準備はすべて整いました。いよいよDjangoのインストールです! + +## Djangoのインストール {#django} + +今 `virtualenv` を起動したので、Djangoをインストールすることができます。 + +その前に、最新バージョンの `pip` がインストールされていることを確認すべきです。pipはDjangoのインストールに使うソフトウェアです。 + +{% filename %}command-line{% endfilename %} + + (myvenv) ~$ python -m pip install --upgrade pip + + +### requirementsファイルによってパッケージをインストールする + +requirementsファイルは `pip install` でインストールする依存関係の一覧が記載されているファイルです: + +インストールしたエディタを使って、最初に `requirements.txt` ファイルを `djangogirls/` フォルダの中に作ります。 エディタで新しいファイルを開いて、`djangogirls/` フォルダ内に `requirements.txt` という名前で保存してください。 ディレクトリはこんな感じになっているはずです: + + djangogirls + ├── myvenv + │ └── ... + └───requirements.txt + + +`djangogirls/requirements.txt` ファイル中に以下のテキストを追加します: + +{% filename %}djangogirls/requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +そして、`pip install -r requirements.txt` を実行してDjangoをインストールします。 + +{% filename %}command-line{% endfilename %} + + (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.1MB) + Installing collected packages: Django + Successfully installed Django-{{ book.django_version }} + + + + +> Windowsでpipを実行してエラーが起きた場合は、あなたのプロジェクトのパス名がスペースかアクセント記号か特殊文字を含んでいないか確認して下さい (例 `C:\Users\User Name\djangogirls`)。 もし含んでいる場合は、スペース・アクセント記号・特殊文字を含まない別の場所(`C:\djangogirls`をオススメします)でディレクトリを作成することを検討してみてください。 新しいディレクトリに新しい仮想環境を作成してから、古いディレクトリを削除して、上記のコマンドを試してください。 (仮想環境には絶対パスが使われているので、仮想環境のディレクトリを移動させてもうまくいきません。) + + + + + +> Djangoをインストールしようとした後でコマンドラインがフリーズして動かなくなってしまうことがあります。その時は、以下のコマンドを代わりに入力してみてください。 +> +> {% filename %}command-line{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> + + + + + +> Ubuntu 12.04でpipを実行してエラーが起きた場合は、仮想環境内にpipを再インストールするために `python -m pip install -U --force-reinstall pip` を実行して下さい。 + + + +以上です!あなたは(ついに)Djangoアプリケーションを作成する準備が整いました! \ No newline at end of file diff --git a/ja/django_models/README.md b/ja/django_models/README.md new file mode 100644 index 00000000000..7ed19e0177d --- /dev/null +++ b/ja/django_models/README.md @@ -0,0 +1,201 @@ +# Djangoモデル + +さて、ブログの中のポストを格納するものが欲しいですよね。そのために `オブジェクト` についてちょっとお話しします。 + +## オブジェクト + +プログラミングには `オブジェクト指向プログラミング` という概念があります。 それは、退屈なプログラムを繰り返し書く代わりにモデルになるものを作って、それが他とどう作用するかを定義するという考え方です。 + +じゃあオブジェクトって何なの?って思いますよね。オブジェクトは状態(プロパティ)と命令(アクション)の塊です。ピンと来ないでしょうから例を挙げましょう。 + +猫をモデルにしたいときは、`猫(Cat)` オブジェクトを作ります。そのプロパティは、`色(color)` 、`年齢(age)` 、`機嫌(mood)`(いい、悪い、眠い)、`飼い主(owner)`( `人(Person)` オブジェクトですね、捨て猫ならそのプロパティは空白)です。 + +`猫` のアクションは、`喉を鳴らす(purr)` 、`引っ掻く(scratch)` 、`餌を食べる(feed)`( `キャットフード(CatFood)` などで、それはまた `味(taste)` というプロパティを持つ別のオブジェクトになるでしょう。) + + Cat + -------- + color + age + mood + owner + purr() + scratch() + feed(cat_food) + + + CatFood + -------- + taste + + +つまり、オブジェクト指向とは実際の物を、プロパティ( `オブジェクト・プロパティ` と呼びます)と命令( `メソッド` と呼びます)を持つコードで表現するという考え方です。 + +ではブログポストはどういうモデルになるでしょうか。ブログが作りたいんですよね? + +それにはブログポストとは何か、それはどんなプロパティがあるかという問いに答えなければなりません。 + +まず確実なのはブログポストにはコンテンツとタイトルが必要ですね。 それからそれを書いた人が分かるといいでしょう。 最後に、ポストをいつ作成、公開したかも分かるといいですね。 + + Post + -------- + title + text + author + created_date + published_date + + +ではブログポストがどうなればいいですか?ポストが公開されるといいですよね? + +なので `publish` メソッドが必要です。 + +達成したいことが分かったので、Djangoでモデリングの開始です! + +## Djangoモデル + +オブジェクトが何か分かったので、ブログポストのDjangoモデルを作りましょう。 + +Djangoのモデルは特別なオブジェクトで、`データベース` に格納されます。 データベースはデータの集まりです。 ここにユーザーやブログポストの情報を格納します。 データを格納するのにSQLiteデータベースを使います。 これはDjangoのデフォルトのデータベースで、今はこれで十分です。 + +データベースの中のモデルは、列(フィールド)と行(データ)があるスプレッドシートと思ってもらっても結構です。 + +### 新しいアプリケーションの作成 + +全部をきちんと整理しておくため、プロジェクトの中に別のアプリケーションを作ります。 初めから全てを整理しておくのはとっても良いことです。 アプリケーションを作るために、次のコマンドをコンソールの中で走らせましょう。(`manage.py` ファイルがある `djangogirls` ディレクトリでコマンドをタイプしてくださいね) + +{% filename %}macOS and Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py startapp blog + + +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + + +新しく `blog` ディレクトリが作られて、今沢山のファイルがそこに入っているのに気がついたでしょう。ディレクトリとファイルはこんな風に見えるはずです: + + djangogirls + ├── blog + │   ├── admin.py + │   ├── apps.py + │   ├── __init__.py + │   ├── migrations + │   │   └── __init__.py + │   ├── models.py + │   ├── tests.py + │   └── views.py + ├── db.sqlite3 + ├── manage.py + ├── mysite + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + + + +アプリケーションを作ったら、Djangoにそれを使うように伝えないといけません。 それは `mysite/settings.py` でします。エディタでこれを開いてください。 `INSTALLED_APPS` を見つけて `]` の上に `'blog.apps.BlogConfig',` という一行を追加します。 そうすると、最終的には以下のようになりますね。 + +{% filename %}mysite/settings.py{% endfilename %} + +```python +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog.apps.BlogConfig', +] +``` + +### ブログポストモデルの作成 + +`blog/models.py` ファイルで `Model` と呼ばれるオブジェクトを全て定義します。これがブログポストを定義する場所です。 + +`blog/models.py` をエディタで開いて中身を全部削除し、下のコードを書きましょう。 + +{% filename %}blog/models.py{% endfilename %} + +```python +from django.conf import settings +from django.db import models +from django.utils import timezone + + +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) + + def publish(self): + self.published_date = timezone.now() + self.save() + + def __str__(self): + return self.title +``` + +> `str` の両側に2つのアンダースコア( `_` )がちゃんと入っているか確認しましょう。 これはPythonでよく使われて、"ダンダー"(ダブルアンダースコア)と呼ばれます。 + +難しそうでしょ?でも大丈夫!ちゃんと説明しますから。 + +`from` とか `import` で始まる行は全部、他のファイルから何かをちょこっとずつ追加する行です。 なので色んなファイルから必要な部分をコピペする代わりに `from ... import ...` で必要部分を入れることができます。 + +`class Post(models.Model):` – この行が今回のモデルを定義します (これが `オブジェクト` です)。 + +- classはオブジェクトを定義してますよ、ということを示すキーワードです。 +- `Post` はモデルの名前で、他の名前をつけることもできます(が、特殊文字と空白は避けなければいけません)。モデルの名前は大文字で始めます。 +- `models.Model` はポストがDjango Modelだという意味で、Djangoが、これはデータベースに保存すべきものだと分かるようにしています。 + +さて今度はプロパティを定義しましょう:`title`、`text`、`created_date`、`published_date`、それに `author` ですね。 それにはまずフィールドのタイプを決めなければいけません。(テキスト? 数値? 日付? 他のオブジェクト、例えばユーザーとの関係?) + +- `models.CharField` – 文字数が制限されたテキストを定義するフィールド +- `models.TextField` – これは制限無しの長いテキスト用です。ブログポストのコンテンツに理想的なフィールドでしょ? +- `models.DateTimeField` – 日付と時間のフィールド +- `models.ForeignKey` – これは他のモデルへのリンク + +コードの細かいところまでは説明し出すと時間がかかるので、ここではしませんが、 モデルのフィールドや上記以外の定義のやり方について知りたい方は是非Djangoドキュメントを見てみて下さい。 (https://docs.djangoproject.com/ja/5.1/ref/models/fields/#field-types) + +`def publish(self):` は何かと言うと、 これこそが先程お話ししたブログを公開するメソッドそのものです。 `def` は、これはファンクション(関数)/メソッドという意味です。`publish` はメソッドの名前で、 変えることもできます。 メソッドの名前に使っていいのは、英小文字とアンダースコアで、アンダースコアはスペースの代わりに使います。 (例えば、平均価格を計算するメソッドは `calculate_average_price` っていう名前にします) + +メソッドは通常何かを `return` します。 一つの例が `__str__` メソッドにあります。 このシナリオでは、`__str__()` を呼ぶと、ポストのタイトルのテキスト(**string**)が返ってきます。 + +`def publish(self):` と `def __str__(self):` の両方が class キーワードに続く行でインデントされているのに気づきましたか? Pythonにモデルのメソッドだと伝えるために、class キーワードに続く行ではメソッドをインデントしましょう。 そうしないと、メソッドはモデルのものではなくなり、思ってもみない振る舞いをするでしょう。 + +もしモデルがまだはっきりつかめないようだったら、気軽にコーチに聞いて下さい! 特にオブジェクトとファンクションを同時に習ったときはとても複雑なのはよく分かってますから。 でも前ほど魔法みたいじゃないといいですけど! + +### データベースにモデルのためのテーブルを作成する + +最後のステップは新しいモデルをデータベースに追加することです。 まず、モデルに少し変更があったこと(今作ったこと)をDjangoに知らせましょう。 コンソールで `python manage.py makemigrations blog` とタイプします。 こんな感じですね。 + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py makemigrations blog + Migrations for 'blog': + blog/migrations/0001_initial.py: + + - Create model Post + + +**メモ:**編集したファイルを忘れずに保存してくださいね。保存しないと、コンピュータが以前のパージョンのファイルを実行してしまい、思ってもみないエラーメッセージに出くわすかもしれません。 + +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: + Applying blog.0001_initial... OK + + +やった~!ポストモデルがデータベースに入りました。どうなったか見たいでしょ?次へ進みましょう! diff --git a/ja/django_orm/README.md b/ja/django_orm/README.md new file mode 100644 index 00000000000..7eb762f9740 --- /dev/null +++ b/ja/django_orm/README.md @@ -0,0 +1,221 @@ +# DjangoのORMとクエリセット + +この章では、Djangoのデータベース接続方法と、データの格納について学びます。やってみましょう! + +## クエリセットとは? + +クエリセットが何かと言うと、モデルのオブジェクトのリストのことです。クエリセットを使って、データベースからデータを読み込んだり、抽出したり、並べ替えたりできます。 + +実際に動かしてみるのが一番わかりやすいので、試してみましょう。 + +## Django shell + +コンソール画面を開いて(PythonAnywhereのコンソールではないですよ)、次のコマンドを入力してみましょう。 + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py shell + + +次のような表示に切り替わるでしょう。 + +{% filename %}command-line{% endfilename %} + +```python +(InteractiveConsole) +>>> +``` + +今、Djangoのインタラクティブコンソールが起動しています。Pythonプロンプトのようにだけ見えますが、ちゃんとDjangoも動いています :) このコンソール画面では、Pythonのコマンドは何でも使えます。 + +### すべてのオブジェクト + +最初に、ポストデータを全部表示させてみましょう。次のコマンドで、ポストのデータを全部表示させることが出来ます。 + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +Traceback (most recent call last): + File "", line 1, in +NameError: name 'Post' is not defined +``` + +ごめんなさい、エラーになってしまいましたね。Postがないというエラーです。その通りなんです。最初にインポートをしなくてはならないのに、忘れていました。 + +{% filename %}command-line{% endfilename %} + +```python +>>> from blog.models import Post +``` + +こんな風に書くだけで、`blog.models` から `Post` モデルをインポート出来ます。それでは、もう一度試してみましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, ]> +``` + +さっきDjangoの管理画面から作ったポストのリストが表示されました。だけど、次はこのコンソール画面から、新たにポストを作ってみたいですよね。それはどうすればいいのでしょうか。 + +### オブジェクトの作成 + +データベースに、新しいPostを作成するには、次のようにします。 + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') +``` + +いい感じなのですが、1つだけマズイことをしているんです。author に `me` を渡していますが、これは `User` モデルのインスタンスでないといけませんよね。それは、どうやればいいと思います? + +そうです、さっきと同じです。Userモデルも先にインポートしておきましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> from django.contrib.auth.models import User +``` + +どんなユーザが、データベースに登録されてましたっけ?覗いてみましょうか。 + +{% filename %}command-line{% endfilename %} + +```python +>>> User.objects.all() +]> +``` + +作成しておいたスーパーユーザがいますね。このユーザを取り出してみましょう(この行をご自身で作ったスーパーユーザのユーザ名に変更して取り出してくださいね)。 + +{% filename %}command-line{% endfilename %} + +```python +>>> me = User.objects.get(username='ola') +``` + +ola という `ユーザ名` の `User` モデルのインスタンスを、`取り出せ` たでしょう?よかった! + +さあ、遂にコンソール画面から、最初のポストを作成出来ますね。 + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') + +``` + +どうでしょうか?ちゃんと出来ているか、確認しておきましょうね。 + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, , ]> +``` + +出来ていますね!リストに新しいポストが1つ追加されています。 + +### さらに投稿を追加しましょう + +楽しくなってきたでしょう?理解を深めるためにもう少しポストを作っておきましょう。2〜3個記事を追加したら、次に進みましょう。 + +### オブジェクトの抽出 + +クエリセットの大部分は、抽出機能だと言えるでしょう。 ユーザolaさんのポストを全部確認してみましょうか。 全部のポストを取り出すのではなく、olaさんのポストだけを取り出したい場合は、`Post.objects.all()` の `all` を `filter` に変更します。 取り出されるブログポストが満たす条件を、カッコ()の中に指定します。 今回の例では、`author` が `me` と等しいという条件です。 Djangoでの表し方は、`author=me` となります。 このようになりますね。 + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(author=me) +, , , ]> +``` + +もしかすると `title` フィールドに title という単語が含まれているポストだけを取り出したくなるかもしれませんね。 + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(title__contains='title') +, ]> +``` + +> **Note** `title` と `contains` の間に、アンダーバー (`_`) が2個続いていますが、 これはDjangoのORMの構文です。フィールド名のtitleと、照合タイプのcontainsを、2つのアンダーバーで連結させています。 もしアンダーバーが1個だけだと、title_contains というフィールド名だと判断されてしまい、エラーになります。("FieldError: Cannot resolve keyword title_contains") + +また、公開済みの全ポストを取り出すことも出来ます。それには、`published_date` が現在以前の全ポストを取り出します。 + +{% filename %}command-line{% endfilename %} + +```python +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) + +``` + +そうでした、残念なことに、コンソールから追加したポストはまだ公開されていませんね。じゃあ、ポストを公開してみるとしましょう。まず公開するポストを決めましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> post = Post.objects.get(title="Sample title") +``` + +そして、`publish` メソッドを呼び出します。 + +{% filename %}command-line{% endfilename %} + +```python +>>> post.publish() +``` + +じゃあ、もう一度公開済みのポストを取り出しましょう。(上方向キーを3回押せば、さっきのコマンドを呼び出せるでしょう。コマンドを表示出来たら、`Enter` キーを押してみましょう) + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +]> +``` + +### オブジェクトの並び替え + +クエリセットは、オブジェクトのリストの並べ替えもやってくれます。試しに `created_date` フィールドで並べ替えてみましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.order_by('created_date') +, , , ]> +``` + +逆順、つまり新しく追加した順に並べ替えることも出来ます。それには、`-`(ハイフン)を使います。 + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.order_by('-created_date') +, , , ]> +``` + +### メソッドチェーンによる複雑なクエリ + +ご覧のように、`Post.objects`の一部のメソッドはクエリセットを返します。 逆に同じメソッドをクエリセットについて呼び出すこともでき、そうすると新しいクエリセットが返ります。 よって、**つなげる**ことで、メソッドの返すクエリセットを組み合わせることができます: + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> +``` + +クエリセットをつなげるのは本当に強力です。つなげていくことでとても複雑なクエリも書くことが出来ます。 + +いいですね!次の章への準備は万端ですね!このプロンプトを閉じるには、以下のようにします。 + +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` \ No newline at end of file diff --git a/ja/django_start_project/README.md b/ja/django_start_project/README.md new file mode 100644 index 00000000000..6bd176747bc --- /dev/null +++ b/ja/django_start_project/README.md @@ -0,0 +1,207 @@ +# プロジェクトを作成しよう! + +> このチャプターの一部はGeek Girls Carrotsのチュートリアルをもとにしています。(https://github.com/ggcarrots/django-carrots) +> +> このチャプターの一部は Creative Commons Attribution-ShareAlike 4.0 International License のライセンスによる [django-marcador tutorial](http://django-marcador.keimlink.de/) をもとにしています。 この django-marcador tutorial は Markus Zapke-Gründemann たちが著作権を保有しています。 + +ここからは、小さなブログを作っていきますよ! + +最初のステップは、Djangoのプロジェクトを新しく作成します。 基本的に、Djangoのスクリプトを実行しDjangoプロジェクトの骨格を作ります。 スクリプトは、これから使う沢山のファイルやディレクトリを自動生成します。 + +Djangoでは、ファイルやディレクトリの名前がとても重要です。 作成されたファイルの名前は変えるべきではありません。 ファイルを移動させるのもいいアイディアとはいえません。 Djangoでは、重要なファイルを決められたファイル構成で作成しておくことが必要です。 + +> virtualenv(仮想環境)を実行しているでしょうか。 もしコンソールのプロンプトの前に `(myvenv)` という文字が表示されていない時は、virtualenv が実行されていないので、有効にする必要があります。 **Djangoのインストール** のチャプターの **仮想環境の操作** のパートで、仮想環境を実行する方法について説明しました。 Windowsでは、`myvenv\Scripts\activate`、MacOS や Linux では、 `source myvenv/bin/activate` というコマンドを入力すると有効にできます。 + + + +MacOS や Linux の場合は、コンソールで以下のコマンドを実行します。**最後のピリオド(ドット) `.` を忘れないようにしてください!** + +{% filename %}コマンドライン{% endfilename %} + + (myvenv) ~/djangogirls$ django-admin startproject mysite . + + +> コマンドの最後にピリオド `.` を入力したことを確認してくださいね。このピリオドは、現在の作業ディレクトリに Django をインストールするということを示しています (ピリオド `.` は、現在のディレクトリを表す省略表記です)。 +> +> **メモ:** 上記のコマンドを入力するときは、`django-admin` で始まる部分のみを入力することを忘れないでください。 ここに書いた `(myvenv) ~/djangogirls$` の部分は、コマンドライン上で入力を受け付けることを示しているプロンプトの一例なので、人によって違うかもしれません。 + + + + + +Windows の場合は、以下のコマンドを実行しないといけません。**(最後にピリオド (ドット) `.` を書いてください)** + +{% filename %}コマンドライン{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . + + +> コマンドの最後にピリオド (.) があることを確認してくださいね。これば、現在の作業ディレクトリにDjangoをインストールするということを示すので、とても重要なのです。(ピリオドは簡略表記です). +> +> **メモ:** 上記のコマンドを入力するときは、`django-admin` で始まる部分のみを入力することを忘れないでください。 ここに書いた `(myvenv) ~/djangogirls$` の部分は、コマンドライン上で入力を受け付けることを示しているプロンプトの一例なので、人によって違うかもしれません。 + + + +django-admin.py は、必要なディレクトリとファイルを作成するスクリプトです。次のようなファイル構造が作成されましたね。: + + djangogirls + ├── manage.py + ├── mysite + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + + +> **注**:ディレクトリ構造には、以前作成した`myvenv`ディレクトリもあります。 + +`manage.py`はサイトの管理に役立つスクリプトです。 それを使用して、他のものをインストールすることなく、私たちのコンピュータ上でWebサーバーを起動することができます。 + +`settings.py`ファイルには、ウェブサイトの設定が含まれています。 + +手紙を送付する場所を確認する郵便業者について話した事を覚えていますか? `urls.py`ファイルには、`urlresolver`(Djangoがビューを見つける仕組みです。Django URLのチャプターで説明します)で使用されるパターンのリストが含まれています。 + +私たちが変更しない他のファイルを今は無視しましょう。 覚えておくべき唯一の事は、間違えてそれらを削除しないことです! + +## 設定変更 + +`mysite/settings.py`にいくつか変更を加えましょう。 前にインストールしたコードエディタを使用してファイルを開きます。 + +**注**:`settings.py`は他のものと同じように通常のファイルであることに注意してください。 「ファイルを開く」メニューを使用して、コードエディタ内から開くことができます。 これにより、`settings.py`ファイルに移動して選択できる通常のウィンドウが表示されます。 あるいは、デスクトップのdjangogirlsフォルダに移動して右クリックしてファイルを開くこともできます。 次に、リストからコードエディタを選択します。 インストールされた他のプログラムでは、ファイルを開けても編集できないかもしれないので、エディタの選択は重要です。 + +私たちのWebサイトが正しい時間で動くといいでしょう。 [Wikipediaのタイムゾーンのリスト](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)に移動して、関連するタイムゾーン (TZ) をコピーします (例:`Asia/Tokyo`)。 + +`settings.py` の中から `TIME_ZONE` と書かれた行を探してください。この行はタイムゾーンを表しているので、自分が住んでいるタイムゾーンに合わせて修正しましょう。たとえば、次のように書きます。 + +{% filename %}mysite/settings.py{% endfilename %} + +```python +TIME_ZONE = 'Asia/Tokyo' +``` + +言語コードは、言語(例えば、英語の場合は`en`、ドイツ語の場合は`de`のように表します)と、国コード(例えば、ドイツの場合は`de`、スイスの場合は`ch`のように表します)からできています。 あなたの母国語が英語でない場合、これを追加すると、Djangoのデフォルトのボタンや通知が設定した言語に変更されます。 ですのでたとえば「Cancel」ボタンがここで定義した言語に翻訳されます。 [Djangoは多くの言語に対応しています。](https://docs.djangoproject.com/ja/5.1/ref/settings/#language-code) + +別の言語を使用する場合は、次の行を変更して言語コードを変更します。 + +{% filename %}mysite/settings.py{% endfilename %} + +```python +LANGUAGE_CODE = 'ja' +``` + +静的ファイルのパスも追加する必要があります。 (静的ファイルとCSSについては、後ほどチュートリアルで説明します)。ファイルの*一番下*に移動し、`STATIC_URL`の下に `STATIC_ROOT`を追加します。: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +STATIC_URL = '/static/' +STATIC_ROOT = BASE_DIR / 'static' +``` + +`DEBUG` が `True` に設定されていて、`ALLOWED_HOSTS` が空のリストの時は、自動的に `['localhost', '127.0.0.1', '[::1]']` という3つのホストに対してチェックが行われます。 このままの設定では、これから私たちがデプロイして使う PythonAnywhere のホストネームが含まれていません。ですから、次のように設定を変更します。 + +{% filename %}mysite/settings.py{% endfilename %} + +```python +ALLOWED_HOSTS = ['127.0.0.1', '.pythonanywhere.com'] +``` + +> **メモ**: Chromebook を使っている人は、次の1行を settings.py ファイルの最後に追加してください。 `MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'` +> +> cloud9を使っている人は、 `ALLOWED_HOSTS` に、`.amazonaws.com` を追加しましょう。 + +## データベースをセットアップする + +あなたのサイトのデータを保管することができるデータベース・ソフトウェアには、たくさんの種類があります。今は、Django がデフォルトで使う `sqlite3` というデータベースを使うことにします。 + +この設定はすでに `mysite/settings.py` ファイルの中に次のように書かれています。 + +{% filename %}mysite/settings.py{% endfilename %} + +```python +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} +``` + +ブログのデータベースを作成するには、コンソールで次のコードを実行してみましょう: `python manage.py migrate` (`manage.py`ファイルのある`djangogirls`ディレクトリにいる必要があります) 。 うまくいったら次のように表示されるでしょう: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py migrate + Operations to perform: + Apply all migrations: auth, admin, 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 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 sessions.0001_initial... OK + + +終わったら、 Webサーバーを起動し、私たちのWebサイトが動作しているかどうかを確認する時間です。 + +## ウェブサーバを起動する + +コマンドラインやコマンドプロンプトで`manage.py`ファイルを含むディレクトリ(`djangogirls`ディレクトリ)に移動してください。 `python manage.py runserver`を実行してWebサーバーを起動できます。 + +{% 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 + + +Windows上で、`UnicodeDecodeError`で失敗した場合は、代わりに次のコマンドを使用します。 + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + + +Webサイトが動いていることを確認してください。ブラウザで以下のアドレスを開いてみましょう。(Firefox, Chrome, Safari, Internet Explorerなど、好きなブラウザを使って大丈夫です) + +{% filename %}ブラウザ{% endfilename %} + + http://127.0.0.1:8000/ + + +Chromebook と Cloud9 を利用している場合は、Webサーバーが起動しているコマンド画面の右上に現れるポップアップウィンドウの中のURLをクリックしましょう。 URLはこんな感じになっていると思います。 + +{% filename %}ブラウザ{% endfilename %} + + https://.vfs.cloud9.us-west-2.amazonaws.com + + +おめでとう! たった今、あなたは最初のウェブサイトを作って、それをWebサーバーの上で起動しました! 素晴らしいですね! + +![インストールできました!](images/install_worked.png) + +コマンド画面は、一度に一つのコマンドしか実行できません。先程開いたコマンド画面では、Webサーバーが今動いています。 Webサーバーが動いている間、次のリクエストを待っています。このコマンドラインに新しいテキストを書いても、新しいコマンドとして実行しません。 + +> Webサーバーの仕組みについては、「インターネットの仕組み」の章を参照してください。 + +Webサーバーを動かしながら、新たにコマンドを入力したい場合は、新しいコマンドプロンプトのウィンドウを開いて、仮想環境を起動してから入力しましょう。2つ目のウィンドウを開く方法が分からなくなったら、[コマンドラインを使ってみよう](../intro_to_command_line/README.md)の章に戻ってやり方を確認しましょう。 Webサーバーを停止するには、実行中のウィンドウに戻り、CTRL + C - ControlキーとCキーを同時に押します(WindowsではCtrl + Breakキーを押す必要があります)。 + +次のステップに進む準備はできましたか? 今度は実際にコンテンツを作り始めましょう! diff --git a/ja/django_start_project/images/install_worked.png b/ja/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..4354c634ddb Binary files /dev/null and b/ja/django_start_project/images/install_worked.png differ diff --git a/ja/django_templates/README.md b/ja/django_templates/README.md new file mode 100644 index 00000000000..3cfe2ed7e36 --- /dev/null +++ b/ja/django_templates/README.md @@ -0,0 +1,108 @@ +# Djangoテンプレート + +何かデータを表示しましょう!Djangoはそれをビルトインの **テンプレートタグ** で実現できます。 + +## テンプレートタグとは? + +HTML中で本当はPythonのコードを書くことはできません。なぜならブラウザが理解できないからです。ブラウザはHTMLだけ分かります。HTMLはどちらかというと静的で、それに対してPythonはもっとずっと動的なことを私たちは知っています。 + +**Djangoテンプレートタグ** はHTMLにPyhtonのようなコードを埋め込むことができて、動的なウェブサイトがより早く簡単に作れます! + +## ブログ一覧テンプレートの表示 + +前の章で、`posts` 変数でテンプレートに記事のリストを渡しました。今からHTMLで表示をしてみましょう。 + +Djangoテンプレートで変数を表示するためには、次のように変数の名前を二重中括弧で括ります。 + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{{ posts }} +``` + +これを `blog/templates/blog/post_list.html` テンプレートでやってみましょう。 エディタでこのファイルを開き、2つめの `
` から3つめの `
` までをまるごと `{{ posts }}` に置き換えて下さい。 ファイルを保存してページをリロードすると: + +![図 13.1](images/step1.png) + +見たとおり、このようになります。 + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +, ]> +``` + +Djangoはposts変数をオブジェクトのリストと認識します。 **Python入門**でどうやってリストを表示できたか覚えていますか? ループを使ってリストを表示しましたよね。 Djangoテンプレートではこう書きます: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% for post in posts %} + {{ post }} +{% endfor %} +``` + +これをブログのテンプレートで使ってみましょう。 + +![図 13.2](images/step2.png) + +動きましたね。 しかし、本当は**HTML入門**で作った静的な記事のように表示してほしいところです。 そこで、HTMLとテンプレートタグを混ぜてみましょう。 `body` タグの中を次のように書いてください: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +
+ +{% for post in posts %} +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` + +{% raw %}`{% for %}` と `{% endfor %}` の間に書いたものはリスト中の各オブジェクトの分だけ繰り返されます。ページをリロードしてみましょう。{% endraw %} + +![図 13.3](images/step3.png) + +post変数がさっきと違って、`{{ post.title }}` や `{{ post.text }}` になっていることに気づきましたか? `Post` モデルで定義したそれぞれのフィールドにアクセスしています。 `|linebreaksbr` はpostのテキスト中の改行を段落に変換するフィルタに通すという意味です。 + +## もう一つ... + +今の時点でのウェブサイトを公開して見てみませんか?もう一度PythonAnywhereでデプロイしてみましょう。デプロイのステップをおさらいします。 + +* まず、GithubにあなたのコードをPushしましょう + +{% filename %}command-line{% endfilename %} + + $ git status + [...] + $ git add --all . + $ git status + [...] + $ git commit -m "Modified templates to display posts from database." + [...] + $ git push + + +* そしたら、[PythonAnywhere](https://www.pythonanywhere.com/consoles/)に戻って、**Bashコンソール**(か、新しいコンソール)に入って、次のようにコマンドを打ちましょう: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd .pythonanywhere.com + $ git pull + [...] + + +(忘れずに `` を自分のPythonAnywhereのサブドメイン名に置き換えましょう、<> は不要です。) + +* 最後にPythonAnywhereの[「Web」ページ](https://www.pythonanywhere.com/web_app_setup/)を開いて、アプリを**リロード**(Reload)します。 (コンソールからPythonAnywhereの他のページにアクセスするには、右上のメニューボタンを使います。)更新された内容が、 https://subdomain.pythonanywhere.com に反映されているはずです。ブラウザで確認してみましょう! PythonAnywhereサイトで表示されるブログの記事が、あなたのパソコンの中のローカルサーバーのものと違っていても大丈夫です。 ローカルコンピュータにあるデータベースと、PythonAnywhere上のデータベースは同期していません。 + +頑張りましたね! さぁ、ここまでできたら、Django 管理画面から新しい投稿を追加してみましょう。(published_date 公開日の設定を忘れずに!)投稿を追加する時、PythonAnywhereのサイトの管理画面()であることを確認してください 。できたら、リロードして投稿したものが表示されるか見てみましょう。 + +うまく動きましたか?ここまでよく頑張りましたね!少しパソコンから離れて、休憩をとりましょう。^_^ + +![図 13.4](images/donut.png) diff --git a/ja/django_templates/images/donut.png b/ja/django_templates/images/donut.png new file mode 100644 index 00000000000..f31cebdc8a3 Binary files /dev/null and b/ja/django_templates/images/donut.png differ diff --git a/ja/django_templates/images/step1.png b/ja/django_templates/images/step1.png new file mode 100644 index 00000000000..cbf6420360a Binary files /dev/null and b/ja/django_templates/images/step1.png differ diff --git a/ja/django_templates/images/step2.png b/ja/django_templates/images/step2.png new file mode 100644 index 00000000000..fd6269c837c Binary files /dev/null and b/ja/django_templates/images/step2.png differ diff --git a/ja/django_templates/images/step3.png b/ja/django_templates/images/step3.png new file mode 100644 index 00000000000..b471fdd4d7b Binary files /dev/null and b/ja/django_templates/images/step3.png differ diff --git a/ja/django_urls/README.md b/ja/django_urls/README.md new file mode 100644 index 00000000000..5b91eb35257 --- /dev/null +++ b/ja/django_urls/README.md @@ -0,0 +1,103 @@ +# Django URL + +もうすぐ最初のWebページ、あなたのブログのホームページを作るところです!でも最初に、ちょっとだけDjangoのURLについて学びましょう。 + +## URLとは? + +URLはWeb上のアドレスです。 サイトのURLは、ブラウザのアドレスバーで見ることができます。 (そう、 `127.0.0.1:8000` や `http://djangogirls.com` がURLです。) + +![URL](images/url.png) + +インターネット上のすべてのページには、独自のURLが必要です。 それによって、これから作るアプリケーションが、URLを指定してアクセスしてきたユーザに、何を見せたらいいのかわかるのです。 Djangoでは `URLconf`(URL設定)と呼ばれるものを使います。 URLconfはパターンの集まりで、適切なビューを見つけるために、DjangoがリクエストされたURLと照合するものです。 + +## DjangoでURLはどのように機能する? + +`mysite/urls.py` を開いて、中身をみてみると: + +{% filename %}mysite/urls.py{% endfilename %} + +```python +"""mysite URL Configuration + +[...] +""" +from django.contrib import admin +from django.urls import path + +urlpatterns = [ + path('admin/', admin.site.urls), +] +``` + +ご覧のとおり、Djangoは既にこのようなものを置いてくれています。 + +三重クオート( `'''` や `"""` )で囲まれた行は、docstringとよばれるコメント行です。ファイル、クラス、またはメソッドの先頭に記述して、それが何をするかを説明するのに用います。 これはPythonによって実行されない行です。 + +前の章で訪れたadminのURLについてはすでに書いてありますね。 + +{% filename %}mysite/urls.py{% endfilename %} + +```python + path('admin/', admin.site.urls), +``` + +`admin/` で始まる全てのURLについて、Djangoが返すべき*ビュー*をこの行で指定しています。 今回の場合、adminで始まるURLをたくさん作ることになりますが、その全てをこの小さいファイルに書くようなことはしません。この方がきれいで読みやすいですし。 + +## あなたの初めてDjango URL! + +さあ最初のURLを作りましょう!'http://127.0.0.1:8000/' をブログの入口ページにして、投稿したブログポストのリストを表示するようにしたいと思います。 + +`mysite/urls.py` ファイルは簡潔なままにしておきたいので、`mysite/urls.py` では`blog` アプリからURLをインポートするだけにしましょう。 + +まず、`blog.urls` をインポートする行を追加しましょう。 ここで、`include`関数を使いたいので、`from django.urls…`の行を変更し、そのインポートを追加する必要があります。 + +`mysite/urls.py` ファイルはこのようになります: + +{% filename %}mysite/urls.py{% endfilename %} + +```python +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('blog.urls')), +] +``` + +これでDjangoは'http://127.0.0.1:8000/' に来たリクエストは `blog.urls` へリダイレクトするようになり、それ以降はそちらを参照するようになります。 + +## blogのURL + +`blog` ディレクトリの下に、新しく `urls.py` という空のファイルを作って、コードエディタで開いて下さい。そして最初の2行を以下のように書きます: + +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views +``` + +これはDjangoの `path` 関数と、`blog` アプリの全ての `ビュー`(といっても、今は一つもありません。すぐに作りますけど!)をインポートするという意味です。 + +その後、最初のURLパターンを追加します。 + +{% filename %}blog/urls.py{% endfilename %} + +```python +urlpatterns = [ + path('', views.post_list, name='post_list'), +] +``` + +見てのとおり、`post_list` という名前の `ビュー` をルートURLに割り当てています。 このURLパターンは空の文字列に一致します。Djangoはビューを見つけるとき、URLのパス(path)の前にくっつくドメイン名(つまり、http://127.0.0.1:8000/ の部分)を無視します。 このパターンは誰かがあなたのWebサイトの 'http://127.0.0.1:8000/' というアドレスにアクセスしてきたら `views.post_list` が正しい行き先だということをDjangoに伝えます。 + +最後の `name='post_list'` は、ビューを識別するために使われるURL の名前です。 これはビューと同じ名前にすることもできますが、全然別の名前にすることもできます。 プロジェクトでは名前づけされたURLを後で使うことになるので、アプリのそれぞれのURLに名前をつけておくのは重要です。また、URLの名前はユニークで覚えやすいものにしておきましょう。 + +もし今 http://127.0.0.1:8000/ にアクセスしたら、'web page not available' のようなメッセージが出るでしょう。 これはサーバー( `runserver` ってタイプしたのを覚えていますか?)が動いていないからです。 なぜこうなったのかを知るためにサーバーのコンソール画面を見てみましょう。 + +![エラー](images/error1.png) + +エラーが表示されていますね。でも心配しないで。これはむしろ、結構便利なものなんですよ:ここでは、**'post_list' という属性(attribute)がない**ことを知らせてくれています。 これは *ビュー* の名前で、Djangoが探して使おうとしましたが、私たちはこれをまだ作っていませんでした。 現時点では、`/admin/` も動作していないと思います。 心配しなくて大丈夫です。ちゃんとできますから。 別のエラーメッセージが表示された場合は、Webサーバーを再起動してみてください。 これを行うには、Webサーバーを実行しているコンソールウィンドウで、Ctrl + C(CtrlキーとCキーを同時に押す)で停止します。 Windowsの場合、Ctrl + Breakかもしれません。 その後、`python manage.py runserver`を実行してWebサーバーを再起動します。 + +> Django URLconfについてもっと知りたい場合は、公式のドキュメントを見て下さい。 https://docs.djangoproject.com/ja/5.1/topics/http/urls/ diff --git a/ja/django_urls/images/error1.png b/ja/django_urls/images/error1.png new file mode 100644 index 00000000000..50618fca3fe Binary files /dev/null and b/ja/django_urls/images/error1.png differ diff --git a/ja/django_urls/images/url.png b/ja/django_urls/images/url.png new file mode 100644 index 00000000000..c22441e930e Binary files /dev/null and b/ja/django_urls/images/url.png differ diff --git a/ja/django_views/README.md b/ja/django_views/README.md new file mode 100644 index 00000000000..9964ded5667 --- /dev/null +++ b/ja/django_views/README.md @@ -0,0 +1,44 @@ +# Djangoビュー – 今こそ作りましょう! + +それでは前の章の続きをやりましょう。確かビューの作成がまだだったので、エラーになっていましたね!:) + +*ビュー* はアプリのロジックを書いていくところです。 ビューは、以前あなたが作った `モデル` に情報を要求し、それを `テンプレート` に渡します。 テンプレートは、次の章で作ります。 ビューはただのPythonの関数です。**Python入門**の章で書いたものよりもちょっと複雑なだけですよ。 + +ビューは、`views.py` に記述します。私たちの場合 `blog/views.py` に書くことになります。 + +## blog/views.py + +では、早速 blog/views.py をコードエディタで開いて何があるか見てみましょう: + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render + +# Create your views here. +``` + +まだ何もないですね。 + +`#` で始まる行は、コメントです。この行に書いたものはPythonは無視します。 + +それでは、次のようなちょっとした *ビュー* を作ってみましょう。 + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` + +見てのとおり、`post_list` という関数(`def` から始まる部分のことです)を作りました。これは `request` を引数に取ります。`blog/post_list.html` テンプレートを(色々なものを合わせて)組み立てる `render` という関数を呼び出して得た値を `return` しています。 + +ファイルを保存したら、どんな風に表示されるか、ブラウザで http://127.0.0.1:8000/ を確認してみましょう。 + +今度は別のエラーになりましたね。なんと書いてあるでしょうか。 + +![エラー](images/error.png) + +サーバーは実行されていることはわかるのですが、正しく表示されないのはなぜでしょう? 心配しないで!ただのエラーページです! コンソールでのエラーメッセージと同じように、これは実際にかなり便利です。 *TemplateDoesNotExist* と書いてありますね。 それでは次の章でテンプレートを作って、エラーを解決しましょう! + +> Djangoのビューについてもっと知りたいのなら、公式ドキュメントをぜひ読んでみてください。 https://docs.djangoproject.com/ja/5.1/topics/http/views/ diff --git a/ja/django_views/images/error.png b/ja/django_views/images/error.png new file mode 100644 index 00000000000..2ef613c8a5d Binary files /dev/null and b/ja/django_views/images/error.png differ diff --git a/ja/dynamic_data_in_templates/README.md b/ja/dynamic_data_in_templates/README.md new file mode 100644 index 00000000000..931797e2031 --- /dev/null +++ b/ja/dynamic_data_in_templates/README.md @@ -0,0 +1,81 @@ +# テンプレート内の動的データ + +ポスト内容を保存する為の Post モデルは、 models.py に定義しました。ポストの一覧を表示する post_list は views.py にあり、そこにテンプレートも加わりました。 これらを準備しましたが、実際のところ、ポストをどうやってHTMLファイルに出力すればいいのでしょうか? 大まかなイメージとしては、データベースに保存された記事を取り出して、テンプレートのHTMLファイルの中に行儀よく並べれば良さそうですね。 + +正確には、*ビュー *が モデルとテンプレートの橋渡しをしてくれます。 私達が作業している `post_list ` *ビュー *の場合、表示したいデータを取り出して、テンプレートファイルに渡すことになります。 どのモデルのデータを、どのテンプレートに表示させるかを、 *ビュー*に 記述します。 + +それでは、実際にやってみましょう。 + +まず`blog/views.py`をエディタで開きます。今のところ `post_list`*ビュー* は、以下のようになっているでしょう。 + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render + +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` + +少し前に、別のファイルに用意したコードをどうやってインクルードするか説明したのですけれど、覚えていますか? それでは `models.py` のモデルを、インクルードしてみましょう。 `from .models import Post` という行を追加してみます。 + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from .models import Post +``` + +`models` の前にあるドットは *カレントディレクトリ* 、もしくは *カレントアプリケーション *のことです。 ` views.py `と `models.py `は、同じディレクトリに置いてあります。 だから、こんな風に`.`とファイル名だけを使って、簡単に記述することが出来るのです。(ファイル名の拡張子`.py `は必要ないです) そして、モデルの名前を指定してインポートします(この場合のモデルは `Post `ですね)。 + +さて、次にすべきことは、実際に `Post `モデルからブログの記事を取り出すことですが、それには `クエリセット `が必要です。 + +## クエリセット + +もう、クエリセットの働きについては、知っていますよね。[Django ORM(クエリセット)](../django_orm/README.md) チャプター で勉強しました。 + +公開したブログ記事を `published_date `で並べ替えをしたいですね。これも、クエリセットの章でやったので、大丈夫ですね? + +{% filename %}blog/views.py{% endfilename %} + +```python +Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +``` + +それでは `blog/views.py`をエディタで開いて、このコードを`def post_list(request)`で始まる関数の中に加えましょう。`from django.utils import timezone`をまず追加するのを忘れないでくださいね。 + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from django.utils import timezone +from .models import Post + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {}) +``` + +最後に残っているのは、クエリセットを参照している変数` posts `をテンプレートに渡す作業です。テンプレートでの表示については次の章でやりましょう。 + +作成したクエリセットは、*変数* `posts `で参照できることに、注意しましょう。この 変数 posts を使って、クエリセットのデータにアクセスします。これから先 posts というと、このクエリセットのことです。 + +`render `関数では、既にパラメータとして `request `とテンプレートファイル `'blog/post_list.html' `が渡されています。リクエストというのは、インターネットを介してユーザから受け取った全ての情報が詰まったものです。最後のパラメータに注目してください。 ` {} `こんな風に書かれていますね。この中に指定した情報を、テンプレートが表示してくれます。{} の中に引数を記述する時は、名前と値をセットにしなくてはなりません。 表示させたいのはクエリセットのデータなので、 `posts` を指定しましょう。 :) `{'posts': posts}`という具合に、記述します。 注意して欲しいのは、シングルクォートです。 `:`(コロン) で区切られた、前の方の posts は、 シングルクォート で囲まれて、 'posts' になっていますよね。こちらが名前で、後ろの方の posts は値、クエリセットのことです。 + +最終的に `blog/views.py `は、以下の様になるはずです。 + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render +from django.utils import timezone +from .models import Post + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {'posts': posts}) +``` + +どうでしたか?次は、このクエリセットをテンプレートで表示させるところを、やってみましょう。 + +Djangoのクエリセットについて、もっと知りたければこちらも読んでみてくださいね。 https://docs.djangoproject.com/ja/5.1/ref/models/querysets/ diff --git a/ja/extend_your_application/README.md b/ja/extend_your_application/README.md new file mode 100644 index 00000000000..b650243e077 --- /dev/null +++ b/ja/extend_your_application/README.md @@ -0,0 +1,214 @@ +{% set warning_icon = '' %} + +# アプリケーションを拡張しよう + +もうウェブサイトを作るのに必要な全ての章は終わりました。モデル、URL、ビュー、テンプレートの書き方はわかっていますし、またウェブサイトを素敵にするやり方もわかります。 + +さあ練習しましょう! + +ブログに最初に必要なものはおそらく、記事を表示するページですよね。 + +もう`Post`モデルが入っていますから、`models.py`は追加する必要はありません + +## 投稿の詳細へのテンプレートリンクを作成する + +`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.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +{% raw %}投稿リストの投稿のタイトルから投稿の詳細ページへのリンクを作りたいです。 投稿の詳細ページにリンクするように`

{{ post.title }}

`を変更しましょう。{% endraw %} + +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} + +```html +

{{ post.title }}

+``` + +{% raw %}不思議な` {% url 'post_detail' pk = post.pk %}`を説明します。 気づいたかもしれませんが、`{% %}`という表記はDjangoのテンプレートタグを使用していることを意味しています。 今私たちはこれをURLを作るために使います!{% endraw %} + +`post_detail`の部分は、Djangoが`blog/urls.py`に書かれた name=post_detail のURLを待ち受けることを表しています。 + +そして`pk=post.pk`についてはどうでしょうか? `pk`はプライマリキーの略で、データベースの各レコードのユニークな名前です。 `Post`モデルでプライマリキーを指定しなかったので、Djangoは私たちのために1つのキーを作成し(デフォルトでは、各レコードごとに1ずつ増える数字で、たとえば1、2、3です)、各投稿に`pk`というフィールド名で追加します。 `Post`オブジェクトの他のフィールド(`title`、`author`など)にアクセスするのと同じ方法で、`post.pk`と書くことによってプライマリキーにアクセスします! + +さて、私たちが http://127.0.0.1:8000/ に行くとエラーが出ます(知っての通り、URLも`post_detail`の*ビュー*もまだ作っていないので)。 このようになります: + +![NoReverseMatch error](images/no_reverse_match2.png) + +## 投稿の詳細へのURLを作成する + +`post_detail` *ビュー*用に`urls.py`にURLを作成しましょう! + +最初の投稿の詳細がこの**URL**で表示されるようにします:http://127.0.0.1:8000/post/1/ + +投稿の内容を表示する`post_detail`という*ビュー*をDjangoに示すように、`blog/urls.py`ファイルでURLを作りましょう。 `blog/urls.py`をエディタで開いて、`path('post//', views.post_detail, name='post_detail'),`という行を追加しましょう。ファイルは次のようになるでしょう。 + +{% filename %}{{ warning_icon }} blog/urls.py{% endfilename %} + +```python +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), +] +``` + +`post//` の部分はURLパターンを指定しています。それについて説明しましょう: + +- `post/` はURLが **post** に続けて **/** で始まることを意味します。ここまでは順調ですね。 +- `` – この部分はトリッキーです。これはDjangoは整数の値を期待し、その値が`pk`という名前の変数でビューに渡されることを意味しています。 +- `/` – それからURLの最後に再び **/** が必要です。 + +つまり、ブラウザに`http://127.0.0.1:8000/post/5/`を入力すると、Djangoは`post_detail`という*ビュー*を探していると理解します。そして`pk`が`5`という情報をその*ビュー*に転送します。 + +よし、私たちは `blog/urls.py` に新しい URL パターンを追加しました! ページを更新しましょう:http://127.0.0.1:8000/ ドーン! サーバーが再び実行を停止しました。 コンソールを見てください - 予想通り、もう一つのエラーがあります! + +![AttributeError](images/attribute_error2.png) + +あなたは次のステップが何であるか覚えていますか? ビューを追加する!ですね。 + +## 投稿の詳細ビューを追加する + +今回は*ビュー*に追加のパラメータ`pk`が与えられます。 私たちの*ビュー*はそれを受け取る必要がありますね? そこで関数を`def post_detail(request, pk):`として定義します。 `urls`で指定した名前(`pk`)とまったく同じ名前を使用する必要があることに注意してください。 この変数を省略するのは正しくないのでエラーになってしまいます! + +今、私たちは1つだけブログ投稿を取得したいと考えています。 これを行うには、次のようなクエリセットが使用できます。 + +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} + +```python +Post.objects.get(pk=pk) +``` + +しかし、このコードには問題があります。 与えられた`プライマリキー`(`pk`)を持つ`Post`が存在しない場合、とてもダサいエラーが発生します。 + +![DoesNotExist error](images/does_not_exist2.png) + +私たちはそれを望んでいません! しかし幸運にもDjangoにはそれを処理するものがあります:`get_object_or_404` です。 与えられた`pk`の`Post`がない場合、前よりもっとよい `Page Not Found 404` ページが表示されます。 + +![Page not found](images/404_2.png) + +いい知らせとして実際には自分の`Page not found`ページを作って自分の好きなようにきれいにすることができます。しかしそれは今すごく重要ではないので、私たちはそれをスキップします。 + +よし、今こそ*ビュー*を`views.py`ファイルに追加するときです! + +`blog/urls.py`では`views.post_detail`というビューを参照する`post_detail`という名前のURLルールを作成しました。 これは、Djangoが`blog/views.py`内の`post_detail`というビュー関数を待っていることを意味します。 + +`blog/views.py`をコードエディタで開き、他の`from`行の近くに次のコードを追加する必要があります。 + +{% filename %}blog/views.py{% endfilename %} + +```python +from django.shortcuts import render, get_object_or_404 +``` + +ファイルの最後に*ビュー*を追加します: + +{% filename %}blog/views.py{% endfilename %} + +```python +def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) +``` + +ページを更新してみましょう:http://127.0.0.1:8000/ + +![Post list view](images/post_list2.png) + +出来ましたね! しかし、ブログ投稿のタイトルのリンクをクリックするとどうなりますか? + +![TemplateDoesNotExist error](images/template_does_not_exist2.png) + +あらいやだ! 別のエラー! しかし、私たちはすでにそれに対処する方法をすでに知っていますね。 そう!テンプレートを追加する必要があります! + +## 投稿の詳細へのテンプレートリンクを作成する + +`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 %} +
+ {{ post.published_date }} +
+ {% endif %} +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endblock %} +``` + +もう一度`base.html`を拡張します。 `content`ブロックでは、投稿の公開日(存在する場合)、タイトル、およびテキストを表示します。 ここで重要なポイントについて見てみます。 + +{% raw %}`{% if ... %} ... {%endif%}`は、何かをチェックしたいときに使用できるテンプレートタグです。 (`if ... else...`を**Python入門**のチャプターでやったのを覚えていますか?) この場合、投稿の`published_date`(公開日)が空でないかを確認します。{% endraw %} + +これで、ページを更新して`TemplateDoesNotExist`がもうなくなったかどうか確認できます。 + +![Post detail page](images/post_detail2.png) + +イェーイ!うまくできていますね! + +# デプロイの時間です! + +あなたのウェブサイトがまだPythonAnywhere上で動くとしたらいいでしょう?またデプロイしてみましょう。 + +{% filename %}command-line{% endfilename %} + + $ 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 + + +それから、[PythonAnywhere Bash コンソール](https://www.pythonanywhere.com/consoles/)で: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(``の部分を、自分の実際のPythonAnywhereのサブドメイン名に山カッコをはずして置き換えることを忘れずに。) + +## サーバー上の静的ファイルの更新 + +PythonAnywhereのようなサーバは、(CSSファイルのような)「静的ファイル」をPythonファイルとは違って扱うのが好きです。なぜなら、それらが高速に読み込まれるように最適化できるからです。 その結果、CSSファイルを変更するたびに、サーバー上で追加のコマンドを実行して、更新するように指示する必要があります。 コマンドは`collectstatic`です。 + +もし仮想環境(virtualenv)が有効になっていなければ有効化するところから始めましょう (PythonAnywhereではこれを行うために`workon`というコマンドを使用します。これはあなたが自身のコンピュータで使用している`source myenv/bin/activate`コマンドと同じようなものです) 。 + +{% filename %}PythonAnywhere command-line{% 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://subdomain.pythonanywhere.comを見て結果を確認しましょう。 + +うまくいってるはずです!おめでとう :) \ No newline at end of file diff --git a/ja/extend_your_application/images/404_2.png b/ja/extend_your_application/images/404_2.png new file mode 100644 index 00000000000..0a6fdf3234e Binary files /dev/null and b/ja/extend_your_application/images/404_2.png differ diff --git a/ja/extend_your_application/images/attribute_error2.png b/ja/extend_your_application/images/attribute_error2.png new file mode 100644 index 00000000000..4b8262476d9 Binary files /dev/null and b/ja/extend_your_application/images/attribute_error2.png differ diff --git a/ja/extend_your_application/images/does_not_exist2.png b/ja/extend_your_application/images/does_not_exist2.png new file mode 100644 index 00000000000..e7015f2c80d Binary files /dev/null and b/ja/extend_your_application/images/does_not_exist2.png differ diff --git a/ja/extend_your_application/images/no_reverse_match2.png b/ja/extend_your_application/images/no_reverse_match2.png new file mode 100644 index 00000000000..aba1c9c8980 Binary files /dev/null and b/ja/extend_your_application/images/no_reverse_match2.png differ diff --git a/ja/extend_your_application/images/post_detail2.png b/ja/extend_your_application/images/post_detail2.png new file mode 100644 index 00000000000..b40c92efb8c Binary files /dev/null and b/ja/extend_your_application/images/post_detail2.png differ diff --git a/ja/extend_your_application/images/post_list2.png b/ja/extend_your_application/images/post_list2.png new file mode 100644 index 00000000000..dd0a0d67a6f Binary files /dev/null and b/ja/extend_your_application/images/post_list2.png differ diff --git a/ja/extend_your_application/images/template_does_not_exist2.png b/ja/extend_your_application/images/template_does_not_exist2.png new file mode 100644 index 00000000000..c856abeda31 Binary files /dev/null and b/ja/extend_your_application/images/template_does_not_exist2.png differ diff --git a/ja/how_the_internet_works/README.md b/ja/how_the_internet_works/README.md new file mode 100644 index 00000000000..b11bce7f017 --- /dev/null +++ b/ja/how_the_internet_works/README.md @@ -0,0 +1,47 @@ +# インターネットのしくみ + +> 家で1人でこのチャプターに挑戦している方へ:このチャプターは、動画(英語)もあるので参考にしてください。 [How the Internet Works](https://www.youtube.com/watch?v=oM9yAA09wdc) +> +> この章は、ジェシカ・マッケラー(http://web.mit.edu/jesstess/www/ )による「インターネットの仕組み」を参照しています。 + +私達は、毎日インターネットを使っています。でも、ブラウザのアドレス欄に https://djangogirls.org のようなアドレスを入力して `Enter` キーを押すと何が起こるか、あなたは実際に知っていますか? + +まず最初に理解する必要があるのは、Webサイトはハードディスクに保存されたたくさんのファイル(ちょうどあなたの動画や音楽、画像のデータのようなファイル)からできているということです。 ただし、Webサイトに固有の部分が1つあります。HTMLと呼ばれるコンピューター向けコードが含まれていることです。 + +プログラミングに慣れていない場合、最初はHTMLを把握するのは難しいかもしれませんが、Webブラウザ(Chrome、Safari、Firefoxなど)とHTMLコードは親和性があります。 Webブラウザはこのコードがわかるようになっていて、コードの指示に従います。そして、あなたのウェブサイトのファイルをあなたが望む方法で表示するのです。 + +あなたのパソコンへファイルを保存するのと同じで、私達はHTMLをハードディスクに保存する必要があります。 インターネットの場合、*サーバー* と呼ばれるパワフルなコンピュータを使い、そのハードディスクに保存します。 サーバーの主な目的は、データを保存したり、データを供給したりすることなので、サーバーは画面やマウス、キーボードを持っていません。 サーバーはデータを供給する(*サーブ* する)役割を持っているので、*サーバー* と呼ばれるのです。 + +はい、では、どのようにインターネットが見えるかを知りたいですよね? + +私たちは絵を描いてみました。 + +![図 1.1](images/internet_1.png) + +上記の絵は混乱しているように見えますよね? 接続されたマシン(*サーバー*)のネットワークは実際こんな感じです。 数十万台のマシン! 世界中はりめぐらされたケーブル! Submarine Cable MapのWebサイト (http://submarinecablemap.com) にアクセスすれば、ネットの複雑さを知ることができます。 ここにウェブサイトからのスクリーンショットがあります: + +![図 1.2](images/internet_3.png) + +すばらしいですね。 でも、インターネットに接続されているすべてのマシンとマシンの間にワイヤを置くことは不可能です。 したがって、マシン(例えば http://djangogirls.org が保存されているマシン)に到達するためには、多くの異なるマシンを介してリクエストを渡す必要があります。 + +こんな感じですね。 + +![図 1.3](images/internet_2.png) + +あなたが http://djangogirls.org と入力すると、「親愛なるDjango Girlsへ。私はdjangogirls.orgのWebサイトが見たいです。それを私に送ってください」とリクエスト(手紙)を送ることになります。 + +あなたの手紙(リクエスト)は、まずあなたの一番近くの郵便局にいきますよね。 そしてそこから、もう少し宛先に近い別の郵便局に行き、またそこからもう少し近い郵便局に行って・・そしてあなたの目的地まで届きます。 特別なことが一つあります。同じ宛先に多くの手紙(*データパケット*)を送ると、まったく別の郵便局(*ルーター*)を通過して届く可能性があるということです。 届くまでの道順は、郵便局ごとの配送方法次第です。 + +![図 1.4](images/internet_4.png) + +このように動作しています。あなたはメッセージを送信し、何らかの応答を期待します。 紙とペンではなく、データのバイトを使用しますが、アイデアは同じです! + +市町村名、郵便番号、国名の住所の代わりに、IPアドレスを使用します。 お使いのコンピュータは、まず djangogirls.org をIPアドレスに変換するようにDNS(Domain Name System)に依頼します。 あなたが連絡したい人の名前を探し、電話番号と住所を見つけることができる昔ながらの電話帳のようなものです。 + +手紙を送るときには、住所、切手など、正しく配送される特定の機能が必要ですよね。 また、受信者が理解できる言語も使用している必要がありますよね? Webサイトを表示するために送信する *データパケット* についても同様です。 HTTP(Hypertext Transfer Protocol)というプロトコルを使用します。(プロトコルとは正しく配送されるための機能や、使う言語などについての取り決めのことです) + +だから、基本的に、あなたがWebサイトを持つなら、*サーバー*(マシン)が必要です。 *サーバー* は *リクエスト* を(手紙で)受け取ると、Webサイトを(別の手紙で)返します。 + +これはDjangoチュートリアルですから、Djangoが何をしているのか知りたいでしょう? あなたが返事を返す時、 いつもみんなに同じ返事を返したいわけではなく、 リクエストを送った人それぞれにパーソナライズされた返事を返した方がよいこともありますよね? Djangoはパーソナライズされた面白い手紙を作るのに役立ちます。 :) + +インターネットの話は以上です!さあ、いよいよあなたのブログサイトを作成する時間です! \ No newline at end of file diff --git a/ja/how_the_internet_works/images/internet_1.png b/ja/how_the_internet_works/images/internet_1.png new file mode 100644 index 00000000000..e289eac2b23 Binary files /dev/null and b/ja/how_the_internet_works/images/internet_1.png differ diff --git a/ja/how_the_internet_works/images/internet_2.png b/ja/how_the_internet_works/images/internet_2.png new file mode 100644 index 00000000000..e8cf8b77999 Binary files /dev/null and b/ja/how_the_internet_works/images/internet_2.png differ diff --git a/ja/how_the_internet_works/images/internet_3.png b/ja/how_the_internet_works/images/internet_3.png new file mode 100644 index 00000000000..6f5d95dec80 Binary files /dev/null and b/ja/how_the_internet_works/images/internet_3.png differ diff --git a/ja/how_the_internet_works/images/internet_4.png b/ja/how_the_internet_works/images/internet_4.png new file mode 100644 index 00000000000..d4748ac48ef Binary files /dev/null and b/ja/how_the_internet_works/images/internet_4.png differ diff --git a/ja/html/README.md b/ja/html/README.md new file mode 100644 index 00000000000..474f452a69d --- /dev/null +++ b/ja/html/README.md @@ -0,0 +1,217 @@ +# HTML 入門 + +テンプレートとは何でしょうか? + +テンプレートは、異なる情報を統一された形式で示すために繰り返し使われるファイルです。例えば、テンプレートは手紙を書く際に役立ちます。それぞれの手紙のメッセージは様々で、宛先も別々かもしれませんが、どの手紙も同じフォーマットを共有できるのです。 + +Djangoのテンプレートのフォーマットは、HTMLと呼ばれる言語 (最初のチャプター**「インターネットのしくみ」**で触れたHTMLのことです) で書かれています。 + +## HTMLとは? + +HTMLは、ChromeやFirefox、Safariなどのウェブブラウザで解読され、利用者にウェブページを表示するためのコードです。 + +HTMLは、「HyperText Markup Language」の頭文字を取ったものです。 **HyperText**はWebページ間を結びつけるハイパーリンクをサポートするテキスト形式という意味です。 **Markup**とは、一つの書類について、コードで修飾を付けて、何かに(この場合、ブラウザに) どう解釈するかを伝えることを意味します。 HTMLコードは、 `<`で始まり、 `>`で終わる**タグ**で構成されています。 これらのタグが、markup修飾の**要素**なのです。 + +## 最初のテンプレート + +テンプレートを作るとは、テンプレートのファイルを作ることです。すべてはファイルですよね。皆さんは、たぶん、このことに、もう気づいていると思います。 + +テンプレートは、`blog/templates/blog`ディレクトリに保存されています。 それでは、最初に、自分のblogディレクトリの中に`templates`という名前のディレクトリを作成してください。 次に、自分のtemplatesディレクトリの中に`blog`という名前のディレクトリを作ります。 + + blog + └───templates + └───blog + + +(なぜ、両方とも`blog`という名前の付いたディレクトリを2つ作成する必要があるのか不思議に思う人もいるかもしれません。あとで分かると思いますが、簡単に言うと、これは、もっと複雑なことをやろうとした時に、それが楽にできるようにしてくれる便利な命名法なのです。) + +それでは、`blog/templates/blog`ディレクトリの中に、`post_list.html`ファイル(とりあえず何も書かれていないファイルにしておきます)を作成しましょう。 + +あなたのウェブサイトを見てみてください: http://127.0.0.1:8000/ + +> もし、`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/ + +![図 11.2](images/step3.png) + +うまく動いています!よくできました:) + +* どんなウェブページでも、最も基本的なタグである``から始まり、そして常に、``で終わります。 みなさん見てとれるように、ウェブサイトの全てのコンテンツは、開始タグの``と閉じタグ``の間にあります。 +* `

`は、段落要素のためのタグです; `

` でそれぞれの段落を閉じます。 + +## HeadとBody + +それぞれのHTMLページは**head**と**body**という要素によって2つにわけられています. + +* **head**は文書についての情報を含む要素で、画面には表示されません。 + +* **body**はWebページの一部として表示されるすべてを含む要素です。 + +``でページの設定をブラウザに伝え、``でページの内容を伝えます。 + +例えば、ウェブページのタイトル要素は``の中に書きます。こんな感じですね。 + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + Ola's blog + + +

Hi there!

+

It works!

+ + +``` + +ファイルを保存し、ページを更新してください。 + +![図 11.3](images/step4.png) + +ブラウザは、どうやって、"Ola's blog"があなたのウェブサイトのタイトルだと理解したのか分かりましたか? ブラウザは、`Ola's blog`の意味を解釈して、あなたのブラウザのタイトルバーに文を配置したのです(この文はブックマークなどにも利用されます)。 + +各々の開始タグは*閉じタグ*とセットで、閉じタグには`/`が付いていて、タグの要素は*入れ子*になっていることに気がついたことと思います(つまり、ある特定のタグを閉じるには、その中にある全てのタグも閉じられていないとだめなのです)。 + +箱の中にものを詰め込むのと同じですね。 大きな箱、 ``があります; その中に``があり、さらにもっと小さな`

`が入っているのです。 + +こうした*閉じ*タグと、*入れ子*のルールを守らなくてはいけません - そうしないと、ブラウザはタグを適切に解釈することができず、あなたのウェブページが正しく表示されなくなるのです。 + +## テンプレートのカスタマイズ + +それでは、ちょっぴり楽しくテンプレートを作り変えてみましょう!次のようないくつか便利なタグがあります。 + +* `

ヘッダー

` 最も重要性の高い見出し +* `

サブのヘッダー

` その次のレベルの見出し +* `

サブのサブのヘッダー

`... など`
`まで +* `

文章の段落

` +* `文章`で文章を強調する +* `文章`でさらに文章を強調する +* `
`は改行(brタグの中には何も書いてはいけません。閉じタグも無しです) +* `リンク` はリンクを生成します +* `
  • 第1の項目
  • 第2の項目
` でリストを作成する、こんな感じに! +* `
`はページ内のセクションを定義 + +いろんな要素をまとめたテンプレートの例がこれです。コピーして`blog/templates/blog/post_list.html`に貼り付けてみましょう: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html + + + Django Girls blog + + + + +
+

published: 14.06.2014, 12:14

+

My first post

+

Aenean eu leo quam. こんにちは! よろしくお願いします!

+
+ +
+

公開日: 2014/06/14, 12:14

+

2番目の投稿

+

こんにちは! よろしくお願いします!

+
+ + +``` + +ここで3つの `div` セクションを作成しました。 + +* 最初の `div` 要素には、私たちのブログのタイトルが含まれています。見出しとリンクです。 +* その他の2つの`div`要素には、このブログにポストされた記事が公開日とともに記載されています。`h2`はクリック可能な記事のタイトルです。2つの`p`(段落) は、1つが日付で、1つがブログにポストされた記事です。 + +その結果、次のような結果が得られます。 + +![図 11.4](images/step6.png) + +いぇーい! ところが今のところ、私たちのテンプレートは、常に完全に**同じ情報**だけしか表示できません。一方で、以前は、テンプレートを使えば、**異なる**情報を**同じ形式**で表示できるようになるとお伝えしていたのですが。 + +本当にやりたいことは、Djangoのadminに追加された本物の記事を表示することです。そして、それが次にやるべきことなのです。 + +## もう一つ: デプロイしましょう! + +ここまでやったことを公開して、インターネットで動かしてみると楽しいですよね。PythonAnywhereでデプロイしてみましょう。 + +### Githubに自分のコードをPushしてみよう + +まずは、最後に実行したときから、どのファイルを変更したか見てみましょう(以下のコマンドを、PythonAnywhereではなく、自分のパソコンで実行してください。)。 + +{% filename %}command-line{% endfilename %} + + $ git status + + +`djangogirls` ディレクトリにいることを確認して、 `git` に対してこのディレクトリ内の変更を全て反映させるよう指示してください: + +{% filename %}command-line{% endfilename %} + + $ git add --all . + + +> **ノート** `--all` をつけると、 `git` は、ファイルを削除したかどうかも判定します (これがない初期設定の状態では、新しいファイルと変更されたファイルしか認識しません)。 `.` が、今いるディレクトリを表すということも思い出してくださいね(第3章にありました)。 + +全てのファイルをアップロードする前に、`git`が何をアップロードするのかチェックしておきましょう(`git`がアップロードする全ファイルは緑で表示されます): + +{% filename %}command-line{% endfilename %} + + $ git status + + +ほぼ完了です。どこを変更したかを履歴に保存するよう指示してみましょう。 何を変更したのか説明するコミットメッセージを残しましょう。 この時、どんな内容を好みで打ち込んでも構いませんが、何をしたかを具体的に書き込んでおけば、将来、作業内容を思い出す助けになるでしょう。 + +{% filename %}command-line{% endfilename %} + + $ git commit -m "Changed the HTML for the site." + + +> **ノート** コミットメッセージは二重クォート記号で囲みましょう。 + +ここまで終われば、GitHubに変更部分をアップロード(push) しましょう。 + +{% filename %}command-line{% endfilename %} + + $ git push + + +### 新しいコードをPythonAnywhereにpullして、自分のウェブアプリを再度実行させる + +* [PythonAnywhereのコンソールページ](https://www.pythonanywhere.com/consoles/)を開き、**Bash コンソール**に移動してください (または新たなBash コンソールを開始してください)。それから次を実行してください。 + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +``を、山カッコ<>をつけずに、実際のPythonAnywhereのサブドメイン名に置き換える必要があります。 通常、サブドメイン名はPythonAnywhereユーザー名ですが、場合によっては多少異なることがあります(ユーザー名に大文字が含まれている場合など)。 このコマンドが機能しない場合は、`ls`(ファイルを一覧にする)コマンドを使用して、実際のサブドメイン名とフォルダ名を見つけ、そこに `cd` します。 + +では、自分のコードがダウンロードされたことを確認しましょう。 それをチェックしたい場合は、**「Files」ページ** に移動して、自分のコードをPythonAnywhereの中で見てみましょう(コンソールページのメニューボタンからPythonAnywhereの他のページにアクセスできます)。 + +* 最後に、[「Web」ページ](https://www.pythonanywhere.com/web_app_setup/)へ移動して、自分のアプリの**Reload**ボタンをクリックします。 + +あなたのアプリが更新され、動いています!ウェブサイトを開いて、再読込してみましょう。どう変わったのか、見えるはずです。:) \ No newline at end of file diff --git a/ja/html/images/step1.png b/ja/html/images/step1.png new file mode 100644 index 00000000000..eb474aaeddd Binary files /dev/null and b/ja/html/images/step1.png differ diff --git a/ja/html/images/step3.png b/ja/html/images/step3.png new file mode 100644 index 00000000000..47ede3f9993 Binary files /dev/null and b/ja/html/images/step3.png differ diff --git a/ja/html/images/step4.png b/ja/html/images/step4.png new file mode 100644 index 00000000000..0e6b48ec4a5 Binary files /dev/null and b/ja/html/images/step4.png differ diff --git a/ja/html/images/step6.png b/ja/html/images/step6.png new file mode 100644 index 00000000000..f044389de53 Binary files /dev/null and b/ja/html/images/step6.png differ diff --git a/ja/images/application.png b/ja/images/application.png new file mode 100644 index 00000000000..79071fe8d1b Binary files /dev/null and b/ja/images/application.png differ diff --git a/ja/installation/README.md b/ja/installation/README.md new file mode 100644 index 00000000000..73a2aacf06f --- /dev/null +++ b/ja/installation/README.md @@ -0,0 +1,69 @@ +# 家でチュートリアルに挑戦する方へ + +[Django Girls のイベント](https://djangogirls.org/events/)ではなく、あなたが一人家でこのチュートリアルに挑戦しているのであれば、このチャプターは無視して次のチャプター [インターネットのしくみ](../how_the_internet_works/README.md) に進みましょう。 + +このチャプターがある理由は、チュートリアルで必要なもののインストールについてカバーしているからです。これは、インストール手順のすべてを一ヶ所にまとめた追加のページです(ワークショップのやり方によっては、このページは役に立ちます)。 ご希望であれば、このページにあるすべてのものを今すぐインストールすることができます。 ただ、いろんなものをパソコンにインストールする前に、一体それらが何なのかを学びたい方は、このチャプターを飛ばしてください。これ以降のページでそれらが必要になったときに、インストールの手順やその説明を行っています。 + +がんばってね! + +# ワークショップに参加している方へ + +[Django Girlsのイベント](https://djangogirls.org/events/)の参加者のみなさん: + +* ワークショップDayの前に「インストールパーティ」が開催される場合があります。 あなたがインストールパーティに参加しているなら、このページをご参照ください! 必要ならコーチの助けを借りて、このチャプターに書いてあるとおりに、ワークショップに必要なすべてのものをインストールしてみましょう。 ワークショップDayでは、以降のチュートリアルの中に出てくるインストールに関連する部分を飛ばすことができます。 +* ワークショップの主催者が、ワークショップ前に自宅であらかじめすべてをパソコンにインストールしてみるようにお願いしているかもしれません。 もしそのように言われていたのなら、このページをご参照ください! できる限り、このチャプターに書いてあるようにやってみましょう。 その後メインのワークショップで、チュートリアルを進めて何かをインストールする箇所が出てきたときに、もしあなたができていなかったとしたら、コーチの助けを借りましょう。 +* インストールパーティが開催されない場合(またはあなたが参加できなかった場合)、そして主催者が事前のインストールをお願いしていない場合、このページは飛ばして、[インターネットのしくみ](../how_the_internet_works/README.md)のチャプターに進みましょう。 チュートリアルを進めながら、必要なものをすべてインストールします。 + +# インストール + +このチュートリアルではブログを作成します。 そのために、チュートリアルを進める中で必要に応じて、さまざまなソフトウェアをコンピュータにインストールする方法や、いくつかのオンラインアカウントを設定する方法について教わります。 このページでは、インストールとアカウント作成の手順すべてを一ヶ所にまとめています(ワークショップのやり方によっては、このページは役に立ちます)。 + + +{% include "/chromebook_setup/instructions.md" %} + + +# コマンドラインの簡単な紹介 {#command-line} + +以下の手順の多くに、「コンソール」、「ターミナル」、「コマンドウィンドウ」、「コマンドライン」という言葉が出てきます。これらはすべて同じものを意味します。コマンドを入力できる、コンピュータのウィンドウです。 メインのチュートリアルに進むと、コマンドラインについてさらに学ぶことができます。 今は、コマンドウィンドウの開き方と、それがどのように見えるかを覚えましょう: +{% include "/intro_to_command_line/open_instructions.md" %} + +# Pythonのインストール {#python} + +{% include "/python_installation/instructions.md" %} + +# コードエディタのインストール {#code-editor} + +{% include "/code_editor/instructions.md" %} + +# 仮想環境のセットアップとDjangoのインストール {#virtualenv} + +{% include "/django_installation/instructions.md" %} + +# Gitのインストール {#git} + +{% include "/deploy/install_git.md" %} + +# GitHubのアカウント作成 {#github} + +[GitHub.com](https://www.github.com)へ行って、新しく無料のユーザーアカウントを登録しましょう。パスワードを忘れないようにしてください(もしパスワードマネージャーを使っているなら、追加しましょう)。 + +# PythonAnywhereのアカウント作成 {#pythonanywhere} + +{% include "/deploy/signup_pythonanywhere.md" %} + +# 読んでみよう + +お疲れ様でした!これで準備が整いました。ワークショップが始まるまでに時間があれば、最初のチャプターいくつかを読んでおくとよいでしょう。 + +* [インターネットのしくみ](../how_the_internet_works/README.md) + +* [コマンドラインを使ってみよう](../intro_to_command_line/README.md) + +* [Python入門](../python_introduction/README.md) + +* [Djangoってなに?](../django/README.md) + +# ワークショップを楽しんでください! + +ここまでで最初の数チャプターの内容を扱ってきたので、ワークショップでは、[プロジェクトを作成しよう!](../django_start_project/README.md)のチャプターからはじめてください。 diff --git a/ja/intro_to_command_line/README.md b/ja/intro_to_command_line/README.md new file mode 100644 index 00000000000..2976a972f5f --- /dev/null +++ b/ja/intro_to_command_line/README.md @@ -0,0 +1,441 @@ +# コマンドラインを使ってみよう + +> 家で1人でこのチャプターに挑戦している方へ:このチャプターは、動画(英語)もあるので参考にしてください。 [Your new friend: Command Line](https://www.youtube.com/watch?v=jvZLWhkzX-8) + +さぁ、これから最初のコードを書いていきますよ。楽しんでいきましょう!:) + +**最初にお友達になるのはコレです。: コマンドライン!** + +プログラマーが黒い画面に向かっている光景を見たことがありますか?ここからは、その黒い画面を触ってみます。最初はちょっとコワイと思うかもしれませんが、そんなことはありません。プロンプトと呼ばれるものがあなたの命令(コマンド)を待っています。 + +> **備考:** このチュートリアルでは、”ディレクトリ”や"フォルダ"という用語が出てきますが、同じ意味です。 + +## コマンドラインって何? + +さて、**コマンドライン** あるいは **コマンドライン インターフェイス**と呼ばれるこの画面は、キーボードで入力したテキストで命令を出してコンピューターと直接対話するように、ファイルを見たり、変更したりするものです。 グラフィカル・インターフェイスではないだけで、WindowsのエクスプローラやMacのFinderと同じ役割です。 このコマンドラインは、 *cmd*や*CLI*、*プロンプト*、*コンソール*、*ターミナル*と呼ばれることもあります。 + +## コマンドラインインタフェースを開く + +では、実際にコマンドラインを開いて、触ってみることとしましょう。 + +{% include "/intro_to_command_line/open_instructions.md" %} + +## プロンプト + +おそらく今、真っ白または真っ黒な画面が開かれていることでしょう。この画面はあなたの命令(コマンド)を待っています。 + + + +MacあるいはLinuxの方は、次のように `$` という記号が表示されていることでしょう。 + +{% filename %}command-line{% endfilename %} + + $ + + + + + + +Windowsの方は、 `>` という記号が表示されていることでしょう。 + +{% filename %}command-line{% endfilename %} + + > + + +上の Linux のセクションを見てください。このチュートリアルの後ろにある PythonAnywhere を扱うところで、似たような表示を見ることになります。 + + + +各コマンドの先頭には、`$` あるいは `>` とスペース1つがつきます。コンピューターが表示してくれるので、自分で入力する必要はありません。:) + +> ちょっと補足です。お手元では `C:\Users\ola>` や `Olas-MacBook-Air:~ ola$` のようにプロンプト記号の前に表示があると思いますが、これは間違いではありません。 + +`$` や `>` と書かれているところまでは、 *コマンドラインプロンプト* あるいは略して*プロンプト*と呼ばれます。プロンプトの意味は「促す」で、あなたが何か入力することを促しています。 + +このチュートリアルでは、コマンドを入力してほしい時は、 `$` や `>` を含めて示しています(たまにこれらの左にも文字がきます)。 $ や > から左側は無視して、コマンドのみを入力してください。コマンドはプロンプトのあとに続きます。 + +## 最初のコマンド (イェイ!) + +次のようにコマンドを入力してみましょう: + + + +{% filename %}command-line{% endfilename %} + + $ whoami + + + + + + +{% filename %}command-line{% endfilename %} + + > whoami + + + + +そして最後に`Enterキー`を押してください。このような結果が返ってきます。 + +{% filename %}command-line{% endfilename %} + + $ whoami + olasitarska + + +ご覧のとおり、コンピューターがあなたのユーザー名を表示してくれましたね。面白いでしょ? :) + +> コピー&ペーストではなく、コマンドを入力して試してみてください。そのうち自然と覚えられるようになりますからね! + +## 基本 + +OSによってコマンドが若干違います。あなたのコンピューターのOS向けの説明に従って、以下は進めていってくださいね。次にいってみましょう。 + +### カレントディレクトリ(現在のディレクトリ) + +今どこのディレクトリにいるか(どのフォルダで作業をしているか)、知りたいですよね?では、このようにキーボードから入力し、`Enterキー`を押してください。 + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska + + +> 補足: 'pwd' は'print working directory'の略で、現在いる作業ディレクトリを表示することを意味します。 + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska + + +> 補足: 'cd' は、'change directory'の略で、ディレクトリを変えることを意味します。PowerShellを使うと、LinuxやmacOSのようにpwdコマンドを使えます。 + + + +おそらく、あなたのマシン上でも似たような表示がされたのではないでしょうか。コマンドラインを起動すると、通常はユーザーのホームディレクトリがカレントディレクトリになります。 + +* * * + +### コマンドについてもっと知る + +コマンドプロンプトに入力するコマンドの多くには、表示して読むことができるヘルプ機能が備わっています!例として、カレントディレクトリを表示するコマンドについてみてみましょう: + + + +macOS と Linux には、`man` コマンドがあり、それはコマンドのヘルプを提供します。 `man pwd` を試してみましょう。他のコマンドも、コマンドの前に `man` と書き、ヘルプを見てみましょう。 `man` の出力は、通常はページ単位で表示されます。 次のページに移動するにはスペースキーを使います。 ヘルプを見るのをやめるには `qキー` を押します。 + + + + + +ほとんどのコマンドでは、コマンドの後ろに `/?` をつけて実行するとヘルプページが出力されます。すべての出力を見るには、コマンドラインを上にスクロールする必要があるかもしれません。`cd /?` を試してみましょう。 + + + +### ファイルとディレクトリの一覧 + +では、カレントディレクトリの中には何があるのでしょうか?表示させてみましょう。 + + + +{% filename %}command-line{% endfilename %} + + $ ls + Applications + Desktop + Downloads + Music + ... + + + + + + +{% 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 + ... + + +> 補足:PowerSellでは、Linux や macOS同様にlsコマンドが使えます。 + +* * * + +### カレントディレクトリの変更 + +次に、デスクトップ(Desktop)というディレクトリに移動してみましょう。 + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + +Desktop というディレクトリ名は、使用しているLinuxアカウントの言語に翻訳されているかもしれません。 その場合は、 `Desktop` を翻訳された名前に置き換えてください; たとえば、ドイツ語なら `Schreibtisch` です。 + + + + + +{% filename %}command-line{% endfilename %} + + > cd Desktop + + + + +本当に変更されたかどうか確認してみてください: + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + + +できていますね! + +> プロのコツ: `cd D` と入力して、キーボードの`Tabキー`を押してください。すると、Dに続く残りの部分が自動的に補完されるので、より早く入力することができます。 もし、Dから始まるディレクトリ名が他にもあれば、`Tabキー`を2度押すと候補の一覧が表示されます。 + +* * * + +### ディレクトリの作成 + +それでは、practice ディレクトリをデスクトップに作成してみましょう。 + + + +{% filename %}command-line{% endfilename %} + + $ mkdir practice + + + + + + +{% filename %}command-line{% endfilename %} + + > mkdir practice + + + + +この短いコマンドで、デスクトップに `practice` という名前のディレクトリが作成されました。 デスクトップを見るとディレクトリが作成されていることを確認できます。あるいは、先ほど学んだコマンド `ls` や `dir` を使っても確認できます。 やってみてください。 :) + +> プロのコツ: 同じコマンドを何度も入力したくない時は、キーボードの上下矢印キー `↑`、`↓` を押せば、最近使用したコマンドが現れます。内容を修正したい場合には,左右矢印キー←,→を利用して修正したい位置にカーソルを移動させることができますよ。 + +* * * + +### 練習! + +練習をしてみましょう。先ほど作成した `practice` ディレクトリの中に、`test` という名前のディレクトリを作成してください。(使うコマンドは、`cd` と `mkdir` ですよ) + +#### 解答: + + + +{% filename %}command-line{% endfilename %} + + $ cd practice + $ mkdir test + $ ls + test + + + + + + +{% filename %}command-line{% endfilename %} + + > cd practice + > mkdir test + > dir + 05/08/2014 07:28 PM test + + + + +おめでとうございます!よくできました! :) + +* * * + +### 片付け + +練習で作ったものをそのまま置いておくと邪魔になりますね。練習がおわったら、削除しましょう。 + +はじめに、作業するディレクトリをデスクトップに戻しましょう。 + + + +{% filename %}command-line{% endfilename %} + + $ cd .. + + + + + + +{% filename %}command-line{% endfilename %} + + > cd .. + + + + +`cd` の後にある `..` で、カレントディレクトリを親ディレクトリに変更します。(今作業しているディレクトリのひとつ上のディレクトリに移動するということですね。) + +現在の作業ディレクトリを確認しておきましょう: + + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + + +では、`practice` ディレクトリを削除しましょう: + +> **注意**: `del` や `rmdir `、`rm` コマンドを使って削除したファイルは元に戻せません。*完全に消えてしまいます*! これらのコマンドを使う時は、よく気をつけてくださいね。 + + + +{% filename %}command-line{% endfilename %} + + $ rm -r practice + + + + + + +{% filename %}command-line{% endfilename %} + + > rmdir /S practice + practice, Are you sure ? Y + + + + +できました!本当に削除されたか、確認してみましょう: + + + +{% filename %}command-line{% endfilename %} + + $ ls + + + + + + +{% filename %}command-line{% endfilename %} + + > dir + + + + +### 終了 + +今回はここまでです。それではコマンドラインを終了しましょう。かっこいいやり方で終了したいですよね? :) + + + +{% filename %}command-line{% endfilename %} + + $ exit + + + + + + +{% filename %}command-line{% endfilename %} + + > exit + + + + +かっこいいでしょう? :) + +## まとめ + +役立つコマンドをいくつかまとめておきます。 + +| コマンド (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** | +| rmdir (or 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) に各OSのコマンド一覧があります。ご参考までに。 + +## 準備OK? + +よし、次はPythonを勉強していきましょう! \ No newline at end of file diff --git a/ja/intro_to_command_line/open_instructions.md b/ja/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..53e38a8d243 --- /dev/null +++ b/ja/intro_to_command_line/open_instructions.md @@ -0,0 +1,29 @@ + + + +使用しているWindowsのバージョンとキーボードによりますが、以下のいずれかの方法でコマンドラインを開けるはずです(いくつか試す必要があるかもしれませんが、これらの方法のすべてを試す必要はありません): + +- [スタートメニュー] あるいはスタート画面の検索ボックスに「コマンドプロンプト」と入力しましょう。 +- [スタートメニュー] → [Windows システムツール] → [コマンドプロンプト] を選択しましょう。 +- [スタートメニュー] → [すべてのプログラム] → [アクセサリ] → [コマンドプロンプト] を選択しましょう。 +- スタート画面を開き、画面の左下隅にマウスをかざすと下矢印が表示されるのでクリックします(タッチパネルの場合は、代わりに画面の下から上に向かってフリックしましょう)。 アプリのページが見えるはずです。 [Windows システムツール] から [コマンドプロンプト] をクリックしましょう。 +- キーボードの [Windows キー] を押しながら [X キー] を押します。 ポップアップメニューが表示されるので [コマンドプロンプト] を選択しましょう。 +- [Windows キー] を押しながら [R キー] を押すと [ファイル名を指定して実行] というウィンドウが立ち上がります。 「cmd」と入力して [OK] をクリックしましょう。 + +!["ファイル名を指定して実行" ウィンドウで "cmd" と入力](../python_installation/images/windows-plus-r.png) + +このチュートリアルの後ろの方では、同時に2つのコマンドラインを開く場面があります。 しかし、Windowsのいくつかのバージョンでは、コマンドラインをすでに1つ開いている状態で2つ目を同じ方法で開こうとした場合、すでに開いている1つ目のコマンドラインが参照されてしまうことがあります。 自分のコンピュータ上で試してみて何が起こるか見てみましょう! コマンドラインが一つしか開かない場合は、上のリストにある他の方法を試してみてください。 上にあるいずれかの方法で新しいコマンドラインを開けるはずです。 + + + + + +[アプリケーション] → [ユーティリティ] → [ターミナル] を選択しましょう。 + + + + + +使用しているシステムによりますが、[アプリケーション] → [アクセサリ] の下、あるいは [アプリケーション] → [システム] の下に [ターミナル] があるでしょう。 もしそこに見当たらない場合は、Googleで検索してみましょう。 :) + + diff --git a/ja/python_installation/README.md b/ja/python_installation/README.md new file mode 100644 index 00000000000..46832893a41 --- /dev/null +++ b/ja/python_installation/README.md @@ -0,0 +1,15 @@ +# Pythonをはじめよう + +ついにここまで来ましたね! + +まずは、最初にPythonとは何かお話させて下さい。Pythonはとても人気のあるプログラミング言語です。Webサイトや、ゲーム、サイエンス、グラッフィックス、などなど、たくさんの場面で使われています。 + +Pythonは1980年代の終わりに、人間が読みやすい(機械だけでなく)言語を目的に開発されました。 だから、他の言語に比べて、Pythonはとてもシンプルで、勉強しやすいのです。でもご心配なく、Pythonはとってもパワフルな言語ですから! + +# Pythonのインストール + +> **注意:**Chromebookをお使いの場合、このチャプターは飛ばして、[Chromebookのセットアップ](../chromebook_setup/README.md)の章をすすめてください。 +> +> **注意:**すでにインストール手順を実行している場合は、これをもう一度行う必要はありません。次の章に進んでください。 + +{% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/ja/python_installation/images/add_python_to_windows_path.png b/ja/python_installation/images/add_python_to_windows_path.png new file mode 100644 index 00000000000..3266efb6177 Binary files /dev/null and b/ja/python_installation/images/add_python_to_windows_path.png differ diff --git a/ja/python_installation/images/python-installation-options.png b/ja/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..a0a6c65d81d Binary files /dev/null and b/ja/python_installation/images/python-installation-options.png differ diff --git a/ja/python_installation/images/windows-plus-r.png b/ja/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/ja/python_installation/images/windows-plus-r.png differ diff --git a/ja/python_installation/instructions.md b/ja/python_installation/instructions.md new file mode 100644 index 00000000000..cdea1ccb916 --- /dev/null +++ b/ja/python_installation/instructions.md @@ -0,0 +1,121 @@ +> 家で1人でこのチャプターに挑戦している方へ:この章は、動画(英語)もあるので参考にしてください。 [Installing Python & Code Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA) +> +> このセクションはGeek Girls Carrots (https://github.com/ggcarrots/django-carrots) のチュートリアルをベースに作成しました。 + +DjangoはPythonで書かれています。 Djangoを使うにはPythonが必要です。 では、インストールするところから始めましょう! 最新のPython3をインストールしてください。それ以前のPythonがインストールされていたら、アップグレードする必要があります。 3.4以降のバージョンであれば問題ありません。 + +下に書いたとおりのやり方で、Pythonをインストールしてください。すでにAnacondaが入っていても以下のとおりにインストールしてください。 + + + +まず、今使っているWindowsが32-bit版か64-bit版か確認しましょう。システム情報の”システムの種類”を確認してください。これを見る方法はいくつかあるので、次のうち1つをやってみましょう: + +* WindowsキーとPause/Breakキーを同時に押します。 +* Windowsのスタートからコントロールパネルを開き、”システムとセキュリティ”、”システム”と順にクリックします。 +* Windowsロゴをクリック、設定 > システム > バージョン情報 とクリックしていきましょう。 + +https://www.python.org/downloads/windows/ からWindows版のPythonをダウンロードできます。 "Latest Python 3 Release - Python x.x.x" というリンクをクリックします。 あなたのWindowsが**64-bit版**なら、**Windows x86-64 executable installer**をダウンロードしてください。 そうでなければ**Windows x86 executable installer**をダウンロードしてください。 インストーラーがダウンロードできたら、ダブルクリックして実行し、指示に従ってください。 + +インストールの途中で、「Setup」というタイトルのウィンドウがでてきたら注意してください。 下にあるとおり、「Add Python 3.6 to PATH」か「Add Python to your environment variables」をチェックしてから「Install Now」をクリックしてください (バージョンが違うと表示が違うこともあります)。 + +![Pythonのパスを通すのを忘れないようにしてください。](../python_installation/images/python-installation-options.png) + +インストールが終わったら、ダイアログボックスが出てきます。ボックス内のリンクを開くと、Pythonやインストールしたバージョンを説明したページに行けます。 ダイアログは閉じてしまいましょう。Pythonの使い方はこのチュートリアルでたっぷり勉強します! + +注意: あなたのWindowsがWindows7、Windows Vistaや、それ以前のバージョンの場合で、Python 3.6.x のインストールがエラーがでて失敗する場合は、下のどちらかのやり方を試してください。 + +1. Windows Updateを実行してすべての更新ファイルを入れてから、Pythonを入れ直す +2. [古いバージョンのPython](https://www.python.org/downloads/windows/)をインストールしてみる。例えば[3.4.6](https://www.python.org/downloads/release/python-346/)。 + +古いバージョンのPythonをインストールした場合、インストール画面は上のものと違うことがあります。 下にスクロールして「Add python.exe to Path」の左のボタンをクリックして「Will be installed on local hard drive(ローカルハードドライブにインストールされます)」を選択してください + +![古いバージョンでも、Pythonのパスを通してください。](../python_installation/images/add_python_to_windows_path.png) + + + + + +> **注意**:macOSにPythonをインストールする前に、Macの設定でApp Store以外のパッケージをインストールできるようにする必要があります。 「システム環境設定」(「アプリケーション」フォルダ内)に移動し、「セキュリティとプライバシー」、「一般」タブの順にクリックします。 「ダウンロードしたアプリを許可する」が「Mac App Store」に設定されている場合は、「Mac App Storeと識別された開発者」に変更します。 + +https://www.python.org/downloads/release/python-361/ からPythonインストーラーをダウンロードします。 + +* *macOS 64-bit/32-bit installer* というファイルをダウンロードします。 +* ダウンロードできたら *python-3.6.1-macosx10.6.pkg* をダブルクリックして実行します。 + + + + + +すでにPythonがインストールされているかもしれません。インストールされているか、そしてどのバージョンが入っているか確かめるには、コンソールを開いて下のコマンドを入力してください。 + +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python 3.6.5 + + +表示されたバージョンが違っても、3.4.0以降(例えば 3.6.0など)であれば、アップグレードの必要はありません。 Pythonがインストールされていなかったり、違うバージョンをインストールしたい場合は、下のコマンドを実行して、まずパソコンのLinuxディストリビューションがなにか確かめてください。 + +{% filename %}command-line{% endfilename %} + + $ grep ^NAME= /etc/os-release + + +表示されたディストリビューション名に従って、以下のインストール方法の1つを実行してください。 + + + + + +下のコマンドをコンソールに入力します。 + +{% filename %}command-line{% endfilename %} + + $ sudo apt install python3 + + + + + + +下のコマンドをコンソールに入力します。 + +{% filename %}command-line{% endfilename %} + + $ sudo dnf install python3 + + +Fedoraのバージョンが古い場合、 `dnf` コマンドが見つからないというエラーが出るかもしれません。そんなときは代わりに `yum` コマンドを使ってください。 + + + + + +下のコマンドをコンソールに入力します。 + +{% filename %}command-line{% endfilename %} + + $ sudo zypper install python3 + + + + +インストールがうまくいったか確認するために、コマンドプロンプトを開いて `python3` と打ち込んでください。 + +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python 3.6.1 + + +バージョンはあなたがインストールしたものが表示されます。なのでPython 3.6.1 と表示されないかもしれません。 + +**注意:** Windowsで `python3` を実行して、コマンドが見つからないとエラーが出た場合、代わりに `python` (`3` をコマンドに入れていません) を使ってみてください。そして、3.4.0以降のPythonのバージョンが表示されるか確認してください。 どちらのコマンドもうまく動かない場合は、新しいコマンドプロンプトを開いて同じことを試してください。Pythonのインストール前にコマンドプロンプトを使っていて、それが開きっぱなしだとこういうことが起きます。 + +* * * + +わからないことがあったり、うまくいかなくて次にどうしたらいいかわからなかったりするときは、コーチに質問してください! うまくいかないこともあります。そういうときは、経験豊富な人に聞くといいですよ。 \ No newline at end of file diff --git a/ja/python_introduction/README.md b/ja/python_introduction/README.md new file mode 100644 index 00000000000..e3319290a6c --- /dev/null +++ b/ja/python_introduction/README.md @@ -0,0 +1,1070 @@ +{% set warning_icon = '' %} + +# Python入門 + +> このチャプターの一部はGeek Girls Carrotsのチュートリアルをもとにしています。(https://github.com/ggcarrots/django-carrots) + +さあ、コードを書いてみましょう! + +## Pythonプロンプト + +> 家で1人でこのパートに挑戦している方へ:このパートと続くパートは、動画(英語)もあるので参考にしてください。 [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U) + +Pythonであそぶために、*コマンドライン* を開きましょう。 やり方は、チャプター [コマンドラインを使ってみよう](../intro_to_command_line/README.md) で学びましたね。 + +準備ができたら、次の指示に従ってやってみましょう。 + +Pythonコンソールを開きましょう。Windowsなら `python` 、Mac OSやLinuxなら `python3` とタイプして `Enter` キーを押してください。 + +{% filename %}command-line{% endfilename %} + + $ python3 + Python 3.6.1 (...) + Type "help", "copyright", "credits" or "license" for more information. + >>> + + +## 最初のPythonコマンド! + +Pythonのコマンドが走ると、プロンプト記号が `>>>` に変わりました。 これは、今Pythonの言語を実行できますという意味です。 `>>>` はタイプしなくていいですよ – Pythonがあなたの代わりにやってくれます。 + +Pythonコンソールを終了したい時は、`exit()` とタイプするか、ショートカット `Ctrl + Z`(Windows)、`Ctrl + D`(Mac/Linux)を使ってください。 そうするともう `>>>` は出なくなります。 + +けど、今はまだコンソールを終了しないで、もっと動かして学びましょう。簡単な計算からはじめましょう。`2 + 3` とタイプして、`Enter` キーを押してください。 + +{% filename %}command-line{% endfilename %} + +```python +>>> 2 + 3 +5 +``` + +できました!答えがでてきましたね。Pythonは計算ができます。他にも、次のようなコマンドを試してみましょう。 + +- `4 * 5` +- `5 - 1` +- `40 / 2` + +2の3乗のような指数の計算は、次のようにタイプします。{% filename %}command-line{% endfilename %} + +```python +>>> 2 ** 3 +8 +``` + +ちょっとの間楽しんであそんでみたら、またココに戻ってきてくださいね。:) + +お分かりのとおり、Pythonはステキな計算機ですね。他になにができるんだろう…と思ったら、次にいってみましょう。 + +## 文字列 + +あなたのお名前を次のようにクォーテーションをつけてタイプしてください。 + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" +'Ola' +``` + +はじめてのString(文字列)が完成です! Stringとは、文字の集合のことです。 シングルクォーテーション (`'`) あるいは、ダブルクォーテーション (`"`) で囲います。 最初と最後は同じ記号にしてください。 クォーテーションの中が文字列であることを意味しています。 + +複数の文字列を結合することもできます。次のように試してみましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> "Hi there " + "Ola" +'Hi there Ola' +``` + +文字列を繰り返すためには、演算子を使って繰り返し回数を指定することもできます。 + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` + +アポストロフィーを文字列の中に含めたい場合は、2通りの方法があります。 + +まずは、ダブルクォーテーションを使う方法です。 + +{% filename %}command-line{% endfilename %} + +```python +>>> "Runnin' down the hill" +"Runnin' down the hill" +``` + +あるいは、バックスラッシュ (``) を使う方法もあります。 + +{% filename %}command-line{% endfilename %} + +```python +>>> 'Runnin\' down the hill' +"Runnin' down the hill" +``` + +できましたか?次に、あなたの名前を大文字に変えてみましょう。次のように記述してください。 + +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola".upper() +'OLA' +``` + +ここで `upper` **関数 (function)** を使うことができましたね! 関数 ( `upper()` など) は、呼び出したオブジェクト ( `"Ola"` のことです) に対してどのような手順でどのような処理をするかをひとまとめにしたものです。 + +あなたの名前の文字数を知りたいときは、その **関数 (function)** もあります! + +{% filename %}command-line{% endfilename %} + +```python +>>> len("Ola") +3 +``` + +どうして、文字列の後に `.` をつけて関数を呼び出したり ( `"Ola".upper()` のように)、あるいは、先に関数を呼び出してかっこの中に文字列をいれているのか、と疑問に思ったかもしれません。 そうですね。時に、オブジェクトに結びついた関数というのがあります。例えば、`upper()` は、文字列にのみ実行される関数です。 私たちはこれを **メソッド (method)** と呼びます。 それとは別に、特定のオブジェクトに関連せず、異なるタイプのオブジェクトに対して実行できる関数があります。例えば `len()` ですね。 `len` 関数の引数として `"Ola"` をかっこの中にいれているのです。 + +### まとめ + +文字列はだいじょうぶですね。ここまでに学んだことをまとめましょう。 + +- **プロンプト** – Pythonプロンプトにコマンド(コード)を入力すると、答えがかえってきます。 +- **数値と文字列** – 数値は計算に、文字列はテキストに使われます。 +- **演算子** – 例えば `+` や `*` のように、値を計算して新しい値を返します。 +- **関数** – `upper()` や `len()` のようにオブジェクトに対して行う機能のことです。 + +すべてのプログラミング言語に共通する基礎になります。 もう少し難易度の高いものに挑戦してみましょう。準備はいいですか? + +## エラー + +さて、新しいことをやってみましょう。あなたの名前の文字数を数えたように、数字の文字数は数えられるでしょうか? `len(304023)` と記述して、`Enter` キーを押してみましょう。 + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` + +はじめてのエラーがでました! {{ warning_icon }} アイコンのついたコードは思ったように動かないコードです。 (今回はチュートリアルで用意されていましたが)思ったように動かないことは学ぶ上で大事です! + +オブジェクトタイプ"int" (integers, 数値) は文字数がありませんと言っています。では、どうすればよいでしょうか?この数字を文字列として扱えれば、文字数を数えられるはずですよね? + +{% filename %}command-line{% endfilename %} + +```python +>>> len(str(304023)) +6 +``` + +うまく行きました! `str` 関数を `len` のかっこの中に記述しました。`str()` はその中身を文字列に変換します。 + +- `str` 関数は、**文字列** に変換します。 +- `int` 関数は、文字列や数値を **整数** に変換します。 + +> 重要!: 数字は文字列にすることはできますが、全ての文字が数字に変換できるわけではありません。 例えば `int('hello')` は数字にはなりませんよね? + +## 変数 + +変数(variables)は、プログラミングの重要なコンセプトです。 後で使うためにつける単なる名札ではありません。 プログラマーは変数を使ってデータを保管したり、 コードを読みやすくして、後でそれが何だったか覚えておかなくてもいいようにします。 + +変数 `name` を新しくつくってみましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> name = "Ola" +``` + +name イコール(=)"Ola" とタイプします。 + +見てのとおり、プログラムは、なにも返してくれませんね。では、変数がきちんとあるか、どうやって確かめたらいいのでしょうか? `name` とタイプして、`Enter` キーを押してください。 + +{% filename %}command-line{% endfilename %} + +```python +>>> name +'Ola' +``` + +やりました!あなたのはじめての変数ができましたね!代入する値を変えることもできます。 + +{% filename %}command-line{% endfilename %} + +```python +>>> name = "Sonja" +>>> name +'Sonja' +``` + +変数には関数も使えます。 + +{% filename %}command-line{% endfilename %} + +```python +>>> len(name) +5 +``` + +素晴らしいですね!変数は、数値にも使えますよ。 + +{% filename %}command-line{% endfilename %} + +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` + +もしも、間違えた変数名を使ってしまったら、どうなるでしょうか?予想できますか?やってみましょう! + +{% 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 +``` + +エラーになりました! 前回とは違うエラータイプです。**NameError** という、初めてみるエラータイプですね。 作成されていない変数を使った時は、Pythonがエラーを教えてくれます。 もし、このエラーに出くわしたら、記述したコードにタイプミスがないか確認してください。 + +ちょっと遊んで、何ができるか試してみてくださいね! + +## print 関数 + +次に挑戦してみましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> name = 'Maria' +>>> name +'Maria' +>>> print(name) +Maria +``` + +単に `name` とタイプした時は、Pythonインタプリタが、変数'name'の文字列*表現(representation)*を返します。ここでは、シングルクォーテーション('')に囲まれた M-a-r-i-aという文字の集まりです。 しかし、`print(name)`と記述した時は、Pythonは変数の中身を出力します。クォーテーションはありません。 + +これからさらに詳しくみていきますが、`print()` は、関数から出力をする時や、複数行の出力を行うときにも便利です。 + +## リスト + +数値と文字列の他にも、すべてのオブジェクトタイプを勉強しておきましょう。 今から**list** というものを紹介していきます。 リストは、その名のとおり、オブジェクトの並びをもつものですね。 :) + +まずはリストを作りましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> [] +[] +``` + +はい、このリストは空っぽです。使いにくいですよね。では、くじ引きの番号のリストを作りましょう。 この番号を何度も繰り返し書きたくはないから、同時に変数に代入してしまいましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery = [3, 42, 12, 19, 30, 59] +``` + +よし、これでリストができました!このリストで何をしましょうか?では、くじ引きの番号がいくつあるか、数えてみましょう。何の関数を使えばいいか、予想できますか?すでに知っていますよね! + +{% filename %}command-line{% endfilename %} + +```python +>>> len(lottery) +6 +``` + +そうです!`len()` がリストにあるオブジェクトの数を取得できます。便利ですね。では、くじ引きの番号をソートしてみましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.sort() +``` + +これは何も返してきません。これはリストに表示される番号を、順番に並べ替えただけです。再度出力して、確かめてみましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery) +[3, 12, 19, 30, 42, 59] +``` + +ご覧のとおり、小さい順に並び替えられましたね。おめでとう! + +逆順に並び替えてみたくなりましたか?やってみましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.reverse() +>>> print(lottery) +[59, 42, 30, 19, 12, 3] +``` + +リストに何かを追加したいときは、次のようにコマンドを記述してください。 + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.append(199) +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +``` + +最初の数字だけを出力したいときは、**インデックス(index)** を使って指定することができます。 インデックスは、アイテムがリストのどこにあるかを指す番号です。 リストの先頭の要素から順に「0」、次に「1」と割り当てられています。 次のとおり試してみてください。 + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery[0]) +59 +>>> print(lottery[1]) +42 +``` + +このように、リスト名と要素のインデックスを [] に記述することで、指定した要素を取り出すことができます。 + +リストから要素を消すには、これまで学んできたインデックスと `pop()` メソッドを使います。 例で試してみましょう。リストの最初の要素を削除しています。 + +{% filename %}command-line{% 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] +``` + +お見事! + +他のインデックスも試して遊んでみてください。例えば、 6, 7, 1000, -1, -6, -1000 などをインデックスに指定するとどうなるでしょうか。コマンドを実行する前に予測してみましょう。結果はどうですか? + +ご参考に、こちらのドキュメントにリストメソッドがすべて記されています。 https://docs.python.org/3/tutorial/datastructures.html + +## 辞書(ディクショナリ) + +> 家で1人でこのパートに挑戦している方へ:このパートは、動画(英語)もあるので参考にしてください。 [Python Basics: Dictionaries](https://www.youtube.com/watch?v=ZX1CVvZLE6c) + +辞書(ディクショナリ)について確認しましょう。リストに似ていますが、インデックスのかわりにキーと呼ばれる識別子で値を参照します。キーは文字列も数値も使えます。ディクショナリは次のように `{}` 括弧で囲んで作成します。 + +{% filename %}command-line{% endfilename %} + +```python +>>> {} +{} +``` + +これで中身が空っぽのディクショナリができましたね。やったね! + +では、つぎのコマンドを記述してみましょう。 (あなた自身の情報に値をおきかえてみてもいいですよ) + +{% filename %}command-line{% endfilename %} + +```python +>>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} +``` + +このコマンドで、`participant` という名前の変数をつくって、3つのキーと値をもつ要素を作成しました。 + +- キー `name` が指す値は `'Ola'` (`string` オブジェクト) +- キー `country` が指す値は `'Poland'` (`string` オブジェクト) +- キー `favorite_numbers` が指す値はリスト `[7, 42, 92]` (数字を3つ持つ`list`) + +次のように書くと各キーの値を確認できます。 + +{% filename %}command-line{% endfilename %} + +```python +>>> print(participant['name']) +Ola +``` + +リストに似ていますね。しかし、ディクショナリでは、インデックスを覚えておく必要がなく、キーの名前でいいのです。 + +もし存在しないキーを参照しようとすると、どうなるでしょうか?予想できますか?実際にやってみましょう! + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> participant['age'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'age' +``` + +またエラーです。今回は **KeyError** というエラーが出ました。Pythonは、このディクショナリにキー `'age'` は存在しませんよ、と教えてくれています。 + +ディクショナリとリストはどう使い分ければよいのでしょうか?そうですね、これはゆっくり考えてみるべきポイントですね!この後の行を読むまえに、答えを考えてみてください。 + +- 必要なのは、順序付けられた一連のアイテムですか? リストを使いましょう。 +- キーに対応する値が必要?キーから値を参照する? ディクショナリを使いましょう。 + +ディクショナリやリストは、作ったあとに変更できるオブジェクトです。これを *mutable* と呼びます。次のように、ディクショナリを作ったあとで、新しいキーと値を追加することができます。 + +{% filename %}command-line{% endfilename %} + +```python +>>> participant['favorite_language'] = 'Python' +``` + +リストと同様に、`len()` 関数をディクショナリに使ってみましょう。ディクショナリでは、キーと値のペアの数を返します。コマンドを入力してやってみましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> len(participant) +4 +``` + +お分かり頂けたでしょうか。 :) では、ディクショナリを使ってもう少し練習してみましょう。準備ができたら、次の行にいってみましょう。 + +ディクショナリの要素を削除する時は、`pop()` メソッドを使います。 例えば、 キー `'favorite_numbers'` の要素を削除するには、次のように記述してください。 + +{% filename %}command-line{% endfilename %} + +```python +>>> participant.pop('favorite_numbers') +[7, 42, 92] +>>> participant +{'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +このように、`'favorite_numbers'` のキーと値が削除されます。 + +同様に、次のように記述することで、すでにあるキーの値を変更することができます。 + +{% filename %}command-line{% endfilename %} + +```python +>>> participant['country'] = 'Germany' +>>> participant +{'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +これで、キー `'country'` の値は、`'Poland'` から `'Germany'` に変わりました。面白くなってきましたか?その調子です! + +### まとめ + +素晴らしいです!これで、あなたはプログラミングについて沢山のことを学びました。ここまでのところをまとめましょう。 + +- **エラー** – あなたのコマンドをPythonが理解できない時にエラーが表示されます。 +- **変数** – コードを簡単にまた読みやすくするために、文字や数値などのオブジェクトにつける名札。 +- **リスト** – 複数の値(要素)が順に並んでいるもの。 +- **ディクショナリ** – キーと値のペアの集合です。 + +次に進む準備はいいですか? :) + +## 比較 + +> 家で1人でこのパートに挑戦している方へ:このパートは、動画(英語)もあるので参考にしてください。[Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4) + +比較することは、プログラミングの醍醐味の1つです。簡単に比較できるものといえば、何でしょうか?そうです、数字ですね。さっそくやってみましょう。 + +{% filename %}command-line{% endfilename %} + +```python +>>> 5 > 2 +True +>>> 3 < 1 +False +>>> 5 > 2 * 2 +True +>>> 1 == 1 +True +>>> 5 != 2 +True +``` + +Pythonにいくつか比較する数字をあたえてみました。数字を比較するだけでなく、演算式の答えも比較することができます。便利でしょ? + +2つの数字がイコールであるかどうかを比べる時に、イコールの記号が2つ `==` 並んでいます。 Pythonを記述する時、イコール1つ `=`は、変数に値を代入するときに使います。 ですので、値同士が等しいかどうか比較するときは、必ず **必ず** イコール記号2つ `==` を記述してください。 等しくないことを比較するときは、 上記の例のように `!=` と記述します。 + +次の2つはどうでしょうか。 + +{% filename %}command-line{% endfilename %} + +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` + +`>` と `<` は簡単でしたね。`>=` と `<=` はどうでしょうか?それぞれの意味は、次のとおりです。 + +- x `>` y : x は y より大きい +- x `<` y : x は y より小さい +- x `<=` y : x は y 以下 +- x `>=` y : x は y 以上 + +すばらしい! もう少しやってみましょう。 + +{% filename %}command-line{% endfilename %} + +```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` の左辺あるいは右辺の少なくとも1つがTrueの時、True。 + +"comparing apples to oranges"という英語の表現を聞いたことはありますか?文字通り訳すと「リンゴとオレンジを比較する」となり、「比較にならないものを比較する」という意味です。Pythonでも同じようなことをやってみましょう。 + +{% 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' +``` + +Pythonは、数値(`int`)と文字列(`str`)の比較はできません。 **TypeError** とエラーが表示され、2つのオブジェクトタイプが比較できないことを教えてくれています。 + +## ブール型(Boolean) + +偶然にも、**ブール型 (Boolean)** というあたらしいオブジェクトタイプを学びました。 + +ブール型は、たった2つの値を持ちます。 + +- True +- False + +Pythonを記述するときは、Trueの最初は大文字のT、残りは小文字です。 **true, TRUE, tRUE は間違いです。– True と記述してください** (False についても同様です。) + +ブール型は、次のように変数に代入することもできます。 + +{% filename %}command-line{% endfilename %} + +```python +>>> a = True +>>> a +True +``` + +このようなこともできます。 + +{% filename %}command-line{% endfilename %} + +```python +>>> a = 2 > 5 +>>> a +False +``` + +ブール型を使って、練習して遊んでみましょう。次のコマンドを試してみてください。 + +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` + +おめでとうございます!ブール型を理解することは、プログラミングでとても大事です。ここまでできましたね! + +# 保存しよう! + +> 家で1人でこのパートに挑戦している方へ:このパートと続くパートは、動画(英語)もあるので参考にしてください。[Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk) + +ここまでインタプリタでPythonのコードをかいてきました。つまり、コードを1行ずつしか書くことができませんでした。 普通のプログラムはファイルに保存され、**インタプリタ** あるいは **コンパイラ** でプログラミング言語を処理して実行します。 ここまで、私たちはプログラムを1行ごとにPython **インタプリタ** で実行してきました。 ここからは、1行以上のコードを実行していきましょう。次のような流れになります。 + +- Pythonインタプリタを終了します。 +- お好きなエディタを起動します。 +- Pythonファイルとしてコードを保存します。 +- 実行します! + +これまで使っていたPythonインタプリタを終了しましょう。`exit()` 関数を入力してください。 + +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` + +これで、コマンドプロンプトに戻りました。 + +前に、[コードエディタ](../code_editor/README.md)セクションからエディタを選択しました。 ここでエディタを開いて、新しいファイルにコードを書き込んでみましょう(Chromebookを使用している場合は、Cloud IDEで新しいファイルを作成し、そのファイルを開きます。ファイルをcloud IDEに含まれたコードエディタで開いています)。 + +{% filename %}editor{% endfilename %} + +```python +print('Hello, Django girls!') +``` + +あなたは、すでにベテランのPython開発者です。今日学んだコードを自由に書いてみてください。 + +コードを書いたら、わかりやすい名前をつけて保存しましょう。 **python_intro.py** と名前をつけて、デスクトップに保存してください。 ファイル名は何でもかまいません。ここで重要なことは、拡張子を **.py** とすることです。 コンピュータにこのファイルは **Pythonで実行するファイルです** とおしえます。 + +> **メモ** コードエディタでは色に注目しましょう!これはとてもクールです。 Pythonコンソールでは、すべての文字は同じ色です。エディタでは、`print` 関数は文字列とは違う色がつきます。 これは「シンタックスハイライト」と呼ばれています。エディタは構文(シンタックス)を強調(ハイライト)します。コードを書くとき、これはとても役に立ちます。 色のおかげで、文字列の最後のクォーテーションの書き忘れや、キーワードの名前(この後学ぶ関数の `def` など)のタイポに気づくことができます。 これが私たちがコードエディタを使う理由の1つです. :) + +ファイルを保存したら、実行してみましょう!コマンドラインのセクションで学んだことを思い出して、ターミナルの **ディレクトリを変更** して、デスクトップにしましょう。 + + + +Macでは、コマンドは次のようになります。 + +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop + + + + + + +Linuxでは、次のようになります。 + +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop + + +(「Desktop」という単語はあなたの地域の言語に翻訳される場合があります。) + + + + + +Windowsのコマンドプロンプトでは、次のようになります。 + +{% filename %}command-line{% endfilename %} + + > cd %HomePath%\Desktop + + + + + + +WindowsのPowerShellでは、次のようになります。 + +{% filename %}command-line{% endfilename %} + + > cd $Home\Desktop + + + + +うまくできない時は、質問してください。まさにそのためにコーチがここにいるんです! + +ではPythonを使用して、ファイル内のコードを次のように実行します。 + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hello, Django girls! + + +注:Windowsでは「python3」はコマンドとして認識されません。代わりに「python」を使ってファイルを実行します。 + +{% filename %}command-line{% endfilename %} + +```python +> python python_intro.py +``` + +できました!ファイルに保存された初めてのPythonプログラムを実行できたのです。すばらしいですね。 + +では、ここからプログラミングに不可欠なツールを学んでいきましょう。 + +## If … elif … else + +ある条件が成立するときにだけコードを実行したいということがよくあります。そのためにPythonでは **if文** を用います。 + +**python_intro.py** ファイルのコードを次のように書き換えてください。 + +{% filename %}python_intro.py{% endfilename %} + +```python +if 3 > 2: +``` + +もしこれを保存して実行すると、次のようなエラーが出ます。 + +{% filename %}{{ warning_icon }} command-line{% endfilename %} + + $ python3 python_intro.py + File "python_intro.py", line 2 + ^ + SyntaxError: unexpected EOF while parsing + + +`3 > 2` という条件が成立する( `True` となりますね)時に実行される処理を、まだ記述していませんね。 では、Python に “It works!” と出力してもらいましょう。 **python_intro.py** ファイルの中身を、次のとおりに書き換えてください。 + +{% filename %}python_intro.py{% endfilename %} + +```python +if 3 > 2: + print('It works!') +``` + +2行目をスペース4つでインデント(字下げ)していることに気が付きましたか? 条件が成り立つ時にどのコードを実行するかPythonが分かるように、インデントする必要があります。 スペース1つでもできますが、Pythonプログラマーはほぼ全員スペース4つとしています。 エディタの設定により、タブ1つもスペース4つと同じになります。 タブかスペースか決めたら、変えないようにしましょう。 例えばスペース4つでインデントしたら、この後もスペース4つでインデントするようにしましょう。インデントにスペースとタブを混ぜてしまうと問題が発生してしまうことがあります。 + +保存して、もう一度実行してみましょう。 + +{% filename %}command-line{% endfilename %} + +```python +$ python3 python_intro.py +It works! +``` + +注:Windowsでは「python3」はコマンドとして認識されないことを思い出してください。これから先、ファイルを実行するときは「python3」の代わりに「python」とタイプしてくださいね。 + +### 条件がTrueじゃないときは? + +前述の例では、if文の条件が True の時だけコードが実行されました。Pythonは、`elif` や `else` といった記述もできます。 + +{% filename %}python_intro.py{% endfilename %} + +```python +if 5 > 2: + print('5 is indeed greater than 2') +else: + print('5 is not greater than 2') +``` + +これを実行した場合、次のように出力されます。 + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + 5 is indeed greater than 2 + + +もし2が5より大きかったら、4行目のコマンドが実行されます。では、`elif` はどうなるのでしょうか? + +{% filename %}python_intro.py{% endfilename %} + +```python +name = 'Sonja' +if name == 'Ola': + print('Hey Ola!') +elif name == 'Sonja': + print('Hey Sonja!') +else: + print('Hey anonymous!') +``` + +実行すると... + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hey Sonja! + + +どうなったかわかりましたか? `elif` を使って、前に書いた条件が成立しない場合に実行される条件を追加することができます。 + +最初の `if` の後に、好きなだけ `elif` を追加することができます。例えば... + +{% filename %}python_intro.py{% endfilename %} + +```python +volume = 57 +if volume < 20: + print("It's kinda quiet.") +elif 20 <= volume < 40: + print("It's nice for background music") +elif 40 <= volume < 60: + print("Perfect, I can hear all the details") +elif 60 <= volume < 80: + print("Nice for parties") +elif 80 <= volume < 100: + print("A bit loud!") +else: + print("My ears are hurting! :(") +``` + +Pythonは上から順番に各条件をテストして実行し、次のように出力します。 + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Perfect, I can hear all the details + + +## コメント + +コメントは `#` で始まる行です。`#` の後にはなんでも書くことができ、Pythonはそれを無視します。コメントを書いたコードは、ほかの人にとってもわかりやすくなります。 + +実際にはこのようになります。 + +{% filename %}python_intro.py{% endfilename %} + +```python +# ボリュームが大きすぎたり小さすぎたりしたら変更する +if volume < 20 or volume > 80: + volume = 50 + print("That's better!") +``` + +コードのすべての行にコメントを書く必要はありません。コメントには、コードの中である処理をする理由や、複雑なコードの動きのまとめを書くと役に立ちます。 + +### まとめ + +これらの練習を通して、学んだことは... + +- **比較** – 比較に用いる `>`, `>=`, `==`, `<=`, `<` そして`and`, `or` といった演算子があります。 +- **ブール型** – `True` と `False` 2つの値のみを持ちます。 +- **ファイルの保存** – コードはファイルに保存することで、大きなプログラムも実行できます。 +- **if … elif … else** – 条件分岐することで、特定の条件によって処理を分けて実行することができます。 +- **コメント** – あなたがコードについて記述できる行。Pythonは実行しません。 + +では、いよいよこのチャプターの最後のパートです! + +## 自作の関数! + +> 家で1人でこのパートに挑戦している方へ:このパートは、動画(英語)もあるので参考にしてください。[Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0) + +Pythonでは `len()` のように関数が実行できるのを覚えていますか? ここでは、自分で関数を作る方法を学びます。 + +関数は、Pythonが実行する一連の命令をひとまとめにしたものです。 Pythonでは、関数は `def` というキーワードからはじまり、名前をつけ、引数を含むことができます。 やってみましょう。 **python_intro.py** の中身を下記のコードに置き換えてください。 + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(): + print('Hi there!') + print('How are you?') + +hi() +``` + +よし!あなたの最初の関数を実行する準備ができましたね! + +ここであなたは、最後の行になぜ関数の名前を書いたのだろう、と疑問に感じたかもしれません。 これは、Pythonがファイルを読み、上から下へ実行していくからです。 なので、関数を使用するには、一番下に再度書く必要があります。 + +では実行して、どうなるか見てみましょう。 + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi there! + How are you? + + +注:思ったように動かなくても慌てないで!画面の出力は動かない理由をつかむのに役立ちます。 + +- `NameError` が出ている場合、おそらく何かミスタイプがあります。同じ名前を使っているかチェックしましょう。関数を定義するときは `def hi():` としていますか?関数を実行するときは `hi()` としていますか? +- `IndentationError` が出ている場合、`print` 関数の2行が同じ数のスペースでインデントされているかチェックしましょう。関数の中のコードは同じ数のスベースでインデントされているとPythonは考えます。 +- 画面に何も表示されていない場合、最後の `hi()` がインデントされて *いない* かチェックしましょう - もしインデントされていたら、関数の一部になってしまっています。関数が呼び出されていません。 + +次に引数をつかった関数を作ってみましょう。先ほどの例を変更し、人の名前を呼んで 'hi' と挨拶をする関数にしてみます。 + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): +``` + +ご覧のように、関数に `name` という引数を与えました。 + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + if name == 'Ola': + print('Hi Ola!') + elif name == 'Sonja': + print('Hi Sonja!') + else: + print('Hi anonymous!') + +hi() +``` + +要確認:`print` 関数は、` if `文の中で4つのスペースでインデントします。 これは、条件が満たされたときに関数が実行されるためです。 では、どのように動くか見てみましょう。 + +{% 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' + + +おっと、エラーがでてしまいました。 ラッキーなことに、Pythonがかなり役に立つエラーメッセージを表示してくれています。 定義した関数 `hi()` は、`name` という引数が必要ですが、関数を呼び出す時に引数を忘れてしまっているということがわかります。 最後の行を修正しましょう。 + +{% filename %}python_intro.py{% endfilename %} + +```python +hi("Ola") +``` + +実行してください。 + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Ola! + + +では、名前を変えてみたらどうなりますか? + +{% filename %}python_intro.py{% endfilename %} + +```python +hi("Sonja") +``` + +実行してください。 + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Sonja! + + +では、OlaやSonja以外の名前に変えた時、どうなるかわかりますか?やってみて、予測が正しいか確認して下さい。このように出力されます。 + +{% filename %}command-line{% endfilename %} + + Hi anonymous! + + +すごいでしょ? 挨拶をする人の名前を変えるたびに繰り返しコードを書く必要がなくなりました。 これが関数を作る理由です。何度も繰り返してコードを書きたくないですよね! + +もっとスマートにしてみましょう。名前が2つよりも多いと、それぞれの名前に対して条件を書くのは大変じゃないですか?ファイルの内容を下記のように書き換えてください。 + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + print('Hi ' + name + '!') + +hi("Rachel") +``` + +では、実行してみましょう: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Rachel! + + +おめでとうございます!関数の書き方を学びましたね!:) + +## ループ + +> 家で1人でこのパートに挑戦している方へ:このパートは、動画(英語)もあるので参考にしてください。[Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0) + +さぁ、もう最後のパートですよ。あっという間ですね。 :) + +先ほどお話ししたとおり、プログラマーはめんどくさがりで、同じことを繰り返すのは好きではありません。プログラミングの目的は、物事を自動化することです。名前を呼んで挨拶をする関数をすべての人に対して手で呼び出したくないですよね?こういう時にループが便利です。 + +リストを覚えていますか?女の子の名前をリストにしてみましょう: + +{% filename %}python_intro.py{% endfilename %} + +```python +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +``` + +名前を呼んで、全員にあいさつをしてみましょう。` hi `関数が使えますね。ループの中で使いましょう: + +{% filename %}python_intro.py{% endfilename %} + +```python +for name in girls: +``` + +この `for` 文は `if` 文に似ています。これらの下に書くコードは、4つのスペースでインデントする必要があります。 + +ファイルに書かれるコードはこのようになります: + +{% filename %}python_intro.py{% endfilename %} + +```python +def hi(name): + print('Hi ' + name + '!') + +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +for name in girls: + hi(name) + print('Next girl') +``` + +実行してみましょう: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Hi Rachel! + Next girl + Hi Monica! + Next girl + Hi Phoebe! + Next girl + Hi Ola! + Next girl + Hi You! + Next girl + + +ご覧のとおり、`girls` リストのすべての要素に対して、`for` 文の中にインデントして書いたことが繰り返されています。 + +`range` 関数を使うことで、`for` 文を数値について使うこともできます。 + +{% filename %}python_intro.py{% endfilename %} + +```python +for i in range(1, 6): + print(i) +``` + +これを実行すると、次のように出力されます: + +{% filename %}command-line{% endfilename %} + + 1 + 2 + 3 + 4 + 5 + + +`range` 関数は、連続する数値を要素とするリストを作ります。引数に指定した開始の数値から終了の数値までのリストです。 + +2つ目の引数(終了の数値)は、リストに含まれないことに注意してください(`range(1, 6)`は1から5がカウントされますが、6は含まれません)。 開始に指定した数値は含まれて、終了に指定した値は含まれないのです。 + +## まとめ + +以上です!**おめでとう!頑張りました!** これは簡単ではなかったと思います。自分を褒めてあげてくださいね。ここまで進めることができたのは、本当にすごいことです! + +公式の完全なPythonチュートリアルは https://docs.python.org/ja/3/tutorial/ にあります。これを見れば、Pythonについてより綿密で完全な学習ができるでしょう。ばんざい!:) + +次のチャプターに進む前に、ストレッチしたり、お散歩したり、目を休ませたりして、少しの間リフレッシュしてくださいね。 :) + +![カップケーキ](images/cupcake.png) \ No newline at end of file diff --git a/ja/python_introduction/images/cupcake.png b/ja/python_introduction/images/cupcake.png new file mode 100644 index 00000000000..8c1820adee8 Binary files /dev/null and b/ja/python_introduction/images/cupcake.png differ diff --git a/ja/template_extending/README.md b/ja/template_extending/README.md new file mode 100644 index 00000000000..ab993f155cc --- /dev/null +++ b/ja/template_extending/README.md @@ -0,0 +1,147 @@ +# テンプレートを拡張しよう + +Djangoのまた別の素敵なところは**テンプレート拡張**です。これは何を意味するのでしょうか?それはHTMLの共通部分をウェブサイトの異なるページで使えるということです。 + +テンプレートは同じ情報やレイアウトを複数の場所で利用したいときに役立ちます。 各ファイル内で繰り返す必要はありません。 さらにもし何か変更したい場合、各テンプレートを変更する必要はなく、1回変更すればいいだけです! + +## 基本テンプレートを作成する + +基本テンプレートはあなたのウェブサイトの各ページを拡張するための最も基本的なテンプレートです。 + +`blog/templates/blog/`以下に`base.html`ファイルを作ってみましょう。 + + blog + └───templates + └───blog + base.html + post_list.html + + +それからエディタで開いて、以下のように`post_list.html`から`base.html`ファイルにすべてコピーしましょう。 + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% load static %} + + + Django Girls blog + + + + + + + + +
+
+
+ {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +
+
+
+ + +``` + +それから`base.html`内の``全体(``と``の間のすべて)を次で置き換えます。 + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ +``` + +{% raw %}`{% for post in posts %}` から `{% endfor %}` が以下のように置き換えられたことに気づいたでしょうか。 {% endraw %} + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% block content %} +{% endblock %} +``` + +でも何のために? あなたはただ`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.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` + +これをcontentブロックに対応するテンプレートのパーツとして使いたいです。このファイルにblockタグを追加する時です! + +{% raw %}追加するblockタグは `base.html` ファイル中のタグにマッチしてほしいですよね。 また、blockタグにはcontentブロックに属するすべてのコードを含めたいですよね。 そうするには、すべてを `{% block content %}` と `{% endblock %}` の間に入れてあげればよいです。 このように:{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +あとやることは一つだけです。これら二つのテンプレートをくっつけてあげる必要があります。これがテンプレートを拡張するということのすべてです!そうするにはこのファイルの先頭にextendsタグを追加します。次のように: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +以上です!ファイルを保存して、ウェブサイトがまだちゃんと動いているか確認しましょう。:) + +> もし `TemplateDoesNotExist` というエラーが出ていたら、 `blog/base.html` ファイルがないという意味で、コンソールで `runserver` が実行されたままになっていると思います。 これを止め(Ctrl+C - ControlとCのキーを同時押し)、それから `python manage.py runserver`コマンドを入力して再度サーバーを動かしてみてください。 \ No newline at end of file diff --git a/ja/whats_next/README.md b/ja/whats_next/README.md new file mode 100644 index 00000000000..3f0244cf496 --- /dev/null +++ b/ja/whats_next/README.md @@ -0,0 +1,42 @@ +# 次のステップは? + +おめでとうございます。**素晴らしいです。**よくやりました! <3 + +### 今何をする? + +休憩してリラックスしてください!本当に大きなことを成し遂げました。 + +休んだ後は、[Facebook](http://facebook.com/djangogirls)や[Twitter](https://twitter.com/djangogirls)でDjango Girlsをぜひフォローしてくださいね。最新の情報を入手できます。 + +### さらにオススメの資料はありますか? + +あります! 様々なプログラミングスキルを学ぶためのオンラインリソースが、*たくさん*あります。沢山ありすぎて何を次にやろうか迷うかもしれませんので、お勧めを示しておきます。 Django Girlsのチュートリアルを始める時にどんな興味を持っていたとしても、あるいは、チュートリアルを終えた今どんな興味があるとしても、あなたが行きたいところへ行くために使える無料の(あるいは、無料で多くのことを学べる)リソースを示します。 + +#### Django + +- このチュートリアルの続きである[Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org/) +- [Django 公式チュートリアル](https://docs.djangoproject.com/ja/5.1/intro/tutorial01/) +- [Getting Started With Django 動画レッスン](http://www.gettingstartedwithdjango.com/) + +#### HTML, CSS ならびに JavaScript + +- [Codecademyのweb開発コース](https://www.codecademy.com/learn/paths/web-development) +- [freeCodeCamp](https://www.freecodecamp.org/) + +#### Python + +- [CodecademyのPythonコース](https://www.codecademy.com/learn/learn-python) +- [GoogleのPythonコース](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/) – CourseraのPython専門講座の無料かつ開放されたバージョンです。 + +#### データ操作 + +- [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 "ミッション" が無料です。 + +あなたが次になにを作るか、楽しみにしています! diff --git a/ko/GLOSSARY.md b/ko/GLOSSARY.md index 7f61177d9a9..e549ec65d06 100755 --- a/ko/GLOSSARY.md +++ b/ko/GLOSSARY.md @@ -1,3 +1,3 @@ # 코드 에디터 -코드 에디터는 코드를 저장하고 다시 불러올 수 있는 프로그램입니다. [코드 에디터](./code_editor/README.md) 에서 배울 수 있습니다. +코드 에디터는 코드를 저장하고 불러올 수 있는 프로그램입니다. 자세한 내용은 [코드 에디터](./code_editor/README.md) 장에서 다룹니다. diff --git a/ko/README.md b/ko/README.md index b885d6db55c..ad189a8814e 100755 --- a/ko/README.md +++ b/ko/README.md @@ -1,57 +1,68 @@ -# 장고 걸스 튜토리얼 (Django Girls Tutorial) +# 장고걸스 튜토리얼 (Django Girls Tutorial) -[![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) -> 이 튜토리얼은 Creative Commons Attribution-ShareAlike 4.0 International 저작권을 따르고 있습니다. 라이센스 전문은 https://creativecommons.org/licenses/by-sa/4.0/ 에서 확인하세요. +> 이 튜토리얼은 Creative Commons Attribution-ShareAlike 4.0 International 저작권을 준수합니다. +> 라이센스 전문은 https://creativecommons.org/licenses/by-sa/4.0 에서 확인하세요. ## 번역 -이 튜토리얼은 [장고걸스서울](https://djangogirls.org/seoul) 운영진 및 코치들과 열정있는 한국인 자원 봉사자들에 의해 한국어로 번역되었습니다. 수고해주신 모든 분들에게 진심으로 감사의 말씀을 전합니다. -번역 : [Jay Park](http://jinto.pe.kr/), [Veronique Cho](https://www.facebook.com/babygirl13xx?fref=ts), [정광윤](https://twitter.com/initialkommit), innatsu, 임정훈, 문지영, 김휘경, 송석리, 여형석, 심혜민 +이 튜토리얼은 열정적인 장고걸스 코치들과 자원봉사자들의 수고로 번역되었습니다. -감수 : [이수진](http://sujinlee.me/), [함기훈](https://www.facebook.com/gihun.ham?fref=ts) +> 번역 업데이트 및 번역자 +> +> - 1차 : 2015. 10. 1. + [이수진](https://github.com/sujinleeme), 함기훈, [박제권](http://jinto.pe.kr/), 조혜선, [정광윤](https://twitter.com/initialkommit), 임정훈, 문지영, 김휘경, 송석리, 여형석, 심혜민 -## 들어가며 +> - 2차 : 2016. 6. 3. + [이수진](https://github.com/sujinleeme) -점점 기술이 중요해진 세상에 살고 있지만 '내가 뒤쳐진게 아닐까' 하는 생각이 문득 든 적이 있었나요? 그동안 웹 사이트를 어떻게 만드는지 궁긍했지만 막상 시작하기 어려웠나요? 소프트웨어라는 세상이 너무 복잡해보여 혼자서 직접 만들기엔 엄두가 나지 않았나요? +> - 3차 : 2017. 5. 19. + [이수진](https://github.com/sujinleeme) + +> - 4차 : 2018. 1. 23. + [데이비드 정](https://github.com/jeo19) -여러분에게 반가운 소식이 있습니다! 프로그래밍은 생각만큼 어려운 것이 아니랍니다. 우리는 여러분들에게 프로그래밍이 얼마나 재미있는 것인지 알려드리고 싶어요. +> - 5차 : 2019. 2. 5. + [이재열](https://github.com/malkoG), [정수민](https://github.com/soomin-jeong) -물론 이 튜토리얼을 읽기만 하면 프로그래머가 되는, 그런 기적은 일어나지 않을 거에요. 프로그래밍에 능숙해지려면 몇 달, 혹은 몇 년이나 공부하고 수련해야하죠. 그러나 프로그래밍이나 웹 사이트 제작은 생각만큼 복잡하지 않아요. 여러분이 겁먹지 않도록 조금씩 설명해 드릴 거에요. +## 환영합니다 -우리가 그랬듯이 여러분들도 프로그래밍을 사랑할 수 있게 되길 바랍니다! +장고걸스 튜토리얼에 오신 여러분들을 환영합니다! 이 곳에서 만나게 되어 기뻐요 :) 여러분을 웹 테크놀로지의 여정으로 초대하여 함께 조금씩 맛보면서 웹이 어떻게 작동하는지 알 수 있도록 도와드릴 거예요. -## 튜토리얼에서 무엇을 배우게 되나요? +아직 발견하지 못한 것을 알아가야 하는 꽤 도전적인 모험이 될 것이지만, 지금 이 튜토리얼을 보는 여러분들은 용기를 가지고 있기 때문에, 끝까지 잘 해낼 거라 믿어요. :) + +## 들어가며 + +점점 기술이 중요해지는 세상에 살고 있지만, 나와는 (아직) 관련이 없다고 생각한 적이 있나요? 그동안 웹 사이트를 어떻게 만드는지 궁금했지만, 막상 시작하기 어려웠나요? 소프트웨어 세상이 복잡해보여 혼자서 직접 만들기엔 엄두가 나지 않았나요? -이 튜토리얼을 끝내면, 여러분들은 간단하고 잘 작동하는 나만의 블로그 사이트를 완성할 수 있어요. 온라인에 웹사이트를 올리는 방법도 배울 거에요. 다른 사람들도 여러분의 작품을 보게 될 거랍니다! +그런 여러분들에게 반가운 소식이 있습니다! 프로그래밍은 생각만큼 어려운 것이 아니랍니다. 우리는 여러분들에게 프로그래밍이 얼마나 재미있는 것인지 알려드리고 싶어요. -우리는 아래와 같은 웹 사이트를 완성할 거에요. +이 튜토리얼을 읽는다고 여러분이 마법처럼 프로그래머가 되는 것은 아니에요. 프로그래밍에 능숙해지려면 몇 달, 혹은 몇 년은 공부하고 수련해야 합니다. 그러나 프로그래밍이나 웹 사이트 제작은 생각만큼 복잡하지 않다는 것을 보여드리고 싶어요. 이 튜토리얼을 읽는 여러분들이 겁먹지 않도록, 차근차근 친절하게 설명해 드릴 거예요. -![그림 0.1][2] +우리가 그랬듯이 여러분들도 프로그래밍을 사랑할 수 있게 되길 바랍니다! - [2]: 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) -우리는 코치와 워크샵 참가자들에게 이 곳에서 도움이 필요한 사람들을 도와달라고 요청해두었답니다! 어떤 질문이든 주저하지 말고 물어보세요! +이 튜토리얼을 끝내면 간단한 기능을 갖춘 나만의 블로그 사이트를 완성할 수 있어요. 온라인에 웹사이트를 올리는 방법도 배울 거예요. 다른 사람들도 여러분의 작품을 보게 될 거랍니다! -자, [기본적인 것부터 시작해볼까요.][3] +우리는 앞으로 아래와 같은 웹 사이트를 만들어 볼 거예요. - [3]: ./how_the_internet_works/README.md +![Figure 0.1](images/application.png) -## 튜토리얼에 참여하기 +> 만약 집에서 혼자 튜토리얼을 따라하고 있거나, 문제가 생겼을 때 도움받을 선생님이 없다면 이 곳에서 질문하세요 : [![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial). 우리의 코치들과 워크샵 참가자들이 여러분들을 도와줄 거예요! 어떤 질문이든 주저하지 말고 물어보세요! -이 튜토리얼은 [DjangoGirls][4]에서 지속적으로 관리하고 있습니다. 오류를 발견하거나 튜토리얼 내용을 업데이트하고 싶다면 [참여 방법][5]을 참고하세요. +자, [이제 그럼 어서 시작해볼까요.](./how_the_internet_works/README.md) - [4]: https://djangogirls.org/ - [5]: https://github.com/DjangoGirls/tutorial/blob/master/README.md +## 집에서 튜토리얼 따라하기 -## 다른 언어로 번역하길 원하시나요? +장고걸스 워크샵에서 모든 분들을 만나뵙고 싶지만, 워크샵에 참석하기 어려운 분들이 있다는 것을 알고 있어요. 그래서 워크샵에 참석하지 못하는 분들은 집에서 튜토리얼을 따라해보실 것을 권장합니다. 혼자서도 집에서 튜토리얼을 보며 학습하실 수 있도록 비디오 동영상을 만들고 있어요. [Coding is for girls 유투브 채널](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A)에서 보실 수 있고, 앞으로 더 많은 영상들을 보여드릴 예정입니다. -튜토리얼은 현재 crowdin.com에서 세계 각국어로 번역이 진행되고 있습니다. : +## 튜토리얼 참여하기 -https://crowdin.com/project/django-girls-tutorial +이 튜토리얼은 [DjangoGirls](https://djangogirls.org/)에서 지속적으로 관리하고 있습니다. 오류를 발견하거나 튜토리얼 내용을 업데이트하고 싶다면 [참여 방법](https://github.com/DjangoGirls/tutorial/blob/master/README.md)을 참고하세요. -여러분이 사용하는 언어가 crowdin에 없다면, [이 곳][6]에 알려주세요. +## 튜토리얼 번역 참여하기 - [6]: https://github.com/DjangoGirls/tutorial/issues/new +장고걸스 튜토리얼은 crowdin.com에서 전세계 언어로 번역되고 있습니다 [https://crowdin.com/project/django-girls-tutorial](https://crowdin.com/project/django-girls-tutorial) +여러분이 사용하는 언어가 없다면, [github 이슈](https://github.com/DjangoGirls/tutorial/issues/new)에 등록하셔서 저희에게 알려주세요. diff --git a/ko/SUMMARY.md b/ko/SUMMARY.md index ea46b047f13..09abc9c4e19 100755 --- a/ko/SUMMARY.md +++ b/ko/SUMMARY.md @@ -2,12 +2,13 @@ * [들어가며](README.md) * [설치하기](installation/README.md) +* [설치하기 (chromebook)](chromebook_setup/README.md) * [인터넷은 어떻게 작동할까요](how_the_internet_works/README.md) * [Command Line 시작하기](intro_to_command_line/README.md) * [Python 설치하기](python_installation/README.md) * [코드 에디터](code_editor/README.md) * [Python 시작하기](python_introduction/README.md) -* [Django란 무엇인가요?](django/README.md) +* [Django란 무엇인가요](django/README.md) * [Django 설치하기](django_installation/README.md) * [나의 첫 번째 Django 프로젝트!](django_start_project/README.md) * [Django 모델](django_models/README.md) @@ -17,10 +18,10 @@ * [Django 뷰 만들기](django_views/README.md) * [HTML 시작하기](html/README.md) * [Django ORM(Querysets)](django_orm/README.md) -* [템플릿의 동적 데이터](dynamic_data_in_templates/README.md) +* [템플릿 동적 데이터](dynamic_data_in_templates/README.md) * [Django 템플릿](django_templates/README.md) * [CSS - 예쁘게 만들기](css/README.md) * [템플릿 확장하기](template_extending/README.md) -* [어플리케이션 확장하기](extend_your_application/README.md) -* [Django 양식](django_forms/README.md) +* [애플리케이션 확장하기](extend_your_application/README.md) +* [Django 폼](django_forms/README.md) * [더 나아가기](whats_next/README.md) diff --git a/ko/chromebook_setup/README.md b/ko/chromebook_setup/README.md new file mode 100755 index 00000000000..c13a8150fe1 --- /dev/null +++ b/ko/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# 크롬북에서 설치하기 + +> **Note** 설치 과정을 모두 마친 분들은 이 부분을 할 필요가 없습니다. [Python 시작하기](../python_introduction/README.md) 장으로 바로 넘어가세요. + +{% include "/chromebook_setup/instructions.md" %} diff --git a/ko/chromebook_setup/instructions.md b/ko/chromebook_setup/instructions.md new file mode 100755 index 00000000000..41784eca435 --- /dev/null +++ b/ko/chromebook_setup/instructions.md @@ -0,0 +1,59 @@ +크롬북 미사용자는 이번 장을 건너뛰고 [파이썬 설치하기](http://tutorial.djangogirls.org/ko/installation/#install-python) 장으로 넘어가세요. + +### Cloud 9 + +Cloud 9는 소프트웨어를 설치, 작성 및 실행할 수 있는 인터넷이 실행되는 컴퓨터에 대한 접근과 코드 에디터를 제공하는 도구입니다. 튜토리얼 실습하는 동안 Cloud 9은 _로컬 머신_ 이라 생각하면 됩니다. macOS, 우분투, 윈도우 사용자 처럼 터미널에서 명령어를 입력할 수 있지만, Cloud 9가 설정된 다른 곳에서 실행 중인 컴퓨터의 터미널에 연결됩니다. + +1. [크롬 웹 스토어](https://chrome.google.com/webstore/detail/cloud9/nbdmccoknlfggadpfkmcpnamfnbkmkcp)에서 Cloud 9를 설치하세요. +2. [c9.io](https://c9.io)에 접속하세요. +3. 새 계정을 만드세요. +4. _Create a New Workspace_ 를 클릭하세요. +5. _django-girls_ 라고 쓰세요. +6. _Blank_(오렌지색 로고가있는 맨 아래 줄 오른쪽에서 두 번째)를 선택하세요. + +이제 메인 창 아래쪽에 다음과 같은 작은 창이 보일 거에요. : + +{% filename %}Cloud 9{% endfilename %} +``` +yourusername:~/workspace $ +``` + +이 하단 부분이 명령어를 입력할 Cloud9 _터미널_입니다. 창 크기를 조금 크게 조절할 수도 있어요. + +### 가상환경 + +가상환경(virtual environment, 줄여서 virtualenv)은 작업하고 있는 프로젝트의 코드를 넣을 수 있는 일종의 전용 상자와 같아요. 가상환경을 사용해 서로 다른 프로젝트마다 코드가 섞이지 않도록 유지할 수 있습니다. + +Cloud 9 터미널에서 아래 명령어를 따라 입력하세요. : + +{% filename %}Cloud 9{% endfilename %} +``` +sudo apt install python3.6-venv +``` + +작동하지 않다면, 코치에게 도움을 구하세요. + +그리고, 실행해보세요. : + +{% filename %}Cloud 9{% endfilename %} +``` +mkdir djangogirls +cd djangogirls +python3.6 -mvenv myvenv +source myvenv/bin/activate +pip install django~=1.11.0 +``` + +(마지막 줄에는 물결표 뒤에 등호(~=) 기호를 사용합니다) + +### GitHub + +[GitHub](https://github.com) 계정을 만드세요. + +### PythonAnywhere + +장고걸스 튜토리얼 중 배포하기 장에서 웹 애플리케이션을 구동하는 코드를 공개적으로 액세스 가능한 컴퓨터(서버라고 합니다)로 옮겨, 다른 사람들이 웹 사이트를 볼 수 있도록 실습할 거에요. + +크롬북은 이미 인터넷에 연결된 컴퓨터(노트북과는 반대)이기 때문에 배포하기 장을 따라하면서 조금 이상하다고 생각할 수 있는데요. cloud 9을 현재 "개발 진행 중"인 공간으로 생각하면서 실습한 후, 맨 마지막에 PythonAnywhere에서 결과물을 배포한다고 생각하면 도움이 될 거에요. + +[www.pythonanywhere.com](https://www.pythonanywhere.com) 에서 새 계정을 만드세요. diff --git a/ko/code_editor/README.md b/ko/code_editor/README.md index 972d341013f..0c143a4da39 100755 --- a/ko/code_editor/README.md +++ b/ko/code_editor/README.md @@ -1,7 +1,11 @@ # 코드 에디터 -이제 코드를 작성하기 위해 코드 에디터를 설치해 봅시다. +> **Note** 집에서 학습하시는 분들은 [파이썬 및 코드 에디터 설치하기](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s) 영상을 보세요. -> **주의** 이전 장 설치하기에서 설치를 이미 했다면, 다음 장으로 넘어가세요! +이제 곧 코드를 작성할 예정이니, 코드 에디터를 설치할 차례입니다! + +> **Note** 크롬북 사용자는 이번 장을 건너뛰고 [크롬북에서 설치하기](../chromebook_setup/README.md) 장으로 넘어가세요. + +> **Note** 설치하기 장에 있는 내용을 모두 마쳤다면 다음 장으로 넘어가도 됩니다! {% include "/code_editor/instructions.md" %} diff --git a/ko/code_editor/instructions.md b/ko/code_editor/instructions.md index d72c2aa4326..2a8c05278fd 100755 --- a/ko/code_editor/instructions.md +++ b/ko/code_editor/instructions.md @@ -1,28 +1,32 @@ -코드 편집기는 종류가 많고 다양해 자신의 취향에 따라 선택할 수 있어요. 대부분의 파이썬 프로그래머는 PyCharm과 같이 복잡하지만 강력한 IDE (통합개발환경: Integrated Development Environments)를 이용합니다. 하지만, 초보자에게 적절하지 않는 도구일 수 있어요. 우리는 간단하지만 강력한 기능을 갖춘 에디터들을 추천합니다. +코드 에디터는 종류가 많고 다양해 자신의 취향에 따라 선택할 수 있어요. 대부분의 파이썬 프로그래머는 PyCharm과 같이 복잡하지만 강력한 IDE(통합개발환경: Integrated Development Environments)를 이용합니다. 하지만 초보자에게 적합하지 않을 수 있어요. 간단하지만 강력한 기능을 갖춘 에디터 프로그램을 아래 추천합니다. -아래 추천 에디터 프로그램 중 내가 사용하고 싶은 것을 선택해 사용해도 되지만, 여러분의 코치가 현재 어떤 에디트를 사용 중인지도 물어보세요. 같은 에디터를 사용하면 도움받기 더 쉽고 편할 거에요. +이 중 내가 사용하고 싶은 것을 선택해 사용해도 되지만, 여러분의 코치가 어떤 프로그램을 사용하는지 물어보세요. 같은 프로그램을 사용하면 도움받기 수월해질 거에요. -## Gedit +## Visual Studio Code +Visual Studio Code는 마이크로소프트가 윈도우, 리눅스, 맥OS를 위해 개발한 소스 코드 에디터입니다. 디버깅, 내장 Git 컨트롤,문법 하이라이팅, 지능형 코드 완성, 스니펫, 코드 리팩토링등 지원을 포함하고 있습니다. + +[이 곳에서 다운받을 수 있어요.](https://code.visualstudio.com/) +## Gedit Gedit는 모든 운영체제에서 사용 가능한 무료 오픈소스에요. -[이 곳](https://wiki.gnome.org/Apps/Gedit#Download)에서 다운받으세요. -## Sublime Text 3 +[다운받기](https://wiki.gnome.org/Apps/Gedit#Download) -Sublime Text는 인기있는 에디터이면서 무료로 사용할 수 있어요. 설치와 사용이 편리하고 모든 운영체제에서 쓸 수 있어요. -[이 곳](https://www.sublimetext.com/3)에서 다운받으세요. +## Sublime Text +Sublime Text는 가장 널리 알려진 프로그램으로 무료로 사용할 수 있어요. 설치와 사용이 편리하고 모든 운영체제에서 쓸 수 있어요. + +[다운받기](https://www.sublimetext.com/) ## Atom +Atom은 [GitHub](https://github.com/)에서 만든 에디터예요. 무료로 제공되는 오픈소스이며, 설치나 사용이 쉬워요. 윈도우, 맥OS, 리눅스에서 쓸 수 있어요. -Atom은 아주 최근에 [GitHub](https://github.com/)에서 만든 에디터예요. 무료로 제공되는 오픈소스이며, 설치나 사용이 쉬워요. 윈도우, 맥OS, 리눅스에서 쓸 수 있어요. -[이 곳](https://atom.io/)에서 다운받으세요. +[다운받기](https://atom.io/) ## 왜 코드 에디터를 설치해야 하나요? - 워드나 노트패드가 있는데도, 굳이 코드 에디터 소프트웨어를 설치해야 하는 이유가 궁금할 거에요. -첫 번째로 코드는 **일반 텍스트**여야 하는데, 워드나 텍스트에딧(Textedit)과 같은 프로그램에서는 일반 텍스트가 아닌 [RTF(Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format)와 같은 사용자 서식을 쓴 리치 텍스트(폰트와 서식이 있는 텍스트) 가 생성되기 때문입니다. +첫 번째로 코드는 **일반 텍스트**여야 하는데, 워드나 텍스트에딧(Textedit)과 같은 프로그램에서는 일반 텍스트가 아닌 [RTF(Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format)와 같은 사용자 서식을 쓴 리치 텍스트(폰트와 서식이 있는 텍스트)가 생성되기 때문입니다. -두 번째 이유는 코드 에디터는 개발에 도움이 되는 여러 기능을 제공하기 때문입니다. 대표적인 예로, 코드를 해석해서 색으로 문법을 하이라이팅해주는 기능이라든가 큰따옴표("")를 자동으로 닫아주는 등과 같은 기능들이지요. +두 번째는 코드 에디터 프로그램은 개발에 유용한 여러 기능을 제공하기 때문입니다. 대표적인 예로, 코드를 해석해 문법을 하이라이팅해주는 기능이라든가 큰따옴표("")를 자동으로 닫아주는 기능이지요. 앞으로 코드 에디터가 어떻게 작동하는지 알아볼 거에요. 곧 여러분은 내가 사용하는 코드 에디터를 제일 좋아하게 될 거랍니다. diff --git a/ko/css/README.md b/ko/css/README.md index 26af1c229a0..8628970b19f 100755 --- a/ko/css/README.md +++ b/ko/css/README.md @@ -1,116 +1,123 @@ # CSS - 예쁘게 만들기 -우리가 만든 블로그가 아직 예쁘지 않죠? 이제 눈에 보기 좋게 예쁘게 만들어 볼 시간이에요. CSS를 사용해 만들어 볼 거에요. +아직 우리가 만든 블로그가 예쁘지 않죠? 이제 눈에 보기 좋게 예쁘게 만들어 볼 시간이에요. CSS를 사용해 만들어볼 거에요. + ## CSS는 무엇인가요? -CSS(Cascading Style Sheets)는 HTML와 같이 마크업랭귀지(markup language)으로 쓰여진 웹사이트를 나타낼 때 사용하는 언어입니다. 우리 웹페이지 얼굴에 예쁘게 메이크업 하는 것과 같아요 ;) +CSS(Cascading Style Sheets)는 HTML와 같이 마크업언어(Markup Language)로 작성된 웹사이트의 외관을 꾸미기 위해 사용되는 언어입니다. 웹사이트에 메이크업을 해볼까요. ;) + +아무것도 없는 상태에서 시작하기 어렵겠죠? 개발자들이 만든 오픈 소스 코드를 사용해 만들어 볼 거에요. 이미 있는 바퀴를 다시 발명하는 것은 재미가 없잖아요. + + +## 부트스트랩을 사용해봐요! -아무것도 없는 상태에서 시작하기 어렵죠? 이번에도 우리는 개발자들이 만들고 인터넷 무료로 배포된 코드를 사용할 거에요. 바퀴를 다시 발명하는 것은 재미가 없잖아요. +부트스트랩(Bootstrap)은 유명한 HTML과 CSS프레임워크로 예쁜 웹사이트를 만들 수 있습니다. : https://getbootstrap.com/ -## Bootstrap을 사용해봐요! +트위터 개발자들이 부트스트랩을 만들었고, 전 세계 자원봉사자들이 지속적으로 참여해 발전시키고 있어요! -부트스트랩(Bootstrap)은 예쁜 웹사이트를 개발하기 위해 사용되는 가장 유명한 HTML과 CSS 프레임워크입니다: https://getbootstrap.com/ -부트스트랩은 트위터 개발자들에 의해 만들어졌고 전 세계 자원봉사자들이 지속적으로 참여해 발전시키고 있어요. +## 부트스트랩 설치하기 -## Bootstrap 설치하기 +부트스트랩을 설치하려면, `.html`파일 내 ``에 이 링크를 넣어야 합니다. -Bootstrap을 설치하려면, `.html` 파일의 `` 안에 이 링크를 넣어야 합니다. (`blog/templates/blog/post_list.html`): +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html ``` -이 링크는 프로젝트에 파일을 새로 추가하는 게 아니에요. 인터넷에 있는 파일을 연결하는 거에요. 따라해보고, 웹사이트를 열어 새로고침 버튼을 눌러보세요. 짠! +이 링크는 프로젝트에 새 파일을 추가하는 게 아니에요. 인터넷에 있는 파일을 연결하는 거죠. 이제 웹사이트를 열어 새로고침 버튼을 눌러보세요. 짠! -![그림 14.1][1] +![Figure 14.1](images/bootstrap1.png) - [1]: images/bootstrap1.png +어때요, 보기 좋아졌죠! -더 보기 좋아졌죠! -## Django 정적 파일 +## 정적 파일 -마지막으로 정적 파일( __static files__)을 다뤄볼 거에요. 정적 파일은 CSS과 이미지 모두를 말합니다. 동적 파일이 아니에요. 그렇기 때문에 콘텐츠 요청 내용이 필요없어 모든 유저들이 동일한 내용을 볼 수 있어요. +마지막으로 __정적 파일(static files)__ 을 다뤄볼 거에요. 정적 파일은 CSS와 이미지 파일에 해당합니다. 이 컨텐츠는 요청 내용에 따라 바뀌는 것이 아니기 때문에 모든 사용자들이 동일한 내용을 볼 수 있어요. -### 어디에 정적 파일을 넣어야 하나요 -서버에서 `collectstatic`를 실행할 때 처럼, 장고는 "admin" 앱에서 정적 파일을 어디서 찾아야하는지 이미 알고 있어요. 이제 `blog`앱에 정적파일을 추가하면 됩니다. +### 정적 파일은 어디에 넣어야 하나요 -blog 앱 안에 `static`폴더를 만드세요. : +서버에서 `collectstatic`를 실행할 때 처럼, 장고는 "admin"앱에서 정적 파일을 어디서 찾아야하는지 이미 알고 있어요. 이제 "blog"앱에 정적파일을 추가하면 됩니다. +"blog"앱 안에 `static`라는 새 폴더를 만드세요. : + +``` djangogirls ├── blog │ ├── migrations - │ └── static + │ ├── static + │   └── templates └── mysite +``` +장고는 app 폴더 안에 있는 `static`폴더를 자동으로 찾을 수 있어요. 이 컨텐츠를 정적 파일로 사용하게 되는 것입니다. -장고는 app폴더 안에 있는 "static" 폴더를 자동으로 찾아 안에 있는 내용을 불러낼 거에요. ## 나의 첫 번째 CSS 파일! CSS파일을 만들어 나만의 스타일을 가진 웹페이지를 만들어봐요. `static`디렉토리 안에 `css`라고 새로운 디렉토리를 만드세요. 그리고 `css`디렉토리 안에 `blog.css`라는 파일을 만드세요. 준비되셨나요? +``` djangogirls └─── blog └─── static └─── css └─── blog.css +``` +CSS를 쓸 차례예요! 코드 에디터에서 `blog/static/css/blog.css`파일을 열어보세요. -CSS를 쓸 차례에요! 여러분이 사용하고 있는 코드에디터에서 `blog/static/css/blog.css`파일을 불러오세요. - -CSS는 꽤 쉽고 워크샵 후에도 스스로 배울 수 있기 때문에 이번에는 CSS에 대해 심도 있게 살펴보지는 않을 거에요. 우리는 여러분이 더 예쁜 웹사이트를 만들 수 있도록 [Codeacademy HTML & CSS course][2]를 실습해보길 추천해요. - - [2]: https://www.codecademy.com/tracks/web - -하지만 조금이라도 해보자구요. 제목 색깔을 바꿔볼까요? 컴퓨터는 특별한 코드를 사용해 색깔을 나타내요. `#`으로 시작해 알파벳(A-F)와 숫자(0-9) 중 6개를 조합해 나타내요. 이 곳에서 색깔 코드를 찾을 수 있어요: http://www.colorpicker.com/ 또는 [미리 정의 된 색][3], 예를 들어 `빨간색` 또는 `녹색` 등도 사용할 수 있습니다. +CSS는 꽤 쉽고 워크샵 후에도 스스로 배울 수 있기 때문에 CSS에 대해 깊이 살펴보지는 않을 거에요. 이 장 맨 마지막 부분에 추천하는 무료 사이트가 있습니다. - [3]: http://www.w3schools.com/colors/colors_names.asp +하지만 조금이라도 해보자구요. 제목 색상을 바꿔볼까요? 컴퓨터는 특별한 코드를 사용해 색상을 나타내요. `#`으로 시작해 알파벳(A-F)와 숫자(0-9) 중 6개를 조합해 헥사코드(hexacode)로 나타냅니다. 이 곳에서 원하는 색상 코드를 찾을 수 있어요. [https://www.colorpicker.com/](https://www.colorpicker.com/) 또는 `빨간색(red)` 또는 `녹색(green)` 등 [미리 명시된 색상](http://www.w3schools.com/colors/colors_names.asp)을 사용할 수 있어요. -`blog/static/css/blog.css`에 아래의 코드를 추가하세요. +`blog/static/css/blog.css` 파일에 아래 코드를 추가하세요. : +{% filename %}blog/static/css/blog.css{% endfilename %} ```css h1 a { color: #FCA205; } ``` -`h1 a`가 CSS 셀렉터(Selector)에요. 즉, 우리는 `h1`요소 안에 어떠한 `a`요소를 넣어 스타일을 적용 할 수 있다는 거죠. (예를 들어 코드가 다음과 같을 때: `

link

`) 이 경우에, 우리는 색을 `#FCA205`, 즉 오렌지색으로 바꾸라고 말한 거에요. 물론, 색을 직접 선택할 수도 있어요! +`h1 a`는 CSS 셀렉터(Selector)라고 합니다. `h1`요소 안에 어떠한 `a`요소를 넣어 스타일을 적용 할 수 있다는 거죠. 예를 들어 `

link

` 라면, 오렌지색 `#FCA205`으로 바꿀 수 있어요. 물론, 내가 원하는 다른 색상을 지정할 수 있어요! -CSS파일에서는 HTML 파일에 있는 각 요소들에 스타일을 적용할 수 있어요. 각 요소는 요소 이름(다시 말하면, `a`, `h1`, `body`), `class`상속 아니면 `id`상속에 의해 식별돼요. Class와 id는 여러분들이 붙인 이름을 갖게 되지요. 클래스는 요소들의 그룹을 결정하는 것이고, id는 특정 요소들을 지칭해요. 예를 들어, 다음 태그들은 CSS에서 태그 이름 `a`, 클래스 `external_link`, id `link_to_wiki_page`을 사용해서 식별해요. +CSS 파일에서는 HTML 파일에 있는 각 요소들에 스타일을 정의할 수 있어요. 요소를 식별하는 첫 번째 방법은 요소 이름을 사용하는 것입니다. HTML 섹션에서 태그로 기억할 수 있습니다. `a`,`h1`,`body`와 같은 것은 모두 요소 이름의 예입니다. 또 `class` 속성이나 `id` 속성에 의해 요소를 식별합니다. 클래스와 ID는 요소에 직접 부여한 이름이에요. 클래스는 요소 그룹을 정의하고 ID는 특정 요소를 가리킵니다. 아래 코드와 같이 태그 이름은 `a`, 클래스는 `external_link` 또는 ID는 `link_to_wiki_page`로 사용하여 태그를 통해 요소를 식별할 수 있습니다. ```html ``` -W3Schools에서 [CSS Selectors][4]에 대해 읽어보세요.. - - [4]: http://www.w3schools.com/cssref/css_selectors.asp +W3Schools에서 [CSS 선택자](https://www.w3schools.com/cssref/css_selectors.asp)에 대해 읽어보시길 바랍니다. -이제 CSS의 내용을 HTML에 적용시킬 차례에요. `blog/templates/blog/post_list.html`파일을 열고 가장 위에 이 라인을 추가하세요: +이제 CSS를 HTML에 추가해봅시다. `blog/templates/blog/post_list.html` 파일을 열고 맨 처음 줄에 이 라인을 추가하세요. +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} ``` -정적 파일이 실행되고 있답니다. :) - -다음, ``와 `` 사이에, 부트스트랩 CSS파일 링크 다음(브라우저는 순서대로 파일을 읽기 때문에 부트스트랩 파일에 있는 코드를 무시할 수 있어요.) 다음 코드를 추가하세요. +여기에서 정적 파일을 로딩하는 거에요. :) +다음 ``와 `` 사이에 부트스트랩 CSS파일 링크 다음에 아래 코드를 추가하세요. +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html ``` -이제까지 CSS파일이 있는 템플릿에 대해 알아 보았어요. +브라우저는 주어진 순서대로 파일을 읽으므로 파일이 올바른 위치에 있는지 확인해야합니다. 그렇지 않으면 파일 코드가 부트 스트랩 파일의 코드를 무시할 수 있습니다. +이제까지 CSS파일이 있는 템플릿에 대해 알아보았어요. -여러분이 만든 파일은 아래와 같아야해요. +코드는 아래와 같아야 해요. +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} Django Girls blog @@ -136,34 +143,34 @@ W3Schools에서 [CSS Selectors][4]에 대해 읽어보세요.. 자, 이제 파일을 저장하고 새로고침을 해보세요! -![그림 14.2][5] - - [5]: images/color2.png +![Figure 14.2](images/color2.png) -잘했어요! 웹사이트 왼쪽 여백을 좀더 주고 싶지 않나요? 한 번 해봐요! +잘했어요! 웹사이트 왼쪽 여백을 좀더 주고 싶지 않나요? 한번 해봐요! +{% filename %}blog/static/css/blog.css{% endfilename %} ```css - body { - padding-left: 15px; - } +body { + padding-left: 15px; +} ``` 이 코드를 CSS에 붙여넣고, 파일을 저장하고 어떻게 바뀌었는지 확인해봐요! -![그림 14.3][6] +![Figure 14.3](images/margin2.png) - [6]: images/margin2.png - -제목의 폰트를 바꾸고 싶나요? `blog/templates/blog/post_list.html`파일 안에 ``에 아래 코드를 붙여넣기 해보세요. +제목 폰트를 바꾸고 싶나요? `blog/templates/blog/post_list.html` 파일 내 ``부분에 아래 코드를 붙여넣기 해보세요. +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - + ``` -이 코드 라인은 구글 폰트 (https://www.google.com/fonts) 에서 *Lobster* 폰트를 불러온 거에요. +`blog/static/css/blog.css` 파일 내 넣은 코드의 순서와 위치를 다시 확인해보세요. 이 라인은 Google 글꼴 (https://www.google.com/fonts)에서 * Lobster* 라는 글꼴을 가져온 것을 말해요. + +그리고 CSS파일  `blog/static/css/blog.css` 에서`h1 a` 선언 블록 (중괄호`{`와`}`) 사이의 코드를 찾으세요. `font-family : 'Lobster';` 를 중괄호 사이에 추가하고 페이지를 새로고침 합니다. -이제 CSS에 `font-family: 'Lobster';`를 추가하세요 ; `blog/static/css/blog.css`파일 안에 `h1 a` 안에 있는 블록 (다음 표기가 된 부분 안에 `{` and `}`) 에 추가하고 새로고침을 누르세요. : +{% filename %}blog/static/css/blog.css{% endfilename %} ```css h1 a { color: #FCA205; @@ -171,24 +178,23 @@ h1 a { } ``` -![그림 14.3][7] - - [7]: images/font.png +![Figure 14.3](images/font.png) 잘했어요! -앞서 말했듯이, CSS는 클래스 개념을 가지고 있어요. 클래스는 기본적으로 여러분이 HTML의 코드 일부에 이름을 붙이고 그 부분만 특정 스타일을 적용할 수 있게 해줍니다. 두 개의 div가 있는데 각각 다르게 사용되서(예를 들어 하나는 제목에 있고 하나는 글 본문에 있는 경우), 서로 다르게 보여야 할 경우에 매우 유용해요. +앞서 말했듯이, CSS는 클래스 개념을 가지고 있어요. 클래스는 HTML의 코드 일부에 이름을 붙이고 그 부분만 특정 스타일을 적용할 수 있게 해줍니다. 각기 다른 div를 (예를 들어 하나는 제목에 있고 하나는 글 본문에 있는 경우) 구분할 때 정말 유용해요. HTML 코드의 일부 이름을 지정하십시오. -이제 HTML 코드의 일부에 이름을 붙여 봅시다. header에 포함된 `div`에 `page-header`라고 class 이름을 붙여봅시다. 다음과 같이 말이죠. : +제목이 포함된 `div`에 `page-header`라는 클래스명을 붙여보세요. : +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -``` +
``` -그리고 이제 블로그 글 안에 있는 `div`에 `post`라고 class 이름을 붙이세요. +그리고 블로그 게시글을 나타내는 `div`에 `post`라고 클래스명을 붙여보세요. +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html

published: {{ post.published_date }}

@@ -197,8 +203,10 @@ h1 a {
``` -다음 각 다른 선택자(selector) 에 정의를 붙여 볼 거에요. 클래스를 나타내는 선택자는 `.`으로 시작합니다. 아래 있는 코드의 이해를 돕기 위해 인터넷에서 CSS에 대한 튜토리얼이나 설명을 참고하면 많은 도움이 될 거에요. 이제 `blog/static/css/blog.css`파일 안에 아래 코드를 복사, 붙여넣기 하세요. : +이제 여러 선택자들을 추가해봅시다. 클래스 선택자는 `.`으로 시작합니다. 인터넷에 많은 CSS 튜토리얼과 설명 가이드가 있으니 찾아보면 도움이 될 거에요. 이제 `blog/static/css/blog.css` 파일에 아래 코드를 복사, 붙여넣기 하세요. + +{% filename %}blog/static/css/blog.css{% endfilename %} ```css .page-header { background-color: #ff9400; @@ -221,7 +229,6 @@ h1, h2, h3, h4 { } .date { - float: right; color: #828282; } @@ -249,8 +256,9 @@ h1, h2, h3, h4 { } ``` -클래스 선언이 있는 post가 있는 곳으로 가세요. 이 부분을 바꿀 거에요. : +자, 다음은 글을 보여주는 HTML 코드를 post라는 클래스 명을 선언해 div로 감싸세요. 이렇게 바꾸면 됩니다. : +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %}
@@ -260,9 +268,9 @@ h1, h2, h3, h4 {
{% endfor %} ``` +`blog/templates/blog/post_list.html` 파일 안에 아래 코드를 넣으세요. -`blog/templates/blog/post_list.html` 안에 아래 코드를 넣으세요. - +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html
@@ -270,7 +278,7 @@ h1, h2, h3, h4 { {% for post in posts %}
- {{ post.published_date }} +

published: {{ post.published_date }}

{{ post.title }}

{{ post.text|linebreaksbr }}

@@ -281,16 +289,14 @@ h1, h2, h3, h4 {
``` -파일을 저장하고 웹사이트를 새로고침하세요. - -![그림 14.4][8] +파일을 저장하고 웹 사이트를 새로고침하세요. - [8]: images/final.png +![Figure 14.4](images/final.png) -와! 멋지지 않나요? 지금까지 붙여넣기한 코드는 이해하기 어렵지 않으니 무슨 뜻인지 이해 할 수 있을 거에요. +방금 붙여 넣은 코드를보고 HTML에 클래스를 추가하고 CSS에서 사용했던 곳을 찾아보세요. 날짜를 초록색으로 바꾸려면 어느 부분을 수정하면 될까요? -아직 CSS를 다루는 것이 서툴다고 걱정하지 말고 여러분이 바꾸고 싶은 부분을 고쳐보세요. 만약 문제가 생겼다면, 걱정하지말아요. 언제든지 되돌리기를 할 수 있으니까요! +CSS를 바꿔보는 것을 두려워하지 마세요. CSS를 가지고 놀다보면 어떻게 작동되는지 좀더 이해할 수 있을 거에요. 망가뜨렸더라도 괜찮아요. 언제든지 되돌릴 수 있으니까요! -워크샵 사전 숙제로 CSS로 더 예쁜 웹사이트를 만들기 위해서[Codeacademy HTML & CSS course][2]를 수강해보길 추천해요. +무료 온라인 [Codecademy HTML & CSS 코스](https://www.codecademy.com/tracks/web)를 수강해보는 것을 추천합니다. CSS로 웹 사이트를 더 아름답게 만드는 방법을 배울 수 있어요. -다음 장을 읽을 준비가 됐나요?! :) +다음 장을 읽을 준비가 되셨나요?! :) diff --git a/ko/css/images/bootstrap1.png b/ko/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/ko/css/images/bootstrap1.png and b/ko/css/images/bootstrap1.png differ diff --git a/ko/css/images/color2.png b/ko/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/ko/css/images/color2.png and b/ko/css/images/color2.png differ diff --git a/ko/css/images/final.png b/ko/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/ko/css/images/final.png and b/ko/css/images/final.png differ diff --git a/ko/css/images/font.png b/ko/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/ko/css/images/font.png and b/ko/css/images/font.png differ diff --git a/ko/css/images/images/bootstrap1.png b/ko/css/images/images/bootstrap1.png new file mode 100644 index 00000000000..bd81cd14373 Binary files /dev/null and b/ko/css/images/images/bootstrap1.png differ diff --git a/ko/css/images/images/color2.png b/ko/css/images/images/color2.png new file mode 100644 index 00000000000..3f82e7d3922 Binary files /dev/null and b/ko/css/images/images/color2.png differ diff --git a/ko/css/images/images/final.png b/ko/css/images/images/final.png new file mode 100644 index 00000000000..067c83d36cc Binary files /dev/null and b/ko/css/images/images/final.png differ diff --git a/ko/css/images/images/font.png b/ko/css/images/images/font.png new file mode 100644 index 00000000000..310f9e85f18 Binary files /dev/null and b/ko/css/images/images/font.png differ diff --git a/ko/css/images/images/margin2.png b/ko/css/images/images/margin2.png new file mode 100644 index 00000000000..895828b688d Binary files /dev/null and b/ko/css/images/images/margin2.png differ diff --git a/ko/css/images/margin2.png b/ko/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/ko/css/images/margin2.png and b/ko/css/images/margin2.png differ diff --git a/ko/deploy/README.md b/ko/deploy/README.md index 5f5ccaca680..d85c65a0519 100755 --- a/ko/deploy/README.md +++ b/ko/deploy/README.md @@ -1,295 +1,275 @@ # 배포하기! -> **Note** 이번 장은 따라오기 조금 힘들 수도 있어요. 끝까지 따라와주세요. 배포는 웹사이트 개발의 가장 중요한 부분이에요. 튜토리얼 중간에 이번 장이 있는 이유는 여러분이 코치가 여러분의 웹사이트를 온라인에서 볼 수 있게 도와주기 위해서에요. 시간이 모자르더라도 튜토리얼을 끝낼 수 있어요. +> **Note** 이번 장은 조금 따라 하기 어려울 수도 있습니다. 하지만 끝까지 따라와 주세요. 배포는 웹 사이트 개발의 가장 중요한 부분이에요. 튜토리얼 중간에 배포 내용이 있는 이유는 코치가 웹사이트를 온라인으로 배포하는 까다로운 과정을 도와줄 수 있기 때문이에요. 시간이 부족하면 혼자서 해볼 수 있을 겁니다. -지금까지는 웹사이트를 내 컴퓨터에서만 볼 수 있었어요. 이제 어떻게 웹사이트를 배포하는지 배워봅시다. 배포(deploy)는 애플리케이션을 인터넷에 올려놓아 다른 사람들도 볼 수 있게 해주는 것 말해요. :) +지금까지는 웹사이트를 내 컴퓨터에서만 볼 수 있었어요. 지금부터 웹사이트를 배포방법을 배워봅시다! 배포(deployment)는 애플리케이션을 인터넷에 올려놓아 다른 사람들도 볼 수 있게 해주는 것 말해요. :) -앞에서 배웠듯이, 웹사이트는 서버라는 곳에 들어 갑니다. 인터넷에는 많은 종류의 서버 제공 업체들이 있어요. 우리는 이 중에 비교적 배포 과정이 간단한 [PythonAnywhere][1]을 사용할 거에요. PythonAnywhere는 방문자가 아주 많지 않은 소규모 어플리케이션으로 무료로 사용할 수 있답니다. 당연히 지금 우리가 만드는 것도 해당되지요. +앞에서 배웠듯이, 웹사이트는 서버라는 곳에 들어갑니다. 인터넷 상에 서버를 제공하는 업체들은 참 많습니다. 우리는 이 중에 비교적 배포 과정이 간단한 [PythonAnywhere](https://www.pythonanywhere.com/)을 사용할 거에요. PythonAnywhere는 방문자가 아주 많지 않은 소규모 애플리케이션을 위한 무료 서비스를 제공하고 있습니다. 지금 우리가 만드는 웹사이트도 해당됩니다. - [1]: https://pythonanywhere.com/ +우리가 사용할 다른 외부 서비스는 [GitHub](https://github.com/)이라는 코드 호스팅 서비스입니다. 요즘에는 모든 프로그래머들은 GitHub 계정을 가지고 있으니, 여러분도 GitHub 계정을 만들어봐요! -우리가 사용할 다른 서비스는 [GitHub][2]라는 코드 호스팅 서비스입니다. 프로그래머들이 애용하는 곳들 중 하나로 대부분의 모든 프로그래머가 GitHub 계정을 가지고 있다고 봐도 될 거예요. 이제 여러분도 하나 만들 때가 되었어요! +로컬컴퓨터, GitHub, Pythonanywhere 이 세 곳은 모두 중요해요. 로컬 컴퓨터는 개발 및 테스트를 수행하는 곳이 될 것입니다. 개발이 완료되면 프로그램 복사본을 GitHub에 저장합니다. 웹사이트는 PythonAnywhere에 있고 GitHub에서 코드 사본을 업데이트할 거에요. - [2]: https://www.github.com - -우리는 GitHub를 작성한 코드를 PythonAnywhere에 넣고 빼기 위한 디딤돌로 사용할 거에요. 즉, 코드를 GitHub에 저장하고 GitHub에 저장된 코드를 PythonAnywhere에서 가져다가 작동하는 방법이에요. - -# Git - -Git은 많은 프로그래머들이 사용하고 있는 "버전 관리 시스템(version control system)"이에요. 이 소프트웨어는 변경 내용을 추적할 수 있어 나중에 특정 버전을 다시 호출 할 수 있어요. 마이크로소프트 워드에 있는 "변경 내용 추적하기(track changes)"와 같은 기능이지만 이보다 훨씬 더 강력합니다. - -## Git 설치하기 - -> **Note** 이미 설치를 끝냈다면, 다시 할 필요가 없어요. 이 부분을 넘기고 Git 저장소를 만드는 것부터 시작하세요. +# Git 설치하기 +> **Note** 이미 설치가 완료되었다면, 다시 할 필요가 없어요. 다음 장으로 넘어가서 Git 저장소를 만드는 것부터 시작하세요. {% include "/deploy/install_git.md" %} ## Git 저장소 만들기 -Git은 코드 저장소(줄여서 "repo"라고 합니다.)에 특정한 파일들 집합의 변화를 추적하여 관리합니다. 이제 프로젝트를 시작해 볼까요? 콘솔창을 열고 `djangogirls` 디렉토리에서 아래 명령어들을 실행하세요. 아래 명령 중에서 Your Name 대신 자신의 이름을, you@example.com 대신에 내 이메일 주소를 입력하세요. - -> **Note** 저장소를 초기화 하기 전에 여러분의 현재 작업 디렉토리가 어디인지 꼭 확인하세요. 맥OS나 Linux라면 `pwd` 명령으로, 윈도우라면 `cd` 명령어를 실행하면 알 수 있을 거에요. 반드시 `djangogirls` 폴더에서 해야합니다. - - $ 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은 코드 저장소(repository: 줄여서 "repo"라고 합니다)에 특정한 파일들 집합의 변화를 추적하여 관리합니다. 이제 프로젝트를 시작해 볼까요? 콘솔 창을 열고 `djangogirls` 디렉터리에서 아래 명령어들을 실행하세요. +> **Note** 저장소를 초기화하기 전에 여러분의 현재 작업 디렉터리가 어디인지 꼭 확인하세요. 맥OS나 Linux라면 `pwd` 명령으로, 윈도우라면 `cd` 명령어를 실행하면 알 수 있을 거예요. 반드시 `djangogirls` 폴더에서 해야 합니다. -git 저장소 초기화는 프로젝트를 시작할 때 딱 한번만 필요합니다. (또한 두 번째, 세 번째 명령인 username과 email 등록 명령은 계속 적용되기 때문에 이 계정에서는 다시 입력할 필요가 없습니다.) - -Git은 이 디렉토리에 모든 파일들과 폴더들의 변경점을 추적할 거에요. 무시(ignore)하도록 지정한 파일들을 제외하고는 말이죠. 기본 디렉토리에다 `.gitignore`라는 파일을 만들어서 특정 파일이나 폴더를 추적하지 않게 할 수 있습니다. 에디터를 열어 아래 내용을 넣어주세요. : - - *.pyc - __pycache__ - myvenv - db.sqlite3 - .DS_Store +{% 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 저장소 초기화는 프로젝트를 시작할 때 딱 한 번만 필요합니다. (username과 email 등록 명령은 계속 적용되기 때문에 이 계정에서는 다시 입력할 필요가 없습니다) -그리고 "djangogirls" 폴더의 맨 위에다 `.gitignore` 라는 파일로 저장하세요. +git은 이 디렉터리에 모든 파일과 폴더들의 변경 점을 추적할 것인데, 특정 파일들을 무시(ignore)하여 추적하지 않게 할 수 있습니다. 기본 디렉터리에 `.gitignore`라는 파일을 만들면 됩니다. 에디터를 열어 아래 내용을 넣어주세요. : -> **Note** 파일명 앞에 마침표로 시작하는 것이 중요합니다! 꼭 붙여주세요. 만약 파일을 만드는 것이 어렵다면 (예를 들어 맥은 파인더에서 마침표로 시작하는 파일을 생성하는 걸 좋아하지 않아요) "다른 이름으로 저장(Save As)" 기능을 사용하세요. 대부분 이렇게 하면 될 거에요. +{% filename %}.gitignore{% endfilename %} +``` +*.pyc +*~ +__pycache__ +myvenv +db.sqlite3 +/static +.DS_Store +``` -`git add`하기 전이나 변경된 것이 있는지 잘 모를 때마다 `git status` 명령어를 사용하는 것은 좋은 방법이에요. 잘못된 파일이 추가된 경우, 이를 멈출 수 있게 도움을 주어요. `git status` 명령은 미추적/수정된/스테이지된 파일들, 브랜치 상태와 그 외 많은 정보들을 보여줍니다. 실행하면 아래와 비슷하게 나타날거에요. : +그리고 `djangogirls` 폴더의 맨 위에다 `.gitignore` 라는 파일로 저장하세요. - $ git status - On branch master +> **Note** 파일명 앞에 마침표로 시작하는 것이 중요합니다! 만약 파일을 만드는 것이 어렵다면 (예를 들어 맥은 파인더에서 마침표로 시작하는 파일을 생성하는 걸 좋아하지 않아요) `다른 이름으로 저장(Save As)` 기능을 사용하세요. - Initial commit +> **Note** `.gitignore` 파일에 있는 `db.sqlite3`이라는 파일은 모든 게시물이 저장된 로컬 데이터베이스입니다. PythonAnywhere는 다른 데이터베이스를 사용하기 때문에 저장소에 추가될 필요가 없습니다. 다른 데이터베이스로는 SQLite로도 사용하지만 보통은 SQLite보다 훨씬 많은 방문자를 보유한 웹사이트일 경우 MySQL을 사용합니다. GitHub 저장소에 SQLite 데이터베이스를 제외하고 저장하면, 지금까지 작성한 모든 게시물을 로컬에서만 사용할 수 있으므로 실제 운영하는 프로덕션 환경에서는 다시 새 데이터베이스를 추가해야합니다. 로컬 데이터베이스는 데이터가 삭제돼도 괜찮은 테스트 공간으로만 사용하세요. - Untracked files: - (use "git add ..." to include in what will be committed) +`git add`하기 전이나 변경된 것이 있는지 잘 모를 때마다 `git status`명령어를 사용하는 것은 좋은 방법이에요. 잘못된 파일이 추가되거나 커밋된 경우, 이를 복구할 수 있습니다. `git status`명령은 미추적/수정된/스테이지된 파일, 브랜치 상태와 그 외 많은 정보를 보여줍니다. 실행하면 아래와 비슷하게 나타날 거에요. - .gitignore - blog/ - manage.py - mysite/ - nothing added to commit but untracked files present (use "git add" to track) +{% filename %}command-line{% endfilename %} +``` +$ git status +On branch master +No commits yet -자 이제 우리가 만든 코드들을 저장소에 넣어봅시다. 콘솔창에 가서 다음 명령어를 실행하세요. : +Untracked files: + (use "git add ..." to include in what will be committed) - $ git add --all . - $ git commit -m "My Django Girls app, 첫번째 커밋" - [...] - 13 files changed, 200 insertions(+) - create mode 100644 .gitignore - [...] - create mode 100644 mysite/wsgi.py + .gitignore + blog/ + manage.py + mysite/ +nothing added to commit but untracked files present (use "git add" to track) +``` -## GitHub에 코드 넣기 +자 이제 우리가 만든 코드들을 저장소에 넣어봅시다. 콘솔 창에 가서 다음 명령어를 실행하세요. -[GitHub.com][2]에서 새로운 무료 계정을 만들세요. (워크샵 전에 미리 가입했다면 더 좋죠!) +{% filename %}command-line{% endfilename %} +``` +$ git add --all . +$ git commit -m "My Django Girls app, first commit" + [...] + 13 files changed, 200 insertions(+) + create mode 100644 .gitignore + [...] + create mode 100644 mysite/wsgi.py + ``` -그 다음 새 저장소(new repository)를 "my-first-blog"라는 이름으로 생성하세요. "초기화시 README 파일 만들기(initialize with a README)" 체크박스는 체크안 한 상태로 두세요. .gitignore 옵션도 비어있는 상태(위에서 직접 만들었죠?)로 두세요. 라이센스도 None으로 두세요. +## GitHub에 코드 배포하기 -![][3] +[GitHub.com](https://github.com/)에서 새 무료 계정을 만드세요. (워크샵 전에 미리 가입했다면 더 좋죠!) - [3]: images/new_github_repo.png +그 다음 새 저장소(new repository)를 "my-first-blog"라는 이름으로 생성하세요. "README 파일과 초기화 하기(initialize with a README)" 체크박스는 체크안 한 상태로 두세요. .gitignore 옵션도 비어있는 상태(위에서 만들었죠?)로 두세요. 라이센스도 비워두세요. -> **주의** 저장소 이름 `my-first-blog`는 중요합니다. -- 물론 원하는대로 이름을 바꿀 수 있지만, 매번마다 변경해서 사용해야하니 정말 불편할 거에요. 가급적이면 `my-first-blog`라는 저장소 이름을 그대로 사용하는 것이 편할 거에요. + -다음 화면에서 저장소 복제 URL(repo's clon URL) 을 볼 수 있을 거에요. "HTTPS" 버전을 선택해서 그 주소를 복사하세요. 그리고 터미널에다 붙여넣으세요. +> **Note** 저장소 이름 `my-first-blog`는 중요합니다. - 물론 내가 원하는 이름으로 바꿀 수 있지만, 매번 변경해서 사용해야 하니 정말 불편할 거에요. 되도록 `my-first-blog`라는 저장소 이름을 그대로 사용하는 것을 권장합니다. -![][4] +다음 화면에서 저장소 복제 URL(repo's clon URL)을 볼 수 있을 거예요. "HTTPS" 버전을 선택해서 그 주소를 복사하세요. 그리고 터미널에다 붙여넣으세요. - [4]: images/github_get_repo_url_screenshot.png + 이제 내 컴퓨터의 Git 저장소를 GitHub에 있는 저장소로 연결해야합니다. -콘솔에 다음과 같이 입력하세요 (``에 꺽쇠괄호(<>)를 떼고 내 Github 유저네임을 입력하세요. - - $ git remote add origin https://github.com//my-first-blog.git - $ git push -u origin master +콘솔에 다음과 같이 입력하세요. (``에 꺽쇠괄호(<>)를 떼고 내 GitHub 사용자이름을 입력하세요) +{% filename %}command-line{% endfilename %} +``` +$ git remote add origin https://github.com//my-first-blog.git +$ git push -u origin master +``` -아래와 같은 화면이 나오면 GitHub 유저네임과 암호를 입력하세요. +아래와 같은 화면이 나오면 GitHub 사용자이름과 암호를 입력하세요. : - Username for 'https://github.com': 여러분의GitHub유저네임 - Password for 'https://hjwp@github.com': 여러분의GitHub암호 - 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. +{% 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][5], [Django Girls Tutorial][6]뿐만 아니라 수많은 훌륭한 오픈소스 소프트웨어 프로젝트들이 GitHub에서 코드를 호스팅하고 있어요. 방금 여러분이 한 것처럼 말이죠. :) +이제 여러분의 코드가 gitHub에 저장됐어요! 가서 확인해보세요! [Django](https://github.com/django/django), [장고걸스 튜토리얼](https://github.com/DjangoGirls/tutorial)뿐만 아니라 수많은 훌륭한 오픈소스 소프트웨어 프로젝트들이 gitHub에서 호스팅하고 있어요. 방금 여러분이 한 것처럼 말이죠. :) - [5]: https://github.com/django/django - [6]: https://github.com/DjangoGirls/tutorial # PythonAnywhere에 블로그 설정하기 -> **Note** 이미 PythonAnywhere 계정이 있으면, 이 부분을 다시 할 필요가 없어요. +> **Note** 설치하기 장에서 PythonAnywhere 계정을 만들었다면 이 부분을 건너뛰세요. {% include "/deploy/signup_pythonanywhere.md" %} + ## GitHub에서 PythonAnywhere로 코드 가져오기 -PythonAnywhere에 가입하면 대시보드 또는 "콘솔(Consoles)" 페이지를 볼 수 있을 거에요. "배시(Bash)" 콘솔로 시작하는 옵션을 선택하세요. -- PythonAnywhere 버전의 콘솔로 PC에 있는 커맨드라인 같은 것이라 생각해도 됩니다. +PythonAnywhere에 가입하면 대시보드 또는 "콘솔(Consoles)" 페이지를 볼 수 있을 거예요. "배시(Bash)" 콘솔로 시작하는 옵션을 선택하세요. - PythonAnywhere 버전의 콘솔로 PC에 있는 커맨드라인 같은 것으로 생각해도 됩니다. > **Note** PythonAnywhere는 리눅스 기반으로 윈도우의 커맨드라인 창과 조금 다르게 보일 수 있어요. -GitHub에 있는 코드를 끌어와 저장소를 "복제"해 PythonAnywhere로 탑재해 볼게요. PythonAnywhere에 있는 콘솔에 다음과 같이 입력하세요. (``대신 내 GitHub 유저네임을 입력하는 것을 잊지 마세요. :) - - $ git clone https://github.com//my-first-blog.git +gitHub에 있는 코드를 끌어와 저장소를 "복제"해 PythonAnywhere로 탑재해 볼게요. PythonAnywhere 콘솔에 다음과 같이 입력하세요. (``대신 내 GitHub 사용자 이름을 입력하는 것을 잊지 마세요) : +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ git clone https://github.com//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 +PythonAnywhere에 코드 복사본을 올릴 거에요. `tree my-first-blog` 명령어를 입력해 확인해보세요. : +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ 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 +``` ### PythonAnywhere에서 가상환경(virtualenv) 생성하기 -PythonAnywhere에서도 내 컴퓨터에 있는 것과 같이 작동할 수 있게 가상 환경(virtualenv)을 생성할 수 있어요. 배시 콘솔(Bash console)에 다음과 같이 입력하세요. : +PythonAnywhere에서도 내 컴퓨터에 있는 것과 같이 작동할 수 있게 가상환경(virtualenv)을 생성할 수 있어요. 배시 콘솔(Bash console)에 다음과 같이 입력하세요. : - $ cd my-first-blog - - $ virtualenv --python=python3.4 myvenv - Running virtualenv with interpreter /usr/bin/python3.4 - [...] - Installing setuptools, pip...done. +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ cd my-first-blog - $ source myvenv/bin/activate +$ virtualenv --python=python3.6 myvenv +Running virtualenv with interpreter /usr/bin/python3.6 +[...] +Installing setuptools, pip...done. - (mvenv) $ pip install django whitenoise - Collecting django - [...] - Successfully installed django-1.8.2 whitenoise-2.0 +$ source myvenv/bin/activate +(myvenv) $ pip install django~=2.0 +Collecting django +[...] +Successfully installed django-2.0.6 +``` -> **Note** The `pip install`은 설치가 될 때까지 인내심이 조금 필요해요. 하지만 몇 분 안에 완료될 거니 조금만 기다려보세요. 만약 5분 이상 시간이 지났다면, 무엇인가 잘못된거니 코치에게 물어보세요. +> **Note** `pip install`은 설치가 될 때까지 인내심이 조금 필요해요. 하지만 몇 분 안에 완료될 거니 조금만 기다려보세요. 만약 5분 이상 시간이 지났다면, 무엇인가 잘못된 거니 코치에게 물어보세요. -### 정적 파일 모으기 - -"백색소음"을 들어본 적이 있나요? 이 것은 "정적 파일"로 불리는 것들을 제공하는 프로그램이에요. 정적 파일이란 HTML, CSS와 같이 정기적인 수정이 없거나 프로그래밍 코드를 실행하지 않는 파일을 말해요. 서버에서 정적 파일은 컴퓨터와 다르게 작동하기 때문에 정적 파일들을 제공하기 위해서 "백색소음"과 같은 프로그램이 필요해요. - -정적 파일은 튜토리얼 뒷부분에 나오는 CSS 부분에서 좀 더 자세히 알아볼게요. - -이제 서버에서 추가명령인 `collectstatic`을 실행하세요. 이 명령은 장고가 서버에 있는 모든 정적 파일들을 모으는 것을 지시해요. 지금 이 파일들이 관리자 사이트를 예쁘게 만들어주는 것이지요. - - (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 +지난번 내 컴퓨터에서 했던 것과 같이 서버에서도 데이터베이스를 초기화 할 거예요. `migrate`와 `createsuperuser`를 사용하세요. : +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +(mvenv) $ python manage.py migrate +Operations to perform: +[...] + Applying sessions.0001_initial... OK +(mvenv) $ python manage.py createsuperuser +``` ## web app으로 블로그 배포하기 -이제 우리의 코드는 PythonAnywhere에 있고 우리의 가상환경(virtualenv)도 준비가 되었으며, 정적 파일들도 모아져 있고, 데이터베이스도 초기화되었네요. 이제 우리는 web app으로 배포할 준비가 되었어요. +이제 코드는 PythonAnywhere에 있고 우리의 가상환경(virtualenv)도 준비가 되었으며, 정적 파일들도 모여 있고, 데이터베이스도 초기화되었네요. 이제 우리는 웹 앱으로 배포할 준비가 되었어요. 로고를 클릭해 PythonAnywhere 대시보드로 와서 **Web**을 클릭하고 **Add a new web app**를 선택하세요. -도메인 이름을 확정한 후, 대화창에 **수동설정(manual configuration)** ("Django"옵션이 *아니에요.*) 을 클릭하세요. 다음, **Python 3.4**을 선택하고 다음(Next)를 클릭하면 마법사가 종료됩니다. +도메인 이름을 확정한 후, 대화창에 **수동설정(manual configuration)** ("Django"옵션이 *아니에요*) 을 클릭하세요. 다음, **Python 3.6**을 선택하고 다음(Next)을 클릭하면 마법사가 종료됩니다. -> **Note** " Django"가 아니라 꼭 "수동설정(Manual configuration)"을 선택하세요. 기본 PythonAnywhere Django 설정을 위해서는 이렇게 하는 것이 더 좋아요. ;-) +> **Note** "Django"가 아니라 꼭 "수동설정(Manual configuration)"을 선택하세요. 기본 PythonAnywhere Django 설정을 위해서는 이렇게 하는 것이 더 좋아요. ;-) ### 가상환경(virtualenv) 설정하기 -이제 우리는 webapp을 위한 PythonAnywhere 설정 화면을 볼 수 있어요. 서버에 있는 앱에 변경사항이 생기면 필요한 화면이에요. +PythonAnywhere 설정 화면으로 이동할 거에요. 서버 앱에 변경사항이 있을 때 이 설정 화면으로 들어가야 합니다. -![][7] + - [7]: images/pythonanywhere_web_tab_virtualenv.png +"가상환경(Virtualenv)" 섹션에서 `가상환경 경로를 입력해주세요(Enter the path to a virtualenv)`라고 쓰여 있는 빨간색 글자를 클릭하고 `/home//my-first-blog/myvenv/` 라고 입력합니다. 이동 경로 저장을 하려면 파란색 박스에 체크 표시를 하고 클릭하세요. -"가상환경(Virtualenv)" 섹션에서 "가상환경 경로를 입력해주세요(Enter the path to a virtualenv)"라고 써져있는 빨간색 글자를 클릭하고 `/home//my-first-blog/myvenv/` 라고 입력합니다. 이동 경로 저장을 하려면 파란색 박스에 체크 표시를 하고 클릭하세요. +> **Note** PythonAnywhere 사용자 이름을 변경하세요. 실수하면 PythonAnywhere는 경고 메시지를 보여줄 거에요. -> **주의**: 가상환경 경로를 적당한 것으로 변경하세요. 실수를 하면 PythonAnywhere가 작은 경고 메시지를 보여줄 거에요. ### WSGI 파일 설정하기 -장고는 "WSGI 프로토콜"을 사용해 작동합니다. 이 프로토콜은 파이썬을 이용한 웹사이트를 서비스하기 위한 표준으로 PythonAnywhere에서도 지원합니다. WSGI 설정을 파일을 수정해 우리가 만든 장고 블로그를 PythonAnywhere에서 인식하게 해봅시다. +장고는 "WSGI 프로토콜(WSGI protocol"을 사용해 작동합니다. 이 프로토콜은 파이썬을 이용한 웹사이트를 서비스하기 위한 표준으로 PythonAnywhere에서도 지원합니다. WSGI 설정을 파일을 수정해 우리가 만든 장고 블로그를 PythonAnywhere에서 인식하게 해봅시다. -"WSGI 설정 파일(WSGI configuration file)" 링크(페이지의 상단 근처에 있는 "코드(Code)" 섹션에 있습니다. -- 아마 `/var/www/_pythonanywhere_com_wsgi.py`와 같이 나타나있을 것입니다.)를 클릭하면 에디터를 볼 수 있을 것입니다. +"WSGI 설정 파일(WSGI configuration file)" 링크(페이지 상단에 있는 "코드(Code)" 섹션 내 `/var/www/_pythonanywhere_com_wsgi.py`부분)를 클릭하면 에디터를 볼 수 있을 것입니다. 모든 내용을 삭제하고 아래 내용을 넣으세요. : +{% filename %}<your-username>_pythonanywhere_com_wsgi.py{% endfilename %} ```python - import os - import sys +import os +import sys - path = '/home//my-first-blog' # 여러분의 유저네임을 여기에 적어주세요. - if path not in sys.path: - sys.path.append(path) +path = '/home//my-first-blog' # PythonAnywhere 계정으로 바꾸세요. +if path not in sys.path: + sys.path.append(path) - os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' +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()) +from django.core.wsgi import get_wsgi_application +from django.contrib.staticfiles.handlers import StaticFilesHandler +application = StaticFilesHandler(get_wsgi_application()) ``` -> **Note** ``에 내 유저네임을 넣는 것을 잊지 마세요. +> **Note** ``을 PythonAnywhere 사용자 이름으로 바꾸는 것을 잊지 마세요. +> **Note** 4번째 라인은 파이썬이 어디서나 응용 프로그램을 찾는 방법을 알고 있는지 확인합니다. 경로명은 공백없이 정확하게 작성해야합니다. 그렇지 않으면 "ImportError"라는 오류 로그가 발생합니다. -이 파일은 PythonAnywhere에게 작동 할 우리의 web app 위치를 알려주고 장고 세팅 파일 이름을 알려주는 역할을 하죠. 또 "백색소음" 정적 파일 툴을 설정해줍니다. +이 파일은 PythonAnywhere에게 웹 애플리케이션의 위치와 Django 설정 파일명을 알려주는 역할을 합니다. + +`StaticFilesHandler`는 CSS를 다루기 위한 것입니다. `runserver` 명령으로 로컬 개발 중에 자동으로 처리됩니다. 튜토리얼의 뒷부분에서 CSS를 작성할 때 정적 파일에 대해 좀 더 알아볼 것입니다. **저장(Save)**을 누르고 **웹(Web)** 탭을 누릅니다. -다 되었어요! 큰 녹색 **다시 불러오기(Reload)** 버튼을 누르면 여러분은 여러분의 어플리케이션을 볼 수 있을 거에요. 여러분은 페이지 최 상단에 가는 링크를 발견할 수 있을 거에요. +다 되었어요! 큰 녹색 **다시 불러오기(Reload)** 버튼을 누르면 여러분은 여러분의 애플리케이션을 볼 수 있을 거예요. 여러분은 페이지 최상단에 가는 링크를 발견할 수 있을 거예요. ## 디버깅 팁 -본인의 사이트에 접속할 때 오류가 보이면, 제일 먼저 **error log(오류 로그)**에서 디버깅 정보를 찾아보세요. PythonAnywhere [Web tab][8]에서 이 링크를 찾을 수 있어요. 여기서 오류 메세지가 있는지 확인하세요. 대부분의 가장 최근의 오류 메세지는 맨 하단에 있어요. 일반적으로 많이 일어나는 문제들은 아래와 같습니다. - - [8]: https://www.pythonanywhere.com/web_app_setup/ +본인의 사이트에 접속할 때 오류가 보이면, 제일 먼저 **error log(오류 로그)**에서 디버깅 정보를 찾아보세요. PythonAnywhere [Web tab](https://www.pythonanywhere.com/web_app_setup/)에서 이 링크를 찾을 수 있어요. 여기서 오류 메시지가 있는지 확인하세요. 대부분의 가장 최근의 오류 메시지는 맨 하단에 있어요. 일반적으로 많이 일어나는 문제들은 아래와 같습니다.: * virtualenv를 생성하고 활성화할 때, Django를 설치할 때, Collestac을 돌릴 때, 데이터베이스를 설치할 때 같은 각 단계를 위한 콘솔 작업을 할 때 한 단계를 빼먹는 경우 @@ -297,16 +277,18 @@ PythonAnywhere에서도 내 컴퓨터에 있는 것과 같이 작동할 수 있 * WSGI 설정 파일에 실수가 있을 때 -- my-first-blog-folder 폴더의 경로를 올바르게 입력했었나요? -* Web app에서 그랬듯이 virtualenv에도 동일한 파이썬 버전을 선택했나요? 둘다 모두 3.4 버전이어야해요. +* Web app에서 그랬듯이 virtualenv에도 같은 파이썬 버전을 선택했나요? 둘 다 모두 3.4 버전이어야 해요 위키에서 [일반적인 디버깅 팁](https://www.pythonanywhere.com/wiki/DebuggingImportError)을 확인할 수 있어요. -* [PythonAnywhere 위키에서 일반적인 디버깅 팁][9]을 확인할 수 있어요. +* 만약 `Invalid HTTP_HOST header: . You may need to add to ALLOWED_HOSTS.` 라는 오류메세지가 나온다면 `/mysite/settings.py`의 마지막 줄에 `ALLOWED_HOSTS = ['localhost', '127.0.0.1', '[::1]', '.pythonanywhere.com']` 를 추가 한 뒤에 다시 **Web** 탭에서 `Reload -[git-scm.com](https://git-scm.com/)에서 맥용 설치파일을 다운받은 다음 실행해 나오는 지시 사항에 따라 설치하시면 됩니다. +Git은 [git-scm.com](https://git-scm.com/)에서 내려받을 수 있습니다. 설치는 쉽답니다. 딱 한 단계만 빼고 기본 설정대로 `다음 다음 다음`을 계속 눌러주면 쉽게 설치할 수 있어요. 다섯 번째 `PATH 환경 설정(Adjusting your PATH environment)`화면에서 주의하세요. `윈도우 커맨드라인에서 Git과 유닉스 도구를 사용(Use Git and optional Unix tools from the Windows Command Prompt)`을 선택하세요. 나머지는 모두 기본 설정대로 해도 됩니다. `윈도우 스타일로 체크아웃, 유닉스 스타일로 라인엔딩 커밋하기(Checkout Windows-style, commit Unix-style line endings)`를 체크하는 것도 좋습니다. -### 리눅스 + -설치가 안되었다면, 패키지 관리자로 git 설치를 해야해요. 다음과 같이 해보세요: + - sudo apt-get install git - # 또는 - sudo yum install git - # 또는 - sudo zypper install git +[git-scm.com](https://git-scm.com/)에서 다운받아 설치하세요. + +> **Note** OS X 10.6, 10.7 또는 10.8을 사용하는 경우 다음 링크에서 git 버전을 설치해야합니다. : [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) + + + + + + +{% filename %}command-line{% endfilename %} +```bash +$ sudo apt install git +``` + + + + + +{% filename %}command-line{% endfilename %} +```bash +$ sudo dnf install git +``` + + + + + +{% filename %}command-line{% endfilename %} +```bash +$ sudo zypper install git +``` + + diff --git a/ko/deploy/signup_pythonanywhere.md b/ko/deploy/signup_pythonanywhere.md index 65f4aaa75fc..df39388e762 100755 --- a/ko/deploy/signup_pythonanywhere.md +++ b/ko/deploy/signup_pythonanywhere.md @@ -1,5 +1,5 @@ -다음 PythonAnywhere에서 무료 계정인 "초보자(Beginner)"로 회원가입 하세요. +PythonAnywhere에서 무료 계정인 "초보자(Beginner)"로 회원가입 하세요. * [www.pythonanywhere.com](https://www.pythonanywhere.com/) -> **Note**: 여러분의 유저네임을 정할 때 블로그 주소의 일부가 여러분의 유저네임으로 되는 것을 염두하고 정하세요. 예를 들어 유저네임이 yourusername이라면 여러분의 블로그 URL은 `yourusername.pythonanywhere.com`이 된답니다. +> **Note** 사용자 이름을 정할 때 블로그 주소의 일부가 되는 것을 기억하세요. 예를 들어 사용자이름이 `yourusername`이면 URL은 `yourusername.pythonanywhere.com`이 된답니다. diff --git a/ko/django/README.md b/ko/django/README.md index 659ddfc9c98..4aba1128e7f 100755 --- a/ko/django/README.md +++ b/ko/django/README.md @@ -1,27 +1,25 @@ -# Django란 무엇인가요? +# 장고란 무엇인가요? -Django (*/ˈdʒæŋɡoʊ/ jang-goh/쟁고/장고*)는 파이썬으로 만들어진 무료 오픈소스 웹 어플리케이션 프레임워크(web application framework) 입니다. 쉽고 빠르게 웹사이트를 개발할 수 있도록 돕는 구성요소로 이루어진 웹 프레임워크이랍니다. +Django(*/dʒæŋɡoʊ/ jang-goh/쟁고/장고*)는 파이썬으로 만들어진 무료 오픈소스 웹 애플리케이션 프레임워크(web application framework)입니다. 쉽고 빠르게 웹사이트를 개발할 수 있도록 돕는 구성요소로 이루어진 웹 프레임워크랍니다. 웹사이트를 구축할 때, 비슷한 유형의 요소들이 항상 필요합니다. 회원가입, 로그인, 로그아웃과 같이 사용자 인증을 다루는 방법이나 웹사이트의 관리자 패널, 폼, 파일 업로드와 같은 것들 말이지요. -그런데 정말 다행이게도, 오래 전에 어떤 웹 개발자들이 새로운 웹 사이트를 개발할 때 서로 비슷한 문제들에 직면한다는 것을 깨달았습니다. 그래서 팀을 조직했구요. 바로 사용할 수 있는 구성요소들을 갖춘 여러 프레임워크를 만들었답니다. (장고도 그 중에 하나인거죠.) - -프레임워크는 다시 발명해야하는 문제로부터 해방감을 주고요. 새로운 웹사이트를 개발할 때 뒤따르는 간접비용의 부담을 덜어준답니다. +그런데 정말 다행이게도, 오래전에 어떤 웹 개발자들이 새로운 웹 사이트를 개발할 때 서로 비슷한 문제들에 직면한다는 것을 깨달았습니다. 그래서 팀을 조직했고요. 바로 사용할 수 있는 구성요소들을 갖춘 여러 프레임워크를 만들었답니다. 장고도 그중에 하나인 거죠. 다시 발명해야 하는 문제로부터 해방감을 주고요. 새로운 웹사이트를 개발할 때 뒤따르는 간접비용의 부담을 덜어준답니다. ## 왜 프레임워크가 필요한가요? -장고라는 것이 실제로 무엇을 위한 것인지 이해하기 위해서는 서버에 대해서 자세히 살펴볼 필요가 있어요. 먼저, 서버가 여러분에게 웹 페이지를 제공하길 원하는지 알아야 해요. +장고라는 것이 실제로 무엇을 위한 것인지 이해하기 위해서는 서버에 대해서 자세히 살펴볼 필요가 있어요. 먼저 서버가 여러분에게 웹 페이지를 제공하길 원하는지 알아야 해요. -편지(request, 요청) 이 도착했는지 확인해주는 메일박스(port, 포트) 가 있다고 상상해보세요. 이 것은 웹 서버가 해주는 일이에요. 웹 서버는 받은 편지를 읽고 웹 페이지와 함께 답장을 준답니다. 그런데 무언가를 주고 싶을 때는 그 안에 내용이 있어야하죠. 장고는 그 특정 컨텐츠를 만들 수 있는 역할을 합니다. +편지(request, 요청)가 도착했는지 확인해주는 메일박스(port, 포트)가 있다고 상상해보세요. 이 것은 웹 서버가 해주는 일이에요. 웹 서버는 받은 편지를 읽고 웹 페이지와 함께 답장을 준답니다. 그런데 무언가를 주고 싶을 때는 그 안에 내용이 있어야 하죠. 장고는 그 특정 콘텐츠를 만들 수 있는 역할을 합니다. ## 누군가가 서버에 웹 사이트를 요청하면 어떤 일이 벌어질까요? -웹 서버에 요청이 오면 장고로 전달됩니다. 그러면 장고는 실제로 어떤 요청이 들어왔는지 확인합니다. 첫 번째로 웹 페이지의 주소를 가져와 무엇을 할지 확인합니다. 이 것이 바로 장고의 **urlresolver**가 하는 역할이에요. (웹 사이트 주소는 URL - Uniform Resource Locator을 말합니다. 그래서 *urlresolver*가 이해하게 됩니다.) 패턴 목록을 가져와 URL과 맞는지 하나 씩 대조해보는 것은 그리 똑똑한 방법이 아니죠. 그러나 장고는 위에서 부터 아래로 그 패턴을 확인해봅니다. 만약 일치하는 게 있다고 하면, 장고는 그 요청을 관련된 함수(*view*) 에 넘겨줍니다.). +웹 서버에 요청이 오면 장고로 전달됩니다. 장고 **urlresolver**는 웹 페이지의 주소를 가져와 무엇을 할지 확인합니다.(*urlresolver*는 웹 사이트 주소인 URL(Uniform Resource Locator)를 통해 이해합니다). 이 urlreslover는 그리 똑똑하지 않습니다. 패턴 목록을 가져와 URL과 맞는지 처음부터 하나씩 대조해 식별합니다. 만약 일치하는 패턴이있으면, 장고는 해당 요청을 관련된 함수(*view*)에 넘겨줍니다 -우편배달부를 생각해보세요. 거리를 걸으며 집집마다 편지와 대조해서 주소와 번지를 확인합니다. 주소와 번지가 일치하면 우편배달부는 그 곳에 편지를 배달합니다. Urlresolver 가 바로 이와 같은 일을 합니다. +집배원을 생각해보세요. 집배원은 거리를 걸으며 집집이 편지와 대조해서 주소와 번지를 확인합니다. 주소와 번지가 일치하면 그곳에 편지를 배달합니다. *urlresolver*가 바로 집배원과 같은 역할을 합니다. -모든 재미난 일들은 *view* 함수에서 모두 처리됩니다: 특정 정보를 데이터베이스에서 찾을 수 있어요. 그런데 만약 사용자가 데이터를 바꿔달라고 수정을 요청한다면 어떻게 될까요? "제 직업에 대한 설명을 바꿔주세요."와 같은 편지를 받았다고 생각해봅시다. *view*함수는 수정할 수 있는 권한이 있는지 확인하고나서, 직업에 대한 설명을 수정해 다시 답장을 주겠지요. "완료했습니다!" 라고요. 그리고 나서 *view*는 답장을 생성하여, 장고는 그 답장을 그 사용자의 웹 브라우저에 보내주는 역할을 합니다. +모든 재미난 일들은 *view* 함수에서 처리됩니다: 특정 정보를 데이터베이스에서 찾을 수 있습니다. 그런데 만약 사용자가 데이터를 바꿔달라고 수정을 요청한다면 어떻게 될까요? "제 직업에 대한 설명을 바꿔주세요."와 같은 편지를 받았다고 생각해봅시다. *view*함수는 수정할 수 있는 권한이 있는지 확인하고 나서, 직업에 대한 설명을 수정해 다시 답장을 주겠지요. "완료했습니다!" 라고요. 그러고 나서 *view*는 답장을 생성하여, 장고는 그 답장을 그 사용자의 웹 브라우저에 보내주는 역할을 합니다. 물론 지금까지의 설명은 아주 간단히 설명한 것에 불과해요. 하지만 모든 기술적인 부분까지 자세히 알 필요가 없답니다. 이 정도 아는 것만으로도 충분하답니다. -좀 더 자세히 아는 것보다, 지금부터는 장고를 이용해 간단하게 조그만 것부터 만들어봐요. 그렇게 하면서 중요한 모든 것들을 하나씩 배워나가도록 해요. +좀 더 자세히 아는 것보다, 지금부터는 장고를 이용해 간단한 것부터 만들어봐요. 그렇게 하면서 중요한 모든 것들을 하나씩 배워나가도록 해요. diff --git a/ko/django_admin/README.md b/ko/django_admin/README.md index 57b771720ac..641223c2a3a 100755 --- a/ko/django_admin/README.md +++ b/ko/django_admin/README.md @@ -1,46 +1,52 @@ -# Django 관리자 +# 장고 관리자 -방금 막 모델링한 글들을 장고 관리자에서 추가하거나 수정, 삭제할 수 있어요. +관리자 화면을 한국어로 변경하길 원할 경우 'settings.py'중 `LANGUAGE_CODE = 'en-us'`를 `LANGUAGE_CODE = 'ko'`로 바꾸세요. -이제 `blog/admin.py` 파일을 열어서 내용을 다음과 같이 바꾸세요. : +방금 막 모델링 한 글들을 장고 관리자에서 추가하거나 수정, 삭제할 수 있어요. - from django.contrib import admin - from .models import Post +이제 `blog/admin.py` 파일을 열어서 내용을 다음과 같이 바꾸세요. - admin.site.register(Post) -코드에서 알 수 있듯이 앞 챕터에서 정의했던 Post 모델을 가져오고(import) 있어요. 관리자 페이지에서 만든 모델을 보려면 `admin.site.register(Post)`로 모델을 등록해야해요. +{% filename %}blog/admin.py{% endfilename %} +```python +from django.contrib import admin +from .models import Post -자, 이제 Post 모델을 볼까요? 웹 서버를 실행하려면 콘솔창에서 `python manage.py runserver`를 실행하는걸 잊지마세요. 브라우저를 열고 주소 창에 http://127.0.0.1:8000/admin/ 입력하면아래와 같은 로그인 페이지를 볼 수 있어요. +admin.site.register(Post) +``` -![로그인 페이지][1] +코드에서 알 수 있듯이 앞 장에서 정의했던 `Post`모델을 가져오고(import) 있어요. 관리자 페이지에서 만든 모델을 보려면 `admin.site.register(Post)`로 모델을 등록해야 해요. - [1]: images/login_page2.png +자, 이제 `Post`모델을 볼까요? 웹 서버를 실행하려면 콘솔 창에서 `python manage.py runserver`를 실행하는걸 잊지 마세요. 브라우저를 열고 주소창에 http://127.0.0.1:8000/admin/ 을 입력하면 아래와 같은 로그인 페이지를 볼 수 있어요. -로그인을 하기 위해서는, 모든 권한을 가지는 *슈퍼유저(superuser)*를 생성해야해요. 커맨드라인으로 돌아가서 `python manage.py createsuperuser`을 입력하고 엔터를 누르세요. 메시지가 나타나면 사용자 이름 (소문자, 공백 없이), 이메일 주소 및 암호를 입력합니다. password 를 입력할 때 화면에 글자가 보이지 않는다고 해도 걱정하지 마세요. 원래 password 는 화면에 보이지 않습니다. 작성한 후에 `enter`를 누르세요. 실행화면은 아래와 같을 거에요. (슈퍼유저로 사용 될 username 과 email 주소는 본인 것이어야해요) +![Login page](images/login_page2.png) - (myvenv) ~/djangogirls$ python manage.py createsuperuser - Username: admin - Email address: admin@admin.com - Password: - Password (again): - Superuser created successfully. +로그인하기 위해서는, 모든 권한을 가지는 *슈퍼 사용자(superuser)*를 생성해야 해요. 커맨드라인으로 돌아가서 `python manage.py createsuperuser`을 입력하고 엔터를 누르세요. +> 새 터미널 창을 열고 virtualenv를 활성화 시켜 웹 서버를 실행시키고 난 후 명령어를 입력해야합니다. 나의 첫 번째 Django 프로젝트! 장의 웹 서버 시작하기섹션에서 명령어를 입력하는 방법을 배웠어요, -브라우저로 돌아와서 장고 관리자 페이지에서 슈퍼유저로 로그인한 후 대시보드를 확인하세요. +메시지가 나타나면 사용자 이름 (소문자, 공백 없이), 이메일 주소 및 암호를 입력합니다. password를 입력할 때 화면에 글자가 보이지 않는다고 해도 걱정하지 마세요. 원래 password는 화면에 보이지 않습니다. 작성한 후에 `enter`를 누르세요. 실행화면은 아래와 같을 거예요. (슈퍼 사용자로 사용할 username 과 email 주소는 본인 계정을 사용하세요) : -![Django 관리자][2] +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py createsuperuser +Username: admin +Email address: admin@admin.com +Password: +Password (again): +Superuser created successfully. +``` - [2]: images/django_admin3.png +브라우저로 돌아와서 장고 관리자 페이지에서 슈퍼 사용자로 로그인한 후 대시보드를 확인하세요. -게시글로 가서 이것 저것 시도해보세요. 5 - 6개 블로그 포스트를 올려보세요. 안에 내용은 걱정하지 마세요. 튜토리얼에 있는 텍스트를 그냥 복사-붙여넣기 할 수 있으니까요. +![Django admin](images/django_admin3.png) -최소한 2, 3개의 글들에 게시 날짜가 있는지 확인하세요. (모두 볼 필요는 없어요) 이건 나중에 도움이 될 거에요. +게시글로 가서 이것저것 시도해보세요. 5~6개 블로그 포스트를 올려보세요. 안에 내용은 걱정하지 마세요. 튜토리얼에 있는 텍스트를 그냥 복사붙여넣기를 할 수 있으니까요. -![Django 관리자][3] +최소한 2, 3개의 글에 게시 날짜가 있는지 확인하세요. (모두 볼 필요는 없어요) 이건 나중에 도움이 될 거에요. - [3]: images/edit_post3.png +![Django admin](images/edit_post3.png) -장고 관리자에 대해서 좀 더 알고 싶다면 장고 공식 문서를 참고하세요. : https://docs.djangoproject.com/en/1.8/ref/contrib/admin/ +장고 관리자에 대해서 좀 더 알고 싶다면 장고 공식 문서를 읽어보세요 : https://docs.djangoproject.com/en/2.0/ref/contrib/admin/ -자, 여러분은 내 첫 번째 장고 모델을 만들었어요! 잠깐 쉴 시간이 필요해요. 열심히 했으니 재충전을 위해 커피 한 잔(또는 차 한 잔) 또는 뭔가 먹고 돌아오세요. +자, 우리는 내 첫 번째 장고 모델을 만들었어요! 잠깐 쉴 시간이 필요해요. 열심히 했으니 재충전을 위해 커피 한 잔(또는 차 한 잔) 또는 뭔가 먹고 돌아오세요. diff --git a/ko/django_admin/images/django_admin3.png b/ko/django_admin/images/django_admin3.png index a450b4f9630..ea01ab951bf 100644 Binary files a/ko/django_admin/images/django_admin3.png and b/ko/django_admin/images/django_admin3.png differ diff --git a/ko/django_admin/images/edit_post3.png b/ko/django_admin/images/edit_post3.png index c8572a73e7d..d577b111424 100644 Binary files a/ko/django_admin/images/edit_post3.png and b/ko/django_admin/images/edit_post3.png differ diff --git a/ko/django_admin/images/images/django_admin3.png b/ko/django_admin/images/images/django_admin3.png index a450b4f9630..ea01ab951bf 100644 Binary files a/ko/django_admin/images/images/django_admin3.png and b/ko/django_admin/images/images/django_admin3.png differ diff --git a/ko/django_admin/images/images/edit_post3.png b/ko/django_admin/images/images/edit_post3.png index c8572a73e7d..d577b111424 100644 Binary files a/ko/django_admin/images/images/edit_post3.png and b/ko/django_admin/images/images/edit_post3.png differ diff --git a/ko/django_admin/images/images/login_page2.png b/ko/django_admin/images/images/login_page2.png index 47153ef6960..6ae26e9959a 100644 Binary files a/ko/django_admin/images/images/login_page2.png and b/ko/django_admin/images/images/login_page2.png differ diff --git a/ko/django_admin/images/login_page2.png b/ko/django_admin/images/login_page2.png index 47153ef6960..6ae26e9959a 100644 Binary files a/ko/django_admin/images/login_page2.png and b/ko/django_admin/images/login_page2.png differ diff --git a/ko/django_forms/README.md b/ko/django_forms/README.md index 0397f7b6b3e..897afc37750 100755 --- a/ko/django_forms/README.md +++ b/ko/django_forms/README.md @@ -1,21 +1,23 @@ -# Django 폼 +# 장고 폼 -이제 한 가지만 더 하면 웹사이트가 완성되어요. 바로 블로그 글을 추가하거나 수정하는 멋진 기능을 추가하는 것이죠. 장고의 `관리자` 기능도 충분히 멋있기는 하지만, 좀 더 입맛에 맞게 바꾸고 예쁘게 꾸미기에는 좀 한계가 있습니다. `폼(양식, forms)`으로 강력한 인터페이스를 만들 수 있어요. - 우리가 상상할 수 있는 거의 모든 것을 할 수 있거든요! +한 가지만 더 하면 웹사이트가 완성됩니다. 바로 블로그 글을 추가하거나 수정하는 멋진 기능을 추가하는 것이죠. 장고의 `관리자` 기능도 충분히 멋있기는 하지만, 좀 더 입맛에 맞게 바꾸고 예쁘게 꾸미기에는 좀 한계가 있습니다. `폼(양식, forms)`으로 강력한 인터페이스를 만들 수 있어요. - 우리가 상상할 수 있는 거의 모든 것을 할 수 있거든요! -장고 폼이 정말 멋진 것은 아무런 준비 없이도 양식을 만들 수 있고, `ModelForm`을 생성해 자동으로 모델에 결과물을 저장할 수 있다는 거에요. +장고 폼이 정말 멋진 것은 아무런 준비 없이도 양식을 만들 수 있고, `ModelForm`을 생성해 자동으로 모델에 결과물을 저장할 수 있다는 거예요. -이 기능이 지금 우리가 할 내용이에요: 폼을 하나 만들어서 `Post` 모델에 적용해봅시다. +이 기능이 지금 우리가 할 내용이에요. 폼을 하나 만들어서 `Post` 모델에 적용해봅시다. -장고의 모든 중요한 부분과 마찬가지로, 폼도 폼만의 파일을 만들어요: `forms.py`. +장고의 모든 중요한 부분과 마찬가지로, 폼도 폼만의 `forms.py`.라는 파일을 만들어요. 우리는 이 이름으로 `blog` 디렉토리 안에 파일을 만들 거에요. - blog - └── forms.py - +``` +blog + └── forms.py +``` -좋아요, 이제 이 파일을 열고 아래 코드를 작성해봐요. : +좋아요. 이제 이 파일을 열고 아래 코드를 작성하세요. : +{% filename %}blog/forms.py{% endfilename %} ```python from django import forms @@ -28,13 +30,14 @@ class PostForm(forms.ModelForm): fields = ('title', 'text',) ``` -위 코드를 보면 첫 번째로 forms model을 import 해야하고 (`from django import forms`), 그 다음으로 `Post` model 도 import 해야합니다. (`from .models import Post`). -`PostForm` 은 이미 다들 예상 하셨듯이 우리가 만들 폼의 이름이에요. 그리고 장고에게 이 폼이 `ModelForm`이라는 것을 알려줘야해요. (그러면 장고가 뭔가 마술을 부릴 거에요) - `forms.ModelForm`은 ModelForm이라는 것을 알려주는 구문이에요. +위 코드를 보면 첫 번째로 forms model을 import 해야 하고 (`from django import forms`), 그다음으로 `Post` model도 import 해야 합니다. (`from .models import Post`). + +`PostForm` 은 이미 다들 예상 하셨듯이 우리가 만들 폼의 이름이에요. 그리고 장고에 이 폼이 `ModelForm`이라는 것을 알려줘야해요. (그러면 장고가 뭔가 마술을 부릴 거에요) - `forms.ModelForm`은 ModelForm이라는 것을 알려주는 구문이에요. -자, 이제 다음으로 `class Meta`가 나오는데요, 이 구문은 이 폼을 만들기 위해서 어떤 model이 쓰여야 하는지 장고에게 알려주는 구문입니다. (`model = Post`). +자, 이제 다음으로 `class Meta`가 나오는데요, 이 구문은 이 폼을 만들기 위해서 어떤 model이 쓰여야 하는지 장고에 알려주는 구문입니다. (`model = Post`). -마지막으로, 이 폼에 필드를 넣으면 완성되겠죠. 이번 폼에서는 `title` 과 `text` 만 보여지게 해 봅시다. - `author` 는 현재 로그인 하고 있는 사람이 될 것이고 (바로 당신이요!) 그리고 `created_date` 는 글이 등록되는 시간이 될 것입니다. (예를 들어, code 상에서요), 됐죠? +마지막으로, 이 폼에 필드를 넣으면 완성되겠죠. 이번 폼에서는 `title`과 `text`만 보여지게 해 봅시다. - `author`는 현재 로그인 하고 있는 사람이 될 것이고 (바로 당신이요!) 그리고 `created_date`는 글이 등록되는 시간이 될 것입니다. (예를 들어, 코드 상에서요), 됐죠? 마쳤습니다! 이제 *뷰* 에서 이 폼을 사용해 템플릿에서 보여주기만 하면 되네요. @@ -42,18 +45,20 @@ class PostForm(forms.ModelForm): ## 폼과 페이지 링크 -`blog/templates/blog/base.html` 파일을 열어봅시다. `page-header` 라는 `div` class 에 링크를 하나 추가할거에요. +`blog/templates/blog/base.html` 파일을 열어봅시다. `page-header` 라는 `div` class에 링크를 하나 추가할 거에요. +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html ``` -이 새로운 뷰를 `post_new` 라고 부를게요. +이 새로운 뷰는 `post_new`입니다. 부트스트랩 테마에 있는 `glyphicon glyphicon-plus` 클래스로 더하기 기호가 보이게 되는데요. -위 구문을 추가하고 나면, 이제 html 파일이 아래처럼 보일 거에요. +위 구문을 추가하고 나면, 이제 html 파일이 아래처럼 보일 거예요. +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} Django Girls blog @@ -79,64 +84,67 @@ class PostForm(forms.ModelForm): ``` -페이지를 저장하고 나서 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'), +path('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`뷰를 구현하지 않았기 때문이죠. 이제 하나 추가해봅시다. +브라우저에 사이트를 다시 불러오면 `AttributeError`가 보이게 됩니다. 왜냐하면, 아직 `post_new`뷰를 구현하지 않았기 때문이죠. 이제 하나 더 추가해봅시다. -## post_new view +## `post_new` view -`blog/views.py` 파일을 열어서 `from` 줄에 아래와 같은 코드를 추가합니다. +`blog/views.py`파일을 열어서 `from`줄에 아래와 같은 코드를 추가합니다. +{% filename %}blog/views.py{% endfilename %} ```python from .forms import PostForm ``` -그리고 *view* 에 추가합니다. +그리고 *view*에 추가합니다. +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) ``` -새 `Post` 폼을 추가하기 위해 `PostForm()` 함수를 호출하도록 하여 템플릿에 넘깁니다. 이따가 *view* 로 다시 돌아와서 이 작업을 하겠지만, 지금 당장은 폼을 위한 템플릿을 먼저 빨리 만들어보도록 할게요. +새 `Post` 폼을 추가하기 위해 `PostForm()` 함수를 호출하도록 하여 템플릿에 넘깁니다. 곧 *view* 로 다시 돌아와서 이 작업을 하겠지만, 지금 당장은 폼을 위한 템플릿을 먼저 빨리 만들어보도록 할게요. ## 템플릿 -이번에는 `blog/templates/blog` 디렉토리 안에 `post_edit.html` 파일을 생성해 폼이 작동할 수 있게 만들거에요. +이번에는 `blog/templates/blog` 디렉터리 안에 `post_edit.html` 파일을 생성해 폼이 작동할 수 있게 만들 거에요. -- 먼저 폼이 보여져야합니다. 그 예로, `{% raw %}{{ form.as_p }}{% endraw %}`로 간단히 만들 수 있어요.. -- 위 코드를 HTML태그로 폼을 감싸세요. `...` -- `Save` 버튼이 필요합니다. 이 것은 HTML 버튼으로 만들 수 있어요: `` +- 먼저 폼이 보여야 합니다. 그 예로, `{% raw %}{{ form.as_p }}{% endraw %}`로 간단히 만들 수 있어요…. +- 위 코드를 HTML 태그로 폼을 감싸세요. `
...
` +- `Save` 버튼이 필요합니다. 이것은 HTML 버튼으로 만들 수 있어요: `` - 마지막으로 `
`을 열어 `{% raw %}{% csrf_token %}{% endraw %}`를 추가하세요. 이 작업은 폼 보안을 위해 중요하답니다! 이 작업을 빼먹고 저장하면 장고는 이렇게 불평할 거에요. -![CSFR 서버가 허용하지 않는 웹 페이지(Forbidden page)][1] +![CSFR Forbidden page](images/csrf2.png) - [1]: images/csrf2.png - -네, 이제 `post_edit.html` 파일의 HTML을 확인해볼게요: +네, 이제 `post_edit.html` 파일의 HTML을 확인해볼게요. +{% filename %}blog/templates/blog/post_edit.html{% endfilename %} ```html {% extends 'blog/base.html' %} @@ -149,34 +157,34 @@ def post_new(request): {% endblock %} ``` -다 작성했으면 화면을 다시 불러옵시다! 여러분의 폼이 이렇게 나타났나요! - -![새 폼(New form)][2] +다 작성했으면 화면을 다시 불러옵시다. 폼이 이렇게 나타났나요! - [2]: images/new_form2.png +![New form](images/new_form2.png) -그런데, 잠깐만요! `title`과 `text` 필드에 아무거나 입력하고 저장해보세요. 어떻게 됐나요? +잠깐만요! `title`과 `text`필드에 아무거나 입력하고 저장해보세요. 어떻게 됐나요? 글이 사라졌어요! 한번 더 해봐도 내가 입력한 글들은 어디론가로 사라지고는 새 글이 추가되지 않아요. 뭐가 잘못된 걸까요? -정답은요: 여러분이 잘못한 게 없어요. 단지 *view* 에 조금 작업이 필요할 뿐이에요. +여러분이 잘못한 게 없답니다. 단지 *view* 추가 작업이 필요할 뿐이에요. ## 폼 저장하기 -`blog/views.py` 다시 여세요. 지금 여러분이 보고 있는 `post_new` 뷰는 아래와 같을 거에요: +`blog/views.py`를 다시 여세요. 지금 여러분이 보고 있는 `post_new`뷰는 아래와 같을 거에요. +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) ``` -폼을 제출할 때, 동일한 뷰를 불러오게 됩니다. 이 때 `request`에는 우리가 입력했던 데이터들을 가지고 있는데, `request.POST`가 이 데이터를 가지고 있습니다. (POST는 글 데이터를 "등록하는(posting)"하는 것을 의미합니다. 블로그 "글"을 의미하는 "post"과 관련이 없어요.) HTML에서 ``정의에 `method="POST"`라는 속성이 있던 것이 기억나나요? 이렇게 POST로 넘겨진 폼 필드의 값들은 이제 `request.POST`에 저장됩니다. `POST`로 된 값을 다른 걸로 바꾸면 안돼요.(`method` 속성의 값으로 넣을 수 있는 유효한 값 중에 `GET` 같은 것도 있지만 post와 어떤 차이점이 있는지 등에 대해서 다루기에는 너무 길어질 것 같아 생략할게요.) +폼을 제출할 때, 같은 뷰를 불러옵니다. 이때 `request`에는 우리가 입력했던 데이터들을 가지고 있는데, `request.POST`가 이 데이터를 가지고 있습니다. (`POST`는 글 데이터를 "등록하는(posting)"하는 것을 의미합니다. 블로그 "글"을 의미하는 "post"와 관련이 없어요) HTML에서 ``정의에 `method="POST"`라는 속성이 있던 것이 기억나나요? 이렇게 POST로 넘겨진 폼 필드의 값들은 이제 `request.POST`에 저장됩니다. `POST`로 된 값을 다른 거로 바꾸면 안 돼요. `method` 속성의 값으로 넣을 수 있는 유효한 값 중에 `GET`같은 것도 있지만, post와 어떤 차이점이 있는지 등에 대해서 다루기에는 너무 길어질 것 같아 생략할게요) 이제 *view* 에서 두 상황으로 나누어 처리해볼게요. -첫 번째: 처음 페이지에 접속했을 때입니다. 당연히 우리가 새 글을 쓸 수 있게 폼이 비어있어야겠죠. -두번째: 폼에 입력된 데이터를 *view* 페이지로 가지고 올 때입니다. 여기서 조건문을 추가시켜야해요. (`if`을 사용하세요.) +* 첫 번째: 처음 페이지에 접속했을 때입니다. 당연히 우리가 새 글을 쓸 수 있게 폼이 비어있어야겠죠. +* 두 번째: 폼에 입력된 데이터를 *view* 페이지로 가지고 올 때입니다. 여기서 조건문을 추가시켜야 해요. (`if`를 사용하세요) +{% filename %}blog/views.py{% endfilename %} ```python if request.method == "POST": [...] @@ -184,16 +192,18 @@ 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(): post = form.save(commit=False) @@ -202,24 +212,26 @@ if form.is_valid(): post.save() ``` -일반적으로, 이 작업을 두 단계로 나눌 수 있어요. : `form.save`로 폼을 저장하는 작업과 작성자를 추가하는 작업입니다.(`PostForm`에는 `작성자(author)` 필드가 없지만, 필드 값이 필요하죠!) `commit=False`란 넘겨진 데이터를 바로 `Post` 모델에 저장하지는 말라는 뜻입니다. - 왜냐하면 작성자를 추가한 다음 저장해야하니까요. 대부분의 경우에는 `commit=False`를 쓰지 않고 바로 `form.save()`를 사용해서 저장해요. 다면 여기서는 작성자 정보를 추가하고 저장해야하기 때문에 commit=False를 사용하는 거에요. `post.save()`는 변경사항(작성자 정보를 포함)을 유지할 것이고 새 블로그 글이 만들어질 거에요! +일반적으로 이 작업을 두 단계로 나눌 수 있어요. `form.save()`로 폼을 저장하는 작업과 작성자를 추가하는 작업입니다. (`PostForm`에는 `작성자(author)` 필드가 없지만, 필드 값이 필요하죠!) `commit=False`란 넘겨진 데이터를 바로 `Post` 모델에 저장하지는 말라는 뜻입니다. 왜냐하면, 작성자를 추가한 다음 저장해야 하니까요. 대부분의 경우에는 `commit=False`를 쓰지 않고 바로 `form.save()`를 사용해서 저장해요. 다만 여기서는 작성자 정보를 추가하고 저장해야 하므로 `commit=False`를 사용하는 거예요. `post.save()`는 변경사항(작성자 정보를 포함)을 유지할 것이고 새 블로그 글이 만들어질 거에요! -끝으로, 새 블로그 글을 작성한 다음에 `post_detail` 페이지로 이동할 수 있으면 좋겠죠? 이 작업을 하려면 한 가지를 더 불러와야해요. +끝으로, 새 블로그 글을 작성한 다음에 `post_detail`페이지로 이동할 수 있으면 좋겠죠? 이 작업을 하려면 한 가지를 더 불러와야 해요. ```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`은 우리가 이동해야 할 뷰의 이름이에요 *post_detail 뷰* 는 `pk`변수가 필요한 거 기억하고 있겠죠? `pk=post.pk`를 사용해서 뷰에게 값을 넘겨줄 거에요. 여기서 `post`는 새로 생성한 블로그 글이에요. -잘 했어요. 너무 설명이 길어졌네요. 이제 *view* 의 전체 코드를 확인할게요. +잘했어요. 너무 설명이 길어졌네요. 이제 *view* 전체 코드를 확인할게요. +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): if request.method == "POST": @@ -235,42 +247,42 @@ 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: Extensions)__ 에서 _publish button_ 에 대해 확인할 수 있어요. +블로그 글을 저장하기 전에 게시일을 설정하고 싶을 거에요. 추후 __장고걸스 튜토리얼__ 중 게시글 추가하기 버튼 만들기에서 확인할 수 있어요. -모두 잘 해냈어요! +모두 잘해냈어요! -## 폼 검증하기 +> 장고 관리자 인터페이스처럼 로그인된 상태라고 생각해봅시다. 하지만 사용자가 로그아웃되는 상황이 발생하기도 하죠. (브라우저가 닫히거나, DB가 재시작된다든가 등) 만약 로그인되지 않은 상태에서 새 글을 저장한다면, 사용자가 로그인되어있지 않아 누가 글을 작성하였는지 알 수 없어요. 그래서 글을 저장할 때 오류가 발생하고, 로그인시키도록 [http://127.0.0.1:8000/admin](http://127.0.0.1:8000/admin) 관리자 페이지가 나타나게 될 거에요. 이 문제는 금방 해결할 수 있어요. 튜토리얼을 마친 후 장고걸스 심화 튜토리얼 - 보안 추가하기 장에서 실습할 수 있어요. -이제 장고 폼이 얼마나 멋진지 알아볼 차례에요. 블로그 글은 `title`과 `test` 필드가 반드시 있어야해요. 우리가 만든 `Post` 모델에서는 이 필드 값들이 필요없다고 했지만(`published_date`는 제외하고) 장고는 모두 기본 값으로 설정되어 있다고 생각합니다. +![Logged in error](images/post_create_error.png) -`title`와 `text`가 없이 폼을 저장해보세요. 어떻게 될지 생각해보세요! -![폼 검증하기][3] +## 폼 검증하기 - [3]: images/form_validation2.png +장고 폼이 얼마나 멋진지 알아볼 차례에요. 블로그 글은 `title`과 `text`필드가 반드시 있어야 해요. 우리가 만든 `Post`모델에서는 이 필드 값들이 필요 없다고 했지만(`published_date`는 제외하고) 장고는 모두 기본값으로 설정되어 있다고 생각합니다. -장고는 모든 필드의 값이 올바른지 검증할 수 있답니다. 정말 멋지죠? +`title`과 `text`없이 폼을 저장해보세요. 어떻게 될지 생각해보세요! -> 앞서 우리가 사용한 장고 관리자 인터 페이스처럼 로그인 된 상태라고 생각해봅시다. 하지만 사용자가 로그아웃이 되는 상황이 발생하기도 하죠.(브라우저가 닫히거나, DB가 재시작된다던가 등) 만약 로그인 되지 않은 상태에서 새 글을 저장한다면, 사용자가 로그인되어있지 않아 누가 글을 작성한지 알 수 없어요. 때문에 글을 저장할 때 오류가 발생하고, 로그인시키도록 http://127.0.0.1:8000/admin 관리자 페이지가 나타나게 될 거에요. 이 문제는 금방 해결할 수 있어요. 다만 이건 이 튜터리얼 후에 해야할 __과제(Homework): 여러분의 사이트에 보안 추가하기__ 챕터로 남겨놓겠습니다. +![Form validation](images/form_validation2.png) -![로그인 오류 (Logged in error)][4] +장고는 모든 필드의 값이 올바른지 검증할 수 있답니다. 정말 멋지죠? - [4]: images/post_create_error.png ## 폼 수정하기 -지금까지 새 폼을 추가하는 방법에 대해 배웠어요. 하지만 이미 있던 글을 수정하려면 어떻게 해야할까요? 이 것도 앞서 했던 것과 매우 비슷해요. 빨리 해보도록 합시다!(만약 여러분이 뭔가 이해하지 못하는 부분이 있다면, 여러분의 코치에게 이전 챕터의 내용에 대해서 물어보고 차례대로 하나씩 해결해 나가야합니다) +지금까지 새 폼을 추가하는 방법에 대해 배웠어요. 하지만 이미 있던 글을 수정하려면 어떻게 해야 할까요? 이것도 앞서 했던 것과 매우 비슷해요. 빨리해보도록 합시다! (만약 이해하지 못하는 부분이 있다면, 여러분의 코치에게 이전 장의 내용에 관해서 물어보고 차례대로 하나씩 해결해 나가야 합니다) -`blog/templates/blog/post_detail.html` 파일을 열어 아래 내용을 추가하세요: +`blog/templates/blog/post_detail.html`파일을 열어 아래 내용을 추가하세요. -```python +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} +```html ``` -이제 템플릿이 아래처럼 보일 거에요. : +이제 템플릿이 아래와 같이 보일 거에요. +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html {% extends 'blog/base.html' %} @@ -288,16 +300,18 @@ def post_new(request): {% 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` 템플릿을 재사용할 거에요. 마지막으로 할 일은 *view* 를 만드는 것입니다. -`blog/views.py` 파일을 열어서 파일의 맨 밑에 코드를 추가해봅시다. : +`blog/views.py`파일을 열어서 파일 맨 밑에 코드를 추가해봅시다. +{% filename %}blog/views.py{% endfilename %} ```python def post_edit(request, pk): post = get_object_or_404(Post, pk=pk) @@ -314,66 +328,84 @@ def post_edit(request, pk): return render(request, 'blog/post_edit.html', {'form': form}) ``` -음.. 코드가 `post_new`과 거의 비슷해보이지 않나요? 하지만 완전히 같지는 않아요. -첫 번째: url로부터 추가로 `pk` 매개변수를 받아서 처리합니다. -두 번째: `get_object_or_404(Post, pk=pk)`를 호출하여 수정하고자 하는 글의 `Post` 모델 `인스턴스(instance)`로 가져옵니다. (원하는 글은 pk를 이용해 찾습니다.) 이렇게 가져온 데이터를 폼을 만들 때와(글을 수정할 때 폼에 이전에 입력했던 데이터가 있어야 하겠죠?) 폼을 저장할 때 사용하게 됩니다. : +음…. 코드가 `post_new`와 거의 비슷해 보이지 않나요? 하지만 완전히 같지는 않아요. +* 첫 번째: url로부터 추가로 `pk` 매개변수를 받아서 처리합니다. +* 두 번째: `get_object_or_404(Post, pk=pk)`를 호출하여 수정하고자 하는 글의 `Post` 모델 `인스턴스(instance)`로 가져옵니다. (`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` 페이지로 가보세요. 거기에 우측 상단에 수정 버튼이 있어야 합니다. - -![수정 버튼(Edit button)][5] +잘했어요. 이제 잘 작동하는지 확인해보세요! `post_detail`페이지로 가보세요. 우측 상단에 수정 버튼이 있어야 합니다. - [5]: images/edit_button2.png +![Edit button](images/edit_button2.png) 수정 버튼을 누르면 우리가 쓴 블로그 글이 들어가 있는 폼을 볼 수 있을 거에요. -![폼 수정하기][6] - - [6]: images/edit_form2.png +![Edit form](images/edit_form2.png) 자유롭게 제목과 텍스트를 수정하고 저장해보세요! 축하합니다! 여러분의 어플리케이션이 점점 더 완벽해지고 있어요! -장고 폼에 대해 자세한 정보가 필요하다면 공식 문서를 읽어보세요. : https://docs.djangoproject.com/en/1.8/topics/forms/ +장고 폼에 대해 자세한 정보가 필요하다면 공식 문서를 읽어보세요. : +https://docs.djangoproject.com/en/2.0/topics/forms/ ## 보안 -링크를 클릭해 새로운 포스트가 나오게 만드는 것은 멋져요! 지금은 웹사이트를 방문하는 누구든지 글을 쓸 수 있지만, 그렇게 하고 싶지 않을 수 있어요. 나에게만 보이고 다른 사람에게는 보이지 않는 버튼을 만들어 볼게요. +링크를 클릭해 새로운 포스트가 나오게 만드는 것은 멋진 일이에요! 지금은 웹사이트를 방문하는 누구든지 글을 쓸 수 있지만, 그렇게 하고 싶지 않을 수 있어요. 나에게만 보이고 다른 사람에게는 보이지 않는 버튼을 만들어 볼게요. -`blog/templates/blog/base.html` 파일에서, `page-header` `div`를 찾아 그 위에 아래와 같이 입력합니다. : +`blog/templates/blog/base.html` 파일에서, `page-header` `div`를 찾아 아래와 같이 작성된 앵커 태그(Anchor Tag)를 찾습니다. +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html ``` -여기에 `{% if %}` 태그를 추가해 관리자로 로그인한 유저들만 링크가 보일 수 있게 만들 거에요. 그게, 바로 여러분이죠! ``태그를 아래와 같이 변경하세요. : +여기에 `{% if %}`태그를 추가해 관리자로 로그인한 유저들만 링크가 보일 수 있게 만들 거에요. 그게, 바로 여러분이죠! ``태그를 아래와 같이 변경하세요. +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% if user.is_authenticated %} {% endif %} ``` -이 `{% if %}`는 브라우저에 페이지를 요청 하는 사용자가 로그인 하는 경우 링크가 발생됩니다. 이는 새 게시글을 완전히 보호해주는 것은 아니지만, 바람직한 방법입니다. 이 부분은 튜토리얼 심화에서 좀더 자세히 다룰거에요. +이 `{% if %}`는 브라우저에 페이지를 요청 하는 사용자가 로그인 하는 경우 링크가 발생됩니다. 이는 새 게시글을 완전히 보호해주는 것은 아니지만, 바람직한 방법입니다. 이 부분은 장고걸스 심화 튜토리얼에서 좀더 자세히 다룰거에요. -로그인 후, 페이지를 새로고침해야하는 경우, 아무것도 변화가 없으면 안되겠죠. 새로운 브라우저 시크릿 창에서 로그인해도 링크가 보이지 않아요! +세부 페이지에 있는 수정 아이콘이 기억나죠? 이번에도 동일하게 다른 사람들이 게시글을 수정하지 못하게 할 거에요. + +`blog/templates/blog/post_detail.html`파일을 열어 아래와 같이 작성된 라인을 찾아주세요. + +```html + +``` +이렇게 바꾸세요. + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} +```html +{% if user.is_authenticated %} + +{% endif %} +``` +로그인했기 때문에, 페이지 새로고침을 해도 아무것도 표시되지 않을 거에요. 새로운 브라우저 또는 시크릿 창을 실행해 보세요. 링크와 아이콘이 보이지 않게 되었어요! ## 한 가지만 더: 배포하세요! 모든 작업을 끝마쳤으면 PythonAnywhere로 배포해야죠! -* 제일 먼저, 여러분의 코드를 커밋하고 Github로 푸시합니다. +* 제일 먼저 코드를 커밋하고 GitHub로 푸시합니다. +{% filename %}command-line{% endfilename %} ``` $ git status $ git add --all . @@ -382,21 +414,15 @@ $ git commit -m "Added views to create/edit blog post inside the site." $ git push ``` -* 그 다음 [PythonAnywhere Bash console(배시 콘솔)][7]을 여세요. : - - [7]: https://www.pythonanywhere.com/consoles/ - - ``` - $ cd my-first-blog - $ source myvenv/bin/activate - (myvenv)$ git pull - [...] - (myvenv)$ python manage.py collectstatic - [...] - ``` - -* 마지막으로 [웹 탭(Web tab)][8]에서 **다시 불러오기(Reload)** 를 누르세요. +* 그 다음 [PythonAnywhere Bash console](https://www.pythonanywhere.com/consoles/)을 여세요. : + +{% filename %}command-line{% endfilename %} +``` +$ cd my-first-blog +$ git pull +[...] +``` - [8]: https://www.pythonanywhere.com/web_app_setup/ +* 마지막으로 [Web tab](https://www.pythonanywhere.com/web_app_setup/)에서 **Reload**를 누르세요. 이제 배포가 완료 되었어요. 잘 작동되는지 확인하세요! 축하합니다. :) diff --git a/ko/django_forms/images/csrf2.png b/ko/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/ko/django_forms/images/csrf2.png and b/ko/django_forms/images/csrf2.png differ diff --git a/ko/django_forms/images/drafts.png b/ko/django_forms/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/ko/django_forms/images/drafts.png and b/ko/django_forms/images/drafts.png differ diff --git a/ko/django_forms/images/edit_button2.png b/ko/django_forms/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/ko/django_forms/images/edit_button2.png and b/ko/django_forms/images/edit_button2.png differ diff --git a/ko/django_forms/images/edit_form2.png b/ko/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/ko/django_forms/images/edit_form2.png and b/ko/django_forms/images/edit_form2.png differ diff --git a/ko/django_forms/images/form_validation2.png b/ko/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/ko/django_forms/images/form_validation2.png and b/ko/django_forms/images/form_validation2.png differ diff --git a/ko/django_forms/images/images/csrf2.png b/ko/django_forms/images/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/ko/django_forms/images/images/csrf2.png and b/ko/django_forms/images/images/csrf2.png differ diff --git a/ko/django_forms/images/images/drafts.png b/ko/django_forms/images/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/ko/django_forms/images/images/drafts.png and b/ko/django_forms/images/images/drafts.png differ diff --git a/ko/django_forms/images/images/edit_button2.png b/ko/django_forms/images/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/ko/django_forms/images/images/edit_button2.png and b/ko/django_forms/images/images/edit_button2.png differ diff --git a/ko/django_forms/images/images/edit_form2.png b/ko/django_forms/images/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/ko/django_forms/images/images/edit_form2.png and b/ko/django_forms/images/images/edit_form2.png differ diff --git a/ko/django_forms/images/images/form_validation2.png b/ko/django_forms/images/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/ko/django_forms/images/images/form_validation2.png and b/ko/django_forms/images/images/form_validation2.png differ diff --git a/ko/django_forms/images/images/new_form2.png b/ko/django_forms/images/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/ko/django_forms/images/images/new_form2.png and b/ko/django_forms/images/images/new_form2.png differ diff --git a/ko/django_forms/images/images/post_create_error.png b/ko/django_forms/images/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/ko/django_forms/images/images/post_create_error.png and b/ko/django_forms/images/images/post_create_error.png differ diff --git a/ko/django_forms/images/new_form2.png b/ko/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/ko/django_forms/images/new_form2.png and b/ko/django_forms/images/new_form2.png differ diff --git a/ko/django_forms/images/post_create_error.png b/ko/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/ko/django_forms/images/post_create_error.png and b/ko/django_forms/images/post_create_error.png differ diff --git a/ko/django_installation/README.md b/ko/django_installation/README.md index 2630ddf2662..561cfbba876 100755 --- a/ko/django_installation/README.md +++ b/ko/django_installation/README.md @@ -1,5 +1,8 @@ -# Django 설치 +# 장고 설치하기 -> **Note** 만약 앞 장에서 이미 모든 설치를 마쳤다면 - 다음 장으로 바로 넘어가세요! +> **Note** 크롬북 사용자는 이번 장을 건너뛰고, [크롬북에서 설치하기](../chromebook_setup/README.md) 장으로 가세요. + + +> **Note** 이미 설치를 끝냈다면 다음 장으로 넘어세요! {% include "/django_installation/instructions.md" %} diff --git a/ko/django_installation/instructions.md b/ko/django_installation/instructions.md index af2c27f7d8b..935f6dd8d4d 100755 --- a/ko/django_installation/instructions.md +++ b/ko/django_installation/instructions.md @@ -1,114 +1,187 @@ -> 이 장의 일부는 Geek Girls Carrots (https://github.com/ggcarrots/django-carrots)의 튜토리얼을 기반으로 작성되었습니다. -> -> Creative Commons Attribution-ShareAlike 4.0 International License 에 따라 [django-marcador 튜토리얼](http://django-marcador.keimlink.de/)를 바탕으로 작성되었습니다. django-marcador 튜토리얼은 Markus Zapke-Gründemann et al에게 저작권이 있습니다. +> **Note** 이 장의 일부는 Geek Girls Carrots (http://django.carrots.pl/)의 튜토리얼을 기초로 작성되었습니다. -## 가상 환경 +> **Note** 이 장의 일부는 Creative Commons Attribution-ShareAlike 4.0 International License에 준수하여 [django-marcador 튜토리얼](https://github.com/ggcarrots/django-carrots)를 기초로 작성되었습니다. django-marcador 튜토리얼 저작권은 Markus Zapke-Gründemann et al이 소유하고 있습니다. -장고를 설치하기 전에, 개발 환경을 깔끔하게 관리하는데 큰 도움이 되는 도구를 설치해보겠습니다. 이 단계를 건너뛸 수 있지만, 한번 직접 해보는 것을 추천합니다. 제대로 설치해야 나중에 문제가 발생하지 않거든요! +## 가상환경(Virtual environment) -자, 이제부터 **가상 환경**(*virtualenv*라고 불러요)을 만들어보겠습니다. Virtualenv는 프로젝트 기초 전부를 Python/Django와 분리시켜줍니다. 다시 말해 웹사이트가 변경되어도 개발 중인 것에 영향을 미치지 않다는 것입니다. 어때요, 깔끔하죠? +장고 설치 전, 개발 환경을 깔끔하게 관리하는 데 큰 도움이 되는 도구를 설치해보겠습니다. 이 단계를 건너뛸 수 있지만, 한번 직접 해보는 것을 추천합니다. 제대로 설치해야 나중에 문제가 발생하지 않거든요! -`virtualenv`를 만드는 데 필요한 것은 생성할 곳을 정하는 것 뿐입니다. 예를 들면, home 디렉토리와 같은 곳이면 적당합니다. 윈도우 환경에서는 `C:\Users\Name` 일 거에요. (`Name` 이라는 것은 윈도우에 로그인할 때 사용한 아이디를 말합니다.) +자, 이제부터 **가상환경(Virtual environment)**(*줄여서 virtualenv*라고 해요)을 만들어보겠습니다. Virtualenv는 프로젝트 기초 전부를 Python/Django와 분리해줍니다. 다시 말해 웹사이트가 변경되어도 개발 중인 것에 영향을 미치지 않는다는 것입니다. 어때요, 깔끔하죠? + +`virtualenv`를 만드는 데 필요한 것은 생성할 곳을 정하는 것뿐입니다. 예를 들면, home 디렉토리와 같은 곳이면 적당합니다. 윈도우 환경에서는 `C:\Users\Name`일 거에요. (`Name`이라는 것은 윈도우에 로그인할 때 사용한 아이디를 말합니다) + +> **Note** 윈도우에서 디렉토리 파일명에 악센트 또는 특수 문자가 포함되지 않도록 주의하세요. 사용자 이름에 악센트 부호가있는 문자가 들어 있으면 다른 디렉토리를 사용하세요. (예: `C:\djangogirls`) 이 튜토리얼에서는 home 디렉토리 아래 `djangogirls`라는 디렉토리를 새로 만들어 사용하도록 할게요. - mkdir djangogirls - cd djangogirls +{% filename %}command-line{% endfilename %} +``` +$ mkdir djangogirls +$ cd djangogirls +``` +이제 `myenv` 라는 이름의 가상환경을 만들어 볼게요. 아래와 같은 형식의 명령을 실행하세요. -이제 `myenv` 라는 이름의 가상 환경을 만들어 볼게요. 아래와 같은 형식의 명령을 실행하세요. +{% filename %}command-line{% endfilename %} +``` +$ python3 -m venv myvenv +``` - python3 -m venv myvenv + +`virtualenv`를 생성하려면 콘솔 창을 열고, (이전 장에서 얘기했는데, 기억나죠?) 그리고 `C:\Python35\python -m venv myvenv`를 실행하세요. 아마도 화면에 이렇게 보일 거에요. : -### 윈도우 +{% filename %}command-line{% endfilename %} +``` +C:\Users\Name\djangogirls> C:\Python35\python -m venv myvenv +``` +여기서 `C:\Python35\python`은 이전에 파이썬을 설치 한 디렉토리이고 `myvenv`는`virtualenv`의 이름입니다. 다른 이름을 사용해도 되지만 알파벳 소문자를 사용하고 공백, 악센트 또는 특수 문자는 사용하지 마세요. 가상환경 이름을 짧게 쓰는 것도 좋은 생각입니다. 자주 입력해야 하니까요. -`virtualenv`를 생성하려면 console창을 열고, (앞쪽 챕터에서 얘기했는데, 기억나죠?) 그리고 `C:\Python34\python -m venv myvenv`를 실행해야해요. 아마도 화면에는 이런 것들이 보이겠죠? + - C:\Users\Name\djangogirls> C:\Python34\python -m venv myvenv + +리눅스와 맥에서 `virtualenv`를 생성하려면 간단하게 `python3 -m venv myvenv`를 입력하면 됩니다. 화면에 이렇게 나타날 거에요. : +{% filename %}command-line{% endfilename %} +``` +$ python3 -m venv myvenv +``` -여기서 `C:\Python34\python` 은 파이썬이 설치된 디렉토리이고, `myvenv` 는 설치할 `가상 환경`의 이름이예요. 이름은 마음대로 정할 수 있지만, 소문자여야하고 공백은 없어야하고 특수문자도 사용하면 안돼요. 이름은 짧게 만드는 것이 좋아요. 자주 입력해야하니까요. +여기서 `myvenv` 는 `가상환경`의 이름이에요. 이름은 마음대로 정할 수 있지만, 소문자여야 하고 공백은 없어야 해요. 이름은 짧게 만드는 게 좋아요. 자주 입력해야 하니까요. -### 리눅스와 맥OS +> **Note** Debian/Ubuntu에서 아래와 같은 오류가 발생할 수 있습니다. : -리눅스와 맥에서 `virtualenv`를 생성하려면 간단하게 `python3 -m venv myvenv`를 실행하면 됩니다. 화면에 이렇게 나타날 거에요: +{% 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. +``` - ~/djangogirls$ python3 -m venv myvenv +이 경우, 위의 지시에 따라 `python3-venv` 패키지를 설치하세요. : +{% filename %}command-line{% endfilename %} +``` +$ sudo apt install python3-venv +``` +> **Note** 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 +``` -여기서 `myvenv` 는 `가상 환경`의 이름이예요. 이름은 마음대로 정할 수 있지만, 소문자여야하고 공백은 없어야해요. 이름은 짧게 만드는게 좋아요. 자주 입력해야하니까요. +이 문제를 해결하려면 `virtualenv` 명령를 사용하세요. : -> **주의:** 우분투 14.04 에서는 이런 오류가 뜰 수 있어요. -> -> Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 -> -> -> 이 문제를 해결하려면 `virtualenv` 명령을 사용해야해요. -> -> ~/djangogirls$ sudo apt-get install python-virtualenv -> ~/djangogirls$ virtualenv --python=python3.4 myvenv -> +{% filename %}command-line{% endfilename %} +``` +$ sudo apt install python-virtualenv +$ virtualenv --python=python3.6 myvenv +``` -## 가상환경 사용하기 +> **Note** 아래와 같은 오류가 발생한다면 -앞의 명령을 사용하면 `myvenv`라는 디렉토리가 만들어져요. (이름을 다르게 했다면 그 이름의 디레토리가 만들어집니다.) 그리고 그 디렉토리에 우리가 사용할 가상 환경이 들어있어요. (디렉토리와 파일들이 있어요.) +{% filename %}command-line{% endfilename %} +``` +E: Unable to locate package python3-venv +``` -#### 윈도우 +이 명령어를 실행하세요. : -다음과 같이 가상환경을 실행하세요. +{% filename %}command-line{% endfilename %} +``` +sudo apt install python3.6-venv +``` + + + +## 가상환경 사용하기 - C:\Users\Name\djangogirls> myvenv\Scripts\activate +앞의 명령을 사용하면 `myvenv`라는 디렉토리가 만들어져요. (이름을 변경하면 그 이름의 디레토리가 만들어집니다) 그리고 그 디렉토리에 우리가 사용할 가상환경이 들어있어요. (디렉토리와 파일들이 있어요) + -#### 리눅스와 맥OS +아래 명령어를 입력해 가상환경을 실행하세요. : -다음과 같이 가상환경을 실행하세요. +{% filename %}command-line{% endfilename %} +``` +C:\Users\Name\djangogirls> myvenv\Scripts\activate +``` - ~/djangogirls$ source myvenv/bin/activate +> **Note** 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 +``` -실행할 때 `myvenv` 부분에 자신이 선택한 `가상 환경`의 이름을 적어야 해요! + -> **주의:** 간혹 `source` 명령이 동작하지 않을 수도 있어요. 그럴 때는 이렇게 하세요. -> -> ~/djangogirls$ . myvenv/bin/activate -> + -`가상환경`이 실행되었는지는 콘솔의 프롬프트를 보면 알 수 있어요. +아래 명령어를 입력해 가상환경을 실행하세요. : - (myvenv) C:\Users\Name\djangogirls> +{% filename %}command-line{% endfilename %} +``` +$ source myvenv/bin/activate +``` +`myvenv`를 여러분이 선택한 `virtualenv` 이름으로 바꾸는 것을 잊지 마세요! -또는 +> **Note** 가끔씩 `source`가 사용할 수 없을 수도 있습니다. 이 경우에는 아래와 같이 입력하세요. : - (myvenv) ~/djangogirls$ +{% filename %}command-line{% endfilename %} +``` +$ . myvenv/bin/activate +``` + -앞쪽에 `(myvenv)`가 보이지요? +콘솔의 프롬프트 앞에`(myvenv)`접두어가 붙어있다면 `virtualenv`가 시작되었음을 알 수 있어요. -가상 환경을 시작하고 나면 `python`이라고만 해도 지정한 버전의 파이썬이 실행되기 때문에 `python3` 대신 `python`이라고 입력해도 된답니다. +가상환경에서 작업 할 때,`python`은 자동으로 올바른 버전을 참조하므로 `python3` 대신`python`를 사용할 수 있습니다. -자, 이제 필요한 것들이 준비되었어요. 드디어 장고를 설치할 수 있어요! +의존성 설치를 모두 마쳤으니, 지금부터 장고를 설치할 수 있습니다! ## 장고 설치하기 -이제 `virtualenv` 가 시작되었으니, `pip`를 이용해 장고를 설치할 수 있어요. 콘솔에서 `pip install django==1.8`를 실행해보세요. (조심하세요. 이퀄기호가 두 개예요: `==`). +`virtualenv`를 실행하기 전, 장고를 설치합시다. + +그전에 장고를 설치하는 데 필요한 `pip`이 최신 버전인지 확인합니다. : + +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~$ python3 -m pip install --upgrade pip +``` +그런 다음 `pip install django~=2.0.0`(Django를 설치하려면 물결표 뒤에 등호 :`~=`)를 입력해 장고를 설치하세요. + +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~$ pip install django~=2.0.0 +Collecting Django~=2.0.6 + Downloading Django-2.0.6-py3-none-any.whl (7.1MB) +Installing collected packages: Django +Successfully installed Django-2.0.6 +``` + + + +> **Note** Windows에서 pip를 사용할 때 오류가 발생하면, 프로젝트 경로 이름(예: `C:\Users\User Name\djangogirls`)에 공백, 액센트 또는 특수 문자가 포함되어 있는지 확인하세요. 그렇다면 공백, 악센트 또는 특수 문자가 없는 다른 경로를 사용하세요. (제안: `C:\djangogirls`). 새 디렉토리에 새 virtualenv를 만든 다음, 이전 가상 디렉토리를 삭제하고 위의 명령을 다시 시도하세요. virtualenv는 절대 경로를 사용하기 때문에 virtualenv 폴더를 이동해도 작동하지 않습니다. - (myvenv) ~$ pip install django==1.8 - Downloading/unpacking django==1.8 - Installing collected packages: django - Successfully installed django - Cleaning up... + + -윈도우에서는 +> Windows에서 pip를 사용할 때 오류가 발생하면, 프로젝트 경로 이름(예: `C:\Users\User Name\djangogirls`)에 공백, 액센트 또는 특수 문자가 포함되어 있는지 확인하세요. 그렇다면 공백, 악센트 또는 특수 문자가 없는 다른 경로를 사용하세요. (제안: `C:\djangogirls`). 새 디렉토리에 새 virtualenv를 만든 다음, 이전 가상 디렉토리를 삭제하고 위의 명령을 다시 시도하세요. virtualenv는 절대 경로를 사용하기 때문에 virtualenv 폴더를 이동해도 작동하지 않습니다. -> 만약 윈도우에서 pip를 실행했는데 오류가 발생했다면 경로에 공백이나 특수문자가 없는지 (`C:\Users\User Name\djangogirls` 처럼요) 확인하세요. 만약 그렇다면 (`C:\djangogirls` 처럼) 공백이나 특수문자가 없는 곳으로 옮겨보세요. 옮긴 후에 다시 한 번 시도해보세요. + -리눅스에서는 + -> 우분투 12.04에서 오류가 발생했다면 `python -m pip install -U --force-reinstall pip` 명령으로 가상환경 내의 pip를 고쳐주세요. +> Ubuntu 12.04에서 pip를 사용하다 오류가 발생해 virtualenv에 pip를 재설치하려면 `python -m pip install -U --force-reinstall pip`를 실행하세요. + -잘했어요! 드디어 장고 어플리케이션을 만들 준비가 끝났습니다! +여기까지 입니다! 이제 정말 장고 애플리케이션을 생성해봅시다! diff --git a/ko/django_models/README.md b/ko/django_models/README.md index 38a569fbc66..3a0a5ec59d2 100755 --- a/ko/django_models/README.md +++ b/ko/django_models/README.md @@ -1,16 +1,16 @@ -# Django 모델 +# 장고 모델 -이번에는 블로그 내 모든 포스트를 저장하는 부분을 만들 거에요. 먼저 우리는 `객체(object)`에 대해서 조금 알고 있어야해요. +이번에는 블로그 내 모든 포스트를 저장하는 부분을 만들 거에요. 먼저 우리는 `객체(object)`에 대해서 조금 알고 있어야 해요. ## 객체(Object) -프로그래밍 개발 방법 중에는 `객체 지향 프로그래밍`이라 부르는 개념이 있어요. 이 개발 방법은 프로그램이 어떻게 작동해야하는지 모든 것을 하나하나 지시하는 것 대신, 모델을 만들어 그 모델이 어떤 역할을 가지고 어떻게 행동해야하는지 정의하여 서로 알아서 상호작용할 수 있도록 만드는 것입니다. +프로그래밍 개발 방법 중에는 `객체 지향 프로그래밍(object oriented programming)`이라 부르는 개념이 있어요. 이 개발 방법은 프로그램이 어떻게 작동해야 하는지 모든 것을 하나하나 지시하는 것 대신, 모델을 만들어 그 모델이 어떤 역할을 가지고 어떻게 행동해야 하는지 정의하여 서로 알아서 상호작용할 수 있도록 만드는 것입니다. -그렇다면 객체란 무엇일까요? 객체란 속성과 행동을 모아놓은 것이라고 할 수 있어요. 낯설게 느껴지지만 예를 들어보면 별 것 아님을 알게 될 거에요. +그렇다면 객체란 무엇일까요? 객체란 속성과 행동을 모아놓은 것이라 할 수 있어요. 객체란 개념이 낯설게 느껴지지만, 예를 들어보면 별것 아님을 알게 될 거에요. -예를 들어 `고양이(Cat)`라는 객체를 모델링한다고 해볼게요. 이 고양이는 여러 속성을 가지고 있어요: `색깔`, `나이`, `분위기`(착한, 나쁜, 졸려워하는), `주인`(주인이 `사람`일 수도 있지만, 길고양이면 주인이 없으니 속성이 빈 값이 될 수 있어요.) 등이 될 수 있겠지요. +예를 들어 `고양이(Cat)`라는 객체를 모델링 한다고 해볼게요. 이 고양이는 여러 속성을 가지고 있어요: `색깔`, `나이`, `분위기`(착한, 나쁜, 졸려 하는), `주인`(주인이 `사람`일 수도 있지만, 길고양이면 주인이 없으니 속성이 빈 값이 될 수 있어요) 등이 될 수 있겠지요. -또 `고양이는` 특정 행동을 할 수 있어요: `야옹야옹하기`, `긁기`, 또는 `먹기` 등이 있겠네요. (`맛`과, 고양이에게 `고양이먹이`는 행동하는 객체가 달라요). +또 `고양이는` 특정 행동을 할 수 있어요: `야옹야옹하기`, `긁기`, 또는 `먹기` 등이 있겠네요. (`맛`과, 고양이에게 `고양이 먹이`는 행동하는 객체가 달라요). 고양이 -------- @@ -26,47 +26,49 @@ -------- 맛 - -기본적으로 객체지향설계 개념은 현실에 존재하는 것을 속성과 행위로 나타내는 것입니다. 여기서 속성은 `객체 속성(properties)`, 행위는 `메서드(methods)`로 구현됩니다). +기본적으로 객체지향설계 개념은 현실에 존재하는 것을 속성과 행위로 나타내는 것입니다. 여기서 속성은 `객체 속성(properties)`, 행위는 `메서드(methods)`로 구현됩니다. 그렇다면 블로그 글을 모델로 만들 수 있을까요? 우리는 블로그를 만들고 싶잖아요, 그렇죠? 우리는 다음 질문에 답할 수 있어야 해요: 블로그 글이란 무엇일까? 어떤 속성들을 가져야 할까? -블로그는 제목과 내용이 필요하죠? 그리고 누가 썼는지도 알 수 있게 작성자(author) 도 추가하면 좋을 것 같아요. 마지막으로, 그 글이 작성된 날짜와 게시된 날짜도 알면 좋겠어요. +블로그는 제목과 내용이 필요하죠? 그리고 누가 썼는지도 알 수 있게 작성자(author)도 추가하면 좋을 것 같아요. 마지막으로, 그 글이 작성된 날짜와 게시된 날짜도 알면 좋겠어요. - Post + Post(게시글) -------- - title - text - author - created_date - published_date - + title(제목) + text(내용) + author(글쓴이) + created_date(작성일) + published_date(게시일) 블로그 글로 할 수 있는 것은 어떤 것들이 있을까요? 글을 출판하는 `메서드(method)`가 있으면 좋겠죠? -그래서 우리는 `publish` 메서드도 만들어야 합니다. +그래서 우리는 `publish`메서드도 만들어야 합니다. -이제 무엇을 만들어야하는지 이미 알았으니, 장고에서 모델을 만들어 봅시다! +이제 무엇을 만들어야 하는지 이미 알았으니, 장고에서 모델을 만들어 봅시다! ## 장고 모델 -객체(object) 가 어떻게 구성되어야 하는지 이전에 살펴봤으니, 이번에는 블로그 글을 위한 장고 모델을 만들어봅시다. +객체(object)가 어떻게 구성되어야 하는지 이전에 살펴봤으니, 이번에는 블로그 글을 위한 장고 모델을 만들어봅시다. -장고 안의 모델은 객체의 특별한 종류입니다. 이 모델을 저장하면 그 내용이 `데이터베이스`에 저장되는 것이 특별한 점이죠. 데이터베이스란 데이터의 집합입니다. 데이터들이 모아져 있는 곳이지요. 이곳에 유저에 대한 정보나 여러분의 블로그 글 등등이 저장되어 있습니다. 우리는 데이터를 저장하기 위해서 여러가지 데이터베이스를 입맛에 맞게 고를 수 있는데요, 여기서는 SQLite 데이터베이스를 사용하겠습니다. 'Sqlite 데이터베이스는 기본 장고 데이터베이스 어댑터입니다.' 라는 것까지만 알고 있어도 충분해요. 어댑터가 무엇인지를 알려면 내용이 너무 길어지니 일단 여기까지만 알고 계세요. +장고 안의 모델은 객체의 특별한 종류입니다. 이 모델을 저장하면 그 내용이 `데이터베이스`에 저장되는 것이 특별한 점이죠. 데이터베이스란 데이터의 집합입니다. 데이터들이 모여 있는 곳이지요. 이곳에 사용자에 대한 정보나 여러분의 블로그 글 등등이 저장되어 있습니다. 우리는 데이터를 저장하기 위해서 여러 가지 데이터베이스를 입맛에 맞게 고를 수 있는데요, 여기서는 SQLite 데이터베이스를 사용하겠습니다. 'sqlite 데이터베이스는 기본 장고 데이터베이스 어댑터입니다.'라는 것까지만 알고 있어도 충분해요. 어댑터가 무엇인지를 알려면 내용이 너무 길어지니 일단 여기까지만 알고 계세요. -쉽게 말해 데이터베이스안의 모델이란 엑셀 스프레드시트와 같다고 말할 수 있어요. 엑셀 스프레드시트를 보면 열(필드) 와 행(데이터) 로 구성되어 있죠? 모델도 마찬가지입니다. +쉽게 말해 데이터베이스 안의 모델이란 엑셀 스프레드시트와 같다고 말할 수 있어요. 엑셀 스프레드시트를 보면 열(필드)와 행(데이터)로 구성되어 있죠? 모델도 마찬가지입니다. -### 어플리케이션 제작하기 +### 어플리케이션 만들기 -잘 정돈된 상태에서 시작하기 위해, 프로젝트 내부에 별도의 어플리케이션을 만들어볼 거에요. 처음부터 모든 것이 잘 준비되어있다면 훌륭하죠. 어플리케이션을 만들기 위해 콘솔창(`djangogirls` 디렉토리에서 `manage.py` 파일)에서 아래 명령어를 실행하세요. +잘 정돈된 상태에서 시작하기 위해, 프로젝트 내부에 별도의 애플리케이션을 만들어볼 거에요. 처음부터 모든 것이 잘 준비되어있다면 훌륭하죠. 애플리케이션을 만들기 위해 콘솔 창(`djangogirls` 디렉토리에서 `manage.py` 파일)에서 아래 명령어를 실행하세요. - (myvenv) ~/djangogirls$ python manage.py startapp blog +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py startapp blog +``` -이제 `blog` 디렉토리가 생성되고 그 안에 여러 파일들도 같이 들어있는 것을 알 수 있어요. 현재 디렉토리와 파일들은 다음과 같을 거에요. : +이제 `blog`디렉터리가 생성되고 그 안에 여러 파일도 같이 들어있는 것을 알 수 있어요. 현재 디렉리와 파일들은 다음과 같을 거예요. : +``` djangogirls ├── mysite | __init__.py @@ -82,74 +84,79 @@ ├── models.py ├── tests.py └── views.py +``` +애플리케이션을 생성한 후 장고에 사용해야 한다고 알려줘야 합니다. 이 역할을 하는 파일이 `mysite/settings.py`입니다. 이 파일 안에서 `INSTALLED_APPS`를 열어, `)`바로 위에 `'blog'`를 추가하세요. 최종 결과물은 아래와 다음과 같을 거예요. : -어플리케이션을 생성한 후 장고에게 사용해야한다고 알려줘야 합니다. 이 역할을 하는 파일이 `mysite/settings.py`입니다. 이 파일 안에서 `INSTALLED_APPS`를 열어, `)`바로 위에 `'blog'`를 추가하세요. 최종 결과물은 아래와 다음과 같을 거에요. +{% filename %}mysite/settings.py{% endfilename %} ```python - INSTALLED_APPS = ( - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'blog', - ) +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog', +] ``` ### 블로그 글 모델 만들기 모든 `Model` 객체는 `blog/models.py` 파일에 선언하여 모델을 만듭니다. 이 파일에 우리의 블로그 글 모델도 정의할 거에요. -`blog/models.py` 파일을 열어서 안에 모든 내용을 삭제한 후 아래 코드를 추가하세요. : - -```python - from django.db import models - from django.utils import timezone +`blog/models.py` 파일을 열어서 안에 모든 내용을 삭제한 후 아래 코드를 추가하세요. +{% filename %}blog/models.py{% endfilename %} - class Post(models.Model): - author = models.ForeignKey('auth.User') - title = models.CharField(max_length=200) - text = models.TextField() - created_date = models.DateTimeField( - default=timezone.now) - published_date = models.DateTimeField( - blank=True, null=True) - - def publish(self): - self.published_date = timezone.now() - self.save() - - def __str__(self): - return self.title +```python +from django.conf import settings +from django.db import models +from django.utils import timezone + + +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) + + def publish(self): + self.published_date = timezone.now() + self.save() + + def __str__(self): + return self.title ``` -> `str`양 옆에 언더스코어(`_`) 를 두 개씩 넣었는지 다시 확인하세요. 이건 관습은 파이썬에서 자주 사용되는데, "던더(dunder; 더블-언더스코어의 준말)"라고도 불려요. +> `str`양 옆에 언더스코어(`_`) 를 두 개씩 넣었는지 다시 확인하세요. 파이썬에서 자주 사용되는데, "던더(dunder; 더블-언더스코어의 준말)"라고도 불려요. -으음... 코드가 좀 무서워졌죠? 걱정마세요. 각 줄마다 어떤 의미인지 설명해드릴거에요. +으음…. 코드가 좀 무서워졌죠? 걱정 마세요. 줄마다 어떤 의미인지 설명해드릴 거에요. -`from` 또는 `import`로 시작하는 부분은 다른 파일에 있는 것을 추가하라는 뜻입니다. 다시 말해, 매번 다른 파일에 있는 것을 복사&붙여넣기로 해야하는 작업을 `from이 대신 불러와주는 거죠 .

+`from` 또는 `import`로 시작하는 부분은 다른 파일에 있는 것을 추가하라는 뜻입니다. 다시 말해, 매번 다른 파일에 있는 것을 복사&붙여넣기로 해야 하는 작업을 `from`이 대신 불러와 주는 거죠. -

class Post(models.Model):`는 모델을 정의하는 코드입니다. (모델은 `객체(object)`라고 했죠?). +`class Post(models.Model):`는 모델을 정의하는 코드입니다. (모델은 `객체(object)`라고 했죠?) -* `class`는 특별한 키워드로, 객체를 정의한다는 것을 알려줍니다. -* `Post`는 모델의 이름입니다. (특수문자와 공백 제외한다면) 다른 이름을 붙일 수도 있습니다. 항상 클래스 이름의 첫 글자는 대문자로 써야 합니다. -* `models.Model`은 Post가 장고 모델임을 의미합니다. 이 코드 때문에 장고는 Post가 데이터베이스에 저장되어야 된다고 알게 됩니다. +- `class`는 특별한 키워드로, 객체를 정의한다는 것을 알려줍니다. +- `Post`는 모델의 이름입니다. (특수문자와 공백 제외한다면) 다른 이름을 붙일 수도 있습니다. 항상 클래스 이름의 첫 글자는 대문자로 써야 합니다. +- `models`은 Post가 장고 모델임을 의미합니다. 이 코드 때문에 장고는 Post가 데이터베이스에 저장되어야 한다고 알게 됩니다. -이제 속성을 정의하는 것에 대해서 이야기 해볼게요. : `title`, `text`, `created_date`, `published_date`, `author`에 대해서 말할 거에요. 속성을 정의하기 위해, 각 필드마다 어떤 종류의 데이터 타입을 가지는지를 정해야해요. 여기서 데이터 타입에는 텍스트, 숫자, 날짜, 유저 같은 다른 객체 참조 등이 있습니다. +이제 속성을 정의하는 것에 대해서 이야기해 볼게요. `title`, `text`, `created_date`, `published_date`, `author`에 대해서 말할 거에요. 속성을 정의하기 위해, 필드마다 어떤 종류의 데이터 타입을 가지는지를 정해야 해요. 여기서 데이터 타입에는 텍스트, 숫자, 날짜, 사용자 같은 다른 객체 참조 등이 있습니다. -* `models.CharField` - 글자 수가 제한된 텍스트를 정의할 때 사용합니다. 글 제목같이 대부분의 짧은 문자열 정보를 저장할 때 사용합니다. -* `models.TextField` - 글자 수에 제한이 없는 긴 텍스트를 위한 속성입니다. 블로그 콘텐츠를 담기 좋겠죠? -* `models.DateTimeField` - 이것은 날짜와 시간을 의미합니다. -* `models.ForeignKey` - 다른 모델이 대한 링크를 의미합니다. +- `models.CharField` - 글자 수가 제한된 텍스트를 정의할 때 사용합니다. 글 제목같이 짧은 문자열 정보를 저장할 때 사용합니다. +- `models.TextField` - 글자 수에 제한이 없는 긴 텍스트를 위한 속성입니다. 블로그 콘텐츠를 담기 좋겠죠? +- `models.DateTimeField` - 날짜와 시간을 의미합니다. +- `models.ForeignKey` - 다른 모델에 대한 링크를 의미합니다. -시간 관계 상 모든 코드들을 하나하나 다 설명하지는 않을 거에요. 대신 모델의 필드와 정의하는 방법에 궁금하다면 아래 장고 공식 문서를 꼭 읽어보길 바랍니다. (https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-types). +시간 관계상 모든 코드를 하나하나 다 설명하지는 않을 거예요. 대신 모델의 필드와 정의하는 방법에 궁금하다면 장고 공식 문서를 꼭 읽어보길 바랍니다. : https://docs.djangoproject.com/en/2.0/ref/models/fields/#field-types) -`def publish(self):`는 무슨 뜻일까요? 이 것이 바로 앞서 말했던 `publish`라는 메서드(method) 입니다. `def`는 이 것이 함수/메서드라는 뜻이고, `publish`는 메서드의 이름입니다. 원한다면 메서드 이름을 변경할 수도 있어요. 이름을 붙일 때는 공백 대신, 소문자와 언더스코어를 사용해야 합니다. 예를 들어, 평균 가격을 계산하는 메서드는 `calculate_average_price`라고 부를 수 있겠네요. +`def publish(self):`는 무슨 뜻일까요? 이것이 바로 앞서 말했던 `publish`라는 메서드(method) 입니다. `def`는 이것이 함수/메서드라는 뜻이고, `publish`는 메서드의 이름입니다. 원한다면 메서드 이름을 변경할 수도 있어요. 이름을 붙일 때는 공백 대신, 소문자와 언더스코어를 사용해야 합니다. 예를 들어, 평균 가격을 계산하는 메서드는 `calculate_average_price`라고 부를 수 있겠네요. -메서드는 자주 무언가를 되돌려주죠. (`return`) 그 예로 `__str__` 메서드를 봅시다. 이 시나리오대로라면, `__str__`를 호출하면 Post 모델의 제목 텍스트(**string**) 를 얻게 될 거에요. +메서드는 자주 무언가를 되돌려주죠. (`return`) 그 예로 `__str__` 메서드를 봅시다. 이 시나리오대로라면, `__str__`를 호출하면 Post 모델의 제목 텍스트(**string**)를 얻게 될 거에요. 아직 모델에 대해서 잘 모르는 부분이 있다면, 코치에게 자유롭게 물어보세요! 지금 배운 내용이 너무 복잡하게 느껴질 수 있어요. 객체와 함수를 배운 적이 없는 분들이 한꺼번에 배우게 된다면 특히 그렇겠죠. 그래도 해 볼 만한 마법이라고 생각했으면 좋겠어요! @@ -157,20 +164,25 @@ 이 장의 마지막 단계입니다. 이제 데이터베이스에 우리의 새 모델, Post 모델을 추가할 거에요. 먼저 우리는 장고 모델에 (우리가 방금 만든!) 몇 가지 변화가 생겼다는 걸 알게 해줘야 합니다. `python manage.py makemigrations blog` 를 입력해 보세요. 아마도 화면에 이렇게 보이겠죠? - (myvenv) ~/djangogirls$ python manage.py makemigrations blog - Migrations for 'blog': - 0001_initial.py: - - Create model Post +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py makemigrations blog +Migrations for 'blog': + blog/migrations/0001_initial.py: + - Create model Post +``` 장고는 데이터베이스에 지금 반영할 수 있도록 마이그레이션 파일(migration file)이라는 것을 준비해 두었답니다. 이제 `python manage.py migrate blog` 명령을 실행해, 실제 데이터베이스에 모델 추가를 반영하겠습니다. : - (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 +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py migrate blog +Operations to perform: + Apply all migrations: blog +Running migrations: + Applying blog.0001_initial... OK +``` -만세! 드디어 글 모델이 데이터베이스에 저장되었습니다. 너무 멋지 않나요? 빨리 다음 장으로 넘어가서 블로그 글을 확인하러 가요! +만세! 드디어 글 모델이 데이터베이스에 저장되었습니다. 너무 멋있지 않나요? 빨리 다음 장으로 넘어가서 블로그 글을 확인하러 가요! diff --git a/ko/django_orm/README.md b/ko/django_orm/README.md index b725c84a6ce..cb7d5d9c5ae 100755 --- a/ko/django_orm/README.md +++ b/ko/django_orm/README.md @@ -1,88 +1,110 @@ -# Django ORM과 QuerySets +# 장고 ORM과 쿼리셋(QuerySets) 이번 장에서는 장고를 데이터베이스에 연결, 데이터를 저장하는 방법에 대해서 알아볼 거에요. 함께 시작해봅시다! -## 쿼리셋(QuerySet)이란 무엇인가요? +## 쿼리셋이란 무엇인가요? -핵심만 말하자면, 쿼리셋은 전달받은 모델의 객체 목록입니다. 쿼리셋은 데이터베이스로부터 데이터를 읽고, 필터를 걸거나 정렬을 할 수 있습니다. +핵심만 말하자면, 쿼리셋(QuerySet)은 전달받은 모델의 객체 목록입니다. 쿼리셋은 데이터베이스로부터 데이터를 읽고, 필터를 걸거나 정렬을 할 수 있습니다. 가장 쉽게 배우는 방법은 예제로 배우는 것이죠. 함께 해볼까요? ## 장고 쉘(shell) -PythonAnywhere가 아닌 로컬 컨솔에서 아래 명령을 입력하세요. : - - (myvenv) ~/djangogirls$ python manage.py shell +PythonAnywhere가 아닌 로컬 콘솔에서 아래 명령을 입력하세요. +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py shell +``` 실행하면 아래처럼 나올 거에요. - (InteractiveConsole) - >>> - - -여러분은 이제 장고 인터랙티브 콘솔(interactive console) 로 들어왔습니다. 파이썬 프롬프트와 비슷하지만 장고만의 마법을 부릴 수 있는 곳이기도 하지요. :) 물론 파이썬의 모든 명령어를 여기서 사용할 수 있습니다. +{% filename %}command-line{% endfilename %} +```python +(InteractiveConsole) +>>> +``` -### 모두 보기 +여러분은 이제 장고 인터랙티브 콘솔(interactive console)로 들어왔습니다. 파이썬 프롬프트와 비슷하지만, 장고만의 마법을 부릴 수 있는 곳이기도 하지요. 물론 파이썬의 모든 명령어를 여기서 사용할 수 있습니다. -자, 이제 먼저 입력했던 모든 글들을 출력하겠습니다. 아래와 같이 입력하세요. +### 모든 객체 조회하기 - >>> 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 +``` 이런! 에러가 나타났어요. 글이 없다고 하네요. 이럴수가... 그런데 이렇게 나오는 것이 맞는 거랍니다. 이 글을 먼저 불러오는 것(import)을 잊었네요! - >>> from blog.models import Post - - -간단합니다. : 우리는 `Post`모델을 `blog.models`에서 불러왔어요. 이제 모든 글들을 출력해봅시다. +{% filename %}command-line{% endfilename %} +```python +>>> from blog.models import Post +``` - >>> Post.objects.all() - [, ] +간단합니다. 우리는 `Post`모델을 `blog.models`에서 불러왔어요. 이제 모든 글을 출력해봅시다. +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.all() +, ]> +``` -우리가 만들었던 그 글 목록이 나타났네요! 장고 관리자 인터페이스로 만들었던 것들이에요. 그런데 파이썬으로 새 글을 포스팅하려면, 어떻게 해야할까요? +게시된 글 목록이 나타났네요! 장고 관리자 인터페이스로 만들었던 것들이에요. 그런데 파이썬으로 새 글을 포스팅하려면, 어떻게 해야 할까요? ### 객체 생성하기 데이터베이스에 새 글 객체를 저장하는 방법에 대해 알아봅시다. - >>> 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`(사용자) 모델의 인스턴스를 가져와 전달해줘야 합니다. 어떻게 해야 할까요? +하지만 여기에 뭔가 빼먹은 것이 하나 있어요. `me`(나)를 빼먹었네요. 작성자로서 `User`(사용자) 모델의 인스턴스를 가져와 전달해줘야 합니다. 어떻게 해야 할까요? 먼저 User 모델을 불러옵니다. : - >>> from django.contrib.auth.models import User - +{% filename %}command-line{% endfilename %} +```python +>>> from django.contrib.auth.models import User +``` 데이터베이스에서 user는 어떤 일을 할까요? 함께 알아봅시다. : - >>> User.objects.all() - [] - +{% filename %}command-line{% endfilename %} +```python +>>> User.objects.all() +]> +``` 슈퍼유저로 등록했었던 그 사용자군요! 이제 이 사용자의 인스턴스(instance)를 가져와 봅시다. : - me = User.objects.get(username='ola') - - -보셨듯이, `유저이름(username)`이 'ola'인 `User` 인스턴스를 받아왔어요. 사용자 이름을 바꿨다면, 바뀐 이름을 넣어줘야겠죠. +{% filename %}command-line{% endfilename %} +```python +>>> me = User.objects.get(username='ola') +``` -드디어 우리 게시물을 만들었네요. : +보았듯이 `사용자이름(username)`이 'ola'인 `User` 인스턴스를 받아왔어요. 사용자 이름을 바꿨다면, 바뀐 이름을 넣어줘야겠죠. - >>> 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() +, , ]> +``` 보세요, 목록에 게시글 하나가 더 늘었네요! @@ -92,66 +114,87 @@ PythonAnywhere가 아닌 로컬 컨솔에서 아래 명령을 입력하세요. : ### 필터링하기 -쿼리셋의 중요한 기능은 데이터를 필터링하는 거에요. 예를 들어, 우리는 ola라는 User가 작성한 모든 글을 찾고 싶다고 해볼게요. 이런 경우 `Post.objects.all()`에서 `all` 대신, `filter`를 사용합니다. 쿼리셋 안에 있는 괄호 안에 우리가 원하는 조건(들)을 넣어줄 거에요. 지금 이 경우에는 `author`가 `me`인 조건을 넣어야겠죠. 이걸 장고로 표현한다면 `author=me`가 됩니다. 이제 이 조건이 반영된 코드를 볼까요. : - - >>> Post.objects.filter(author=me) - [, , , ] - - -또는 모든 글들 중, `제목(title)`에 'title'이라는 글자가 들어간 글들만을 뽑아내서 보고 싶다면요? - - >>> Post.objects.filter( title__contains='title' ) - [, ] +쿼리셋의 중요한 기능은 데이터를 필터링하는 거예요. 예를 들어, 우리는 ola라는 사용자가 작성한 모든 글을 찾고 싶다고 해볼게요. 이런 경우 `Post.objects.all()`에서 `all`대신, `filter`를 사용합니다. 쿼리셋 안에 있는 괄호 안에 원하는 조건을 넣어줄 거예요. 지금 이 경우에는 `작성자(author)`가 `나(me)`인 조건을 넣어야겠죠. 이걸 장고로 표현한다면 `author=me`가 됩니다. 이제 이 조건이 반영된 코드를 볼까요. +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.filter(author=me) +[, , , ] +``` -> **Note** `title`와 `contains` 사이에 있는 밑줄(`_`)이 2개입니다. 장고 ORM은 필드 이름("title")과 연산자과 필터("contains")를 밑줄 2개를 사용해 구분합니다. 밑줄 1개만 입력한다면, "FieldError: Cannot resolve keyword title_contains"라는 오류가 뜰 거에요. +모든 글들 중, `제목(title)`에 'title'이라는 글자가 들어간 글들만을 뽑아내서 보고 싶다면요? -우리는 출판된 글 목록을 볼 수 있어요. 이를 위해 `출판 날짜(published_date)`가 과거인 글들을 필터링하면 가져오면 되겠죠. +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.filter(title__contains='title') +[, ] +``` - >>> from django.utils import timezone - >>> Post.objects.filter(published_date__lte=timezone.now()) - [] +> **Note** `title`와 `contains` 사이에 있는 밑줄(`_`)이 2개(`__`)입니다. 장고 ORM은 필드 이름("title")과 연산자과 필터("contains")를 밑줄 2개를 사용해 구분합니다. 밑줄 1개만 입력한다면, `FieldError: Cannot resolve keyword title_contains`라는 오류가 뜰 거예요. -안타깝게도, 파이썬 콘솔에서 추가한 게시물은 아직 보이지 않네요. 하지만 바꿀 수 있어요! 먼저 게시하려는 게시물의 인스턴스를 얻어야 해요. : +게시글 목록을 볼 수 있어요. `게시일(published_date)`로 과거에 작성한 글을 필터링하면 목록을 불러올 수 있어요. - >>> post = Post.objects.get(title="Sample title") +{% filename %}command-line{% endfilename %} +```python +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) +[] +``` +안타깝게도, 파이썬 콘솔에서 추가한 게시물은 아직 보이지 않네요. 하지만 바꿀 수 있어요! 먼저 게시하려는 게시물의 인스턴스를 얻어야 해요. +{% filename %}command-line{% endfilename %} +```python +>>> post = Post.objects.get(title="Sample title") +``` -그리고 `publish` 메서드를 사용해서 출판합시다! - - >>> post.publish() +그리고 `publish`메서드를 사용해서 게시합시다! +{% filename %}command-line{% endfilename %} +```python +>>> post.publish() +``` 이제 (위쪽 화살표 버튼 3번을 누르고 `enter`를 눌러) 다시 게시된 글의 목록을 가져와 봅시다. - >>> Post.objects.filter(published_date__lte=timezone.now()) - [] - +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +[] +``` ### 정렬하기 -퀘리셋은 객체 목록을 정렬도 할 수 있어요. 이제 `created_date` 필드를 정렬해봅시다. : - - >>> Post.objects.order_by('created_date') - [, , , ] - - -`-`을 맨 앞에 붙여주면 내림차순으로 정렬도 가능해요. : +퀘리셋은 객체 목록을 정렬할 수 있어요. 이제 `created_date`필드를 정렬해봅시다. - >>> Post.objects.order_by('-created_date') - [, , , ] +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.order_by('created_date') +[, , , ] +``` +`-`을 맨 앞에 붙여주면 내림차순 정렬도 가능해요. -### 쿼리셋(QuerySets) 연결하기 +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.order_by('-created_date') +[, , , ] +``` -쿼리셋들을 함께 **연결(chaining)**할 수도 있어요. +### 쿼리셋 연결하기 - >>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +쿼리셋들을 함께 **연결(chaining)**할 수 있어요. +{% filename %}command-line{% endfilename %} +``` +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +``` 이 방법은 정말 강력해 복잡한 쿼리도 작성할 수 있게 해준답니다. 좋아요! 이제 다음 내용으로 넘어갈 때로군요! 다음 명령을 입력해, 쉘을 종료하세요. : - >>> exit() - $ +{% filename %}command-line{% endfilename %} +```python +>>> exit() +$ +``` diff --git a/ko/django_start_project/README.md b/ko/django_start_project/README.md index 6df66517785..c09d642c460 100755 --- a/ko/django_start_project/README.md +++ b/ko/django_start_project/README.md @@ -1,49 +1,65 @@ -# 나의 첫 번째 Django 프로젝트! +# 나의 첫 번째 장고 프로젝트! -> 이번 장은 Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) 의 튜토리얼을 바탕으로 작성되었습니다. -> -> 이번 장의 일부는 Creative Commons Attribution-ShareAlike 4.0 International License를 준수하여 [django-marcador tutorial][1]을 바탕으로 작성되었습니다. Django-marcador 튜토리얼은 Markus Zapke-Gründemann et al에게 저작권이 있습니다. +> **Note** 이 장의 일부는 Geek Girls Carrots (http://django.carrots.pl/)의 튜토리얼을 기초로 작성되었습니다. + + +> **Note** 이 장의 일부는 Creative Commons Attribution-ShareAlike 4.0 International License에 준수하여 [django-marcador 튜토리얼](https://github.com/ggcarrots/django-carrots)를 기초로 작성되었습니다. django-marcador 튜토리얼 저작권은 Markus Zapke-Gründemann et al이 소유하고 있습니다. + +아주 간단한 블로그 사이트를 만들어 볼 거예요! - [1]: http://django-marcador.keimlink.de/ +첫 단계는 장고 프로젝트를 시작하는 거예요. 다시 말해 장고의 기본 골격을 만들어주는 스크립트를 실행할 거예요. 이 디렉토리와 파일 묶음은 나중에 사용할 것입니다. -이제 우리는 아주 간단한 블로그를 만들어 볼 거에요! +장고에서는 디렉토리와 파일명이 매우 중요하답니다. 파일명을 마음대로 변경해서도 안되고 다른 곳으로 옮겨도 안됩니다. 장고는 중요한 것들을 찾을 수 있게 특정한 구조를 유지해야 합니다. -첫 단계는 장고 프로젝트를 시작하는 거에요. 다시 말해 장고의 기본 골격을 만들어주는 스크립트를 실행할 거에요. 이 디렉토리와 파일 묶음은 나중에 사용할 것입니다. +> 모든 작업은 가상환경(virtualenv) 안에서 해야 하는 것을 꼭 기억하세요. 현재 콘솔 창에서 접두어로 `(myvenv)`가 안 보인다면 먼저 virtualenv를 활성화해야 합니다. **Django 설치하기** 장에서 **virtualenv 작동법**에 대해 배웠어요. 윈도우에서는 `myvenv\Scripts\activate`를 타이핑하고, 맥 OS과 리눅스에서는 `source myvenv/bin/activate`을 입력하세요. -장고에서는 디렉토리나 파일 이름이 매우 중요하답니다. 우리가 생성할 그 파일들의 이름을 마음대로 변경해서는 안됩니다. 또한 그 파일들을 다른 곳으로 옮겨도 안됩니다. 장고는 중요한 것들을 찾을 수 있게 특정한 구조를 유지해야합니다. + -> 모든 것은 가상환경(virtualenv) 안에서 해야한다는 것을 기억하세요. 현재 콘솔창에서 접두어로 `(myvenv)`가 안보인다면 먼저 virtualenv를 활성화해야 합니다. **Django 설치하기**장의 **virtualenv 작동법**에서 이미 다루었던 내용입니다. 윈도우에서는 `myvenv\Scripts\activate`를 타이핑하고 Mac OS / Linux에서는 `source myvenv/bin/activate`을 입력하세요. +맥 OS과 리눅스 콘솔에서는 다음과 같이 명령을 실행해야해요. **명령어 끝에 `.`(점, 마침표)을 입력하는 것을 잊지마세요.** : -맥과 리눅스 콘솔에서는 다음과 같이 명령을 실행해야해요. **명령어 끝에 `.`(점, 마침표) 을 입력하는 것을 잊지마세요.** : +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ django-admin startproject mysite . +``` - (myvenv) ~/djangogirls$ django-admin startproject mysite . +> 점 `.`은 현재 디렉토리에 장고를 설치하라고 스크립트에 알려주기 때문에 중요해요. (축약된 표시입니다) +> +> **Note** 위 명령을 입력할 때 `django-admin`로 시작하는 부분만 입력하세요. 여기에 보이는 `(myvenv) ~/djangogirls$`부분은 커맨드 라인에 입력을 가져오게 하는 메세지(프롬트프 prompt)입니다. + + -윈도우에서도 **명령 끝에 `.`(점) 을 입력하는 것을 잊지마세요.**: + - (myvenv) C:\Users\Name\djangogirls> django-admin startproject mysite . +윈도우에서도 **명령 끝에 `.`(점)을 입력하는 것을 잊지마세요** : +{% filename %}command-line{% endfilename %} +``` +(myvenv) C:\Users\Name\djangogirls> django-admin.py startproject mysite . +``` > 점 `.`은 현재 디렉토리에 장고를 설치하라고 스크립트에 알려주기 때문에 중요해요. (축약된 표시입니다) > -> **Note** 위 명령을 입력할 때 `django-admin` 또는 `django-admin.py`로 시작하는 부분만 입력하세요. 여기에 보이는 `(myvenv) ~/djangogirls$`과 `(myvenv) C:\Users\Name\djangogirls>` 부분은 커맨드라인에 입력을 가져오게 하는 메세지(프롬트프 prompt) 입니다. +> **Note** 위 명령을 입력할 때 `django-admin.py`로 시작하는 부분만 입력하세요. 여기에 보이는 `(myvenv) C:\Users\Name\djangogirls>`부분은 커맨드 라인에 입력을 가져오게 하는 메세지(프롬프트 prompt)입니다. + + -`django-admin.py`은 스크립트로 디렉토리와 파일들을 생성합니다. 스크립트 실행 후에는 아래와 같이 새로 만들어진 디렉토리 구조를 볼 수 있을 거에요. +`django-admin.py`은 스크립트로 디렉토리와 파일들을 생성합니다. 스크립트 실행 후에는 아래와 같이 새로 만들어진 디렉토리 구조를 볼 수 있을 거예요. djangogirls ├───manage.py - └───mysite - settings.py +    └───mysite +            settings.py urls.py wsgi.py __init__.py -`manage.py` 파일 또한 스크립트인데, 사이트 관리를 도와주는 역할을 합니다. 이 스크립트로 다른 설치 작업 없이, 컴퓨터에서 웹 서버를 시작할 수 있습니다. +`manage.py`는 스크립트인데, 사이트 관리를 도와주는 역할을 합니다. 이 스크립트로 다른 설치 작업 없이, 컴퓨터에서 웹 서버를 시작할 수 있습니다. `settings.py`는 웹사이트 설정이 있는 파일입니다. -앞에 우편 배달부는 어느 곳으로 편지를 배달해야하는지 판단해야한다고 말했던 것을 기억하고 있나요? `urls.py` 파일은 `urlresolver`가 사용하는 패턴 목록을 포함하고 있습니다. +앞에 우편배달부는 어느 곳으로 편지를 배달해야 하는지 판단해야 한다고 말했던 것을 기억하고 있나요? `urls.py`파일은 `urlresolver`가 사용하는 패턴 목록을 포함하고 있습니다. 지금 그 파일들을 수정하지 않을 거니 무시하세요. 실수로 파일을 지우지 않게 조심하세요! @@ -51,87 +67,122 @@ `mysite/settings.py`을 조금 고쳐 볼게요. 설치한 코드 에디터를 열어 파일을 열어주세요. -웹사이트에 정확한 현재 시간을 넣으면 좋겠죠. [위키피디아 타임존 리스트][2]에 가서 해당 시간대(타임존) 를 복사하세요. (예: `Europe/Berlin`) +웹사이트에 정확한 현재 시간을 넣으면 좋겠죠. [위키피디아 타임존 리스트][2]에 가서 해당 시간대(타임존)를 복사하세요. (예: `Asia/Seoul`) [2]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones Settings.py에서 `TIME_ZONE`있는 줄을 찾으세요. 그리고 이를 해당 시간대로 변경하세요. +{% filename %}mysite/settings.py{% endfilename %} ```python TIME_ZONE = 'Asia/Seoul' ``` -"Asia/Seoul"를 수정하세요. +다음으로 정적파일 경로를 추가할 거에요. (정적 파일은 튜토리얼 후반부에서 CSS와 함께 다룰 거에요) 파일의 *끝(end)*으로 내려가서, `STATIC_URL`항목 바로 아래에 `STATIC_ROOT`을 추가하세요. -다음으로 정적파일 경로를 추가할 거에요. (정적 파일은 튜토리얼 후반부에서 CSS와 함께 다룰 거에요) 파일의 *끝(end)*으로 내려가서, `STATIC_URL`항목 바로 아래에 `STATIC_ROOT`을 추가하세요. : +{% filename %}mysite/settings.py{% endfilename %} +```python +STATIC_URL = '/static/' +STATIC_ROOT = BASE_DIR / 'static' +``` +`DEBUG`가`True`이고 `ALLOWED_HOSTS`가 비어 있으면, 호스트는 `['localhost', '127.0.0.1', '[::1]']`에 대해서 유효합니다. 애플리케이션을 배포할 때 PythonAnywhere의 호스트 이름과 일치하지 않으므로 다음 설정을 아래와 같이 변경해줘야 합니다. : + +{% filename %}mysite/settings.py{% endfilename %} ```python - STATIC_URL = '/static/' - STATIC_ROOT = os.path.join(BASE_DIR, 'static') +ALLOWED_HOSTS = ['127.0.0.1', '.pythonanywhere.com'] ``` +> **Note** 크롬북 사용자는, `settings.py` 맨 마지막 줄에 아래 코드를 추가하세요. : +> `MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'` + ## 데이터베이스 설정하기 -사이트 내 데이터를 저장하기 위한 많은 다양한 데이터베이스 소프트웨어들이 있습니다. 그 중에서 우리는 `sqlite3`을 사용할 거에요. +사이트 내 데이터를 저장하기 위한 많은 다양한 데이터베이스 소프트웨어들이 있습니다. 그중에서 우리는 `sqlite3`을 사용할 거예요. -사실 이미 `mysite/settings.py` 파일 안에 설치가 되어있어요. : +이미 `mysite/settings.py`파일 안에 설치가 되어있어요. +{% filename %}mysite/settings.py{% endfilename %} ```python - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - } +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', } +} ``` -블로그에 데이터베이스를 생성하기 위해서 콘솔창에서 아래 코드를 실행하세요: `python manage.py migrate` (이 명령을 실행하기 위해서는 `djangogirls`디렉토리 안에 있는 `manage.py` 필요합니다) 잘 작동되면, 아래와 같은 내용이 나옵니다. : +블로그에 데이터베이스를 생성하기 위해서 콘솔 창에서 아래 코드를 실행하세요. : `python manage.py migrate` (이 명령을 실행하기 위해서는 `djangogirls`디렉터리 안에 있는 `manage.py`가 필요합니다) - (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... - Running migrations: - Rendering model states... DONE - Applying contenttypes.0001_initial... OK - Applying auth.0001_initial... OK - Applying admin.0001_initial... 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 sessions.0001_initial... OK +잘 작동되면, 아래와 같은 내용이 나옵니다. +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py migrate +Operations to perform: + Apply all migrations: auth, admin, 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 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 sessions.0001_initial... OK +``` -잘했네요! 이제 웹 서버를 시작해 웹사이트가 잘 작동하는지 확인해봐요! +잘했어요! 이제 웹 서버를 시작해 웹 사이트가 잘 작동하는지 확인해봐요! -프로젝트 디렉토리(the `djangogirls` directory)에 `manage.py` 파일이 있어야 합니다. 콘솔에서는 `python manage.py runserver` 명령을 실행해, 웹서버를 바로 시작할 수 있습니다. : +프로젝트 디렉토리(`djangogirls`)에 `manage.py`파일이 있어야 합니다. 콘솔에서는 `python manage.py runserver`명령을 실행해, 웹 서버를 바로 시작할 수 있습니다. - (myvenv) ~/djangogirls$ python manage.py runserver +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py runserver +``` +크롬북 사용자는 아래 명령어를 입력하세요. : -윈도우에서 `UnicodeDecodeError`를 썼는데 오류가 난다면 아래 명령을 대신 써보세요. : +{% filename %}Cloud 9{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py runserver 0.0.0.0:8000 +``` - (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 +윈도우에서 `UnicodeDecodeError`오류가 난다면 아래 명령을 대신 써보세요. : +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py runserver 0:8000 +``` -웹 사이트가 모두 잘 작동하는지 확인해봐요. 사용하는 브라우져(파이어폭스, 크롬, 사파리, 인터넷 익스플로어 등 여러분의 원하는대로)를 열어서 주소를 입력하세요. : +웹 사이트가 모두 잘 작동하는지 확인해봐요. 사용하는 브라우저(파이어폭스, 크롬, 사파리, 인터넷 익스플로어 등 여러분의 원하는 대로)를 열어서 주소를 입력하세요. - http://127.0.0.1:8000/ +{% filename %}browser{% endfilename %} +``` +http://127.0.0.1:8000/ +``` +크롬북 사용자는 항상 테스트 서버를 통해 접근해야 합니다.: -웹서버는 멈출 때까지 명령 프롬프를 실행할 거에요. 실행 중 다른 명령을 입력하려면 새로운 창을 열어 virtualenv를 활성화시키면 됩니다. 웹 서버를 중지하려면, 실행되고 있는 창으로 돌아가 CTRL+C를 동시에 누르세요. (윈도우라면, Ctrl+Break를 눌러야 할지도 모릅니다) +{% filename %}browser{% endfilename %} +``` +https://django-girls-.c9users.io +``` 축하해요! 여러분은 방금 웹 서버를 활용한 첫 웹사이트를 만들었어요! 정말 멋지죠? -![잘 작동합니다!][3] +![It worked!](images/it_worked2.png) + +웹 서버가 실행되는 동안 추가 명령을 입력 할 수있는 새로운 명령어 프롬프트가 표시되지 않습니다. 새 텍스트를 터미널에서 입력할 수 있지만 명령은 실행되지 않습니다. 웹 서버가 들어오는 요청을 수신 대기하기 위해 지속적으로 실행하고 있기 때문이에요. + +> 인터넷은 어떻게 작동될까요 장에서 웹 서버에 대해 배웠었어요. + - [3]: images/it_worked2.png +웹 서버가 실행되는 동안 추가 명령을 입력하려면 새 터미널 창을 열고 virtualenv를 활성화하세요. 웹 서버를 중지하려면 실행중인 창으로 다시 전환하고 CTRL + C - Control+C 키를 함께 누르세요. (윈도우에서는 Ctrl + Break를 눌러야 할 수도 있습니다) -다음 단계로 넘어갈 준비가 되셨나요? 이제는 새로운 내용을 만들어 볼 시간이에요! +다음 단계로 넘어갈 준비가 되셨나요? 새로운 것을 또 배워볼까요! diff --git a/ko/django_start_project/images/images/it_worked2.png b/ko/django_start_project/images/images/it_worked2.png index 4412ecfc49e..4efa554e567 100644 Binary files a/ko/django_start_project/images/images/it_worked2.png and b/ko/django_start_project/images/images/it_worked2.png differ diff --git a/ko/django_start_project/images/it_worked2.png b/ko/django_start_project/images/it_worked2.png index 4412ecfc49e..4efa554e567 100644 Binary files a/ko/django_start_project/images/it_worked2.png and b/ko/django_start_project/images/it_worked2.png differ diff --git a/ko/django_templates/README.md b/ko/django_templates/README.md index 5caa17c549c..1d81a9ecdef 100755 --- a/ko/django_templates/README.md +++ b/ko/django_templates/README.md @@ -1,36 +1,38 @@ -# Django 템플릿 +# 장고 템플릿 -이제 데이터를 보여줄 차례에요! 이를 위해 장고는 내장된 __template tags__ 라는 유용한 기능을 제공합니다. +이제 데이터를 보여줄 차례에요! 이를 위해 장고는 내장된 __템플릿 태그(template tags)__ 라는 유용한 기능을 제공합니다. ## 템플릿 태그는 무엇인가요? HTML에 여러분은 파이썬 코드를 바로 넣을 수 없어요. 브라우져는 파이썬 코드를 이해할 수 없기 때문이에요요 브라우저는 HTML만을 알고 있어요. 알다시피 HTML는 정적이지만, 파이썬은 동적입니다. -__장고 템플릿 태그(Django template tags)__ 는 파이썬을 HTML로 바꿔주어, 빠르고 쉽게 동적인 웹사이트를 만들 수 있게 도와주어요. 야호! +**템플릿 태그**는 파이썬을 HTML로 바꿔주어, 빠르고 쉽게 동적인 웹 사이트를 만들 수 있게 도와주어요. 야호! ## post 목록 템플릿 보여주기 -이전 장에서 글 목록이 들어있는 `posts` 변수를 템플릿에 넘겨주었습니다. 이제 넘겨진 posts 변수를 받아서 HTML에 나타나도록 해볼 차례예요. +이전 장에서 글 목록이 들어있는 `posts` 변수를 템플릿에 넘겨주었습니다. 이제 넘겨진 `posts`변수를 받아 HTML에 나타나도록 해볼 차례예요. -장고 템플릿 안에 있는 값을 출력하려면, 변수 이름안에 중괄호를 넣어 표시해야합니다. 이렇게요. : +장고 템플릿 안에 있는 값을 출력하려면, 변수 이름 안에 중괄호를 넣어 표시해야 합니다. +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {{ posts }} ``` -`blog/templates/blog/post_list.html` 템플릿에서 하세요. 두 번째 `

`에서 세 번째 `
`까지를 `{{ posts }}`로 바꾸세요. 파일을 저장하고 페이지를 새로 고침하면 이렇게 보입니다. : +`blog/templates/blog/post_list.html` 템플릿에서 하세요. 두 번째 `
`에서 세 번째 `
`까지를 `{{ posts }}`로 바꾸세요. 파일을 저장하고 페이지를 새로고침하면 이렇게 보입니다. -![그림 13.1][1] +![Figure 13.1](images/step1.png) - [1]: images/step1.png - -우리는 아래와 같이 만들었어요. : - - [, ] +아래와 같이 만들었어요 : +{% filename %}blog/templates/blog/post_list.html{% endfilename %} +```html +[, ] +``` -이는 장고가 {{ posts}} 를 객체들의 목록으로 이해하고 처리했다는 것을 의미해요. **파이썬 들어가기** 에서 어떻게 목록을 보여줬는지 기억하고 있나요? 맞아요, for loop을 이용해서죠! 장고 템플릿에서는 이렇게 해야합니다. : +이는 장고가 `{{ posts }}`를 객체 목록으로 이해하고 처리했다는 것을 의미해요. **Python 시작하기** 장에서 어떻게 목록을 보여줬는지 기억하고 있나요? 맞아요, `for loop`을 이용해서죠! 장고 템플릿에서는 이렇게 써야 합니다. +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %} {{ post }} @@ -39,12 +41,12 @@ __장고 템플릿 태그(Django template tags)__ 는 파이썬을 HTML로 바 여러분의 템플릿 파일에 적용해 보세요. -![그림 13.2][2] +![Figure 13.2](images/step2.png) - [2]: images/step2.png +잘 작동하네요! 그런데 디자인이 별로죠. 앞에서 **HTML 시작하기** 했던 정적 블로그 게시글들이 보이게 만들면 참 좋을텐데 말이에요. HTML과 템플릿 태그를 섞어 사용하면 멋있게 만들 수 있어요. `body`를 아래와 같이 수정하세요. -잘 작동하네요! 그런데 디자인이 별로죠. 앞에서 __HTML 소개__ 챕터에서 했던 정적 글들처럼 보이면 참 좋을텐데 말이에요. HTML과 템플릿 태그를 섞어 사용하면 멋있게 만들 수 있어요. 우리의 `body`는 다음과 같을 거에요. : +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html

Django Girls Blog

@@ -59,20 +61,19 @@ __장고 템플릿 태그(Django template tags)__ 는 파이썬을 HTML로 바 {% endfor %} ``` -{% raw %} `{% for %}` 와 `{% endfor %}`사이에 넣은 모든 것은 목록의 모든 객체를 반복하게 됩니다. 페이지를 새로고침 해보세요: {% endraw %} - -![그림 13.3][3] +{% raw %}`{% for %}` 와 `{% endfor %}`사이에 넣은 모든 것은 목록의 모든 객체를 반복하게 됩니다. 페이지를 새로고침 해보세요.{% endraw %} - [3]: images/step3.png +![Figure 13.3](images/step3.png) -`{{ post.title }}`라던가 `{{ post.text }}` 같이 이전과 다른 표기법을 사용한 것을 눈치 채셨나요? `Post` 모델에서 정의한 각 필드의 데이터에 접근하기 위해 이 표기법을 사용합니다. 또한 `|linebreaksbr` 같이 파이프 문자(|)도 사용해요. 이건 블로그 글 텍스트에서 행이 바뀌면 문단으로 변환하도록 하라는 의미입니다. 행바뀜을 문단으로 변환하는 필터를 적용한다는 표현을 쓰기도 합니다. +`{{ post.title }}`라던가 `{{ post.text }}`같이 이전과 다른 표기법을 사용한 것을 눈치채셨나요? `Post`모델에서 정의한 각 필드의 데이터에 접근하기 위해 이 표기법을 사용합니다. 또한 `|linebreaksbr`같이 파이프 문자(|)도 사용해요. 이건 블로그 글 텍스트에서 행이 바뀌면 문단으로 변환하도록 하라는 의미입니다. 행바뀜을 문단으로 변환하는 필터를 적용한다는 표현을 쓰기도 합니다. ## 한 가지 더 -나혼자만 웹 사이트를 보는게 아니라 다른 사람들도 인터넷으로 볼 수 있으면 참 좋겠죠? 이제 PythonAnywhere에 다시 여러분이 만든 블로그를 배포해봅시다. 아래에 각 단계별로 요약했어요. +나 혼자만 웹 사이트를 보는 게 아니라 다른 사람들도 인터넷으로 볼 수 있으면 참 좋겠죠? 이제 PythonAnywhere에 다시 여러분이 만든 블로그를 배포해봅시다. 아래에 각 단계별로 요약했어요. -* 제일 먼저, Github에 여러분의 코드를 git의 push를 사용해서 넣으세요. +* 제일 먼저, GitHub에 여러분의 코드를 git의 push를 사용해서 넣으세요. +{% filename %}command-line{% endfilename %} ``` $ git status [...] @@ -84,24 +85,20 @@ $ git commit -m "Modified templates to display posts from database." $ git push ``` -* 다음 [PythonAnywhere][4]로 돌아와 **배시 콘솔창(Bash console)** 으로 가서(또는 이미 닫았다면 새 콘솔창을 여세요), 다음 명령어를 실행하세요. : +* 다음 [PythonAnywhere](https://www.pythonanywhere.com/consoles/)로 돌아와 **Bash console**로 가서(또는 이미 닫았다면 새 콘솔창을 여세요), 다음 명령어를 실행하세요. : - [4]: https://www.pythonanywhere.com/consoles/ - - ``` - $ cd my-first-blog - $ git pull - [...] - ``` - -* 마지막으로 [웹 탭(Web tab)][5]에서 **다시 불러오기(Reload)** 를 누르세요. 업데이트가 보여야 해요! +{% filename %}command-line{% endfilename %} +``` +$ cd my-first-blog +$ git pull +[...] +``` - [5]: https://www.pythonanywhere.com/web_app_setup/ +* 마지막으로 [Web tab](https://www.pythonanywhere.com/web_app_setup/)에서 **Reload**를 누르세요. 업데이트 내용이 보여야 해요! PythonAnywhere 사이트의 블로그 게시물이 로컬 서버에 호스팅 된 블로그에 나타나는 게시물과 일치하지 않는 것이 정상입니다. 로컬 컴퓨터와 PythonAnywhere의 데이터베이스는 동기화되지 않습니다. -축하합니다! 이제 장고 관리자로 가서 새로운 블로그 글을 추가하고(출판 날짜를 추가하는 것을 잊지 마세요!) 다시 새로고침 하세요. 그러면 새 글이 보일 거에요. +축하합니다! 이제 장고 관리자 페이지로 가서 새 블로그 글을 추가하고(게시일을 추가하는 것을 잊지 마세요!) https://yourname.pythonanywhere.com/admin 로 가야하는 것을 잊지마세요. 새로고침하면 새 글이 보일 거에요. -잘 작동하니까 멋지죠? 참 자랑스러워요! 잠시 쉬고 오세요. :) +잘 작동하니까 멋지죠? 잘 해낸 여러분들이 참 자랑스러워요! 잠시 쉬고 오세요. :) -![그림 13.4][6] +![Figure 13.4](images/donut.png) - [6]: images/donut.png diff --git a/ko/django_templates/images/donut.png b/ko/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/ko/django_templates/images/donut.png and b/ko/django_templates/images/donut.png differ diff --git a/ko/django_templates/images/images/donut.png b/ko/django_templates/images/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/ko/django_templates/images/images/donut.png and b/ko/django_templates/images/images/donut.png differ diff --git a/ko/django_templates/images/images/step1.png b/ko/django_templates/images/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/ko/django_templates/images/images/step1.png and b/ko/django_templates/images/images/step1.png differ diff --git a/ko/django_templates/images/images/step2.png b/ko/django_templates/images/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/ko/django_templates/images/images/step2.png and b/ko/django_templates/images/images/step2.png differ diff --git a/ko/django_templates/images/images/step3.png b/ko/django_templates/images/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/ko/django_templates/images/images/step3.png and b/ko/django_templates/images/images/step3.png differ diff --git a/ko/django_templates/images/step1.png b/ko/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/ko/django_templates/images/step1.png and b/ko/django_templates/images/step1.png differ diff --git a/ko/django_templates/images/step2.png b/ko/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/ko/django_templates/images/step2.png and b/ko/django_templates/images/step2.png differ diff --git a/ko/django_templates/images/step3.png b/ko/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/ko/django_templates/images/step3.png and b/ko/django_templates/images/step3.png differ diff --git a/ko/django_urls/README.md b/ko/django_urls/README.md index 7591b085c28..680ae59c152 100755 --- a/ko/django_urls/README.md +++ b/ko/django_urls/README.md @@ -1,121 +1,98 @@ -# Django urls +# 장고 urls -첫 웹페이지를 만들어 보기로 해요. : 여러분의 블로그를 위한 홈페이지요! 하지만 먼저 장고 url에 대해서 조금 배워보기로 합시다. +첫 웹 페이지를 만들어 봅시다. 블로그 홈페이지요! 먼저 장고 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][1] +![Url](images/url.png) - [1]: images/url.png +인터넷의 모든 페이지는 고유한 URL을 가지고 있어야 해요. 애플리케이션은 사용자가 URL을 입력하면 어떤 내용을 보여줘야 하는지 알고 있어요. 장고는 `URLconf (URL configuration)`를 사용합니다. `URLconf`는 장고에서 URL과 일치하는 뷰를 찾기 위한 패턴들의 집합입니다. -인터넷에 있는 모든 페이지들은 자신만의 URL을 가지고 있어야 해요. 이런 방식으로 어플리케이션은 URL을 입력한 사용자에게 어떤 내용을 보여줘야 할지 알게 됩니다. 장고는 `URLconf` (URL configuration)를 사용합니다. URLconf는 장고에서 URL과 일치하는 뷰를 찾기 위한 패턴들의 집합입니다. +## 장고 URL은 어떻게 작동할까요? -## Django에서 URL은 어떻게 작동할까요? - -코드 에디터에서 `mysite/urls.py`파일을 열면 아래와 같을 거예요. : +코드 에디터에서 `mysite/urls.py`파일을 열면 아래 내용이 보일 거에요. +{% filename %}mysite/urls.py{% endfilename %} ```python - from django.conf.urls import include, url - from django.contrib import admin +"""mysite URL Configuration - urlpatterns = [ - # Examples: - # url(r'^$', 'mysite.views.home', name='home'), - # url(r'^blog/', include('blog.urls')), +[...] +""" +from django.contrib import admin +from django.urls import path - url(r'^admin/', include(admin.site.urls)), - ] +urlpatterns = [ + path('admin/', admin.site.urls), +] ``` 장고가 이미 어떤 내용을 넣어 두었네요. -`#`로 시작되는 줄은 주석이에요. 이 말은 파이썬은 이 줄을 실행하지 않는다는 뜻이지요. 꽤 유용하겠죠? - -이전 장에서 봤던 관리자 URL도 여기에 이미 있어요. : - - url(r'^admin/', include(admin.site.urls)), - - -이 의미는 `admin/`으로 시작하는 모든 URL을 장고가 *view*와 대조해 찾아낸다는 뜻입니다. 이 경우 많은 admin URL을 포함해야 하기 때문에 작은 파일안에 모두 들어가지 않아요. 여기에 좀 더 읽기 좋고 깔끔한 방법이 있어요. - -## 정규표현식(Regex) - -장고가 URL을 뷰에 매칭시키는 방법이 궁금하죠? 이 부분은 조금 까다로울 수 있어요. 장고는 `regex`를 사용하는데, "정규표현식(regular expressions)"의 줄임말입니다. 정규식은 정말 (아주!) 많은 검색 패턴의 규칙을 가지고 있어요. 정규식은 심화 내용이기 때문에, 자세한 내용은 다루지 않을 거예요. +세 개의 따옴표들(`"""`, `'''`) 사이에 있는 줄들은 독스트링(docstring)입니다. 독스트링은 파일 제일 첫 부분, 클래스 또는 메서드 윗 부분에 작성해, 이들이 어떤 일을 수행하는지 알려줍니다. 파이썬은 이 부분을 실행하지 않을 거에요. -패턴을 만드는 방법이 궁금하다면, 아래에 있는 표기법을 확인하세요. 우리는 패턴을 찾는데 필요한 몇 가지 규칙만 필요합니다. : +이전 장에서 봤던 관리자 URL도 여기에 이미 있어요. - ^ 문자열이 시작할 때 - $ 문자열이 끝날 때 - \d 숫자 - + 바로 앞에 나오는 항목이 계속 나올 때 - () 패턴의 부분을 저장할 때 - - -이외에 url 정의는 문자적으로 만들 수 있어요. - -이런 사이트 주소가 있다고 해봅시다. : `http://www.mysite.com/post/12345/` 여기에서 `12345`는 글 번호를 의미합니다. - -뷰마다 모든 글 번호을 작성하는 것은 정말 힘든 일이 될 거에요. 정규 표현식으로 url과 매칭되는 글 번호를 뽑을 수 있는 패턴을 만들 수 있어요. 이렇게 말이죠. : `^post/(\d+)/$`. 어떤 뜻인지 하나씩 나누어 어떤 뜻인지 알아볼게요. : +{% filename %}mysite/urls.py{% endfilename %} +```python + path('admin/', admin.site.urls), +``` -* **^post/**는 장고에게 url 시작점에 (오른쪽부터) `post/`가 있다는 것을 말해 줍니다. `^`) -* **(\d+)**는 숫자(한 개 또는 여러개) 가 있다는 뜻입니다. 내가 뽑아내고자 글 번호가 되겠지요. -* **/**는 장고에게 `/`뒤에 문자가 있음을 말해 줍니다. -* **$**는 URL의 끝이 방금 전에 있던 `/`로 끝나야 매칭될 수 있다는 것을 나타냅니다. +장고는 `admin/`로 시작하는 모든 URL을 *view*와 대조해 찾아냅니다. 무수히 많은 URL이 `admin URL`에 포함될 수 있어 일일이 모두 쓸 수 없답니다. 그래서 정규표현식을 사용합니다. ## 나의 첫 번째 Django url! -첫 번째 URL을 만들어 봅시다! 우리는 ''가 홈페이지 주소로 만들어 글 목록이 보이게 만들어 볼 거에요. +첫 번째 URL을 만들어 봅시다! 'http://127.0.0.1:8000/' 주소를 블로그 홈 페이지로 지정하고 여기에 글 목록을 보여줄 거에요. -또한 `mysite/urls.py`파일을 깨끗한 상태로 유지하기 위해, `blog` 어플리케이션에서 메인 `mysite/urls.py`파일로 url들을 가져올 거에요. +또한 `mysite/urls.py`파일을 깨끗한 상태로 유지하기 위해, `blog` 애플리케이션에서 메인 `mysite/urls.py`파일로 url들을 가져올 거에요. -먼저 `#`로 시작하는 줄을 삭제하고 main url ('')로 `blog.urls`를 가져오는 행을 추가해 봅시다. +먼저 `blog.urls`를 가져오는 행을 추가해 봅시다. `blog.urls`를 가져오려면, `include` 함수가 필요합니다. `from django.urls ` 행을 찾아 `import` 뒤에 `include` 함수를 추가하세요. 이제 `mysite/urls.py` 파일은 아래처럼 보일 거에요. - from django.conf.urls import include, url - from django.contrib import admin - - urlpatterns = [ - url(r'^admin/', include(admin.site.urls)), - url(r'', include('blog.urls')), - ] - +{% filename %}mysite/urls.py{% endfilename %} +```python +from django.contrib import admin +from django.urls import path, include -지금 장고는 ''로 들어오는 모든 접속 요청을 `blog.urls`로 전송하고 추가 명령을 찾을 거예요. +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('blog.urls')), +] +``` -파이썬에서 정규 표현식을 작성할 때는 항상 문자열 앞에 `r`을 붙입니다. 이는 파이썬에게는 별 의미가 없지만, 파이썬에게 문자열에 특수 문자를 있다는 것을 알려줍니다. +지금 장고는 http://127.0.0.1:8000/ 로 들어오는 모든 접속 요청을 `blog.urls`로 전송해 추가 명령을 찾을 거예요. ## blog.urls -`blog/urls.py`이라는 새 파일을 생성하세요. 좋아요! 이제 다음 두 줄을 추가하세요. - - from django.conf.urls import url - from . import views - - -우리는 장고의 메소드와 `blog` 어플리케이션에서 사용할 모든 `views`들을 불러오고 있어요. (물론 아직 뷰를 하나도 안 만들었지만, 곧 만들 거니 조금만 기다리세요!) - -그다음, 첫 번째 URL 패턴을 추가하세요. - - urlpatterns = [ - url(r'^$', views.post_list, name='post_list'), - ] +`blog/urls.py`이라는 새 파일을 생성하세요. 좋아요! 이제 아래 두 줄을 추가하세요. +{% filename %}blog/urls.py{% endfilename %} +```python +from django.urls import path +from . import views +``` -이제 `post_list`라는 이름의 `view`가 `^$` URL에 할당되었습니다. 이 정규표현식은 `^`에서 시작해 `$`로 끝나는 지를 매칭할 것입니다. 즉 문자열이 아무것도 없는 경우만 매칭하겠죠. 틀린 것이 아니에요. 왜냐하면 장고 URL 확인자(resolver)는 '' 는 URL의 일부가 아니기 때문입니다. 이 패턴은 장고에게 누군가 웹사이트에 '' 주소로 들어왔을 때`views.post_list`를 보여주라고 말할 거에요. +여기서 장고 함수인 `path`와 `blog` 애플리케이션에서 사용할 모든 `views`를 가져왔어요. (물론 아직 뷰를 만들기 전이지만 일 분 내로 만들거에요!) -마지막 부분인 `name='post_list'` 는 URL에 이름을 붙인 것으로 뷰를 식별합니다. 이 부분은 뷰의 이름과 같을 수도 완전히 다를 수도 있습니다. 이름을 붙인 URL은 프로젝트의 후반에 사용할 거에요. 그러니 앱의 각 URL을 이름짓는 것은 중요합니다. 또 URL에 고유한 이름을 붙여, 외우고 부르기 쉽게 만들어야 해요. +그 다음, 첫 번째 URL 패턴을 추가하세요. -모두 잘 되고 있나요? '' 으로 접속해 결과를 확인해보세요. +{% filename %}blog/urls.py{% endfilename %} +```python +urlpatterns = [ + path('', views.post_list, name='post_list'), +] +``` -![Error][2] +이제 `post_list`라는 `view`가 루트 URL에 할당되었습니다. 이 URL 패턴은 빈 문자열에 매칭이 되며, 장고 URL 확인자(resolver)는 전체 URL 경로에서 접두어(prefix)에 포함되는 도메인 이름(i.e. http://127.0.0.1:8000/)을 무시하고 받아들입니다. 이 패턴은 장고에게 누군가 웹사이트에 'http://127.0.0.1:8000/' 주소로 들어왔을 때 `views.post_list`를 보여주라고 말해줍니다. - [2]: images/error1.png +마지막 부분인 `name='post_list'`는 URL에 이름을 붙인 것으로 뷰를 식별합니다. 뷰의 이름과 같을 수도 완전히 다를 수도 있습니다. 이름을 붙인 URL은 프로젝트의 후반에 사용할 거예요. 그러니 앱의 각 URL마다 이름 짓는 것은 중요합니다. URL에 고유한 이름을 붙여, 외우고 부르기 쉽게 만들어야 해요. -이런, 잘 "작동" 하는 것 같지 않다구요? 걱정마세요. 이건 그냥 오류 페이지에요. 그러니 무서워하지마세요! 오류는 꽤 유용하게 쓰인 답니다. : +http://127.0.0.1:8000/ 접속했는데 '웹 페이지를 사용할 수 없음(web page not available)'이라는 메시지가 표시되었나요?. 이는 서버(`runserver`라고 입력하는 것을 기억 하는가?)가 실행되지 않았기 때문이에요. 에러가 발생한 이유를 찾으려면 서버 콘솔 창을 보세요. +![Error](images/error1.png) -페이지에서 **no attribute 'post_list'**라는 오류가 보일 거에요. *post_list*에서 혹시 떠오르는 것이 있나요? 바로 뷰(view) 를 말하는 거죠! 모두 준비가 되었다는 뜻이에요. 아직 *view*를 안 만들었다는 것만 빼고요. 걱정 마세요. 금방 만들어 볼 거에요. +콘솔에서 에러가 발생했네요. 하지만 걱정하지 마세요. 에러는 해결할 방법을 알려준답니다. : **no attribute 'post_list'** 라는 메시지가 보일거에요. 이 메시지는 장고가 찾고 사용하고자 하는 _뷰_가 아직 없다는 거에요. 이 단계에서 `/admin/`도 접속되지 않을 거에요. 앞으로 고쳐볼 테니 걱정하지 마세요. 혹시 여러분이 다른 에러 메시지를 보게 된다면, 웹 서버를 껐다 다시 켜보세요. 커맨드라인(혹은 콘솔)으로 가서 `Ctrl + C`를 눌러 웹 서버를 중단하면 됩니다. 다시 `python manage.py runserver` 명령어를 실행해 서버를 다시 시작하세요. -> 장고 URL 설정에 대해 더 알고 싶다면 공식 문서를 읽어보세요. : https://docs.djangoproject.com/en/1.8/topics/http/urls/ +> 장고 URL 설정에 대해 더 알고 싶다면 장고 공식 문서를 읽어보세요. : +https://docs.djangoproject.com/en/2.0/topics/http/urls/ diff --git a/ko/django_urls/images/error1.png b/ko/django_urls/images/error1.png index cc17593d19d..250028e996b 100644 Binary files a/ko/django_urls/images/error1.png and b/ko/django_urls/images/error1.png differ diff --git a/ko/django_urls/images/images/error1.png b/ko/django_urls/images/images/error1.png index cc17593d19d..250028e996b 100644 Binary files a/ko/django_urls/images/images/error1.png and b/ko/django_urls/images/images/error1.png differ diff --git a/ko/django_urls/images/images/url.png b/ko/django_urls/images/images/url.png index 6cd1bd96291..b59f9dce992 100644 Binary files a/ko/django_urls/images/images/url.png and b/ko/django_urls/images/images/url.png differ diff --git a/ko/django_urls/images/url.png b/ko/django_urls/images/url.png index 6cd1bd96291..b59f9dce992 100644 Binary files a/ko/django_urls/images/url.png and b/ko/django_urls/images/url.png differ diff --git a/ko/django_views/README.md b/ko/django_views/README.md index f84358f74d8..2d8450bff08 100755 --- a/ko/django_views/README.md +++ b/ko/django_views/README.md @@ -1,38 +1,40 @@ -# Django 뷰 만들기 +# 장고 뷰 만들기 -지난 장에서 만들었던 버그를 잡을 시간이 왔어요 :) +지난 장에서 만들었던 버그를 잡을 시간이 왔어요! :) -뷰(*view*) 는 어플리케이션의 "로직"을 넣는 곳이에요. 뷰는 앞 챕터에서 만들었던 `모델`에게서 필요한 정보를 받아와서 `템플릿`에 전달하는 역할을 합니다. 다음 장에서 템플릿을 만들어 볼 거에요. 뷰는 **파이썬 들어가기** 장에서 했던 것 보다 조금 복잡해 보이지만, 그래도 결국 파이썬의 메서드일 뿐이에요. +뷰(*view*) 는 애플리케이션의 "로직"을 넣는 곳이에요. 뷰는 이전 장에서 만들었던 `모델`에서 필요한 정보를 받아와서 `템플릿`에 전달하는 역할을 합니다. 다음 장에서 템플릿을 만들어 볼 거에요. 뷰는 __Python 시작하기__ 장에서 했던 것보다 어려워보이지만, 파이썬 함수일 뿐이에요. -뷰는 `views.py` 파일 안에 있습니다. 우리는 *views* 를 `blog/views.py` 파일 안에 추가할 거에요. +뷰는 `views.py` 파일 안에 있습니다. 우리는 *views*를 `blog/views.py`파일 안에 추가할 거에요. ## blog/views.py -좋아요. 이제 이 파일을 열고 안에 있는 내용을 살펴봅시다. : +좋아요. 이제 이 파일을 열고 안에 있는 내용을 살펴봅시다: +{% filename %}blog/views.py{% endfilename %} ```python - from django.shortcuts import render -``` - # Create your views here. +from django.shortcuts import render +# Create your views here. +``` -여기에는 별 내용이 없네요. 가장 간단한 *view* 를 이렇게 만들어봅시다. +별 내용이 없네요. 간단한 *view*를 만들어봅시다. +{% filename %}blog/views.py{% endfilename %} ```python - def post_list(request): - return render(request, 'blog/post_list.html', {}) +def post_list(request): + return render(request, 'blog/post_list.html', {}) ``` -방금 우리는 `post_list`라는 메서드를 만들었습니다. (`def`가 메서드를 만들 때 사용하는 키워드였죠?) 그리고 이 메서드는 `요청(request)`을 넘겨받아 `render` 메서드를 호출합니다. render 메서드는 넘겨진 요청(request)과 `blog/post_list.html` 템플릿 받아 리턴된 내용이 브라우저에 보여지게 됩니다. +방금 `post_list`라는 함수(`def`)를 만들었습니다. 이 함수는 `요청(request)`을 넘겨받아 `render`메서드를 호출합니다. 이 함수는 `render` 메서드를 호출하여 받은(return) `blog/post_list.html`템플릿을 보여줍니다. + -파일을 저장하고, http://127.0.0.1:8000/로 접속해 결과를 확인해보세요. +파일을 저장하고, http://127.0.0.1:8000/ 로 접속해 확인해보세요. -에러가 발생했어요! 이제 아래 내용을 읽어보세요. : +에러가 발생했네요! 아래 내용을 읽어보세요. -![오류][1] +![Error](images/error.png) - [1]: images/error.png +*TemplateDoesNotExist*는 쉽게 해결할 수 있습니다. 잘 따라왔다면 방금 에러가 보이는게 맞아요. 다음 장에서 버그를 해결하기 위해 템플릿 파일을 만들 거에요! -*TemplateDoesNotExist* 는 쉽게 해결할 수 있습니다. : 잘 따라왔다면 이러한 에러가 발생하는게 맞아요. 다음 장에서 이 버그를 해결하기 위해 템플릿 파일을 만들 거에요! +> 장고 뷰에 대해 더 알고 싶다면 장고 공식 문서를 읽어보세요. : https://docs.djangoproject.com/en/2.0/topics/http/views/ -> Django 뷰에 대해 자세히 알고 싶으시면 공식 문서를 읽어 보세요. https://docs.djangoproject.com/en/1.8/topics/http/views/ diff --git a/ko/django_views/images/error.png b/ko/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/ko/django_views/images/error.png and b/ko/django_views/images/error.png differ diff --git a/ko/django_views/images/images/error.png b/ko/django_views/images/images/error.png index 391c9e61e16..2ef613c8a5d 100644 Binary files a/ko/django_views/images/images/error.png and b/ko/django_views/images/images/error.png differ diff --git a/ko/domain/README.md b/ko/domain/README.md deleted file mode 100755 index a3008963445..00000000000 --- a/ko/domain/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# 도메인 - -Heroku(헤로쿠) 에서 도메인을 받을 수 있지만 너무 길어 기억하기도 힘들고 썩 좋아보이지도 않네요. 간단하고 기억하기 쉬운 멋진 도메인이 있다면 참 좋겠죠? - -이번 장에서는 구입한 도메인을 헤로쿠에 설정하는 방법에 대해 배울 거에요. - -## 어디에서 도메인을 등록하나요? - -어떤 도메인을 선택하냐에따라 가격이 다르지만, 일반적으로 1년에 15, 000원정도 비용이 들어요. 또한 같은 도메인이라고 하더라도 어느 회사를 고르냐에 따라서 더 쌀 수도, 비쌀 수도 있습니다. 도메인을 구입할 수 있는 곳은 참 다양하고 많은데요, 간단히 [구글 검색][1]을 해봐도 얼마나 많은지 알 수 있을거에요. - - [1]: https://www.google.com/search?q=register%20domain - -우리가 선호하는 한 회사는 [I want my name][2]이에요. 이 곳에서는 "고통없는 도메인 관리를 할 수 있습니다(painless domain management)"라고 광고를 하고 있고 실제로도 그렇더군요. - - [2]: https://iwantmyname.com/ - -## IWantMyName에서 어떻게 도메인을 등록할까요? - -[iwantmyname][3]에 가셔서 검색창에 내가 원하는 도메인 이름을 입력하세요. - - [3]: https://iwantmyname.com - -![][4] - - [4]: images/1.png - -그러면 검색창에 입력한 단어가 들어간 모든 도메인 목록을 볼 수 있어요. 웃는 얼굴 아이콘이 있다면 구매가 가능한 도메인이고, 슬픈 얼굴 아이콘이 있다면 이미 누군가가 구입한 도메인입니다. - -![][5] - - [5]: images/2.png - -여기서 우리는 `djangogirls.in` 를 사기로 결정했어요. : - -![][6] - - [6]: images/3.png - -결제할게요. 아직 iwantmyname에 회원가입을 안했다면 먼저 가입부터 하세요. 이후에 도메인 결제를 위해 여러분의 신용카드를 입력하세요! - -그 다음, 메뉴에 있는 `도메인(Domains)`을 클릭하고 방금 새로 구입한 도메인을 선택하세요. 이후 `DNS 레코드 관리(manage DNS records)` 링크를 클릭하세요. : - -![][7] - - [7]: images/4.png - -아래 그림의 입력폼이 있는 곳으로 가세요. : - -![][8] - - [8]: images/5.png - -아래 세부 내용을 기입하세요: - Hostname: www - Type: CNAME - Value: your domain from Heroku (for example djangogirls.herokuapp.com) - TTL: 3600 - -![][9] - - [9]: images/6.png - -"추가" 버튼을 누른 후 하단의 "변경사항 반영" 버튼도 클릭하세요. - -도메인 작동까지 몇 시간이 걸릴 수 있으니, 조금 기다려보세요! - -## 헤로쿠에서 도메인 설정하기 - -사용자 지정 도메인을 사용하고자하는 경우에도 헤로쿠에게 말해야해요. - -[Heroku Dashboard][10]로 가서, 헤로쿠에 로그인 한 다음, 앱을 선택하세요. 앱 설정으로 들어가 `도메인`영역에 내 도메인을 추가하고 저장하세요. - - [10]: https://dashboard.heroku.com/apps - -잘했어요! diff --git a/ko/dynamic_data_in_templates/README.md b/ko/dynamic_data_in_templates/README.md index b84d6edc329..c6a50165b4c 100755 --- a/ko/dynamic_data_in_templates/README.md +++ b/ko/dynamic_data_in_templates/README.md @@ -1,75 +1,78 @@ -# 템플릿의 동적 데이터 +# 템플릿 동적 데이터 -블로그 글이 각각 다른 장소에 조각조각 나눠져있어요. `Post` 모델은 `models.py`파일에 정의되어 있고, `post_list` 모델은 `views.py` 파일에 정의되어 있습니다. 템플릿도 추가해야해요. 하지만 실제로 HTML 템플릿에서 글들이 어떻게 보여질까요? 보여주고자 하는 컨텐츠(데이터베이스 안에 저장되어 있는 모델들) 를 가져와서 우리의 템플릿에 넣어서 멋있게 보여줄 것입니다. +블로그 글은 각각 다른 장소에 조각조각 나눠져있어요. `Post`모델은 `models.py`파일에, `post_list`모델은 `views.py`파일에 있어요. 그리고 앞으로 템플릿도 추가해야 합니다. HTML 템플릿에서 글 목록을 어떻게 보여줄까요? 이번 장에서는 콘텐츠(데이터베이스 안에 저장되어 있는 모델)를 가져와 템플릿에 넣어 보여주는 것을 해볼 거에요. -여기서 *views* 가 모델과 템플릿을 연결하는 역할을 한다는 것을 알 수 있어요. `post_list` *view* 에서 보여주고 템플릿에 넘기기 위해서 모델을 가져와야해요. 그래서 기본적으로 *view* 에서는 템플릿에서 무엇을 보여줄 지 (모델) 을 선택을 하지요. +*뷰(view)*는 모델과 템플릿을 연결하는 역할을 합니다. `post_list`를 *뷰*에서 보여주고 이를 템플릿에 전달하기 위해서는, 모델을 가져와야 합니다. 일반적으로 *뷰*가 템플릿에서 모델을 선택하도록 만들어야 합니다. -자, 모두 했나요? +자, 모두 준비됐나요? -이제 `blog/views.py` 파일을 열어봅시다. `post_list` *view* 파일이 아래처럼 보일 거에요. +`blog/views.py`파일을 열어봅시다. `post_list` *뷰* 내용을 봅시다. +{% filename %}blog/views.py{% endfilename %} ```python - from django.shortcuts import render +from django.shortcuts import render - def post_list(request): - return render(request, 'blog/post_list.html', {}) +def post_list(request): + return render(request, 'blog/post_list.html', {}) ``` -다른 파일들에 있는 코드를 가져오는 것에 대해서 이야기 했던거 기억나나요? 이제 `models.py` 파일에서 정의한 모델을 가져올 때입니다. 이제 `from .models import Post` 행을 추가해 봅시다. 아래와 같을 거에요. : +다른 파일에 있는 코드를 가져오는 방법, 기억나나요? `models.py`파일에 정의된 모델을 가져올 거에요. `from .models import Post`을 추가하세요. +{% filename %}blog/views.py{% endfilename %} ```python - from django.shortcuts import render - from .models import Post +from django.shortcuts import render +from .models import Post ``` -`from` 다음에 있는 마침표(.)는 *현재 디렉토리* 또는* 현재 어플리케이션*을 의미합니다. `views.py`와 `models.py` 파일들이 같은 디렉토리에 있기 때문에 우리는 `.`와 (`.py` 확장자를 붙이지 않아도) 파일의 이름만으로도 쉽게 사용할 수 있습니다. 자 다음은 모델(`Post`)의 이름을 불러옵니다.). +`from` 다음에 있는 마침표(.)는 현재 *디렉토리* 또는 *애플리케이션*을 의미합니다. 동일한 디렉터리 내 `views.py`, `models.py`파일이 있기 때문에 `. 파일명` (`.py`확장자를 붙이지 않아도)으로 내용을 가져올 수 있습니다. 이제 `Post`모델을 불러봅시다. -그럼 그 다음은요? `Post` 모델에서 실제 블로그 글들을 가져와야 하는데 이때 필요한 특별한 것이 바로 `QuerySet`입니다. +`Post`모델에서 블로그 글을 가져오기 위해서는 `쿼리셋(QuerySet)`이 필요합니다. ## 쿼리셋(QuerySet) -여러분은 쿼리셋이 어떻게 동작하는지를 이미 친숙해져 있어야해요. 자세한 내용은 [Django ORM (쿼리셋)][1]에서 다루었어요. +여러분은 이미 쿼리셋에 익숙해야 해요. 자세한 내용은 [Django ORM과 QuerySets](../django_orm/README.md) 장에서 다루었어요. - [1]: ../django_orm/README.md - -자, 이제는 블로그 글 목록을 주의깊게 봅시다. 글 목록이 출판되고 `출판된 날짜(published_date)` 기준으로 정렬되면 좋겠죠? 사실 이미 쿼리셋 챕터에서 해놓어요! +자, 블로그 글 목록을 살펴봅시다. 글 목록을 게시일 `published_date`기준으로 정렬해볼까요? 이미 Django ORM과 QuerySets 장에서 해본 내용이에요. +{% filename %}blog/views.py{% endfilename %} ```python - Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +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)`함수에 아래 코드 내용을 넣어봅시다. 제일 먼저 `timezone` 모듈을 불러와야하니 `from django.utils import timezone`를 추가하는 것을 잊지 마세요. +{% filename %}blog/views.py{% endfilename %} ```python - from django.shortcuts import render - from django.utils import timezone - from .models import Post +from django.shortcuts import render +from django.utils import timezone +from .models import Post - def post_list(request): - posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') - return render(request, 'blog/post_list.html', {}) +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {}) ``` -우리는 지금 `posts`쿼리셋을 나타내는 *변수* 를 만들고 있다는 것을 주의하세요. 이 변수는 퀴리셋의 이름으로 취급하며 이 이름으로 참조할 수도 있습니다. +아직 안한 부분은 `posts` QuerySet을 템플릿 컨텍스트에 전달하는 것입니다. 걱정하지 마세요. 맨 마지막에 이 부분을 다룰 거에요. -위 코드에서 `timezone.now()` 함수를 쓰기 때문에 `timezone` 모듈 import가 필요합니다. +우리는 `posts`라는 *변수*를 만들고 있다는 것을 기억하세요. 이 변수는 퀴리셋의 이름입니다. -마지막 부족한 부분은 `posts` 쿼리셋을 처리해서 템플릿에 보내는 것입니다.(이 부분은 다음 장에서 다룰 거에요.) +다음 장에서 `posts`쿼리셋을 템플릿에 보내는 방법을 배울 거에요. -`render`함수에서는 이미 요청 시 매개변수`request`와 템플릿 파일 'blog/post_list.html'를 가지고 있습니다. `{}` 와 같이 보이는 마지막 매개 변수는 템플릿을 사용하기 위해 무엇인가를 추가하는 장소입니다. 이름을 넣어줘야 합니다. (여기서는 `'posts'`이에요.) 이렇게 보일지도 모르겠어요. : `{'posts': posts}`. `:` 표시를 해 구분하는 것을 잊지 마세요. ; 양쪽에 작은 따옴표를 붙이는 것도요. `''`. +`render`함수에는 매개변수 `request`(사용자가 요청하는 모든 것)와 'blog/post_list.html' 템플릿이 있습니다. `{}`이 보일 텐데, 이곳에 템플릿을 사용하기 위해 매개변수를 추가할 거에요. (이 매개변수를`'posts'`라고 할거에요)`{'posts': posts}`이렇게 작성할거에요. `:`이전에 문자열이 와야하고, 작은 따옴표`''`를 양쪽에 붙이는 것을 잊지 마세요. -그래서 최종적으로 `blog/views.py` 파일이 아래처럼 될 거에요. : +이제 `blog/views.py`코드는 아래 코드처럼 보일 겁니다. ```python - from django.shortcuts import render - from django.utils import timezone - from .models import Post +from django.shortcuts import render +from django.utils import timezone +from .models import Post - def post_list(request): - posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') - return render(request, 'blog/post_list.html', {'posts': posts}) +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {'posts': posts}) ``` -다 되었습니다! 이제 템플릿 파일로 돌아가서 이 쿼리셋을 보이게 해볼 차례에요. +여기까지에요! 템플릿 파일로 돌아가 쿼리셋을 보이게 만들어 봅시다. -쿼리셋에 대해서 좀 더 자세히 알고 싶다면 장고 공식 문서를 읽어보세요. : https://docs.djangoproject.com/en/1.8/ref/models/querysets/ +쿼리셋에 대해 더 알고 싶다면 장고 공식 문서를 읽어보세요. : +https://docs.djangoproject.com/en/2.0/ref/models/querysets/ diff --git a/ko/extend_your_application/README.md b/ko/extend_your_application/README.md index 48cbcea26e0..6e8ae2790e3 100755 --- a/ko/extend_your_application/README.md +++ b/ko/extend_your_application/README.md @@ -1,17 +1,20 @@ -# 프로그램 어플리케이션 확장하기 +{% set warning_icon = '' %} -우리는 지금까지 웹사이트 제작에 필요한 모든 단계들을 마쳤어요. 모델, url, 뷰와 템플릿을 만드는지 알게 되었고요. 또 웹사이트를 어떻게 멋지게 꾸미는지 알게 되었어요. +# 프로그램 애플리케이션 확장하기 -이제 연습해 봅시다! +지금까지 웹 사이트 제작 단계를 모두 마쳤어요. 모델, url, 뷰와 템플릿을 만드는 방법을 알게 되었고요. 웹 사이트를 예쁘게 꾸미는 방법도 알게 되었어요. -블로그에 가장 필요한 것은 페이지에 포스트가 보이게 만드는 것이겠죠? +이제 또 실습해봅시다! -이미 앞에서 `Post` 모델을 만들었으니 `models.py`에 추가할 내용은 없습니다. +블로그 게시글이 각 페이지마다 보이게 만들어 봅시다. + +이미 앞에서 `Post`모델을 만들었으니 `models.py`에 새로 추가할 내용은 없어요. ## Post에 템플릿 링크 만들기 -`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' %} @@ -25,112 +28,114 @@

{{ post.text|linebreaksbr }}

{% endfor %} -{% endblock content %} +{% endblock %} ``` -{% raw %}우리는 post 목록에 있는 제목에서 post의 내용 페이지로 가는 링크를 만들 거에요. `

{{ post.title }}

` 를 변경해 봅시다. post의 상세 페이지는 {% endraw %} 로 연결됩니다. +{% raw %} `post`제목 목록이 보이고 해당 링크를 클릭하면, `post`상세 페이지로 이동하게 만들어 볼 거에요. `

{{ post.title }}

`부분을 수정해 봅시다. {% endraw %} +{% filename %}{{warning_icon}}blog/templates/blog/post_list.html{% endfilename %} ```html

{{ post.title }}

``` -`{% url 'post_detail' pk=post.pk %}`에 대해 설명할 때가 왔군요! 예상하셨겠지만 `{% %}` 표기는 장고 템플릿 태그를 사용하고 있는 것을 말합니다. 이번에는 우리를 위한 URL를 만들어 사용해 봅시다! +{% raw %}`{% url 'post_detail' pk=post.pk %}`을 설명할 때가 왔군요! `{% %}`는 장고 템플릿 태그을 말합니다. URL를 생성해 사용해봅시다.{% endraw %} -`blog.views.post_detail`는 우리가 만들려고 하는 경로인 `post_detail` *view* 입니다. 반드시 주의하세요 : `blog`는 우리의 응용 프로그램 (디렉토리 `blog`)의 이름이에요. `views`는 `views.py` 파일의 이름에서 나온 것이에요. 마지막인 `post_detail`는 *view* 의 이름입니다. +`blog.views.post_detail`는 `post_detail` *뷰* 경로입니다. `blog`는 응용프로그램(디렉터리 `blog`)의 이름인 것을 꼭 기억하세요. `views`는 `views.py`파일명이에요. 마지막 부분 `post_detail`는 *view* 이름입니다. -http://127.0.0.1:8000/를 열어보세요. 오류 메세지가 나올 거에요. (예상대로, 아직 `post_detail`을 위한 *view* 파일 만들지 않아 오류가 나는 것이죠.) 아마 이렇게 나왔을 거에요. : +`pk = post.pk`이란 무엇일까요? `pk`는 데이터베이스의 각 레코드를 식별하는 기본키(Prmiary Key)의 줄임말 입니다. Post 모델에서 기본키를 지정하지 않았기 때문에 장고는 `pk`라는 필드를 추가해 새로운 블로그 게시물이 추가될 때마다 그 값이 1,2,3 등으로 증가하게 됩니다. Post 객체의 다른 필드 (제목, 작성자 등)에 액세스하는 것과 같은 방식으로 post.pk를 작성하여 기본 키에 액세스합니다 `post.pk`를 써서 기본키에 접근할 수 있고 같은 방법으로 `Post`객체내 다른 필드(`title`, `author`)에도 접근할 수 있습니다! -![NoReverseMatch error][1] +이제 http://127.0.0.1:8000/ 를 열어보세요. 아마 오류 메세지가 나올 거에요. (아직 `post_detail` *뷰*를 만들지 않아 오류가 나는 거에요) 이런 화면이 보일 거에요. : - [1]: images/no_reverse_match2.png +![NoReverseMatch error](images/no_reverse_match2.png) -## Post 상세 페이지에 URL 만들기 +## Post 상세 페이지 URL 만들기 -`urls.py` 파일에 `post_detail` *view* 를 위한 URL를 만들어 봅시다! +`post_detail`*뷰*가 보이게 `urls.py`에 URL를 만들어 봅시다! -첫 번째 게시물의 상세 **URL** 은 이렇게 나올 거에요. : http://127.0.0.1:8000/post/1/ +첫 게시물의 상세 페이지 **URL**이 http://127.0.0.1:8000/post/1/가 되게 만들 거에요. -`blog/urls.py`파일에 URL을 만들어, 장고가 `post_detail`이란 *view* 로 보내, 전체 블로그 글이 보일 수 있게 만들어 봅시다. `url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail')` 코드를 `blog/urls.py` 파일에 추가하세요. 그러면 아래처럼 보일 거에요. : +`blog/urls.py`파일에 URL을 만들어, 장고가 `post_detail` *뷰*로 보내, 게시글이 보일 수 있게 해봅시다. `path('post//', 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]+)` - 이 부분은 좀 까다롭습니다. 이 정규 표현식의 의미는 장고가 여러분이 여기에 넣은 모든 것을 `pk`변수에 넣어 뷰로 전송하겠다는 뜻입니다. `[0-9]`은 문자를 제외하고, 숫자 0부터 9까지 하나의 숫자만 있다는 뜻입니다. `+`는 하나 또는 그 이상의 숫자가 와야한다는 것을 의미합니다. 따라서 `http://127.0.0.1:8000/post//`라고 하면 post/ 다음에 숫자가 없기 때문에 해당이 안되지만, `http://127.0.0.1:8000/post/1234567890/`는 완벽하게 매칭됩니다. - - `/` - 다음에 __/__ 가 한번 더 와야 한다는 의미입니다. - - `$` - "마지막"! 입니다. 그 뒤로 더이상 문자가 오면 안됩니다. +여기서 `post//`는 URL 패턴을 나타내요. 하나씩 차근차근 알아볼 거에요. + - `post/`란 URL이 **post** 문자를 포함해야 한다는 것을 말합니다. 아직 할 만하죠? + - ``는 조금 까다롭습니다. 장고는 정수 값을 기대하고 이를 `pk`라는 변수로 뷰로 전송하는 것을 말합니다. + - `/`은 다음에 **/** 가 한 번 더 와야 한다는 의미입니다. -브라우저에 `http://127.0.0.1:8000/post/5/`입력하면, 장고는 `post_detail`인 *view* 를 찾고 있다고 생각하고 `pk`가 `5`와 일치한 *view* 로 정보를 보내게 됩니다.. +브라우저에 `http://127.0.0.1:8000/post/5/`라고 입력하면, 장고는 `post_detail` *뷰*를 찾아 매개변수 `pk`가 `5`인 값을 찾아 *뷰*로 전달합니다. -`pk`는 `primary key`의 약자입니다. 장고 프로젝트에서 자주 사용되는 이름이에요. 물론 여러분은 내가 원하는 변수 이름을 사용할 수 있어요. (기억하세요 : 변수 이름에 공백문자는 사용할 수 없으며 소문자와 `_`를 사용할 수 있습니다.) 예를 들어, `(?P[0-9]+)`의 변수를 `post_id`바꾼다면 하면 정규표현식도 `(?P[0-9]+)`으로 바뀌게 됩니다. +좋아요, 새로운 URL 패턴을 `blog/urls.py`에 추가했어요! 페이지를 새로고침 하세요. http://127.0.0.1:8000/ 쾅! 또 에러가 났어요! 예상했던 대로에요! -좋아요, 이제 새로운 URL 패턴을 `blog/urls.py` 파일에 추가했어요! 이제 페이지를 새로고침 하세요. : http://127.0.0.1:8000/ 쾅! 또 에러가 났어요! 예상대로에요! +![AttributeError](images/attribute_error2.png) -![AttributeError][2] +다음 단계는 무엇일까요? 그렇죠. 뷰를 추가해야죠! -다음 단계는 무엇일까요? 그렇죠. : view를 추가해야죠! +## Post 상세 페이지 내 뷰 추가하기 -## Post 상세 페이지에 뷰 추가하기 +*뷰*에 매개변수 `pk`를 추가해봅시다. *뷰*가 `pk`를 식별해야겠죠? 그래서 함수를 `def post_detail(request, pk):`라고 정의합니다. urls(`pk`)과 동일하게 이름을 사용해야 합니다. 변수가 생략되면 오류가 날 거예요! -이제 *view* 는 추가적으로 매개 변수`pk`를 받아야합니다. *view* 에 가져다가 써야겠죠? 그래서 함수를 정의할 때, pk를 받도록 `def post_detail(request, pk):`라고 정의 할 것입니다. 기입된 urls(`pk`)에 지정한 것과 정확히 똑같은 이름을 사용해야함을 주의하세요. 변수가 생략되면 문제가 생겨 오류가 날 거에요! - -이제, 우리는 딱 한 개 블로그만 보고 싶어요. 이를 위해 다음과 같이 쿼리셋(queryset)을 사용해야해요. : +블로그 게시글 한 개만 보려면, 아래와 같이 쿼리셋(queryset)을 작성해야해요. +{% filename %}{{warning_icon}}blog/views.py{% endfilename %} ```python - Post.objects.get(pk=pk) +Post.objects.get(pk=pk) ``` -하지만 이 코드에는 문제가 있어요. `primary key` (`pk`)가있는 `Post`가 없다면 보고 싶지 않은 오류가 나올 거에요! +하지만 이 코드에는 문제가 있어요. 만약 해당 `primary key(pk)`의 `Post`를 찾지 못하면 오류가 나올 거에요! + +![DoesNotExist error](images/does_not_exist2.png) -![DoesNotExist error][3] +우리가 원하는게 아니죠! 장고에는 이를 해결하기 위해 `get_object_or_404`라는 특별한 기능을 제공해요. `pk`에 해당하는 `Post`가 없을 경우, 멋진 페이지(`페이지 찾을 수 없음 404 : Page Not Found 404)`를 보여줄 거에요. -우리가 원하는게 아니에요! 장고에서는 이를 해결 하기위해 특별한 기능을 제공해요. : `get_object_or_404`이에요. 이 기능을 사용하면 `pk`에 맞는 `Post`가 없을 경우, 멋진 페이지(`페이지 찾을 수 없음 404 : Page Not Found 404)`를 보여줄 거에요. +![Page not found](images/404_2.png) -![Page not found][4] +나중에 `페이지 찾을 수 없음(Page not found)`페이지를 예쁘게 만들 수 있어요. 지금 당장 중요한 것이 아니니 이 부분은 생략할게요. -좋은 점은 여러분 만의 `페이지 찾을 수 없음(Page not found)` 페이지를 예쁘게 만들 수 있다는 거에요. 지금 당장 중요한 것이 아니까 생략할게요. +좋아요. 이제 `views.py`파일에 새로운 *뷰*를 추가합시다! -좋아요. 이제 `views.py` 파일에 *view* 를 추가합시다! +`blog/urls.py`파일에서 `views.post_detail`라는 뷰를 `post_detail`이라 이름을 붙이도록 URL 법칙을 만들었어요. 이는 장고가 `post_detail`이라는 이름을 해석할 때, `blog/views.py`파일 내부의 `post_detail`이라는 뷰 함수로 이해하도록 해줍니다. -`blog/views.py` 파일을 열어서 아래 코드를 추가하세요. : +`blog/views.py`파일을 열고, `from`으로 시작하는 행에서 다음과 같이 코드를 추가해주세요. : +{% filename %}blog/views.py{% endfilename %} ```python - from django.shortcuts import render, get_object_or_404 +from django.shortcuts import render, get_object_or_404 ``` -`from`행 근처로 가서, 파일 맨 끝에 *view* 를 추가하세요. : +그리고, 파일 마지막 부분에 *뷰*를 추가하세요. +{% filename %}blog/views.py{% endfilename %} ```python - def post_detail(request, pk): - post = get_object_or_404(Post, pk=pk) - return render(request, 'blog/post_detail.html', {'post': post}) +def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) ``` -브라우저를 새로고침 해보세요. : http://127.0.0.1:8000/ +그리고 브라우저를 새로고침 하세요. http://127.0.0.1:8000/ -![Post list view][5] +![Post list view](images/post_list2.png) -잘 되네요! 그런데 블로그 제목 안의 링크를 클릭하면 어떻게 되나요? +잘 작동하네요! 그런데 블로그 제목 링크를 클릭하면 어떻게 되나요? -![TemplateDoesNotExist error][6] +![TemplateDoesNotExist error](images/template_does_not_exist2.png) -이런! 또 에러가 나왔네요! 하지만 이제는 이런 걸 어떻게 다뤄야하는지 알고 있죠? 우리는 이제 템플릿을 추가해 볼 거에요! +이런! 또 에러가 나왔네요! 하지만 이제 어떻게 해야하는지 알고 있죠? 드디어 템플릿을 추가할 차례에요! -## Post 상세 페이지에 템플릿 만들기 +## Post 상세 페이지 템플릿 만들기 -`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' %} @@ -147,20 +152,21 @@ urlpatterns = [ {% endblock %} ``` -다시 한 번 `base.html`을 확장해 봅시다. `content` 블록에서, 블로그 글의 published_date 출판일(존재한다면) 과 제목, 내용을 보이게 할 거에요. 그런데 제일 중요한 것을 얘기해봐야하지 않겠어요? +다시 한 번 `base.html`을 확장한 거에요. `content`블록에서 블로그 글의 게시일, 제목과 내용을 보이게 만들었어요. -{% raw %}`{% if ... %} ... {% endif %}` 는 무엇인가를 확인할 때 사용하는 템플릿 태그 입니다. (`if ... else ..` 를 __파이썬 들어가기__ 장에서 본 기억이나나요?) 우리는 post의 `출판 날짜(published_date)`가 비어있는지 아닌지 확인하고 싶어요. {% endraw %} +{% raw %} 가장 중요한 부분은 `{% if ... %} ... {% endif %}`라는 템플릿 태그인데, 내용이 있는지 확인할 때 사용합니다. (`if ... else ..`구문은 __Python 시작하기__ 장에서 배웠어요) `post`의 `게시일(published_date)`이 있는지, 없는지를 확인하는 거에요. {% endraw %} -페이지를 새로고침하면 `페이지 찾을 수 없음(Page not found)` 페이지가 없어진 것을 알 수 있어요. +페이지를 새로고침하면 `페이지 찾을 수 없음(Page not found)` 페이지가 없어졌어요. -![Post detail page][7] +![Post detail page](images/post_detail2.png) 야호! 잘 되네요! -## 한 가지만 더: 배포하세요! +## 한 가지만 더 합시다. 배포하세요! -PythonAnywhere에서도 웹사이트가 잘 작동하는지 봐야겠죠? 다시 한 번 배포해봅시다. +PythonAnywhere에도 웹사이트가 잘 작동하는지 봐야겠죠? 다시 한 번 배포합시다. +{% filename %}command-line{% endfilename %} ``` $ git status $ git add --all . @@ -168,27 +174,15 @@ $ git status $ git commit -m "Added view and template for detailed blog post as well as CSS for the site." $ git push ``` +* 그 다음 [PythonAnywhere Bash console](https://www.pythonanywhere.com/consoles/)을 여세요. -* 그 다음 [PythonAnywhere Bash console][8]을 여세요: - +{% filename %}command-line{% endfilename %} ``` $ cd my-first-blog -$ source myvenv/bin/activate -(myvenv)$ git pull -[...] -(myvenv)$ python manage.py collectstatic +$ git pull [...] ``` -* 마지막으로 [웹 탭(Web tab)][9]에서 **다시 불러오기(Reload)** 를 누르세요. - -이제 배포가 완료 되었어요. 잘 작동되는지 확인해 보세요! 축하합니다. :) +* 마지막으로 [Web tab](https://www.pythonanywhere.com/web_app_setup/)에서 **Reload(다시 불러오기)** 를 누르세요. - [2]: images/attribute_error2.png - [3]: images/does_not_exist2.png - [4]: images/404_2.png - [5]: images/post_list2.png - [6]: images/template_does_not_exist2.png - [7]: images/post_detail2.png - [8]: https://www.pythonanywhere.com/consoles/ - [9]: https://www.pythonanywhere.com/web_app_setup/ +배포를 마쳤습니다. 잘 작동되는지 확인해 보세요! 축하합니다. diff --git a/ko/extend_your_application/images/404_2.png b/ko/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/ko/extend_your_application/images/404_2.png and b/ko/extend_your_application/images/404_2.png differ diff --git a/ko/extend_your_application/images/attribute_error2.png b/ko/extend_your_application/images/attribute_error2.png index 6edcd9933c3..33a3b36b1d3 100644 Binary files a/ko/extend_your_application/images/attribute_error2.png and b/ko/extend_your_application/images/attribute_error2.png differ diff --git a/ko/extend_your_application/images/does_not_exist2.png b/ko/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/ko/extend_your_application/images/does_not_exist2.png and b/ko/extend_your_application/images/does_not_exist2.png differ diff --git a/ko/extend_your_application/images/no_reverse_match2.png b/ko/extend_your_application/images/no_reverse_match2.png index 306926206f8..aba1c9c8980 100644 Binary files a/ko/extend_your_application/images/no_reverse_match2.png and b/ko/extend_your_application/images/no_reverse_match2.png differ diff --git a/ko/extend_your_application/images/post_detail2.png b/ko/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/ko/extend_your_application/images/post_detail2.png and b/ko/extend_your_application/images/post_detail2.png differ diff --git a/ko/extend_your_application/images/post_list2.png b/ko/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/ko/extend_your_application/images/post_list2.png and b/ko/extend_your_application/images/post_list2.png differ diff --git a/ko/extend_your_application/images/template_does_not_exist2.png b/ko/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/ko/extend_your_application/images/template_does_not_exist2.png and b/ko/extend_your_application/images/template_does_not_exist2.png differ diff --git a/ko/how_the_internet_works/README.md b/ko/how_the_internet_works/README.md index f7c37d237c7..fd57199cf07 100755 --- a/ko/how_the_internet_works/README.md +++ b/ko/how_the_internet_works/README.md @@ -1,53 +1,45 @@ # 인터넷은 어떻게 작동할까요 -> 이번 장은 Jessica McKellar의 "How the internet works" 에서 영감을 받아 작성되었습니다. (http://web.mit.edu/jesstess/www/) +> **Note** 이번 장은 Jessica McKellar의 글 ["How the internet works"](http://web.mit.edu/jesstess/www/)을 기초로 작성되었습니다. -우리는 매일 인터넷을 사용하고 있어요. 하지만 브라우저 주소창에 https://djangogirls.org 를 입력하고 `엔터`키를 누르면 어떤 일이 일어나는지 혹시 알고 있었나요? +우리는 매일 인터넷을 사용합니다. 그러나 브라우저 주소창에 [http://djangogirls.org](http://djangogirls.org)를 입력하고 `엔터`키를 누르면 어떤 일이 일어나는지 알고 있나요? -먼저 알아야 할 것은 웹사이트란 하드 디스크에 저장된 파일묶음이라는 거에요. 동영상, 음악, 사진 파일처럼요. 웹사이트가 다른 파일과 다른 점은 HTML이라는 컴퓨터 코드가 들어있다는 것이에요. +웹 사이트란 동영상, 음악, 사진 파일처럼 하드 디스크에 저장된 파일묶음과 같습니다. 웹 사이트가 일반 파일과 다른 점은 HTML이라는 프로그래밍 코드가 들어있다는 것이에요. -만약 프로그래밍에 익숙하지 않다면, HTML을 이해하는 게 어려울 수도 있어요. 하지만 브라우저들(크롬, 사파리, 파이어폭스 같은 것들요) 은 HTML을 사랑한답니다. 웹 프라우저는 코드를 이해하고 지시에 따르고, 내가 원하는 방식으로 정확하게 구현될 수 있도록 설계되었어요. +프로그래밍에 익숙하지 않은 분이라면, HTML을 이해하기 어려울 수도 있어요. 하지만 브라우저들(크롬, 사파리, 파이어폭스)은 HTML을 사랑한답니다. 웹 브라우저는 코드를 이해하고 지시에 따라 정확하게 구현되도록 설계되었어요. -다른 파일처럼 HTML 파일도 하드 디스크 어딘가에 저장해야합니다. 인터넷에선 *서버* 라는 특별하고 강력한 컴퓨터를 사용해요. 데이터를 저장하고 제공하는 것이 주된 목적이기 때문에 모니터나 마우스, 키보드가 필요없지요. 데이터를 *제공(serve)* 하는 일을 하기 때문에 *서버(server)* 라고 부릅니다. +다른 파일처럼 HTML도 하드 디스크 어딘가에 저장해야 합니다. 인터넷에선 *서버*라는 특별하고 강력한 컴퓨터를 사용합니다. 데이터를 저장하고 제공하는 것이 주된 목적이기 때문에 모니터나 마우스, 키보드가 필요 없지요. 데이터를 *제공(serve)*하는 일을 하므로 *서버(server)*라고 부릅니다. -그래요, 하지만 인터넷이 어떻게 생겼는지 궁금하지 않나요? +인터넷은 어떻게 생겼을지 궁금하죠? -그림을 그려봤습니다. 이렇게 생겼어요. : +여러분들의 이해를 돕기 위해 그림을 그려봤어요! -![그림 1.1][1] +![Figure 1.1](images/internet_1.png) - [1]: images/internet_1.png +조금 지저분해 보이죠? 사실 인터넷은 수 많은 기계들이 연결된(앞서 얘기한 *서버* 라는) 하나의 네트워크랍니다. 수백, 수천 대의 기계들이요! 긴, 아주 긴 케이블들이 지구 전체를 둘러싸고 있답니다! 해저 케이블 지도 사이트 (http://submarinecablemap.com/) 에 가보면 케이블이 얼마나 복잡하게 연결되어있는지 알 수 있어요. 아래 사진은 웹사이트에서 가져온 스크린 샷입니다. -조금 지저분해 보이죠? 사실 인터넷은 수 많은 기계들이 연결된(앞서 얘기한 *서버* 라는) 의 하나의 네트워크랍니다. 수백, 수천 대의 기계들이요! 긴, 아주 긴 케이블들이 지구 전체를 둘러싸고 있답니다! 해저 케이블 지도 사이트 (http://submarinecablemap.com/)에 가보면 케이블이 얼마나 복잡하게 연결되어있는지 알 수 있어요. 아래 사진은 웹사이트에서 가져온 스크린 샷입니다. +![Figure 1.2](images/internet_3.png) -![그림 1.2][2] - - [2]: images/internet_3.png - -멋지지 않나요? 그러나 인터넷에 연결되어 있는 모든 기계들을 전부 연결하는 것은 불가능한 일입니다. 그래서 어떤 기계(예를 들어 https://djangogirls.org 이 저장되어 있는 것 같은)에 도달하기 위해서는 수없이 많은 다른 기계들을 통과해야 한답니다. +멋지지 않나요? 그러나 인터넷에 연결된 모든 기계 전부 연결하는 것은 불가능한 일입니다. 그래서 특정한 기계(예를 들어 https://djangogirls.org 가 저장되었다면)에 도달하기 위해서는 수없이 많은 다른 기계들을 통과해야 한답니다. 그림으로 보면 다음과 같습니다. -![그림 1.3][3] - - [3]: images/internet_2.png - -주소창에 https://djangogirls.org 을 입력하는 건, "사랑하는 장고 걸즈 여러분, 저는 장고걸즈 웹사이트를 보고 싶어요. 저에게 그 웹 사이트를 보여주세요!"라고 편지를 써서 보내는 것과 같아요. +![Figure 1.3](images/internet_2.png) -이 편지는 나와 가장 가까이에 있는 동네 우체국으로 갑니다. 받을 사람에게 가까운 다른 우체국으로, 다른 우체국으로 전달되면서 주소지에 최종 도착하게 됩니다. 특이한 점은 같은 장소에서 많은 양의 편지(*데이터 패킷*을 보내면, 각기 다른 우체국(*라우터*) 을 통해 전달됩니다. 또 우체국마다 배포되는 방법이 다르지요. +주소창에 https://djangogirls.org 을 입력하는 건, "사랑하는 장고걸스 여러분, 저는 장고걸스 웹사이트를 보고 싶어요. 저에게 그 웹 사이트를 보여주세요!"라고 편지를 써서 보내는 것과 같아요. -![그림 1.4][4] +이 편지는 나와 가장 가까이에 있는 동네 우체국으로 갑니다. 받을 사람에게 가까운 다른 우체국으로, 다른 우체국으로 전달되어 주소지에 최종 도착하게 됩니다. 특별한 점은 같은 장소에서 많은 양의 편지(*데이터 패킷*)을 보내면, 각기 다른 우체국(*라우터*)를 통해 전달된다는 것입니다. 또 우체국마다 전달되는 방법이 다르지요. - [4]: images/internet_4.png +![Figure 1.4](images/internet_4.png) 맞아요, 간단해요. 메시지를 보내고 답장을 기다리는 거죠. 물론 종이랑 펜 대신 몇 바이트의 데이터를 사용하는 것이지만, 기본 개념은 같답니다! -그리고 도로명과 도시이름, 우편번호를 쓰는 대신 IP주소라는 것을 써야해요. 컴퓨터는 먼저 DNS(도메인 주소 시스템)에게 djangogirls.org 의 IP주소가 무엇인지 물어봅니다. 전화주소록에서 연락하고 싶은 대상의 이름을 찾아 전화번호와 주소를 찾아내는 방법과 비슷하지요. +그리고 도로명과 도시 이름, 우편번호를 쓰는 대신 IP주소라는 것을 써야 해요. 컴퓨터는 먼저 DNS(도메인 주소 시스템)에 djangogirls.org IP주소가 무엇인지 물어봅니다. 전화주소록에서 연락하고 싶은 대상의 이름을 찾아 전화번호와 주소를 찾아내는 방법과 비슷하지요. -편지를 보낼 때는 몇가지 규칙을 지켜야 제대로 배달되어요. 주소가 적혀있어야 하고, 우표가 있어야 해요. 수령인이 이해할 수 있는 언어로 적혀져야하구요. 그렇죠? 이처럼 *데이터 패킷*에도 동일하게 적용되어야 웹사이트를 볼 수 있습니다. 우리는 HTTP (하이퍼텍스트 전송 프로토콜) 라는 프로토콜을 사용합니다. +편지를 보낼 때 규칙을 지켜야 제대로 배달되어요. 주소가 적혀있어야 하고, 우표가 있어야 해요. 수령인이 읽을 수 있는 언어로 작성되어야 하고요. 이처럼 *데이터 패킷*에도 같이 적용되어야 웹사이트를 볼 수 있습니다. 우리는 HTTP(Hypertext Transfer Protocol: 하이퍼텍스트 전송 프로토콜)라는 프로토콜을 사용합니다. -따라서 기본적으로 웹사이트를 만들려면 그 웹사이트가 동작할 *서버* (기계) 가 필요해요. *서버*에서 *요청*(편지) 을 받으면, 다시 웹사이트(다른 편지) 로 되돌려줍니다. +이처럼 기본적으로 웹 사이트를 만들려면 그 웹 사이트가 동작할 *서버*(기계)가 필요합니다. *서버*에서 *요청*(편지)을 받으면, 다시 웹 사이트(다른 편지)로 되돌려줍니다. -장고 튜토리얼을 시작할 때부터, 장고가 무슨 일을 하는지 궁금하셨죠? 여러분이 답장을 보낼 때, 모든 사람에게 항상 동일한 내용을 보내고 싶지 않을 거에요. 받는 사람에 따라 각각 다른 답장을 보내면 더 좋지 않을까요? 이와 같이 장고는 맞춤형 편지를 보낼 수 있도록 도와준답니다. :) +장고걸스 튜토리얼을 시작할 때부터, 장고가 무슨 일을 하는지 궁금하셨죠? 답장 전송 시 모든 사람이 같은 내용을 받는 것이 아니라, 받는 사람마다 각각 다른 답장을 보내면 더 좋지 않을까요? 이처럼 장고는 각 사용자에게 맞춤형 편지를 보낼 수 있게 도와준답니다. :) -이제 수다는 그만하고, 정말 뭔가 만들어 보자구요! +이제 수다는 그만하고, 정말 뭔가 만들어 보자고요! diff --git a/ko/how_the_internet_works/images/internet_1.png b/ko/how_the_internet_works/images/internet_1.png index 9c5bcf0b003..e289eac2b23 100644 Binary files a/ko/how_the_internet_works/images/internet_1.png and b/ko/how_the_internet_works/images/internet_1.png differ diff --git a/ko/how_the_internet_works/images/internet_2.png b/ko/how_the_internet_works/images/internet_2.png index dd5861f376f..e8cf8b77999 100644 Binary files a/ko/how_the_internet_works/images/internet_2.png and b/ko/how_the_internet_works/images/internet_2.png differ diff --git a/ko/how_the_internet_works/images/internet_3.png b/ko/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/ko/how_the_internet_works/images/internet_3.png and b/ko/how_the_internet_works/images/internet_3.png differ diff --git a/ko/how_the_internet_works/images/internet_4.png b/ko/how_the_internet_works/images/internet_4.png index 2661cec1b61..aeb95a91164 100644 Binary files a/ko/how_the_internet_works/images/internet_4.png and b/ko/how_the_internet_works/images/internet_4.png differ diff --git a/ko/html/README.md b/ko/html/README.md index db9c62f970f..d5c61a1bcfe 100755 --- a/ko/html/README.md +++ b/ko/html/README.md @@ -1,209 +1,209 @@ # HTML 시작하기 -템플릿이 무엇인지 궁금하셨죠? +템플릿은 어떤 일을 하는지 궁금했죠? -템플릿이란 서로 다른 정보를 일정한 형태로 표시하기 위해 재사용 가능한 파일이예요. 예를 들면 편지를 쓸때도 템플릿을 사용할 수 있어요. 편지의 내용이나 수신인 주소는 달라져도 동일한 디자인, 레이아웃을 사용하는 경우가 있으니까요. +템플릿이란 서로 다른 정보를 일정한 형태로 표시하기 위해 재사용 가능한 파일을 말해요. 예를 들면 편지에도 같은 템플릿을 사용할 수 있어요. 편지의 내용이나 수신인 주소는 달라져도 같은 디자인, 레이아웃을 사용하는 때도 있으니까요. -장고의 템플릿 양식은 HTML을 사용합니다. (HTML은 첫 번째 장 **인터넷은 어떻게 작동할까요** 에서 들어봤죠) +장고 템플릿 양식은 HTML을 사용합니다. (HTML은 인터넷은 어떻게 작동할까요에서 들어본 내용이죠) ## HTML이란 무엇일까요? -HTML은 크롬이나 파이어폭스, 사파리같은 웹브라우저가 해석할 수 있는 간단한 코드예요. 사용자에게 웹페이지를 표시할 때 사용해요. +HTML은 크롬이나 파이어폭스, 사파리 같은 웹 브라우저가 해석할 수 있는 간단한 코드예요. 사용자에게 웹 페이지를 표시할 때 사용합니다. -HTML은 "HyperText Markup Language"의 줄인 말입니다. **하이퍼텍스트(HyperText)** 는 텍스트인데 페이지간에 하이퍼링크를 담을 수 있다는 뜻이예요. **마크업(Markup)** 이란 누군가에게(여기서는 브라우저) 문서를 해석하는 방법을 표시(mark)를 했다는 뜻이에요. HTML 코드는 **태그(tag)** 들로 이루어져있어요. 태그는 `<` 로 시작하고 `>`로 끝나요. 이런 태그들은 마크업 **요소(elements)** 를 나타냅니다. +HTML은 "HyperText Markup Language"의 줄임말로, __하이퍼텍스트(HyperText)__ 는 페이지 간 하이퍼링크가 포함된 텍스트라는 뜻입니다. **마크업(Markup)** 이란 누군가(브라우저)가 문서를 해석하도록 표시(mark)를 했다는 뜻이에요. HTML은 **태그(tag)** 들로 이루어져 있어요. 태그는 `<(여는 태그)` 로 시작하고 `>(닫는 태그)`로 끝나는데, 이는 마크업 **요소(elements)** 를 말합니다. -## 첫번째 템플릿! +## 첫 번째 템플릿! -템플릿을 만드는 것은 템플릿 파일을 만든다는 뜻이예요. 모든 것은 파일에 저장되겠죠? 이미 눈치챘을 것 같군요. +템플릿은 곧 템플릿 파일을 만든다는 뜻이에요. 템플릿 파일에 모든 내용이 저장되겠죠? 이미 알고 있을 것 같아요. -템플릿은 `blog/templates/blog` 디렉토리에 저장됩니다. 그러니까 먼저 블로그 디렉토리에 `templates` 디렉토리를 생성해야해요. 그리고, 템플릿 디렉토리에 `blog` 라는 디렉토리를 만드세요. +템플릿은 `blog/templates/blog`디렉토리에 저장됩니다. 먼저 `blog`디렉터리 안에 하위 디렉터리인 `templates`을 생성하세요. 그리고 `template`디렉토리 내 `blog`라는 하위 디렉토리를 생성하세요. - blog - └───templates - └───blog - - -(왜 `blog` 디렉토리를 하나 더 만들어야하는지 궁금할 거에요. 나중에 알게 되겠지만, 작업이 좀더 복잡해질 때 편하게 만들기 위해 사용하는 관습같은 거에요.) +``` +blog +└───templates + └───blog +``` -다음 `blog/templates/blog` 디렉토리에 `post_list.html` (비어있는) 파일을 만드세요. +(왜 똑같은 `blog`디렉토리를 하나 더 만들어야하는지 궁금할 거에요. 나중에 알게 되겠지만, 나중에 폴더 구조가 복잡해 질 때 좀더 쉽게 찾기 위해 사용하는 관습적인 방법이랍니다) -웹사이트를 확인해보세요. : http://127.0.0.1:8000/ +다음 `blog/templates/blog`디렉토리 안에 `post_list.html`이라는 새 파일(현재는 빈 파일)을 만드세요. -> 여전히 `TemplateDoesNotExists` 에러가 나온다면, 웹 서버를 다시 시작하세요. 커맨드라인(혹은 콘솔창)으로 가서 Ctrl + C를 눌러 웹 서버 작동을 멈춥니다. 그런 후 다시 `python manage.py runserver` 명령을 실행해 서버를 재시작합니다. +그리고 웹 사이트를 확인해보세요. http://127.0.0.1:8000/ -![그림 11.1][1] +> `TemplateDoesNotExists`에러가 보인다면, 웹 서버를 다시 시작하세요. 커맨드라인(혹은 콘솔)으로 가서 `Ctrl + C`를 눌러 웹 서버를 중단합니다. 다시 `python manage.py runserver`명령을 실행해 서버를 재시작합니다. - [1]: images/step1.png +![Figure 11.1](images/step1.png) -이제 에러가 사라졌어요! 축하합니다. :) 하지만 웹사이트가 비어있어 아무 내용도 보여지지 않네요. 이제 고쳐나가 봅시다. +이제 에러가 사라졌어요! 축하합니다. 하지만 웹 사이트에 아무것도 보이지 않네요. 이제 하나씩 고쳐나가 봅시다. -템플릿 파일 post_list.html에 아래 내용을 넣어주세요. : +`post_list.html`템플릿 파일에 아래 내용을 넣어주세요. +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - -

Hi there!

-

It works!

- + +

Hi there!

+

It works!

+ ``` -웹 사이트가 어떻게 보이나요? 확인해보세요. : http://127.0.0.1:8000/ +웹 사이트가 어떻게 보이나요? 확인해보세요. http://127.0.0.1:8000/ -![그림 11.2][2] +![Figure 11.2](images/step3.png) - [2]: images/step3.png +잘 작동하네요! 잘 했습니다. -잘 작동하네요! 잘 했습니다. :) - -* 모든 웹 페이지는 ``로 시작해서 ``로 끝나게 됩니다. 가장 기본적인 태그이지요. 웹사이트의 모든 내용은 시작 태그 ``과 닫는 태그인`` 사이에 넣어야만 합니다. -* `

`는 문단 태그입니다. 문단의 끝은 `

`로 닫습니다. +* 모든 웹 페이지는 ``로 시작해 ``로 마칩니다. 가장 기본적인 태그이지요. 모든 내용은 시작 태그 ``과 닫는 태그인`` 사이에 넣어야합니다. +* `

`는 문단 태그입니다. 문단의 끝 역시 `

`로 닫습니다. ## Head & body -각 HTML 페이지는 두 가지 요소, **head** 와 **body** 로 구분됩니다. +각 HTML 페이지는 두 가지 요소, **head**와 **body**로 구분됩니다. -* **head** 는 문서에 대한 정보를 담고 있지만 이 정보는 화면에 직접적으로 보여지 않습니다. +*  **head** 는 문서 정보를 가지고 있지만, 웹 페이지에서 보이지 않는 정보들을 담는 영역입니다. -* **body** 는 웹사이트에 보여지는 모든 내용을 담고 있습니다. +*  **body** 란 웹 페이지에 직접적으로 보이는 내용이 들어갑니다. 웹 페이지의 내용은 모두 이 body태그안에 들어갑니다. ``는 브라우저에 페이지에 대한 설정들을 알려주고, ``는 실제 페이지에 보여줄 내용을 알려줍니다. -그 예로, `` 안에 웹페이지의 제목을 넣어봅시다. : - +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - - - Ola's blog - - -

Hi there!

-

It works!

- - + + + Ola's blog + + +

Hi there!

+

It works!

+ + ``` -파일을 저장하고 페이지를 새로고침 해보세요. +파일을 저장하고 페이지를 새로고침 하세요. -![그림 11.3][3] +![Figure 11.3](images/step4.png) - [3]: images/step4.png +브라우저는 어떻게 "Ola's blog"를 웹 페이지의 제목으로 이해했을까요? 바로 브라우저가 `Ola's blog`를 해석해 브라우저 제목 표시줄에 내용을 반영한 것입니다. (해당 페이지를 북마크를 할 때도 동일합니다) -브라우저가 어떻게 "Ola's blog"를 웹 페이지의 제목으로 이해했을까요? 바로 브라우저가 `Ola's blog`를 해석해 브라우저 제목 표시줄에 내용을 반영한 것입니다. (북마크를 할 때도 이렇게 사용됩니다.) +태그는 `/`로*태그 마침*하고 여러 태그를 *중첩(nested)*해서 사용할 수 있습니다. (모든 태그를 꼭 닫아줘야합니다) -태그는 `/`로*태그 마침*하고 *중첩(nested)* 해서 사용할 수 있습니다. (모든 태그가 닫힐 때까지 특정 태그 하나만 닫을 수 없습니다.) +태그는 상자에 뭔가 집어넣는 것과 같아요. ``라고 하는 큰 상자가 있다면, 상자 안에는 `` 상자가 있고, 또 그 상자 안에는 `

`라는 더 작은 상자가 있는 것과 같아요. -이 개념은 박스에 뭔가 집어 넣는 것과 같아요. 여러분에게 ``라고 하는 큰 박스가 있습니다. 박스 안에는 `` 박스가 있고, 또 그 박스 안에는 `

`라는 더 작은 박스들이 있는 것이죠. - -*태그 마침* 과 *중첩* 의 규칙을 잘 따라야 해요. 그렇지 않으면, 브라우저가 해석을 할 수 없어, 페이지가 원하는 모습으로 나오지 않게 됩니다. +*태그 마침*과 *중첩*의 규칙을 잘 따라야 해요. 그렇지 않으면, 브라우저가 해석할 수 없어 페이지가 원하는 모습으로 나오지 않게 됩니다. ## 맞춤형 템플릿 만들기 -여러분은 이제 좀 더 재밌어질 것입니다. 여러분만의 템플릿을 만들어봅시다! 여기 몇 가지 유용한 태그들이 있습니다. : +앞으로 좀 더 재밌어질 거에요. 나만의 템플릿을 만들어 볼 거에요! 아래 태그들을 짚고 넘어가세요. -* `

A heading

` - 가장 중요한 머리말에 사용하는 태그 -* `

A sub-heading

` 그 다음 수준의 머리말에 사용하는 태그 -* `

A sub-sub-heading

` ... 그 다음 머리말.. `
` 까지 계속 수준이 낮아집니다. -* `text` 텍스트를 강조할 때 사용하는 태그 -* `text` 여러분의 텍스트를 강력하게 강조할 때 사용하는 태그 -* `
` 개행. 행을 내누기(br 태그 안에는 속성으로 아무 것도 넣을 수 없습니다.) -* `link` 링크 걸기 -* `
  • first item
  • second item
` 목록을 만듭니다. 지금 여러분이 보고 있는 목록처럼요! -* `
` 페이지의 섹션을 정의합니다. +* `

A heading

` - 큰 제목 +* `

A sub-heading

` - 중 제목 +* `

A sub-sub-heading

` - 소 제목... `
`레벨까지 사용할 수 있습니다. +* `text` - 텍스트 기울기 (Italic) +* `text` - 텍스트를 두껍게(Bold) +* `
` - 줄바꿈 (br은 스스로 닫히는 태그로 속성을 사용할 수 없습니다) +* `link` - 하이퍼링크 걸기 +* `
  • first item
  • second item
`- 목록 만들기 +* `
` - 페이지 섹션 -여기에 완전한 템플릿 예제가 있습니다. : +아래 템플릿 예제가 있습니다. +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - - - 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.

-
- - + + + 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`(문단)의 하나는 날짜를, 다른 하나는 블로그를 위한 거에요. - -이 태그들로 이렇게 변합니다. : +* 첫 번째 `div`는 블로그 제목을 가지고 있어요. 머리말과 링크이지요. +* 나머지 두 `div`는 블로그 게시일과 `h2`로 된 블로그 제목과 링크를가 있습니다. 두 `p(문단)`의 하나는 날짜를, 다른 하나는 블로그를 가리키죠. -![그림 11.4][4] +태그로 웹 페이지 화면이 아래와 같이 바뀝니다. - [4]: images/step6.png +![Figure 11.4](images/step6.png) -야호! 지금까지 만든 우리 템플릿은 계속 **같은 내용**만 보여주었죠. 그러나 앞에서 템플릿은 **같은 양식**을 사용하지만 **다른** 정보들을 보여줄 때 사용한다고 말했었죠.. +야호! 이전 템플릿은 **동일한 내용** 만을 보여줬어요. 이처럼 템플릿은 **같은 양식** 을 사용하지만, **다른** 정보들을 보여줄 때 사용됩니다. -장고 관리자에서 실제 추가한 글들을 보여주는 방법은 앞으로 배우게 될 거에요. +장고 관리자에서 추가한 글을 보여주는 방법은 곧 알아볼 거에요. ## 하나 더: 배포하기! -방금 작업했던 것이 인터넷에서도 볼 수 있으면 좋겠죠? PythonAnywhere으로도 배포해 봅시다. : - -### Github에 코드를 커밋, 푸시하세요! - -제일 먼저, 마지막 배포 이후 수정된 파일을 확인해 봅시다. (PythonAnywhere가 아닌 로컬에서 실행하세요.) : - - $ git status - +방금 고친 내용을 인터넷에서도 봐야겠죠? PythonAnywhere으로도 배포해 봅시다. -`djangogirls` 디렉토리에서 `git`에게 현재 폴더에 있는 모든 변경 내용을 포함라고 말합니다. +### GitHub에 코드를 커밋, 푸시하세요! - $ git add --all . +제일 먼저, 마지막 배포 이후 수정된 파일을 확인해 봅시다. (PythonAnywhere가 아닌 로컬에서 실행하세요) +{% filename %}command-line{% endfilename %} +``` +$ git status +``` -> **Note** `-A` ("all"의 축약어) 는 `git`이 삭제한 파일을 인식합니다. (기본적으로, 새로 추가하거나 변경한 파일만 인지합니다.) 또한 `.`의미가 현재 디렉토리라는 것을 기억하고 있죠? (3장에서 언급한 내용이에요.) +`djangogirls` 디렉터리에서 `git`에게 현재 폴더에 있는 모든 변경 내용을 포함시키라고 말해봅시다. -파일 업로드 전, `git`으로 업로드 할 파일들을 확인해봅시다. (`git`에서 업로드 할 모든 파일들이 녹색으로 나타나야 합니다.) : +{% filename %}command-line{% endfilename %} +``` +$ git add --all . +``` - $ git status +> **Note** `-A` ("all"의 축약어)는 `git`이 삭제한 파일을 인식합니다. (기본적으로, 새로 추가하거나 변경한 파일만 인식합니다) `.`가 현재 디렉터리라는 것을 기억하고 있죠? (3장에서 언급한 내용이에요) +파일 업로드 전, `git`으로 업로드 할 파일들을 확인해봅시다. (`git`에서 업로드 할 모든 파일들은 녹색으로 표시됩니다) -거의 다 왔습니다. 이제 저장소에 변경 사항을 저장할 단계예요. 우리는 "커밋 메시지(commit message)"를 주어, 어떤 것이 수정 변경되었는지 알려줄 거에요. 이번에는 아무거나 적어도 괜찮습니다. 하지만 앞으로는 내가 수정한 내용을 간략하게 적어 다음에 기억할 수 있도록 하는 것이 좋을 거에요. +{% filename %}command-line{% endfilename %} +``` +$ git status +``` - $ git commit -m "Changed the HTML for the site." +거의 다 왔습니다. 이제 github 저장소에 변경 사항을 히스토리에 저장할 단계예요. `커밋 메시지(commit message)`를 입력해, 수정 변경된 내용을 알려줄 거에요. 메시지 내용은 아무거나 적어도 되지만, 나중에 작업 내용을 기억할 수 있도록 설명 내용을 간단히 입력하는 것이 좋습니다. +{% filename %}command-line{% endfilename %} +``` +$ git commit -m "Changed the HTML for the site." +``` -> **Note** 커밋 메시지는 쌍따옴표(")로 감싸주세요. +> **Note** 커밋 메시지를 쌍따옴표(")로 감싸주세요. -완성되면, Github으로 업로드(푸쉬) 하세요. : +완성되면, github으로 업로드(푸쉬) 하세요. - git push +{% filename %}command-line{% endfilename %} +``` +$ git push +``` ### PythonAnywhere에서 새 코드를 가져와, 웹 앱을 다시 불러옵니다. -* [PythonAnywhere 콘솔 페이지][5]를 열고 **배시 콘솔** (또는 새로운 창)을 준비합니다. 그 다음, 명령어를 입력합니다. : - - [5]: https://www.pythonanywhere.com/consoles/ - - $ cd ~/my-first-blog - $ source myvenv/bin/activate - (myvenv)$ git pull - [...] - (myvenv)$ python manage.py collectstatic - [...] +* [PythonAnywhere 콘솔 페이지](https://www.pythonanywhere.com/consoles/)를 열고 **배시 콘솔** (또는 새로운 창)에서 아래와 같이 명령어를 입력합니다. +{% filename %}command-line{% endfilename %} +``` +$ cd ~/my-first-blog +$ git pull +[...] +``` -그러면 코드가 다운되는 것을 볼 수 있어요. 다 되었는지 확인하고 싶으면 **파일 탭(Files tab)**에 가서 내 코드가 PythonAnywhere에 있는지 확인합니다. - -* 마지막으로 [웹 탭(Web tab)][6]으로 가서 여러분의 웹 앱을 **다시 불러오기** 하세요. +코드가 다운되고 있죠? 다 되었는지 확인하고 싶으면 **파일 탭(Files tab)**에 가서 내 코드가 PythonAnywhere에 있는지 확인합니다. - [6]: https://www.pythonanywhere.com/web_app_setup/ +* 마지막으로 [Web tab](https://www.pythonanywhere.com/web_app_setup/)으로 가서 웹 앱을 **다시 불러오기(Reload)**를 하세요. -인터넷에도 업데이트 되었네요! 브라우저로 가서 웹사이트를 새로고침하세요. 변경한 내용들이 보일 거에요. :) +인터넷에도 업데이트 되었어요! 브라우저를 새로고침하면 변경된 내용을 확인할 수 있어요. 변경한 내용이 보일 거에요. :) diff --git a/ko/html/images/step1.png b/ko/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/ko/html/images/step1.png and b/ko/html/images/step1.png differ diff --git a/ko/html/images/step3.png b/ko/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/ko/html/images/step3.png and b/ko/html/images/step3.png differ diff --git a/ko/html/images/step4.png b/ko/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/ko/html/images/step4.png and b/ko/html/images/step4.png differ diff --git a/ko/html/images/step6.png b/ko/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/ko/html/images/step6.png and b/ko/html/images/step6.png differ diff --git a/ko/images/application.png b/ko/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/ko/images/application.png and b/ko/images/application.png differ diff --git a/ko/installation/README.md b/ko/installation/README.md index 1afda107099..52cd67e4252 100755 --- a/ko/installation/README.md +++ b/ko/installation/README.md @@ -1,49 +1,49 @@ # 집에서 튜토리얼을 보시는 분들에게 -[장고 걸스 이벤트](https://djangogirls.org/events/)가 아닌 집에서 튜토리얼을 자습하시는 분들은 이 장을 건너뛰고 [인터넷은 어떻게 작동할까요?](../how_the_internet_works/README.md) 부터 읽으세요. +[장고걸스 워크샵](http://djangogirls.org/events/)이 아닌 집에서 튜토리얼을 학습하는 분들은 이 장을 건너뛰고 [인터넷은 어떻게 작동할까요](../how_the_internet_works/README.md)부터 읽으세요. -이번 장에는 설치와 관련된 모든 내용을 모았습니다. 장고 걸스 이벤트에서는 워크샵 사전에 설치과정을 완벽하게 마치는 '설치의 밤'이 있습니다. 워크샵 중간 중간에 설치 문제로 진행에 어려움을 겪지 않게 하기 위해서지요. +이번 장에는 설치와 관련된 모든 내용을 모두 모았습니다. 장고걸스 워크샵은 행사 전날, '설치의 밤'에서 모든 프로그램을 설치하고 개발환경을 준비하는 시간이 준비되어 있습니다. 워크샵 중간에 설치 문제로 진행에 어려움을 겪지 않게 하기 위해서지요. -이 방법이 괜찮다면, 컴퓨터에 먼저 모든 설치를 끝내고 내용을 따라가도 좋습니다. 혹은 먼저 학습을 시작하고 싶다면 이번 장을 넘기세요. 뒷 부분에서도 설치 방법에 대해 다룹니다. +컴퓨터에 먼저 모든 설치를 끝내고 내용을 따라가도 좋고, 설치 부분을 건너뛰고 먼저 학습을 시작해도 됩니다. 튜토리얼 뒷부분에서도 설치 방법에 대해 다룹니다. 모두 행운을 빌어요! # 설치하기 -우리는 워크샵에서 블로그를 완성할 거에요. 워크샵 사전에 몇 가지 설치를 끝낸다면, 하루 종일 코딩할 준비가 된 거랍니다. +우리는 워크숍 하루 동안 나만의 블로그를 완성해 볼거에요. 워크숍 사전에 모든 설치가 완벽하게 끝냈다면, 온종일 코딩할 준비가 된 거랍니다. -# Python 설치하기 + +{% include "/chromebook_setup/instructions.md" %} + +# Python 설치하기 {% include "/python_installation/instructions.md" %} -# virtualenv 설정하고 Django 설치하기 - +# virtualenv 환경 설정 및 Django 설치하기 {% include "/django_installation/instructions.md" %} # 코드 에디터 설치하기 - {% include "/code_editor/instructions.md" %} # Git 설치하기 - {% include "/deploy/install_git.md" %} # GitHub 계정 만들기 - -[GitHub.com](https://www.github.com)에 가서 무료 사용자 계정으로 회원가입을 하세요. +[GitHub.com](http://www.github.com)에서 무료 사용자 계정으로 회원가입을 하세요. # PythonAnywhere 계정 만들기 - {% include "/deploy/signup_pythonanywhere.md" %} -# 코딩 시작 - -축하합니다. 드디어 여러분은 시작할 준비가 되었답니다! 워크샵 전에 튜토리얼의 앞 부분을 미리 읽어두면 시작하는데 도움이 될 거에요. : +# 읽어보기 - * [인터넷은 어떻게 작동할까요?](../how_the_internet_works/README.md) +축하합니다. 드디어 코딩을 시작할 준비가 되었답니다! 워크숍 전에 튜토리얼의 앞 부분을 미리 읽어보세요. - * [커맨드라인(command line) 시작하기](../intro_to_command_line/README.md) +* [인터넷은 어떻게 작동할까요](../how_the_internet_works/README.md) +* [Command line 시작하기](../intro_to_command_line/README.md) +* [Python 시작하기](../python_introduction/README.md) +* [Django란 무엇인가요](../django/README.md) - * [파이썬(python) 시작하기](../intro_to_command_line/README.md) - * [Django란 무엇일까요?](../django/README.md) +# 워크샵 즐기기! +워크샵을 시작하면, 앞 부분의 내용을 모두 읽었다는 가정 하에 바로 [나의 첫 번째 장고 프로젝트!](../django_start_project/README.md) 장부터 할 수 있게 준비해주세요. diff --git a/ko/intro_to_command_line/README.md b/ko/intro_to_command_line/README.md index 9e20fa8ab1d..71a3220215c 100755 --- a/ko/intro_to_command_line/README.md +++ b/ko/intro_to_command_line/README.md @@ -1,54 +1,56 @@ -# Command Line 시작하기 +# 커맨드 라인 시작하기 -재미있을 것 같지 않아요? 조금만 더 하면 여러분은 첫 번째 코드를 쓸 수 있어요 :) +> **Note** 집에서 학습하시는 분들은 ['내 친구 커맨드 라인를 소개합니다'](https://www.youtube.com/watch?v=jvZLWhkzX-8) 영상을 보세요. -**여러분에게 첫 번째 친구를 소개합니다: 바로, 커맨드 라인(command line) 입니다!** +벌써부터 기대되지 않나요? 바로 일 분안에 여러분도 코딩 할 수 있어요! -해커들이 사용하는 까만 윈도우 창을 어떻게 사용하는지 보여드릴 거에요. 처음에는 이 검은색 창이 약간 무서워 보일 수도 있지만, 여러분의 명령어를 기다리는 녀석일 뿐이에요. +**여러분에게 첫 번째 친구를 소개합니다. 바로, 커맨드 라인(command line) 입니다!** -> **Note** 이 설명서에서 '디렉토리(directory)'와 '폴더(folder)'라는 두가지 단어를 사용하지만 둘다 같은 뜻이랍니다. +해커들이 사용하는 까만 윈도우 창을 어떻게 사용하는지 보여드릴 거에요. 처음에는 이 검은색 창이 무서워 보일 수도 있지만, 명령어를 기다리는 아이일 뿐이에요. -## command line이란 무엇일까요? +> **Note** 이 설명서에서 '디렉토리(directory)'와 '폴더(folder)' 모두 같은 뜻입니다. -**커맨드 라인(command line)** 또는 **커맨드-라인 인터페이스(command-line interface)**라고도 불리는 윈도우는 컴퓨터에서의 보기, 처리, 그리고 파일 조작을 위한 텍스트 기반 응용 프로그램입니다. 윈도우 익스플로어나 맥OS의 Finder와 같아요. 하지만 그래픽 인터페이스는 없답니다. 커맨드 라인은 *cmd*, *CLI*, *프롬프트(prompt)*, *콘솔(console)* 혹은 *터미널(terminal)*로 불립니다. +## 커맨드 라인은 무엇일까요? + +**커맨드 라인(command line)**은 **커맨드-라인 인터페이스(command-line interface)**, *cmd*, *CLI*, *프롬프트(prompt)*, *콘솔(console)*, *터미널(terminal)* 라고도 불리는 텍스트 기반 응용 프로그램으로 파일 보기, 처리, 조작이 가능합니다. 윈도우 익스플로러나 맥OS의 파인더와 비슷합니다. 하지만 그래픽 인터페이스는 없어요. ## 커맨드 라인 열기 -커맨드 라인을 열고 몇 가지 실험을 해봅시다. +커맨드 라인을 열어 몇 가지 실습해봅시다. ### 윈도우 시작메뉴로 가서 → 모든 프로그램 → 보조프로그램 → 명령 프롬프트. -### Mac OS X +### macOS 응용 프로그램 → 유틸리티 → 터미널. ### 리눅스 -프로그램 → 보조 프로그램 → 터미널을 실행하면 될 거에요. 하지만 시스템에 따라 다를 수도 있어요. 그럴 때는 구글에서 찾아보세요. :) +프로그램 → 보조 프로그램 → 터미널을 실행하면 될 거에요. 하지만 시스템에 따라 다를 수도 있으니 구글에서 찾아보세요. ## 프롬프트(prompt) 이제 까만 배경이나 하얀 배경의 윈도우가 뭔가를 지시해주길 기다리고 있을 거에요. -맥이나 리눅스의 경우, 이런 `$` 기호가 보일 거예요. : +맥이나 리눅스의 경우, 이런 `$` 기호가 보일 거예요 : $ -윈도우의 경우, 이런 `>` 기호가 보일 거에요. : +윈도우의 경우, 이런 `>` 기호가 보일 거에요 : > -각각의 명령어는 접두어로 위와 같은 기호와 공백 한 칸이 붙습니다. 하지만 여러분이 입력할 필요는 없어요. 컴퓨터가 대신 해줄 거예요 :) +각 명령어는 접두어로 위와 같은 기호와 공백 한 칸이 붙습니다. 하지만 여러분이 입력할 필요는 없어요. 컴퓨터가 대신 해줄 거예요 :) -> 잠깐만요 : 상황에 따라 프롬트 기호 앞에 `C:\Users\ola>` 혹은 `Olas-MacBook-Air:~ ola$` 같은 것이 보일 수 있는데, 문제가 있는 것이 아니라 아주 잘 동작하는 거랍니다. 이 튜토리얼에서는 제일 간단한 형태로 표시하는 거예요. +> 잠깐만요 : 상황에 따라 프롬트 기호 앞에 `C:\Users\ola>` 혹은 `Olas-MacBook-Air:~ ola$` 같은 것이 보일 수 있는데, 문제가 있는 것이 아니라 아주 잘 동작하는 거랍니다. 이 튜토리얼에서는 간략히 작성한 거에요. ## 나의 첫 번째 명령 (야호!) -쉬운 것 부터 시작할게요. 아래 명령어를 입력해 보세요. : +쉬운 것 부터 시작할게요. 아래 명령어를 입력해 보세요 : $ whoami @@ -58,43 +60,47 @@ > whoami -그리고 `enter`를 누르세요. 다음과 같이 보일 거에요. +그리고 `enter`를 누르세요. 다음과 같이 보일 거에요 : $ whoami olasitarska -컴퓨터는 유저이름을 스크린에 보여줍니다. 이거 좀 괜찮죠? :) +컴퓨터는 사용자 이름을 스크린에 보여줍니다. 이거 좀 괜찮죠? :) -> 복사해서 붙여넣기 하지 말고, 직접 입력해 보세요. 더 잘 외워질 거예요! +> 복사 붙여넣기 하지 말고, 직접 입력해 보세요. 더 잘 외워질 거예요! ## 기본 명령어 각각의 운영체제에 따라, 명령어들이 조금씩 다를 수도 있으니까, 여러분의 운영체제에 해당하는 설명을 따라주세요. 그럼 같이 해볼까요? -### 현재 디렉토리 +### 현재 디렉터리 + +현재 어느 디렉터리에 있는지 확인하려면 아래 명령어를 입력하고 `enter`를 눌러보세요. -우리가 어디쯤 있는지 알면 좋겠죠? 아래의 명렁을 입력하고 `enter`를 눌러보세요. : +맥 : $ pwd /Users/olasitarska -윈도우의 경우 : +윈도우 : > cd C:\Users\olasitarska -위와 비슷한 결과가 출력되었을 거예요. 커맨드라인을 열면, 항상 '홈 디렉토리' 에서 시작합니다. +위와 비슷한 결과가 출력되었을 거예요. 커맨드라인을 열면, 항상 `Home` 디렉터리에서 시작합니다. -> Note: 'pwd' 는 'print working directory' 의 줄임말이에요. +> Note: 'pwd' 는 'print working directory'의 줄임말이에요. * * * -### 파일과 디렉토리 목록 보기 +### 파일과 디렉터리 목록 보기 -여기에는 뭐가 있는지 알아낼 수 있다면 좋겠지요? 그럼 같이 해봐요. +디렉토리에 어떤 것이 있는지 확인하려면 이렇게 입력하세요. + +맥 : $ ls Applications @@ -104,7 +110,7 @@ ... -윈도우의 경우 : +윈도우 : > dir Directory of C:\Users\olasitarska @@ -117,25 +123,29 @@ * * * -### 현재 디렉토리 변경 +### 현재 디렉터리 변경 + +자, 바탕화면 디렉터리로 가볼까요 : -자, 바탕화면 디렉토리로 가볼까요. : +맥 : $ cd Desktop -윈도우의 경우 : +윈도우 : > cd Desktop -변경되었는지 확인해 볼까요. : +변경되었는지 확인합시다. + +맥 : $ pwd /Users/olasitarska/Desktop -윈도우의 경우 : +윈도우 : > cd C:\Users\olasitarska\Desktop @@ -143,41 +153,46 @@ 맞군요! -> 전문가 팁 : `cd D`까지 입력하고 `tab`(탭) 키를 누르면, 커맨드 라인이 자동으로 나머지 부분을 완성해 주기 때문에, 시간을 절약할 수 있어요. "D"로 시작하는 폴더가 2개 이상일 경우, `tab`(탭) 키를 두 번 누르면, 해당하는 폴더들을 모두 보여줍니다. +> 전문가 팁 : `cd D`까지 입력하고 `tab`(탭) 키를 누르면, 커맨드 라인이 자동으로 나머지 부분을 완성해주어, 입력하는 시간을 절약할 수 있어요. "D"로 시작하는 폴더가 2개 이상일 경우, `tab`(탭) 키를 두 번 누르면, 해당하는 폴더들을 모두 보여줍니다. * * * -### 새 디렉토리 만들기 +### 새 디렉터리 생성하기 + +바탕 화면에 `practice` 디렉터리를 만들어 볼까요? 이렇게 하면 됩니다. +(되도록 폴더명은 한국어 대신 영어로 작성하는 것이 좋아요 - 장고걸스서울) -바탕 화면에 연습 디렉터리를 만들어 볼까요? 이렇게 하면 됩니다. : +맥 : $ mkdir practice -윈도우의 경우 : +윈도우 : > mkdir practice -이 간단한 명령어가, 바탕화면에 `practice` 라는 이름의 폴더를 만들어 줍니다. 바탕화면에서 직접 보거나, 명령어 `ls` 혹은 `dir`을 실행해서 확인할 수 있어요! 한 번 해보세요. :) +이 간단한 명령어로, 바탕화면에 `practice`폴더를 만듭니다. 바탕화면에서 직접 보거나, 명령어 `ls` 혹은 `dir`을 실행해서 확인할 수 있어요! 한 번 해보세요. -> 전문가 팁 : 같은 명령어를 여러 번 반복해서 입력하고 싶지 않다면, 키보드의 `위 화살표`와 `아래 화살표`를 눌러서 최근 사용한 명령어들을 볼 수 있어요. +> 전문가 팁 : 같은 명령어를 여러 번 반복해 입력하고 싶지 않다면, 키보드 `위 화살표`와 `아래 화살표`를 누르세요. 최근 사용한 명령어들을 볼 수 있어요. * * * ### 연습문제! -작은 도전 과제를 드릴게요. : 새로 만든 `practice` 디렉토리 안에 `test` 라는 이름의 디렉토리를 만들어 보세요. 명령어 `cd` 와 `mkdir`을 사용하세요. +연습 과제를 드릴게요. 새로 만든 `practice`디렉터리 안에 `test` 라는 이름의 디렉터리를 만들어 보세요. 명령어 `cd`와 `mkdir`을 사용하세요. #### 답 : +맥 : + $ cd practice $ mkdir test $ ls test -윈도우의 경우: +윈도우: > cd practice > mkdir test @@ -191,63 +206,73 @@ ### 정리 -어지럽힌 흔적은 남기고 싶지 않지요, 지금까지 한 것들을 모두 지워봅시다! +지금까지 연습한 내용을 모두 지워봅시다! 우선, 바탕화면으로 돌아가야해요. +맥 : + $ cd .. -윈도우의 경우 : +윈도우 : > cd .. -`..`과 `cd` 명령은 현재 디렉토리에서 (현재 디렉토리보다 한수준 위인) 부모 디렉토리로 보내줄겁니다. +`..`과 `cd` 명령은 현재 디렉터리에서 부모 디렉터리(현재 디렉터리 레벨보다 상위인)로 보내줄겁니다. + +현재 위치를 확인해 보세요. -현재 위치를 확인해 보세요. : +맥 : $ pwd /Users/olasitarska/Desktop -윈도우의 경우 : +윈도우 : > cd C:\Users\olasitarska\Desktop -이제 `practice` 디렉토리를 삭제할 시간이에요.: +이제 `practice` 디렉터리를 삭제해봐요. + +> **Note**: `del`, `rmdir`, `rm`을 사용하여 파일을 지우면, 재복구가 불가능합니다. *지워진 파일들을 영원히 사라지게 됩니다!* 그러니, 이 명령어들은 꼭 주의해서 사용하세요. -> **주의**: `del`, `rmdir` 혹은 `rm` 을 사용하여 파일을 지울 경우, 복구할 수가 없습니다. *지워진 파일들을 영원히 사라지게 됩니다!* 그러니, 이 명령어들은 주의해서 사용하세요. +맥 : $ rm -r practice -윈도우의 경우 : +윈도우 : > rmdir /S practice practice, Are you sure ? Y -완료되었습니다! 정말 삭제되었는지 확인해 보세요. : +완료되었습니다! 완전히 삭제되었는지 확인해 보세요. + +맥 : $ ls -윈도우의 경우 : +윈도우 : > dir ### 종료 -여기까지 입니다! 이제 커맨드 라인을 닫으시면 됩니다. 해커 스타일로 해볼까요, 괜찮죠?:) +여기까지 입니다! 이제 커맨드 라인을 닫으세요. 해커 스타일로 해볼까요, 괜찮죠?:) + +맥 : $ exit -윈도우의 경우 : +윈도우 : > exit @@ -256,23 +281,21 @@ ## 요약 -유용한 명령어들을 요약한 표입니다. : +아래 유용한 명령어를 모았습니다. | 명령어(윈도우) | 명령어(맥 OS/리눅스) | 설명 | 예시 | | -------- | ------------- | ------------------- | ------------------------------------------------- | | exit | exit | 창을 닫는다 | **exit** | -| cd | cd | 디렉토리를 변경한다 | **cd test** | -| dir | ls | 디렉토리 혹은 파일 목록을 보여준다 | **dir** | +| 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** | - -커맨드 라인 명령어들 중에, 몇 가지만 알아보았어요. 이번에는 이 정도만 알고 있어도 괜찮습니다. +| mkdir | mkdir | 새 디렉터리를 만든다 | **mkdir testdirectory** | +| del | rm | 디렉터리 혹은 파일을 지운다 | **del c:\test\test.txt** | -더 알고 싶다면, [ss64.com][1]에서 각 운영체제별로 정리된 명령어 모음을 볼 수 있어요. +지금까지 커맨드 라인 명령어 일부를 알아보았어요. 이 정도만 알고 있어도 코딩하는데 문제가 없습니다. - [1]: http://ss64.com +더 알고 싶다면, [ss64.com](http://ss64.com)에서 각 운영체제별로 정리된 명령어 모음을 볼 수 있어요. ## 준비되셨나요? diff --git a/ko/python_installation/README.md b/ko/python_installation/README.md index e94f9b80653..75bcb86b438 100755 --- a/ko/python_installation/README.md +++ b/ko/python_installation/README.md @@ -1,13 +1,18 @@ -# Python 시작하기 +# 파이썬 시작하기 -여기까지 오셨군요! +잘 오셨습니다! -먼저 파이썬(Python) 이란 무엇인지부터 알려드릴게요. 파이썬은 아주 인기있는 프로그래밍 언어로, 파이썬을 이용하면 웹사이트, 게임, 과학용 소프트웨어, 그래픽 소프트웨어 등을 만들 수 있답니다. +제일 먼저 파이썬(Python)에 대해 설명할게요. 파이썬은 아주 인기있는 프로그래밍 언어로, 웹 사이트는 물론 게임, 과학용 소프트웨어, 그래픽 소프트웨어 등 다양한 것을 만들 수 있답니다. -파이썬은 1980년대 후반에 만들어졌어요. 기계 뿐만 아니라 인간도 읽을 수 있도록 만드는 것이 목적이었어요. 파이썬이 다른 프로그래밍 언어보다 훨씬 간단하게 보이는 이유도 그 때문이죠. 그리고 배우기 쉽습니다. 하지만 파이썬은 아주 강력한 언어랍니다. +파이썬은 1980년대 후반에 프로그래밍 언어를 기계 뿐만 아니라 인간도 읽을 수 있도록 만들고자 탄생한 언어입니다. 파이썬이 다른 프로그래밍 언어보다 훨씬 간단하게 보이고, 배우기도 쉬운 이유도 그 때문이죠. 하지만 파이썬은 아주 강력한 기능을 가진 프로그래밍 언어랍니다. -# Python 설치 +# 파이썬 설치하기 + +> **Note** 크롬북 사용자는 이번 장을 건너뛰고,  [크롬북에서 설치하기](../chromebook_setup/README.md) 장으로 넘어가세요. + + +> **Note** 설치를 마친 분은 다음 장으로 넘어가세요! -> **Note** 만약 이미 설치 단계를 마쳤다면 이 부분을 다시 할 필요가 없으니, 바로 다음 장으로 넘어 가세요. {% include "/python_installation/instructions.md" %} + diff --git a/ko/python_installation/images/add_python_to_windows_path.png b/ko/python_installation/images/add_python_to_windows_path.png index 9510d6f2176..d9bc40e7403 100644 Binary files a/ko/python_installation/images/add_python_to_windows_path.png and b/ko/python_installation/images/add_python_to_windows_path.png differ diff --git a/ko/python_installation/images/python-installation-options.png b/ko/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..e4ed9e985e4 Binary files /dev/null and b/ko/python_installation/images/python-installation-options.png differ diff --git a/ko/python_installation/images/windows-plus-r.png b/ko/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/ko/python_installation/images/windows-plus-r.png differ diff --git a/ko/python_installation/instructions.md b/ko/python_installation/instructions.md index 39cd7295313..91f156d660f 100755 --- a/ko/python_installation/instructions.md +++ b/ko/python_installation/instructions.md @@ -1,68 +1,106 @@ -> 위 내용은 Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) 을 바탕으로 작성되었습니다. -장고는 파이썬으로 만들어졌습니다. 장고를 하기 위해서는 파이썬이 있어야 합니다. 우선 설치부터 해볼까요! 우리는 파이썬 3.4를 사용할 거예요. 그보다 낮은 버전이 설치되었다면, 업그레이드가 필요합니다. +> **Note** 집에서 학습하시는 분들은 [파이썬 & 코드에디터 설치하기](https://www.youtube.com/watch?v=pVTaqzKZCdA) 영상을 보세요. -### 윈도우 -윈도우용 파이썬은 https://www.python.org/downloads/release/python-343/에서 다운 받을 수 있습니다. 사이트에서 ***.msi** 파일을 다운 받고, 실행(더블클릭으로)한 다음, 지시 사항을 따라가세요. 파이썬을 설치한 경로(디렉토리)를 기억해두어야 합니다. 나중에 필요하거든요! +> **Note** 이 장은 Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) 튜토리얼을 기초로 작성되었습니다. -한가지 주의할 것은 설치 마법사의 "Customize"라는 두 번째 화면입니다. 여기서 보이듯이 스크롤을 내려 아래쪽에 있는 "Add python.exe to the Path" 항목을 체크해주세요. +장고는 파이썬 언어로 작성됐습니다. 파이썬이 있어야 장고를 할 수 있어요. 우선 설치부터 해볼까요! 우리는 파이썬 3.6를 사용할 거예요. 이보다 낮은 버전이 설치되었다면, 버전 업그레이드 하세요. -![파이썬을 패쓰(path)에 추가하는 것을 잊지 마세요!][9] + - [9]: ../python_installation/images/add_python_to_windows_path.png +사용 중인 컴퓨터 윈도우 운영체제가 32비트인지 64비트인지 확인하려면 https://support.microsoft.com/en-au/kb/827218 에서 확인하세요. 윈도우 용 파이썬은 https://www.python.org/downloads/windows/ 웹 사이트에서 다운로드 할 수 있습니다. "Latest Python 3 Release - Python x.x.x"링크를 클릭하세요. **64 비트** 버전의 Windows인 경우 **Windows x86-64 executable installer**를 다운로드하세요. 이외에는 **Windows x86 executable installer**을 다운로드하세요. 설치 프로그램을 다운로드 한 후에 실행(더블 클릭)하고 지시 사항을 따르세요. -### 리눅스 +> **Note** 설치하는 동안 "Setup(설치하기)"이라고 표시된 창이 나타납니다. 다음과 같이 "Add Python 3.6 to PATH(python3.6를 경로에 추가)"체크 박스를 체크하고 "Install Now(지금 설치하기)"를 클릭하세요. -아마 이미 파이썬이 설치되었을 거에요. 설치되어있는지 (그리고 어떤 버전인지) 확인하려면, 콘솔을 열어 다음 명령을 실행하세요. +![Don't forget to add Python to the Path](../python_installation/images/python-installation-options.png) - $ python3 --version - Python 3.4.3 +다음 단계에서는 윈도우 명령 프롬프트를 사용할 거에요 (윈도우 명령어도 알려드릴 거에요. 지금은 일부 명령을 입력해야하는 경우 시작 메뉴 → 모든 프로그램 → 보조 프로그램 → 명령 프롬프트로 이동하세요. Windows 키를 누르고 "실행"창이 팝업 될 때까지 "R"키를 누르면 됩니다. 명령어를 입력하려면 "cmd"를 입력하고 "실행"창에서 엔터키를 누르세요. (윈도우 최신 버전에서는 "명령 프롬프트"가 메뉴에 없을 수 있어 검색해 실행하면 됩니다) +![Type "cmd" in the "Run" window](../python_installation/images/windows-plus-r.png) -파이썬이 설치되어 있지 않거나 버전이 다르면 이렇게 해보세요. : +> **Note** 윈도우 이전 버전(윈도우7, Vista 등)에서 파이썬 3.6.x 설치오류가 생기면, 다음과 같이 해보세요. -#### Debian 또는 Ubuntu +1. 모든 윈도우 업데이트 후 파이썬 3.6를 다시 설치합니다. +2. 또는 [파이썬 이전 버전](https://www.python.org/downloads/windows/)을 설치합니다. -콘솔에서 다음 명령을 실행하세요. +버전이 낮은 파이썬 설치 시, 설치 화면이 위에 표시된 것과 약간 다르게 보일 수 있습니다. "Add Python 3.6. to PATH"를 보려면 아래로 스크롤 한 다음 왼쪽의 버튼을 클릭하고 "Will be installed on local hard drive(로컬 하드 드라이브에 설치)"를 선택하세요. - $ sudo apt-get install python3.4 +![Add Python to the Path, older versions](../python_installation/images/add_python_to_windows_path.png) + -#### Fedora (21까지) + -콘솔에서 다음 명령을 실행하세요. +> **Note** macOS에서는 파이썬 설치하기 전, Mac 설정에서 App Store가 아닌 패키지를 설치할 수 있도록 설정해야합니다. 시스템 환경 설정 (응용 프로그램 폴더에 있음)으로 이동하여 "보안 및 개인 정보"를 클릭 한 다음 "일반"탭을 클릭하세요. "다운로드 한 응용 프로그램 허용"이 "Mac App Store"로 설정된 경우 "Mac App Store 및 확인된 개발자"로 변경하세요. - $ sudo yum install python3.4 +웹 사이트로 가서 파이썬 설치 파일을 다운 받으세요. : https://www.python.org/downloads/release/python-351/ +* *macOS 64-bit/32-bit installer* 파일을 다운받습니다. +* *python-3.6.1-macosx10.6.pkg*을 더블클릭해 설치합니다. -#### Fedora (22부터) + -콘솔에서 다음 명령을 실행합니다. + - $ sudo dnf install python3.4 +이미 파이썬이 설치되었을 겁니다. 설치된 버전을 확인하려면 콘솔을 열고 다음 명령을 입력하세요. : +{% filename %}command-line{% endfilename %} +``` +$ python3 --version +Python 3.6.1 +``` -#### openSUSE +3.6.0 버전과 같이 '마이크로 버전'의 파이썬이 설치되어있는 경우 업그레이드 할 필요가 없습니다. 다른 버전의 파이썬을 설치하고 싶으면 아래와 같이하면 됩니다. : -콘솔에서 다음 명령을 실행합니다. + - $ sudo zypper install python3 + -### OS X +콘솔에 아래 명령어를 입력하세요. : -https://www.python.org/downloads/release/python-343/ 에서 파이썬 설치프로그램을 다운 받아야 합니다. +{% filename %}command-line{% endfilename %} +``` +$ sudo apt install python3.6 +``` - * *Mac OS X 64-bit/32-bit installer* 파일을 다운 받으세요. - * *python-3.4.3-macosx10.6.pkg* 을 더블 클릭해 설치 프로그램을 시작하세요. + -*터미널*을 열고 `python3` 명령을 실행해 잘 설치되었는지 확인하세요. + - $ python3 --version - Python 3.4.3 +콘솔에 아래 명령어를 입력하세요. : +{% filename %}command-line{% endfilename %} +``` +$ sudo dnf install python3 +``` -* * * + -더 알고 싶은 것이 있거나, 설치가 잘 되지 않고 어찌 해야할지 모르겠다면 코치를 불러주세요! 잘 설치 되지 않는 경우도 있을 수 있습니다. 그럴 때는 경험이 있는 분에게 도움을 구해보세요. + + +콘솔에 아래 명령어를 입력하세요. : + +{% filename %}command-line{% endfilename %} +``` +$ sudo zypper install python3 +``` + + + +설치가 성공적으로 마쳤는지 확인하려면, *터미널* 을 열고 `python3` 명령어를 입력해보세요. + +{% filename %}command-line{% endfilename %} +``` +$ python3 --version +Python 3.6.1 +``` + +> **Note** 윈도우에서 `python3`명령어를 입력한 후 에러 메세지가 나온다면 `python`(`3`을 빼고)이라 입력해보고 파이썬 3.6버전인지 체크해보세요. + +설치 도중 문제가 생기거나 잘되지 않으면 코치들에게 도움을 요청하세요! 가끔은 경험이 많은 분들에게 도움을 받는 것이 더 좋을 수 있습니다. diff --git a/ko/python_introduction/README.md b/ko/python_introduction/README.md index a16a0233c5d..b998cae833b 100755 --- a/ko/python_introduction/README.md +++ b/ko/python_introduction/README.md @@ -1,795 +1,989 @@ -# Python 시작하기 +{% set warning_icon = '' %} -> 이번 장의 일부는 Geek Girls Carrots (https://github.com/ggcarrots/django-carrots)의 튜토리얼을 바탕으로 작성되었습니다. +# 파이썬 시작하기 -자, 코딩 한 번 해봅시다! +> **Note** 이 장의 일부는 [Geek Girls Carrots 튜토리얼](https://github.com/ggcarrots/django-carrots)을 기초로 작성되었습니다. -## 파이썬 프롬프트(Python prompt) -파이썬과 놀기 위해서는 *커맨드 라인*을 열어야 합니다. [커맨드 라인 시작하기][1]에서 배웠던 걸 기억하고 있겠지요? +자, 지금부터 코딩 한번 해볼까요? - [1]: ../intro_to_command_line/README.md +## 파이썬 프롬프트(Python prompt) -준비되었다면, 아래 내용을 잘 따라오세요. +> **Note** 집에서 학습하시는 분은 [파이썬 기초: 숫자, 문자열, 리스트, 변수, 에러](https://www.youtube.com/watch?v=MO63L4s-20U) 영상을 보세요. -파이썬 콘솔을 실행하기 위해 윈도우에서는 `python`을 입력하고, 맥OS나 리눅스라면 `python3`를 입력하고 `엔터`를 입력하세요. +파이썬과 놀아보려면 *커맨드 라인* 창을 켜야합니다. [Command Line 시작하기](../intro_to_command_line/README.md) 장에서 어떻게 하는지 배웠어요. - $ python3 - Python 3.4.3 (...) - Type "help", "copyright", "credits" or "license" for more information. - >>> +준비되었다면, 아래 내용을 잘 따라오세요. +파이썬 콘솔을 실행하기 위해, 윈도우에서는 `python`을 입력하고, 맥OS나 리눅스라면 `python3`를 입력하고 `엔터`를 입력하세요. -## 나의 첫 번째 파이썬 명령! +{% filename %}command-line{% endfilename %} +``` +$ python3 +Python 3.6.1 (...) +Type "help", "copyright", "credits" or "license" for more information. +>>> +``` -파이썬을 실행시키고 나면 프롬프트가 `>>>`로 바뀝니다. 이제부터는 파이썬 언어의 명령어만 사용할 수 있다는 뜻이예요. `>>>`를 입력할 필요 없어요. 파이썬이 대신해 줄 테니까요. +## 첫 번째 파이썬 명령어! -파이썬 콘솔에서 나가려면 `exit()` 을 입력하거나, 윈도우에서는 `Ctrl + Z` 를, 맥이나 리눅스에서는 `Ctrl + D`를 입력하면 됩니다. 그러면 `>>>` 는 사라질 거에요. +파이썬을 실행시키면 프롬프트가 `>>>`로 바뀝니다. 이제부터는 파이썬 언어 명령어만 사용할 수 있다는 뜻이예요. `>>>`를 입력할 필요 없어요. 파이썬이 대신해 줄 테니까요. -물론 지금 파이썬 콘솔을 종료할 필요가 없답니다. 아직 파이썬 콘솔에 대해 좀 더 배워야하니까요. 아주 간단한 것부터 시작해봅시다. 먼저, 수학 사칙연산처럼 `2 + 3`을 입력하고 `엔터`를 쳐보세요. +파이썬 콘솔에서 나가려면 `exit()`을 입력하거나, 윈도우에서는 `Ctrl + Z`를, 맥이나 리눅스에서는 `Ctrl + D`를 입력하면 됩니다. 그러면 `>>>` 는 사라질 거에요. - >>> 2 + 3 - 5 +물론 지금 파이썬 콘솔을 종료할 필요가 없답니다. 아직 파이썬 콘솔에 대해 좀 더 배워야 하니까요. 아주 간단한 사칙연산부터 해봅시다. `2 + 3`을 입력하고 `엔터`를 쳐보세요. +{% filename %}command-line{% endfilename %} +```python +>>> 2 + 3 +5 +``` -잘했어요! 값이 출력되었나요? 파이썬은 수학을 할 줄 알아요. 다른 명령도 테스트해 보세요. : - `4 * 5` - `5 - 1` - `40 / 2` +잘했어요! 값이 출력되었나요? 파이썬은 수학을 할 줄 알아요. 다른 사칙연산도 입력해보세요. -조금 놀아봤다면 다시 여기로 돌아와주세요. :) +- `4 * 5` +- `5 - 1` +- `40 / 2` -보시다시피, 파이썬은 훌륭한 계산기랍니다. 그 밖에 여러분들이 할 수 있는 것들이 궁금하다면... +2의 3승과 같이 지수 계산을 위해서는 아래와 같이 입력하세요. -## 문자열(String) +{% filename %}command-line{% endfilename %} +```python +>>> 2 ** 3 +8 +``` -이름은 어떨까요? 따옴표로 이름을 감싸서 입력해보세요. +조금 놀아보고 다시 여기로 돌아와주세요. :) - >>> "Ola" - 'Ola' +이처럼 파이썬은 훌륭한 계산기랍니다. 이외에도 할 수 있는 것들이 많아요! +## 문자열(String) -처음으로 문자열을 만들었군요! 문자열은 컴퓨터가 처리할 수 있는 연속된 문자를 말해요. 문자열은 반드시 시작과 끝이 같은 문자여야 해요. 문자열은 작은따옴표(`'`) 나 큰따옴표(`"`)로 감싸야 해요. (둘 간의 차이점은 없어요. 단지 하나로 감싸나 둘로 감싸나 차이일 뿐이에요) 이 따옴표는 파이썬에게 안에 문자열이 들어있다고 알려줍니다. +이름을 써봅시다. 따옴표(")를 양쪽에 감싸서 입력해보세요. -문자열들은 줄줄이 사탕처럼 연결될 수 있어요. 이렇게요. : +{% filename %}command-line{% endfilename %} +```python +>>> "Ola" +'Ola' +``` - >>> "Hi there " + "Ola" - 'Hi there Ola' +처음으로 문자열을 만들었군요! 문자열은 컴퓨터가 처리할 수 있는 연속된 문자를 말해요. 문자열은 반드시 시작과 끝이 문자여야 하고, 양쪽을 작은따옴표(`'`) 나 큰따옴표(`"`)로 감싸야 해요. (차이점은 없어요) 이 따옴표는 파이썬에게 안에 문자열이 들어있다고 알려줍니다. +문자열은 줄줄이 사탕처럼 연결될 수 있어요. 이렇게요. -문자열이랑 숫자를 곱할 수도 있어요. +{% filename %}command-line{% endfilename %} +```python +>>> "Hi there " + "Ola" +'Hi there Ola' +``` - >>> "Ola" * 3 - 'OlaOlaOla' +문자열과 숫자를 함께 곱할 수도 있어요. +{% filename %}command-line{% endfilename %} +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` 문자열 안에 작은따옴표를 넣고 싶다면, 두 가지 방법이 있어요. -큰따옴표를 사용하는 방법과 - - >>> "Runnin' down the hill" - "Runnin' down the hill" - - -백슬래시 (``) 기호를 이용하는 방법이예요. - - >>> 'Runnin\' down the hill' - "Runnin' down the hill" - - -알겠나요? 이제 이름을 대문자로 만들어볼까요. : +큰따옴표("")를 사용하는 방법과 - >>> "Ola".upper() - 'OLA' +{% filename %}command-line{% endfilename %} +```python +>>> "Runnin' down the hill" +"Runnin' down the hill" +``` +백슬래시(`\`)를 이용하는 방법이예요. -방금 문자열에 `upper`이라는 **함수(function)**를 사용했어요! 함수(`upper()` 같은 것)란 파이썬이 주어진 대상(`"Ola"`같은)에 대해서 수행할 수 있는 일련의 명령을 말해요. +{% filename %}command-line{% endfilename %} +```python +>>> 'Runnin\' down the hill' +"Runnin' down the hill" +``` -이름에 들어있는 글자의 수를 알고 싶을 때, 사용하는 함수도 있어요. +{% filename %}command-line{% endfilename %} +```python +>>> "Ola".upper() +'OLA' +``` - >>> len("Ola") - 3 +방금 문자열에 `upper`이라는 __메소드(method)__를 사용했어요! 메소드는(`upper()`같은 것)는 파이썬이 객체(`"Ola"`같은)를 대상으로 수행할 수 있는 일련의 명령을 말해요. + +총 글자 수를 알고 싶을 때, `len()` __함수(function)__을 사용해요. +{% filename %}command-line{% endfilename %} +```python +>>> len("Ola") +3 +``` -함수 호출 시, 어떤 함수는 문자열 뒤에 `.`를 붙이고, (`"Ola".upper()` 처럼), 또 어떤 함수는 함수 뒤에 문자열이 들어간 괄호를 붙이는지 궁금하셨죠? `upper()`와 같은 함수는 객체에 속하게 되어 해당 문자열에서만 수행되기 때문이죠. 이 같은 경우, 함수를 **메서드(method)**라고 합니다. 그리고, `len()`과 같은 함수들은 특정한 대상에 속하지 않고 여러 가지 객체를 대상으로 사용할 수 있습니다. 그래서 `len` 함수에 `"Ola"`를 매개 변수(parameter)로 준 거예요. +왜 어떤 함수는 문자열 뒤에 `.`를 붙이고, (`"Ola".upper()`처럼), 또 어떤 함수는 뒤에 문자열이 들어간 괄호(`len("Ola")처럼`)를 붙이는지 궁금하셨죠? ` upper()`같은 함수는 문자열만 쓸 수 있는 함수로, **메서드(method)**라고 합니다. 반면에 `len()`과 같은 함수는 문자열이나 숫자 등 여러 객체를 사용할 수 있어요. 그래서 `len()`함수에 `"Ola"`를 매개변수(parameter)로 준 거예요. -### 요약 +### 요약하기 -자, 문자열은 충분히 다루었어요. 지금까지 우리가 공부한 것들을 정리해봅시다. : +자, 문자열은 충분히 다루었어요. 지금까지 우리가 공부한 내용을 정리해봅시다. * **프롬프트(the prompt)** - 명령어(코드)를 파이썬 프롬프트에 입력하면 파이썬이 응답합니다. -* **숫자와 문자열(numbers and strings)** - 파이썬에서는 셈을 할 때는 숫자를 사용하고 글을 다룰 때는 문자열을 사용합니다. -* **연산자(operators)** - 값들을 이용해서 새로운 값을 만들 때는 + 나 * 같은 연산자를 이용합니다. -* **함수(functions)** - upper()나 len()처럼 대상에 명령을 수행합니다. +* **숫자와 문자열(numbers and strings)** - 사칙연산을 할 때는 숫자를 사용하고 글을 다룰 때는 문자열을 사용합니다. +* **연산자(operators)** - `+` 나 `*`같은 연산자를 사용합니다. +* **함수(functions)** - 객체에 `upper()`나 `len()`처럼 명령을 수행합니다. -지금까지 프로그래밍 언어의 기초에 대해 알아보았어요. 더 어려운 부분으로 넘어가도 괜찮겠죠? 그럼요! +지금까지 가장 기본적인 프로그래밍 문법을 살펴보았어요. 더 어려운 부분으로 넘어가도 괜찮겠죠? ## 오류 -이제 새로운 것을 해봅시다. 이름의 글자 길이를 알아냈듯이 숫자의 길이도 알 수 있을까요? `len(304023)` 을 입력하고 `엔터`를 입력해보세요. : - - >>> len(304023) - Traceback (most recent call last): - File "", line 1, in - TypeError: object of type 'int' has no len() +새로운 것을 배워봅시다. 총 글자 수도 알아냈듯이 숫자 수도 알 수 있을까요? `len(304023)`을 입력하고 `엔터`를 입력하세요. +{% filename %}{{warning_icon}}command-line{% endfilename %} +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` -첫 번째 에러가 나타났어요! "int" (정수) 형식의 객체는 길이가 없기 때문이지요. 이제 어떻게 할 수 있을까요? 숫자(number)를 문자열(String)로 바꿔 쓸 수 있지 않을까요? 문자열은 길이를 갖고 있으니까요, 그렇죠? +첫 번째 에러가 나타났어요! 여기서 {{warning_icon}} 아이콘은 `이 코드는 여러분이 예상하는 대로 실행되지 않을 것입니다.`를 의미합니다. (의도적으로 만들어낸 것이라도) 실수도 배움의 중요한 과정 중 하나랍니다! - >>> len(str(304023)) - 6 +"int"(정수)객체는 길이가 없기 때문이지요. 이제 어떻게 할 수 있을까요? 숫자(number)를 문자열(String)로 바꿔 쓸 수 있지 않을까요? 문자열은 길이를 갖고 있으니까요, 그렇죠? +{% filename %}command-line{% endfilename %} +```python +>>> len(str(304023)) +6 +``` -잘 되네요! 앞에서 우리는 `len` 함수 내부에 `str` 함수를 사용했어요. `str` 함수는 모든 것을 문자열로 변환한답니다. +잘 되네요! 앞에서 우리는 `len()`함수 내부에 `str()`함수를 사용했어요. `str()`함수는 모든 대상을 문자열로 변환한답니다. -* `str`함수는 대상을 **문자열** 로 변환합니다 -* `int` 함수는 대상을 **정수** 로 변환합니다. +* `str()`함수는 대상을 **문자열**로 변환합니다 +* `int()`함수는 대상을 **정수**로 변환합니다. -> 중요 : 우리는 숫자를 텍스트로 변환할 수는 있지만, 반드시 텍스트를 숫자로 변환할 수 있는건 아닙니다. - `int('hello')` 가 어떻게 될 것 같나요? +> 중요 : 숫자는 텍스트로 변환되지만, 반대로 텍스트는 숫자로 변환될 수 없습니다. - 그렇다면 `int('hello')`는 가능할까요? ## 변수 -변수는 프로그래밍에서 중요한 개념입니다. 변수란 어떤 것을 나중에도 사용할 수 있도록 이름을 붙인 것일 뿐 입니다. 프로그래머들은 이 변수를 데이터 저장하는데 사용하고, 작성한 코드를 다 기억할 필요없이 코드를 읽기 쉽게 하기 위해 사용하지요. - -`name`이라는 새로운 변수를 만들어 보세요. : - - >>> name = "Ola" - - -봤죠? 간단해요. 매우 쉬어요! : name은 Ola와 같다. +변수는 프로그래밍에서 중요한 개념입니다. 변수란 여러 번 사용될 수 있게 이름을 붙인 거랍니다. 작성한 코드를 다 기억할 필요없이 코드를 읽기 쉽게 하기 위해 사용하지요. 프로그래머들은 변수를 사용해 데이터를 저장합니다. -여러분도 알겠지만, 프로그램은 이전에 수행한 것을 보여주지 않아요. 그러면 실제 변수에 어떤 값이 들어있는지 알려면 어떻게 해야할까요? 간단하게 `name`를 입력하고 `엔터`를 입력하세요. : +`name`이라는 새로운 변수를 만들어 보세요. - >>> name - 'Ola' +{% filename %}command-line{% endfilename %} +```python +>>> name = "Ola" +``` +봤죠? 간단해요. 매우 쉬워요! "이름은 올라와 같다"라고 쓰는 거에요. -야호! 여러분이 만든 첫 변수입니다! :) 언제든지 여러분은 변수를 바꿀 수 있어요. : +여러분도 알겠지만, 프로그램은 이전에 수행한 내용을 보여주지 않아요. 그렇다면 변수값을 알려면 어떻게 해야할까요? `name`를 입력하고 `엔터`를 입력하세요. - >>> name = "Sonja" - >>> name - 'Sonja' +{% filename %}command-line{% endfilename %} +```python +>>> name +'Ola' +``` +야호! `name`은 여러분이 만든 첫 변수랍니다! :) 언제든지 변수값을 바꿀 수 있어요. -또 함수 안에서 변수를 사용할 수 있습니다. : +{% filename %}command-line{% endfilename %} +```python +>>> name = "Sonja" +>>> name +'Sonja' +``` - >>> len(name) - 5 +또 함수 안에 변수명을 사용할 수 있습니다. +{% filename %}command-line{% endfilename %} +```python +>>> len(name) +5 +``` 멋지죠? 물론 변수는 무엇이든지 담을 수 있으니, 당연히 숫자도 가능하죠! 해봅시다. : - >>> a = 4 - >>> b = 6 - >>> a * b - 24 - - -그런데 만약 잘못된 이름을 사용했다면 어떻게 될까요? 해봅시다! - - >>> city = "Tokyo" - >>> ctiy - Traceback (most recent call last): - File "", line 1, in - NameError: name 'ctiy' is not defined - - -에러가 나타났네요! 보다시피, 파이썬에는 많은 종류의 오류들이 있습니다. **NameError**는 그 중 하나입니다. 파이썬은 아직 정의하지 않은 변수를 사용하면 이 오류를 보여줍니다. 나중에 똑같은 오류를 보게 된다면, 이름에 오타가 없는지 확인해보세요. - -잠시동안 변수와 놀아봅시다. 그리고 어떤 것들을 할 수 있는지 살펴보아요! - -## print 함수 - -아래와 같이 따라해보세요: - - >>> name = 'Maria' - >>> name - 'Maria' - >>> print(name) - Maria - +{% filename %}command-line{% endfilename %} +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` -`name`을 쳤을 때, 파이썬 해석기는 'name' 변수의 문자열 *표현(representatio)*으로 응답하는데, 그 모양은 작은따옴표('') 로 둘러싸인 M-a-r-i-a 문자들 입니다. `print(name)`라고 치면, 파이썬은 화면에 따옴표 없이 더 깔끔한 변수를 "출력(print)"합니다. +그런데 만약 잘못된 변수명을 입력하면 어떻게 나올까요? -나중에 보겠지만, `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 +``` -## 리스트 (List) +에러가 나타났네요! 보다시피, 파이썬에는 많은 종류의 오류들이 있습니다. **NameError**는 그 중 하나입니다. 파이썬은 아직 정의하지 않은 변수를 사용하면 이 오류를 보여줍니다. 나중에도 **NameError**라는 오류를 보게 된다면, 이름에 오타가 있는지 확인해야겠죠. -문자열과 정수 외에, 파이썬은 객체 정렬 위한 여러 방법들이 있어요. 이제 **리스트**라고 불리는 녀석에 대해서 알아보기로 하겠습니다. 리스트를 이렇게 생각하시면 됩니다. : 다른 객체들을 나열한 객체 +조금 더 변수와 놀아봅시다. 그리고 어떤 것들을 할 수 있는지 살펴보아요! -이제 리스트를 만듭시다. : - >>> [] - [] +## print() 함수 +아래와 코드를 따라 입력해보세요. : -네, 리스트가 비어있어요. 별로 유용해 보이지 않죠? 이제 로또 번호 목록을 만들어 봅시다. 매번 직접 우리가 반복하기는 귀찮으니, 리스트에 변수를 넣어봅시다. : +{% filename %}command-line{% endfilename %} +```python +>>> name = 'Maria' +>>> name +'Maria' +>>> print(name) +Maria +``` - >>> lottery = [3, 42, 12, 19, 30, 59] +`name`을 쳤을 때, 파이썬 해석기는 'name' 변수의 문자열 *표현(representation)*으로 응답하는데, 그 모양은 작은따옴표('')로 둘러싸인 M-a-r-i-a 문자입니다. `print(name)`라고 치면, 파이썬은 화면에 따옴표없이 더 깔끔한 화면을 보여(`print`)줍니다. +나중에 차차 알게 될 거지만, `print()`는 함수 안에 있는 내용을 출력할 때, 여러 내용들을 확인하고 싶을 때 유용하게 사용됩니다. -좋아요, 리스트를 만들었네요! 어떻게 쓰면 될까요? 목록에 수 많은 로또 번호가 있다고 생각해봅시다. 함수를 사용할 수 있는 아이디어가 떠올랐나요? 여러분들은 이미 앞에서 해봤어요! - >>> len(lottery) - 6 +## 리스트(List) +문자열과 정수 외에도 객체를 정렬할 수 있는 여러 방법들이 있습니다. **리스트**라고 불리는 아이에 대해 알아봅시다. 리스트란 서로 다른 객체들을 일렬로 나열한 것이라고 생각하시면 됩니다. -네! `len()` 함수는 리스트 안에 있는 객체의 수를 알려줍니다. 편리하지 않나요? 이제 정렬을 해봅시다. : +아래와 같이 리스트를 만듭시다. : - >>> lottery.sort() +{% filename %}command-line{% endfilename %} +```python +>>> [] +[] +``` +리스트가 비어있네요. 별로 유용해 보이지 않죠? 이제 로또 번호 목록을 만들어 봅시다. 매번 직접 우리가 반복하기는 귀찮으니, 리스트에 변수를 넣어봅시다. -아무것도 보여주지 않네요. 이 함수는 리스트 안의 숫자들을 오름차순으로 정렬합니다. 어떻게 변했는지 리스트를 출력해봅시다. : +{% filename %}command-line{% endfilename %} +```python +>>> lottery = [3, 42, 12, 19, 30, 59] +``` - >>> print(lottery) - [3, 12, 19, 30, 42, 59] +좋아요, 리스트를 만들었어요! 이제 무엇을 할 수 있을까요? 리스트 안에 들어간 로또 번호는 몇 개인지 알려면 어떻게 해야할까요? `len()`함수를 사용할 수 있겠죠? 이미 앞에서 해봤어요! +{% filename %}command-line{% endfilename %} +```python +>>> len(lottery) +6 +``` -위에 나왔듯이, 리스트 안에 있는 숫자들은 오름차순으로 정렬되었습니다. 축하합니다! +네! `len()`함수는 리스트 안에 있는 객체의 수를 알려줍니다. 유용하죠? 이제 정렬을 해봅시다. -만약 반대로 내림차순으로 정렬하고 싶다면요? 하면 됩니다! +{% filename %}command-line{% endfilename %} +```python +>>> lottery.sort() +``` - >>> lottery.reverse() - >>> print(lottery) - [59, 42, 30, 19, 12, 3] +숫자를 오름차순으로 정렬했지만 출력값이 보이지 않네요. 어떻게 변했는지 리스트를 출력해 확인해봅시다. : +{% filename %}command-line{% endfilename %} +```python +>>> print(lottery) +[3, 12, 19, 30, 42, 59] +``` -참 쉽죠? 여러분이 리스트에 새로운 값을 추가하고 싶다면, 추가할 때마다 매번 다시 정렬 명령을 해줘야 합니다. : +리스트 안에 있는 숫자들은 오름차순으로 정렬되었어요. 잘했습니다! - >>> lottery.append(199) - >>> print(lottery) - [59, 42, 30, 19, 12, 3, 199] +이번에는 내림차순으로 정렬해볼까요? +{% filename %}command-line{% endfilename %} +```python +>>> lottery.reverse() +>>> print(lottery) +[59, 42, 30, 19, 12, 3] +``` -만약 첫 번째 숫자 하나만 보여주고 싶다면, **인덱스(index)**를 사용하세요. 인덱스는 리스트 안의 아이템 위치를 나타내는 숫자입니다. 프로그래머는 0부터 세는 것을 선호합니다. 따라서 리스트에 있는 첫 번째 객체는 인덱스 0부터 시작하고, 그 다음은 1, 그 다음은 2.. 가 됩니다. 해봅시다. : +참 쉽죠? 여러분이 리스트에 새로운 값을 추가하고 싶다면 이렇게 해보세요. : - >>> print(lottery[0]) - 59 - >>> print(lottery[1]) - 42 +{% filename %}command-line{% endfilename %} +```python +>>> lottery.append(199) +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +``` +첫 번째 숫자 하나만 보여주고 싶다면, **인덱스(indexes)**를 사용하세요. 인덱스는 리스트 내 아이템 위치를 나타내는 숫자입니다. 프로그래머는 0부터 세는 것을 선호합니다. 따라서 리스트에 있는 첫 번째 객체는 인덱스 0부터 시작하고, 그 다음은 1, 그 다음은 2.. 순번대로 번호를 매길 수 있습니다. `.[index숫자]`를 입력해볼까요. -리스트의 이름이나 대괄호 안에 들어가는 객체의 인덱스를 사용해서, 리스트 안에 있는 다른 객체로도 접근이 가능합니다. +{% filename %}command-line{% endfilename %} +```python +>>> print(lottery[0]) +59 +>>> print(lottery[1]) +42 +``` -리스트에서 뭔가 지우려면 **indexes** 위에서 이미 배운대로 `pop()` 문을 사용해야 합니다. (del은 delete의 약자에요) 이제 한번 해보고 이전에 배웠던 것을 다시 떠올려봅시다. ; 목록에서 첫 번째 숫자를 삭제할 것입니다. +이렇게 리스트 이름과 대괄호`([])`안 객체의 인덱스를 사용해서, 리스트 안에 있는 다른 객체로도 접근이 가능합니다. - >>> print(lottery) - [59, 42, 30, 19, 12, 3, 199] - >>> print(lottery[0]) - 59 - >>> lottery.pop(0) - >>> print(lottery) - [42, 30, 19, 12, 3, 199] +리스트 내 아이템을 지우려면 인덱스와 함께 `pop()`메소드를 사용하면 됩니다. 아래 예제 코드를 따라하면서 배운 내용을 다시 기억해봅시다. 리스트에 맨 처음 있는 객체를 삭제해봅시다. +{% filename %}command-line{% 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] +``` -마법 같네요! +마법 같지 않나요! -재미로 몇 번 더 여러 인덱스를 테스트해보세요: 6, 7, 1000, -1, -6, -1000 등이요. 결과값을 보기 전에 미리 어떤 값이 나올지 예상할 수 있었나요? 생각했던 정답이 나왔나요? +재미로 몇 번 더 여러 인덱스를 테스트해보세요: 6, 7, 1000, -1, -6, -1000 등이요. 결과값을 보기 전에 미리 정답을 유추해보세요. 생각했던 정답이 나왔나요? -이번 장에 나온 리스트 메서드와 관련된 모든 내용은 파이썬 공식 문서에서 찾을 수 있습니다. : https://docs.python.org/3/tutorial/datastructures.html +이번 장에서 배운 리스트 메서드와 관련된 모든 내용은 파이썬 공식 문서에서 있습니다. :https://docs.python.org/3/tutorial/datastructures.html ## 딕셔너리(Dictionary) -딕셔너리는 리스트와 유사하지만, 인덱스가 아닌 키(key)로 값을 찾습니다. 키는 문자열이든, 숫자든지 상관없습니다. 빈 딕셔너리를 만드는 문법은 아래와 같습니다. : +> 집에서 학습하시는 분들은 [파이썬 기초: 딕셔너리(Dictionaries)](https://www.youtube.com/watch?v=ZX1CVvZLE6c) 영상을 보세요. - >>> {} - {} +딕셔너리는 리스트와 유사하지만, 인덱스가 아닌 키(key)로 값을 찾습니다. 키는 문자열이든, 숫자든지 상관없습니다. 빈 딕셔너리를 만드는 문법은 아래와 같습니다. +{% filename %}command-line{% endfilename %} +```python +>>> {} +{} +``` 방금 비어있는 딕셔너리를 하나 만들었답니다. 만세! -자, 이제 아래 명령어를 따라 작성해 봅시다. (안에 있는 정보는 마음대로 바꿔도 됩니다): - - >>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} - +자, 이제 아래 명령어를 따라 작성해 봅시다. (딕셔너리 안에 있는 값은 마음대로 수정해도 됩니다) -위 명령어로 `paticipant`라는 이름의 변수를 만들었습니다. 이 변수 안에는 3개의 키-값 쌍이 들어있습니다. +{% filename %}command-line{% endfilename %} +```python +>>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} +``` -* 키(key) 는 `name`이고, 값(value) 는 `'Ola'`를 가리킵니다. (`string(문자열)` 객체이지요), -* 키 `country`의 값은 `'Poland'`입니다. (또 다른 `string`입니다.), -* 그리고 키 `favorite_numbers`는 `[7, 42, 92]`를 가리킵니다. (`리스트`에는 세 개의 숫자가 있습니다) -여러분은 아래와 같은 문법으로 개별 키의 값에 접근할 수 있습니다. +위 명령어로 `paticipant`라는 새 변수를 만들었습니다. 이 변수 안에는 3개의 키-값 쌍이 들어있어요. - >>> print(participant['name']) - Ola +* 키(key) 는 `name`이고, 값(value) 는 `'Ola'`를 가리킵니다. (`string`입니다) +* 키 `country`의 값은 `'Poland'`입니다. (또 다른 `string`입니다) +* 그리고 키 `favorite_numbers`는 `[7, 42, 92]`를 가리킵니다. (`list`에 숫자 세 개가 있습니다) +아래와 같은 문법으로 개별 키의 값에 접근할 수 있습니다. -리스트와 조금 비슷하죠. 다만 인덱스가 아닌, 이름을 사용해 값에 접근한다는 것을 기억하세요. +{% filename %}command-line{% endfilename %} +```python +>>> print(participant['name']) +Ola +``` -만약 파이썬에 키에 대응하는 값이 없는 경우에는 어떻게 될까요? 예측할 수 있나요? 그럼 한 번 알아봅시다! +리스트와 조금 비슷해보이지만 인덱스가 아닌, 이름을 사용해 값을 찾는다는 것을 기억하세요. - >>> participant['age'] - Traceback (most recent call last): - File "", line 1, in - KeyError: 'age' +만약 파이썬에 키(key)에 대응하는 값이 없다면 어떻게 될까요? 그럼 테스트 해봅시다! +{% filename %}{{warning_icon}}command-line{% endfilename %} +```python +>>> participant['age'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'age' +``` -보세요, 에러가 났네요! 이번에는 **KeyError**에러가 났습니다. 파이썬은 친절하게 키 `'age'`가 딕셔너리에 존재하지 않는다고 알려주네요. +보세요, **KeyError**에러가 났습니다. 파이썬은 친절하게 `'age'`키가 딕셔너리에 존재하지 않는다고 알려주네요. 그렇다면 언제 딕셔너리를 쓰고, 언제 리스트를 사용해야할까요? 이를 위한 판단 기준은 다음과 같습니다. -* 아이템을 나열할 때 정렬이 필요하나요? 그렇다면 리스트를 사용하세요. -* 키(key) 과 값(value) 이 서로 연관되어 있어야 하나요? 또는 보다 효과적으로 (키를 사용해서) 어떤 값을 찾아야 하나요? 그렇다면, 딕셔너리를 사용하세요. - -딕셔너리는 리스트와 유사하지만, *변경(mutable)*할 수 있습니다. 딕셔너리가 만들어진 후에도, 그 값을 마음대로 변경할 수 있다는 뜻이지요. 키/값 을 나중에 추가할 수 있답니다. 바로 이렇게요. : - - >>> participant['favorite_language'] = 'Python' +* 리스트 : 아이템 정렬이 필요할 때 +* 딕셔너리 : 키(key)과 값(value)이 서로 연관되어 있거나, 효과적으로 (키를 사용해서) 어떤 값을 찾을 때 +딕셔너리는 리스트와 유사하지만, *변경(mutable)*할 수 있습니다. 딕셔너리가 만들어진 후에도, 그 값을 마음대로 변경할 수 있다는 뜻이지요. 키/값을 나중에 추가할 수 있답니다. -리스트처럼 딕셔너리도 `len()` 메서드를 사용하여 키-값 쌍의 수를 리턴합니다. 한 번 커맨드라인에서 확인합시다. : - - >>> len(participant) - 4 - + {% filename %}command-line{% endfilename %} +```python +>>> participant['favorite_language'] = 'Python' +``` -다들 이해를 잘 하고 있으리라 믿어요 :) 딕셔너리로 좀 더 재미있는 것을 해볼까요? 좀더 흥미로운 내용이 다음에 있어요. +리스트처럼 딕셔너리도 `len()`메서드를 사용하여 키-값 쌍의 수를 리턴합니다. 한 번 커맨드라인에서 확인합시다. -`del` 명령어로 딕셔너리에 있는 아이템을 삭제할 수 있습니다. `'favorite_numbers'` 키를 삭제하고 싶으면, 아래와 같은 명령어를 입력하면 됩니다. : +{% filename %}command-line{% endfilename %} +```python +>>> len(participant) +4 +``` - >>> participant.pop('favorite_numbers') - >>> participant - {'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +다들 이해를 잘 하고 있으리라 믿어요 :) 딕셔너리로 좀 더 재미있는 것을 해볼까요? +`pop()`메소드로 딕셔너리에 있는 아이템을 삭제해봅시다. 아래 예제를 따라서 `'favorite_numbers'` 키를 삭제해봅시다. -위에 보여지는 결과처럼 'favorite_numbers' 에 해당하는 키-값 쌍이 삭제되었네요. +{% filename %}command-line{% endfilename %} +```python +>>> participant.pop('favorite_numbers') +[7, 42, 92] +>>> participant +{'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +``` -이뿐만 아니라 딕셔너리 안에 이미 만들어진 키에 해당하는 값도 변경할 수 있습니다. 다음 내용을 해보세요. : +'favorite_numbers' 에 해당하는 키-값 쌍이 삭제되었네요. - >>> participant['country'] = 'Germany' - >>> participant - {'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} +키에 해당하는 값도 변경할 수 있습니다. 이렇게 해보세요. : +{% filename %}command-line{% endfilename %} +```python +>>> participant['country'] = 'Germany' +>>> participant +{'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} +``` -보셨듯이, `'country'` 키에 해당하는 값이 `'Poland'`에서 `'Germany'`로 변경되었네요. :) 재미있죠? 야호! 우리는 또 굉장한 것을 배웠네요. +`'country'` 키에 해당하는 값이 `'Poland'`에서 `'Germany'`로 변경되었네요. :) 재미있죠? 야호! 또 굉장한 것을 배웠네요. ### 요약 -훌륭하네요! 이제 모두가 프로그래밍에 대해서 많은 것을 알게 되었어요. 지금까지 우리가 배운 내용은 다음과 같아요. : +훌륭하네요! 이제 모두가 프로그래밍에 대해서 많은 것을 알게 되었어요. 지금까지 우리가 배운 내용을 정리해볼까요. -* **에러** - 파이썬이 작성된 명령어를 이해하지 못할 때 발생하는 에러를 읽고 이해할 수 있습니다. -* **변수** - 객체에 이름을 붙여 코드를 가독성 좋게 작성할 수 있습니다. -* **리스트** - 특정한 순서로 정렬된 객체들이 저장된 목록임을 알고 있습니다. -* **딕셔너리** - 키(key)-값(value) 쌍으로 이루어진 객체들이 저장된 것임을 알고 있습니다. +* **에러** - 파이썬이 작성된 명령어를 이해하지 못할 때 에러가 발생합니다. +* **변수** - 객체에 적절한 이름을 붙여 코드를 가독성 좋게 작성할 수 있습니다. +* **리스트** - 특정한 순서로 정렬된 객체들이 저장된 목록입니다. +* **딕셔너리** - 키(key)-값(value) 쌍으로 이루어진 객체들이 저장됩니다. 다음 내용이 기대되나요? :) ## 비교하기 -무엇인가 비교하는 것은 프로그래밍에서 매우 중요한 부분이에요. 비교를 할 때, 제일 쉬운 방법은 무엇일까요? 당연히, 숫자입니다. 어떻게 하는지 알아볼게요. : +> 집에서 학습하시는 분들은 [파이썬 기초: 비교연산자(Comparisons)](https://www.youtube.com/watch?v=ZX1CVvZLE6c) 영상을 보세요. - >>> 5 > 2 - True - >>> 3 < 1 - False - >>> 5 > 2 * 2 - True - >>> 1 == 1 - True - >>> 5 != 2 - True +비교는 프로그래밍에서 매우 중요한 부분이에요. 비교를 할 때, 제일 쉬운 방법은 무엇일까요? 바로 숫자입니다. 어떻게 하는지 알아볼게요. : +{% filename %}command-line{% endfilename %} +```python +>>> 5 > 2 +True +>>> 3 < 1 +False +>>> 5 > 2 * 2 +True +>>> 1 == 1 +True +>>> 5 != 2 +True +``` -파이썬이 숫자들을 비교했네요. 여러분도 보았듯이, 파이썬은 숫자 뿐만 아니라 메서드 결과도 비교 가능합니다. 멋지죠? +파이썬이 두 숫자를 비교했네요. 파이썬은 메서드 결과도 비교 가능합니다. 멋지죠? -두 숫자를 비교할 때 왜 등호 부호 `==`를 사용하는지 궁금했죠? 우리는 변수에 값을 넣을 때 한 개의 등호 기호 `=`를 사용하죠. 그렇기 때문에, 두 대상이 같은지 서로 비교하기 위해서는 **항상** 두 개의 등호 기호 `==`를 사용해야 합니다. 마찬가지로 두 대상이 서로 같지 않다라고 말할 수 있습니다. 위 예제에서 볼 수 있었듯이 서로 같은 대상이 아닐 때는 `!=` 기호를 사용합니다. +두 숫자를 비교할 때 왜 등호 부호 `==`를 사용하는지 궁금했죠? 변수에 값을 넣을 때 등호 기호`=` 하나만 사용했기 때문에, 두 대상이 같은지 서로 비교하기 위해서는 **항상** 두 개의 등호 기호 `==`를 사용해야 합니다. 마찬가지로 서로 다른 대상일 경우에는 `!=` 기호를 사용합니다. 두 번 더 테스트 해볼게요. : - >>> 6 >= 12 / 2 - True - >>> 3 <= 2 - False - - -`>`와 `<`는 알겠지만, `>=`와 `<=`는 무슨 뜻일까요? 아래 내용을 읽어보세요. : +{% filename %}command-line{% endfilename %} +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` -* x `>` y : x는 y보다 크다 -* x `<` : x는 y보다 작다 -* x `<=` : x가 y보다 작거나 같다 -* x `>=` : x가 y보다 크거나 같다 -잘했어요! 좀 더 해볼까요? 이런 건 어떨까요. : +`>`와 `<`는 알겠는데, 그렇다면 `>=`와 `<=`는 무슨 뜻일까요? 아래 내용을 읽어보세요. : - >>> 6 > 2 and 2 < 3 - True - >>> 3 > 2 and 2 < 1 - False - >>> 3 > 2 or 2 < 1 - True +- x `>` y : x는 y보다 크다 +- x `<` y : x는 y보다 작다 +- x `<=` y : x가 y보다 작거나 같다 +- x `>=` y : x가 y보다 크거나 같다 +잘했어요! 좀 더 해볼까요? -파이썬은 얼마든지 원하는 만큼 숫자를 비교할 수 있고 답을 알려줄 거에요! 똑똑한 녀석이죠? +{% filename %}command-line{% endfilename %} +```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가 됩니다. +파이썬은 얼마든지 원하는 만큼 숫자를 비교할 수 있고 답을 알려줄 거랍니다! 똑똑한 녀석이죠? -"사과를 오렌지에 비교하기"라는 말을 들어본 적이 있나요? 파이썬에게 시켜봅시다. : +- **and** - `and` 연산자는, 두 값 모두 참(`True`)일 경우에만 결과가 참(`True`)이 됩니다. +- **or** - `or` 연산자는, 둘 중 하나만 참(`True`)일 경우에 결과가 참(`True`)이 됩니다. - >>> 1 > 'django' - Traceback (most recent call last): - File "", line 1, in - TypeError: unorderable types: int() > str() +"사과를 오렌지에 비교하기"라는 말을 들어본 적이 있나요? 파이썬에게 시켜봅시다. +{% 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' +``` 이처럼 파이썬은 숫자(`int`)와 문자열(`str`)을 비교할 수 없어요. 대신 **TypeError**를 보여줘 두 타입이 서로 비교 대상이 아니라는 것을 알려줍니다. -## Boolean (불리언) +## Boolean(불리언) -방금 전 파이썬의 새로운 객체 종류를 배웠는데요. 바로 **Boolean**입니다. 여기 있는 것 중에 가장 쉬운 걸 거에요. +방금 전 파이썬의 새로운 객체 종류를 배웠는데요. 바로 **Boolean**입니다. 이번 장에서 가장 쉬운 내용이에요. -Boolean 객체는 종류는 딱 두 가지 뿐이에요.: - 참(True) - 거짓(False) +불리언의 객체 두가지 입니다. +- True(참) +- False(거짓) -그런데 파이썬이 이해시키려면, 항상 'True'라고 써야 합니다. (즉 첫 글자가 대문자고 나머지는 소문자여야만, Boolean으로 이해하는 것이죠.) **true, TRUE, tRUE는 모두 틀린 표현이에요. -- True만 올바른 표현입니다.** (False도 마찬가지입니다.) +파이썬은 항상`True`라고 써야 이해합니다. 첫 글자가 대문자고 나머지는 소문자여야만, Boolean으로 이해합니다. **true, TRUE, tRUE는 모두 틀린 표현이에요. -- `True`만 올바른 표현입니다.** (`False`도 마찬가지입니다) -Boolean도 변수로 사용할 수도 있습니다! 다음을 보세요. : +불리언을 변수로 사용할 수도 있습니다! 아래 코드를 실행해보세요. - >>> a = True - >>> a - True +{% filename %}command-line{% endfilename %} +```python +>>> a = True +>>> a +True +``` +또 이런 방법으로도 쓸 수 있습니다. -이런 식으로도 쓸 수 있습니다. +{% filename %}command-line{% endfilename %} +```python +>>> a = 2 > 5 +>>> a +False +``` - >>> a = 2 > 5 - >>> a - False +아래 명령어를 실행해보면서 불리언을 가지고 놀아보세요. +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` -아래 명령어를 실행해보면서 Boolean을 가지고 놀아보세요. : +축하합니다! 불리언은 프로그래밍에 있어서 가장 멋진 기능 중 하나에요. 여러분은 불리언을 앞으로 어떻게 사용해야 하는지 방금 배웠답니다! -* `True and True` -* `False and True` -* `True or 1 == 1` -* `1 != 2` +# 코드 저장하기! -축하합니다! Boolean은 프로그래밍에 있어서 가장 멋진 기능 중 하나에요. 여러분은 Boolean을 앞으로 어떻게 사용해야 하는지 방금 배웠답니다! +> **Note** 집에서 학습하는 분들은 [파이썬 기초: 파일 저장 및 "If" 조건문](https://www.youtube.com/watch?v=dOAg6QVAxyk) 영상을 보세요. -# 코드 저장하기! -지금까지 우리는 인터프리터(interpreter)에서 파이썬 코드를 입력해 왔어요. 한 번에 코드 한 줄만 입력할 수 있었어요. 일반적으로 프로그램은 파일로 저장되어 프로그래밍 언어 **인터프리터(interpreter)** 또는 **컴파일러(complier)**로 실행됩니다. 지금까지 우리는 파이썬 **인터프리터**에서 한 줄씩 코드를 입력해 프로그램을 실행시켰어요. 이제 앞으로는 한 줄 이상 더 많은 코드를 작성해 실행해 볼 거에요. 빨리 해볼게요. : +지금까지 우리는 인터프리터(interpreter)에서 파이썬 코드를 입력해 왔어요. 한 번에 코드 한 줄만 입력할 수 있었어요. 일반적으로 프로그램은 파일로 저장되어 프로그래밍 언어 **인터프리터(interpreter)** 또는 **컴파일러(complier)**로 실행됩니다. 지금까지 우리는 파이썬 **인터프리터**에서 한 줄씩 코드를 입력해 프로그램을 실행시켰어요. 이제 앞으로는 한 줄 이상 더 많은 코드를 작성해 실행해 볼 거에요. 빨리 해볼게요. * 파이썬 인터프리터를 종료하세요. * 선택한 코드 에디터를 실행하세요. * 코드를 새 파이썬 파일로 저장하세요. * 실행하세요! -사용했던 파이썬 인터프리터를 종료하려면, exit()~~~ 함수를 입력하세요. : +사용했던 파이썬 인터프리터를 종료하려면, `exit()`함수를 입력하세요. - >>> exit() - $ - - -그러면 커맨드 프롬프트(또는 콘솔창) 가 초기화 됩니다. +{% filename %}command-line{% endfilename %} +```python +>>> exit() +$ +``` -앞서 우리는 [코드 편집기][2] 섹션에서 어떤 코드 편집기를 사용할지 정했었습니다. 이제 편집기를 실행해서 새 코드를 작성하여 새 파일로 저장합니다: +그러면 커맨드 프롬프트(또는 콘솔)가 초기화됩니다. - [2]: ../code_editor/README.md +앞서 우리는 [코드 에디터](../code_editor/README.md) 장에서 사용할 에디터를 정했습니다. 이제 에디터를 실행해 코드를 작성하고 새 파일로 저장합니다. +{% filename %}editor{% endfilename %} ```python - print('Hello, Django girls!') +print('Hello, Django girls!') ``` -> **Note** 우리는 코드 에디터의 멋진 기능을 알고 있어야 해요. : 파이썬 콘솔에서는 모든 코드가 같은 색이였지만, 이제 `print` 함수와 그 안에 있는 문자열이 다른 색깔로 되어 구분할 수 있다는 것을 알게 되었을 거에요. 이를 "문법 하이라이팅(syntax highlighting)" 하는데, 코딩할 때 필요한 기능이죠. 이 기능은 여러분에게 색깔로 힌트를 알려줘요. 예를 들어, 문자열이 제대로 닫히지 않았다던가, 특정 키워드(함수에서 사용하는 `def` 같은 특별한 의미로 쓰이는 단어. 앞으로 다룰 거에요.)를 사용할 때, 다른 색으로 지정해서 바로 알 수 있게 해주죠. 그래서 우리는 코드 에디터를 사용한답니다. :) +당연히 여러분은 숙련된 파이썬 개발자에요. 지금 배운 코드를 자유롭게 작성해보세요. -오늘 우리 모두가 파이썬 개발자가 되었답니다. 그러니 오늘 배운 코드를 가지고 놀아보세요. +이제 파일명과 함께 저장해야합니다. 파일명을 ** python_intro.py **이라고 붙이고 데스크탑에 저장해 봅시다. 파일명은 마음대로 써도 되지만 파일 확장자는 __.py__ 로 끝나야합니다. **.py**파일 확장자로 운영체제에게 **파이썬 실행 파일**이니 파이썬을 실행하라고 지시합니다. -이제 파일을 저장하고 파일 이름을 바꾸세요. 바탕화면에 **python_intro.py** 파일로 저장하세요. 원하는 파일이름으로 저장할 수 있지만, 파일 이름이 반드시 **.py**로 끝나야 해요. **.py**파일 확장자는 운영체제에게 **파이썬 실행 파일**이니 파이썬을 실행하라고 지시합니다. -파일을 저장했다면, 커맨드라인 장에서 배웠던 것을 써먹어야죠! 터미널에서 데스크탑으로 **디렉토리 변경**을 해보세요. +> **Note** 코드 에디터의 멋진 기능을 알고 있어야 해요. 파이썬 콘솔에서는 모든 코드가 같은 색이였지만, 코드 에디터에는 `print()`함수와 문자열이 다른 색상으로 구분되었어요. 이를 `문법 하이라이팅(syntax highlighting)`하는데, 코딩할 때 필요한 기능입니다. 색상로 구분을 파악할 수 있고 오류도 확인할 수 있어요. 예를 들어, 문자열이 제대로 닫히지 않았다던가, 특정 키워드(함수에서 사용하는 `def`)를 사용할 때, 다른 색상으로 구분되기 때문에 쉽게 파악이 가능합니다. 그래서 코드 에디터를 사용하는 거랍니다. :) -맥이라면 명령어는 다음과 같을 것입니다. : +파일을 저장했다면, 커맨드라인 장에서 배웠던 것을 써먹어야죠! 터미널에서 데스크탑(또는 Desktop, 바탕화면)으로 **디렉토리 변경**을 해보세요. - cd ~/Desktop + +맥OS : -리눅스는 다음과 같아요. ("Desktop"이라는 문자는 해당 국어로 번역되어 있을 것에요. 한국어라면 "데스크탑" 또는 "바탕화면"으로 번역되어 있을 것입니다.) +{% filename %}command-line{% endfilename %} +``` +$ cd ~/Desktop +``` + - cd ~/Desktop + - 또는 "바탕화면"으로 번역되어 있다면 - cd ~/바탕화면 +리눅스 : +{% filename %}command-line{% endfilename %} +``` +$ cd ~/Desktop +``` - 또는 "데스크탑"으로 번역되어 있다면 - cd ~/데스크탑 + + -윈도우라면 다음과 같이 하세요. : +윈도우 : - > cd %HomePath%\Desktop +{% filename %}command-line{% endfilename %} +``` +> cd %HomePath%\Desktop +``` + +따라하다 어려움이 있다면, 코치에게 도움을 요청하세요. -혹시 하다가 막히면, 코치에게 도움을 요청하세요. +파일 내 코드를 실행하기 위해 파이썬을 불러봅시다. -이제 파일 안에 있는 코드를 실행하기 위해 다음과 같이 파이썬을 실행해 봅시다. : +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hello, Django girls! +``` - $ python3 python_intro.py - Hello, Django girls! +> **Note** 윈도우에서 'python3' 명령어를 인식하지 못하면 'python'라고 입력하세요. -잘했어요! 우리는 첫 파이썬 프로그램이 저장된 파일을 실행했어요. 내가 드디어 해냈다고 느껴지나요? +잘했어요! 드디어 파이썬 프로그램이 저장된 파일을 실행했어요. 뿌듯하죠? -다음으로 프로그래밍의 필수 도구를 알아볼 차례에요. : +다음으로 프로그래밍의 필수 도구를 배울 차례에요. ## If...elif...else -코드의 많은 부분은 조건을 만났을 때 실행된답니다. 이를 위해 파이썬은 **if문**을 사용합니다. +대부분의 코드는 조건문을 만났을 때 실행됩니다. 파이썬은 **if**문을 사용합니다. -**python_intro.py** 파일을 다음과 같이 수정하세요: +**python_intro.py** 파일을 다음과 같이 수정하세요. +{% filename %}python_intro.py{% endfilename %} ```python - if 3 > 2: +if 3 > 2: ``` -저장하고 실행하면 아래와 같은 에러를 보게 될 거에요. : - - $ python3 python_intro.py - File "python_intro.py", line 2 - ^ - SyntaxError: unexpected EOF while parsing +저장하고 실행하면 아래와 같은 에러가 보일 거에요. +{% filename %}{{warning_icon}}command-line{% endfilename %} +``` +$ python3 python_intro.py +File "python_intro.py", line 2 + ^ +SyntaxError: unexpected EOF while parsing +``` -파이썬은 조건문 `3 > 2`가 참인 경우(또는 값이 `True`인 경우)에 어떤할 지 물어 보네요. 이 경우에 파이썬이 "It works!"를 출력하게 해봅시다. : **python_intro.py** 파일을 아래와 같이 수정하세요. : +파이썬은 조건문 `3 > 2`가 참인 경우(또는 값이 `True`인 경우)에 어떻게 할 것인지 물어보네요. 이 경우에 파이썬이 "It works!"를 출력하게 해봅시다. **python_intro.py** 파일을 아래와 같이 수정하세요. +{% filename %}python_intro.py{% endfilename %} ```python - if 3 > 2: - print('It works!') +if 3 > 2: + print('It works!') ``` -두 번째 줄 들여쓰기 된 코드에 스페이스 4칸을 준 게 보이나요? 조건의 결과(여기서는 3>2) 가 참일 경우에, 실행할 코드에 들여쓰기를 해줘야 합니다. 물론 스페이스 한 칸만 띄울 수 있지만, 거의 모든 파이썬 프로그래머들은 코드를 깔끔하게 작성하기 위해 4칸을 사용해요. `탭(tab)` 한 번은 스페이스 4칸을 준 것과 같아요. +두 번째 줄에 들여쓰기 된 코드에 스페이스 4칸을 준 게 보이나요? 조건의 결과(`3 > 2`) 가 참일 경우에, 실행할 코드에 들여쓰기를 해줘야 합니다. 물론 스페이스 한 칸만 띄울 수 있지만, 거의 모든 파이썬 프로그래머들은 코드를 정갈하게 작성하기 위해 4칸을 사용해요. `탭(tab)`한 번은 들여쓰기 4칸과 같습니다. -이제 저장하고 실행해보세요. : - - $ python3 python_intro.py - It works! +이제 저장하고 실행해보세요. +{% filename %}command-line{% endfilename %} +```python +$ python3 python_intro.py +It works! +``` ### 조건이 참(True) 이 아니라면 어떻게 되나요? -앞의 예제에서 코드가 조건이 True인 경우에만 실행되게 만들었어요. 하지만 파이썬은 `elif`문과 `else`문도 사용할 수 있습니다. +앞 예제에서 조건이 참(`True`)인 경우에만 실행되게 만들었어요. 하지만 파이썬은 `elif`문과 `else`문도 사용할 수 있습니다. +{% filename %}python_intro.py{% endfilename %} ```python - if 5 > 2: - print('5 is indeed greater than 2') - else: - print('5 is not greater than 2') +if 5 > 2: + print('5 is indeed greater than 2') +else: + print('5 is not greater than 2') ``` -실행하면 다음과 같이 출력됩니다. : - - $ python3 python_intro.py - 5 is indeed greater than 2 +실행하면 다음과 같이 출력됩니다. +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +5 is indeed greater than 2 +``` -만약 2가 5보다 크다면 두번째 명령이 실행됩니다. 참 쉽죠? 이제 `elif`가 어떻게 작동하는지 봅시다. : +만약 2가 5보다 크다면 두번째 명령이 실행됩니다. 참 쉽죠? 이제 `elif`가 어떻게 작동하는지 봅시다. +{% filename %}python_intro.py{% endfilename %} ```python - name = 'Sonja' - if name == 'Ola': - print('Hey Ola!') - elif name == 'Sonja': - print('Hey Sonja!') - else: - print('Hey anonymous!') +name = 'Sonja' +if name == 'Ola': + print('Hey Ola!') +elif name == 'Sonja': + print('Hey Sonja!') +else: + print('Hey anonymous!') ``` -그리고 실행해보세요. : - - $ python3 python_intro.py - Hey Sonja! +그리고 실행해보세요. +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hey Sonja! +``` 어떻게 됐나요? `elif`문은 맨 처음 조건이 아닐 경우 그 다음 조건을 처리하게 해줍니다. -여러분은 `if` 문을 쓴 다음에 원하는 만큼 `elif` 문을 계속 추가할 수 있어요. 이렇게요. : +`if` 문을 쓴 다음에 원하는 만큼 `elif` 문을 계속 추가할 수 있어요. 이렇게요. +{% filename %}python_intro.py{% endfilename %} ```python - volume = 57 - if volume < 20: - print("It's kinda quiet.") - elif 20 <= volume < 40: - print("It's nice for background music") - elif 40 <= volume < 60: - print("Perfect, I can hear all the details") - elif 60 <= volume < 80: - print("Nice for parties") - elif 80 <= volume < 100: - print("A bit loud!") - else: - print("My ears are hurting! :(") +volume = 57 +if volume < 20: + print("It's kinda quiet.") +elif 20 <= volume < 40: + print("It's nice for background music") +elif 40 <= volume < 60: + print("Perfect, I can hear all the details") +elif 60 <= volume < 80: + print("Nice for parties") +elif 80 <= volume < 100: + print("A bit loud!") +else: + print("My ears are hurting! :(") ``` 파이썬이 각 테스트를 순서대로 실행하고 출력합니다: - $ python3 python_intro.py - Perfect, I can hear all the details +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Perfect, I can hear all the details +``` +## 주석(Comments) + +주석은 `#`으로 시작하는 줄입니다. 파이썬은 `#`의 내용을 무시합니다. 주석은 코드를 읽는 다른 사람들이 보다 쉽게 이해할 수 있도록 작성합니다. +아래 예제를 보세요. : + +{% filename %}python_intro.py{% endfilename %} +```python +# volume 값을 바꿔보세요 +if volume < 20 or volume > 80: + volume = 50 + print("That's better!") +``` + +모든 라인마다 주석을 작성할 필요는 없지만, 코드의 역할과 복잡한 수행 내용을 정리 요약할 때 사용됩니다. ### 요약 -지금까지 우리는 세 예제로 다음과 같은 것들을 배웠어요. : +지금까지 배운 내용을 정리해봅시다. -* **비교하기** - 파이썬에서 `>`, `>=`, `==`, `<=`, `<` 그리고 `and`, `or` 연산자를 사용해 비교합니다. -* **Boolean** -두 둘 중 하나의 값만 가질 수 있는 객체입니다. : `True` 또는 `False` -* **파일 저장하기** - 복잡한 프로그램을 실행할 수 있도록 코드를 파일로 저장합니다. -* **if...elif...else** - 조건문을 작성해 특정 조건이 주어졌을 때만 코드가 실행되도록 만듭니다. +- **비교하기** - 파이썬에서 `>`, `>=`, `==`, `<=`, `<` 그리고 `and`, `or` 연산자를 사용해 비교합니다. +- **불리언(Boolean)** -두 둘 중 하나의 값만 가질 수 있는 객체입니다. `True` 또는 `False` +- **파일 저장하기** - 복잡한 프로그램을 실행할 수 있도록 코드를 파일로 저장합니다. +- **`if`...`elif`...`else`** - 조건문을 작성해 특정 조건이 주어졌을 때만 코드가 실행되도록 만듭니다. 드디어 이번 장의 마지막 부분입니다! ## 나만의 함수 만들기! -앞에서 했던 파이썬 `len()` 같은 함수를 기억하나요? 네, 좋은 소식이에요. 지금부터는 함수를 만드는 법을 배울 거에요! +> **Note** 집에서 학습하는 분들은 [파이썬 기초: 함수](https://www.youtube.com/watch?v=5owr-6suOl0) 영상을 보세요. + +앞에서 했던 `len()`와 같은 함수를 사용했었죠? 지금부터는 직접 함수를 만드는 법을 배울 거에요! -함수는 파이썬이 실행해야하는 명령어의 나열이에요. 파이썬의 각 함수는 `def`로 시작해, 이름을 가지고, 몇 가지 매개 변수를 가집니다. 쉬운 것부터 시작할게요. **python_intro.py**파일을 열어 코드를 다음과 같이 고치세요. : +함수는 파이썬이 명령어의 나열이에요. 파이썬의 각 함수는 `def`로 시작하고, 이름을 붙일 수 있고, 여러 매개변수를 가질 수 있어요. 쉬운 것부터 시작할게요. **python_intro.py** 파일을 열어 코드를 다음과 같이 고치세요. +{% filename %}python_intro.py{% endfilename %} ```python - def hi(): - print('Hi there!') - print('How are you?') +def hi(): + print('Hi there!') + print('How are you?') - hi() +hi() ``` -네, 우리가 만든 첫 번째 함수네요! +우리가 만든 첫 번째 함수네요! -파일 맨 밑에 왜 함수의 이름을 적는지 궁금할거에요. 왜냐하면 파이썬은 파일을 위에서 아래로 읽어 실행하기 때문이에요. 함수를 사용하기 위해서는 하단에 다시 적어야 합니다. +파일 맨 밑에 왜 함수의 이름을 적었는지 궁금할 거에요. 왜냐하면 파이썬은 파일을 위에서 아래로 읽어 실행하기 때문이에요. 함수를 사용하기 위해서는 하단에 다시 적어야 합니다. -이제 실행해서 어떻게 되는지 봅시다. : +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hi there! +How are you? +``` - $ python3 python_intro.py - Hi there! - How are you? +> **Note** 동작하지 않더라도 당황하지 마십시오! 에러 메세지와 출력값은 원인을 파악하고 해결할 수 있게 도와줍니다. +- `NameError`에러는 잘못 입력한 내용이 있을 때 발생합니다. `def hi () :`로 함수를 생성 할 때와`hi ()`로 호출 할 때 같은 이름을 사용했는지 확인하세요. +- `IndentationError`에러가 나오면, `print` 라인 둘 다 라인의 시작 부분에 같은 공백을 가지고 있는지 확인하세요. 파이썬은 함수 안의 모든 코드가 깔끔하게 정렬되어야합니다. +- 출력값이 보이지 않는다면 마지막 `hi()`가 *들여쓰기가 되었는지* 를 확인하세요. - 들여쓰기가 된 행은 함수의 일부가 되기 떄문에 실행되지 않습니다. -정말 간단하네요! 매개 변수와 함께 첫 번째 함수를 만들어 볼게요. 전에 사용했던 예제를 다시 사용할 거에요. 함수를 실행하면, 사람들에게 이름과 함께 'hi'를 말하게요. +다음으로 매개 변수와 함께 첫 번째 함수를 만들어 볼게요. 전에 사용했던 예제를 다시 사용할 거에요. 함수를 실행하면, 이름을 부르고 'hi'를 말하게요. +{% filename %}python_intro.py{% endfilename %} ```python - def hi(name): +def hi(name): ``` -함수에 매개변수인 `name`를 주었어요. +함수에 매개변수인 `name`를 넣었어요. : +{% filename %}python_intro.py{% endfilename %} ```python - def hi(name): - if name == 'Ola': - print('Hi Ola!') - elif name == 'Sonja': - print('Hi Sonja!') - else: - print('Hi anonymous!') +def hi(name): + if name == 'Ola': + print('Hi Ola!') + elif name == 'Sonja': + print('Hi Sonja!') + else: + print('Hi anonymous!') - hi() +hi() ``` -기억하세요 : `if`문 안의 `print`함수는 4칸을 들여쓰기 했습니다. 조건문에 해당하는 경우에만 실행되게 만들기 위해서에요. 이제 어떻게 되는지 보세요. : - - $ 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' +> **Note**: `if`문 안의 `print()`함수는 4칸을 들여쓰기 했습니다. 조건문에 해당하는 경우에만 실행되게 만들기 위해서에요. 이제 어떻게 되는지 보세요. +{% 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' +``` -이런, 에러가 나왔네요. 다행히도, 파이썬 에러는 유용한 오류 메세지를 보여주네요. 에러 메시지를 보면 함수 `hi()`가 한 개의 인자값(`name`) 을 필요로 하는데, 그 함수를 호출할 때 빼먹고 실행했다는 것을 알려주고 있어요. 이제 아래와 같이 코드를 수정해봅시다. : +이런, 에러가 나왔네요. 다행히도, 파이썬 에러는 유용한 오류 메세지를 보여준답니다. 에러 메시지를 보면 함수 `hi()`가 한 개의 인자값(`name`) 을 필요로 하는데, 그 함수를 호출할 때 빼먹고 실행했다는 것을 알려주고 있어요. 이제 아래와 같이 코드를 수정해봅시다. +{% filename %}python_intro.py{% endfilename %} ```python - hi("Ola") +hi("Ola") ``` -그리고 다시 실행해보세요. : - - $ python3 python_intro.py - Hi Ola! +그리고 다시 실행해보세요. +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hi Ola! +``` -만약 이름을 바꾸면 어떻게 될까요? +이름을 바꿔볼까요? +{% filename %}python_intro.py{% endfilename %} ```python - hi("Sonja") +hi("Sonja") ``` -그리고 실행하세요. : - - $ python3 python_intro.py - Hi Sonja! +그리고 실행하세요. +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hi Sonja! +``` -이제 다른 이름(Ola와 Sonja가 아닌) 을 넣는다면 어떻게 될까요? 한번 넣어서 실행해봅시다. 이렇게 나와야 해요. : - Hi anonymous! +이제 다른 이름(Ola와 Sonja가 아닌)을 넣는다면 어떻게 될까요? 아래처럼 나오게 만들어보세요. : +{% filename %}command-line{% endfilename %} +``` +Hi anonymous! +``` -어때요, 정말 굉장하지 않나요? 이로써 인사 함수가 호출될 때마다, 사람 이름을 매번 반복할 필요가 없어요. 그래서 함수가 필요해요 - 매번 똑같은 코드를 반복해 작성하지 않아도 돼요! +어때요, 정말 굉장하지 않나요? 이로써 인사 함수가 호출될 때마다, 매번 사람 이름을 반복할 필요가 없어요. 그래서 함수가 필요답니다. 매번 똑같은 코드를 반복해 작성하지 않아도 돼요! -좀 더 똑똑한 것을 해볼게요. -- 2명 이상 이름이 있는 경우, 이름마다 조건문을 추가하는 건 꽤 귀찮은 일이 될거에요. 그렇죠? +좀 더 똑똑하게 만들어 볼게요. 2명 이상 이름이 있는 경우, 모든 이름마다 조건문을 추가하는 건 꽤 귀찮은 일이 될거에요. 그렇죠? +{% filename %}python_intro.py{% endfilename %} ```python - def hi(name): - print('Hi ' + name + '!') +def hi(name): + print('Hi ' + name + '!') - hi("Rachel") +hi("Rachel") ``` -이제 코드를 실행해 봅시다: - - $ python3 python_intro.py - Hi Rachel! +이제 코드를 실행해 봅시다. : +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hi Rachel! +``` -축하합니다! 우리는 이제 함수를 작성하는 법을 알게 되었어요! :) +축하합니다! 우리는 이제 함수를 만들 수 있게 되었어요! :) ## 반복하기 +> 집에서 학습하는 분들은 [파이썬 기초: For 문](https://www.youtube.com/watch?v=aEA6Rc86HF0) 영상을 보세요. + 이제 마지막 부분입니다. 금방 했죠? :) -프로그래머는 반복되는 일을 스스로 하기를 좋아하지 않아요. 프로그래밍이란 어떤 일들을 자동화하는 것이니까 반복적인 경우가 생기면 그걸 반복해서 해결하는 코드를 짜는 것이지요. 앞에서 했던 예제와 같이 인사해야 하는 사람이 수백명 있을 경우, 설마 각각 사람마다 인사하려고 hi('누구누구') 코드를 수백번 입력하고 싶지는 않겠지요? 이런 경우에 바로 반복문(loop)를 사용할 수 있어요. +프로그래머는 반복되는 일을 하는 것을 좋아하지 않아요. 프로그래밍은 모든 것을 자동화하는 것입니다. 모든 사람의 이름을 일일이 입력해서 hi 라는 메세지를 출력하게 만들고 싶지 않겠죠. 반복문을 사용하면 이를 해결할 수 있습니다. -리스트 아직 기억하고 있어요? 아래 girls 리스트를 보세요. : +리스트를 기억하고 있죠? 아래 girls 리스트를 보세요. +{% filename %}python_intro.py{% endfilename %} ```python - girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] ``` -우리는 여자 아이들 이름을 불러 인사를 하고 싶어요. 우리는 이미 `hi` 함수를 만들었으니 반복문을 사용해봅시다. : +우리는 여자 아이들 이름을 불러 인사를 하고 싶어요. 우리는 이미 `hi` 함수를 만들었으니 반복문을 사용해봅시다. :) +{% filename %}python_intro.py{% endfilename %} ```python - for name in girls: +for name in girls: ``` -for~~~ 문은 if~~~ 문과 비슷하게 동작합니다. ; 두 경우 모두 다음에 오는 코드들을 4칸 들여쓰기 해야합니다. +```for```과 ```if```문의 다음 줄은 4칸 들여쓰기를 해야합니다. -아래 완성된 코드입니다. : +아래 완성된 코드입니다. +{% filename %}python_intro.py{% endfilename %} ```python - def hi(name): - print('Hi ' + name + '!') +def hi(name): + print('Hi ' + name + '!') - girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] - for name in girls: - hi(name) - print('Next girl') +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +for name in girls: + hi(name) + print('Next girl') ``` -실행하면 다음과 같습니다. : +실행하면 다음과 같습니다. - $ python3 python_intro.py - Hi Rachel! - Next girl - Hi Monica! - Next girl - Hi Phoebe! - Next girl - Hi Ola! - Next girl - Hi You! - Next girl +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hi Rachel! +Next girl +Hi Monica! +Next girl +Hi Phoebe! +Next girl +Hi Ola! +Next girl +Hi You! +Next girl +``` -`girls` 리스트의 요소마다 여러분이 `for`문에 넣은, 들여쓰기를 한 모든 코드들이 반복됩니다. +`girls` 리스트의 요소마다 여러분이 `for`문 안에 들여쓰기를 한 모든 코드들이 반복됩니다. -`for`문에 `range` 함수로 숫자를 사용할 수 있어요. +`for`문에 `range()` 함수로 숫자범위를 지정해 사용할 수 있어요. +{% filename %}python_intro.py{% endfilename %} ```python - for i in range(1, 6): - print(i) +for i in range(1, 6): + print(i) ``` -이렇게 출력됩니다. : - - 1 - 2 - 3 - 4 - 5 +이렇게 출력됩니다. +{% filename %}command-line{% endfilename %} +``` +1 +2 +3 +4 +5 +``` -`range`는 매개 변수로 넘겨진 숫자부터 시작하는 숫자 리스트를 만들어주는 함수입니다. +`range()`는 매개변수로 넘겨진 숫자부터 시작하는 숫자 리스트를 만들어주는 함수입니다. -파이썬에서는 두 숫자 중 두 번째는 리스트에 포함되지 않는다는 것을 주의하세요. (즉 `range(1, 6)`는 1부터 5까지 카운트 하며 숫자 6은 리스트에 포함되지 않습니다.) "range"는 반만 열려 있기 때문에, 첫번째 숫자는 포함되지만 마지막 숫자는 포함되지 않아요. +두 숫자 중 두 번째(마지막)숫자는 리스트에 포함되지 않는다는 것을 기억하세요. (즉 `range(1, 6)`는 1부터 5까지 카운트 하며 숫자 6은 리스트에 포함되지 않습니다) "range()"는 반만 열려 있기 때문에, 첫번째 숫자는 포함되지만 마지막 숫자는 포함되지 않아요. ## 요약 -이제 다 끝났어요. **모두 정말 대단해요!** 어려운 내용이었는데 잘 해낸 나 자신을 자랑스럽게 생각하세요. 여기까지 온 것이 자랑스럽습니다! - -다음 장으로 넘어가지 전에 좀 쉬고 와도 좋아요. 스트레칭을 하던가, 잠깐 산책을 하던가, 눈을 쉬게 한다던가 말이죠. :) +이제 다 끝났어요. **모두 정말 대단해요!** 지금까지 어려운 내용을 잘 따라온 여러분들이 정말 자랑스러워요! -![컵케이크][3] +다음 장으로 가기전에 잠시 쉬는 시간을 가져도 좋아요. 스트레칭을 하던가, 잠깐 산책을 하던가, 눈을 쉬게 한다던가 말이죠. :) - [3]: images/cupcake.png +![Cupcake](images/cupcake.png) diff --git a/ko/python_introduction/images/cupcake.png b/ko/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/ko/python_introduction/images/cupcake.png and b/ko/python_introduction/images/cupcake.png differ diff --git a/ko/template_extending/README.md b/ko/template_extending/README.md index 00af8a02eb3..d0f1e844b78 100755 --- a/ko/template_extending/README.md +++ b/ko/template_extending/README.md @@ -8,7 +8,7 @@ 기본 템플릿은 웹사이트 내 모든 페이지에 확장되어 사용되는 가장 기본적인 템플릿입니다. -`blog/templates/blog/`에 `base.html` 파일을 만들어 봅시다: +`blog/templates/blog/`에 `base.html` 파일을 만들어 봅시다. : blog └───templates @@ -19,8 +19,9 @@ 그 다음 파일을 열어 `post_list.html`에 있는 모든 내용을 `base.html`에 아래 내용을 복사해 붙여넣습니다. +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} Django Girls blog @@ -53,8 +54,9 @@ ``` -그 다음 `base.html`에서 `` (``와 `` 사이에 있는 모든 내용)의 모든 내용을 아래와 같이 바꿉니다: +그 다음 `base.html`에서 `` (``와 `` 사이에 있는 모든 내용)의 모든 내용을 아래와 같이 바꿉니다. : +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html ``` - Salve esses arquivos e atualize seu site. -![Figura 14.4][8] - - [8]: images/final.png +![Figura 14.4](images/final.png) -Uhuu! Ficou incrível, né? O código que nós acabamos de colar não é tão difícil de entender e você deve ser capaz de entender a maior parte apenas lendo. +Uau! Está lindo, né? Olhe para o código que acabamos de colar para encontrar os locais onde adicionamos classes no HTML e as usamos no CSS. Onde você faria uma mudança se você quisesse a data na cor turquesa? -Não tenha medo de mexer um pouco com esse CSS e tentar mudar algumas coisas. Se você quebrar alguma coisa, não se preocupe, você sempre pode desfazê-lo! +Não tenha medo de mexer um pouco com esse CSS e tentar mudar algumas coisas. Brincar com o CSS pode ajudá-la a entender o que diferentes coisas estão fazendo. Se quebrar algo, não se preocupe - você sempre pode desfazer! -De qualquer forma, recomendamos que faça esse curso on-line [Codeacademy HTML & CSS Course][2] como dever de casa pós-workshop para aprender tudo o que você precisa saber sobre como tornar seus sites mais bonitos com CSS. +Nós realmente recomendamos fazer este curso gratuito on-line: [Curso de HTML & CSS do Codeacademy](https://www.codecademy.com/tracks/web). Isso pode ajudá-la a aprender tudo sobre como deixar seus sites mais bonito com CSS. -Pronto para o próximo capítulo?! :) +Pronta para o próximo capítulo?! :) \ No newline at end of file diff --git a/pt/css/images/bootstrap1.png b/pt/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/pt/css/images/bootstrap1.png and b/pt/css/images/bootstrap1.png differ diff --git a/pt/css/images/color2.png b/pt/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/pt/css/images/color2.png and b/pt/css/images/color2.png differ diff --git a/pt/css/images/final.png b/pt/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/pt/css/images/final.png and b/pt/css/images/final.png differ diff --git a/pt/css/images/font.png b/pt/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/pt/css/images/font.png and b/pt/css/images/font.png differ diff --git a/pt/css/images/margin2.png b/pt/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/pt/css/images/margin2.png and b/pt/css/images/margin2.png differ diff --git a/pt/deploy/README.md b/pt/deploy/README.md index cc776c8520d..f7143d87e74 100755 --- a/pt/deploy/README.md +++ b/pt/deploy/README.md @@ -1,90 +1,80 @@ -# Implantação! +# Deploy! -> **Nota** O capítulo seguinte pode ser às vezes um pouco difícil de passar. Persista e termine-o; Implantação é uma parte importante do processo de desenvolvimento de website. Este capítulo está localizado no meio do tutorial para que seu tutor possa lhe ajudar com o processo ligeiramente complexo de colocar seu site online. Isto significa que você ainda pode terminar o tutorial por conta própria se você continuar em outro momento. +> **Observação:** Pode ser um pouco difícil chegar ao final desse capítulo. Persista e termine-o; o deploy é uma parte importante do processo de desenvolvimento de um website. Colocar o seu site no ar é um pouco mais complicado, então esse capítulo está no meio do tutorial para que sua monitora possa lhe ajudar nessa tarefa. Isto significa que você pode terminar o tutorial por conta própria se o tempo acabar. -Até agora nosso site só estava disponível no seu computador, agora você vai aprender como publicar ele na internet! A implantação é o processo de publicação do seu aplicativo na Internet de tal forma que as pessoas possam, finalmente, ver seu aplicativo :). +Até agora, seu site só estava disponível no seu computador. Agora você aprenderá como implantá-lo (fazer o 'deploy')! O deploy é o processo de publicação da sua aplicação na Internet de forma que as pessoas possam, finalmente, vê-la. :) -Como você aprendeu, um website precisa estar localizado num servidor. Existem muitos provedores, mas iremos utilizar o que tem um processo de deploy relativamente simples: [PythonAnywhere][1]. PythonAnywhere é gratuito para aplicações pequenas que não possuem muitos visitantes, então será suficiente para você por enquanto. +Como você aprendeu, um website precisa estar em um servidor. Existem vários provedores de servidores na internet, nós vamos usar o [PythonAnywhere](https://www.pythonanywhere.com/). O PythonAnywhere é gratuito para pequenas aplicações que não recebem muitos visitantes, então vai ser suficiente para você por enquanto. - [1]: https://pythonanywhere.com/ +O outro serviço externo que usaremos é [GitHub](https://www.github.com), que é um serviço de hospedagem de código. Existem outros, mas atualmente quase todos os programadores possuem uma conta no GitHub e agora, você também terá a sua! -O outro serviço externo que usaremos é [GitHub][2], que é um serviço de hospedagem de código. Existem outros, mas quase todos os programadores possuem uma conta no GitHub atualmente e agora você também! - - [2]: https://www.github.com - -Usaremos o GitHub como um trampolim para transportar nosso código para o PythinAnywhere. +Estes três lugares serão importantes para você. Seu computador local é o lugar onde você fará o desenvolvimento e testes. Quando estiver satisfeita com as mudanças, você colocará uma cópia de seu programa no GitHub. Seu site estará na PythonAnywhere e você irá atualizá-lo ao subir uma nova cópia do seu código para o GitHub. # Git -Git é "sistema de controle de versão" usado por muitos programadores - um software que controla mudanças nos arquivos ao longo do tempo para que você possa recuperar versões específicas depois. Um pouco como "controlar mudanças" no Microsoft Word, mas muito mais poderoso. - -## Instalando o Git - -### Windows - -Você pode baixar Git em [git-scm.com][3]. Você pode apertar "next next next" em todos os passos exceto um; no quinto passo chamado "Adjusting your PATH environment", escolha "Run Git and associated Unix tools from the Windows command-line" (a opção de baixo). Além disso, o padrão está ótimo. Checkout estilo Windows, commit Unix-style linhas de confirmação está bom. - - [3]: https://git-scm.com/ - -### MacOS +> **Observação:** Se você já fez os passos de instalação, não precisa fazer novamente - você pode pular para a próxima seção e comece a criar seu repositório Git. -Baixar Git [git-scm.com][3] e siga as instruções. +{% include "/deploy/install_git.md" %} -### Linux +## Começando o seu repositório no Git -Se ele já não estiver instalado, Git deve estar disponível através de seu gerenciador de pacotes, então tente: +O Git controla as alterações em um determinado conjunto de arquivos no que chamamos de repositório de código (ou "repo"). Vamos criar um para o nosso projeto. Abra o seu console e execute esses comandos no diretório `djangogirls`: - sudo apt-get install git - # or - sudo yum install git +> **Observação:** Verifique o seu diretório atual com um `pwd` (OSX/Linux) ou o comando `cd` (Windows) antes de inicializar o repositório. Você deve estar na pasta `djangogirls`. - -## Começando nosso repositório no Git - -Git controla as alterações para um determinado conjunto de arquivos no que chamamos de repositório de código (ou "repo"). Vamos começar um para nosso projeto. Abra o console e execute esses comandos, no diretório `djangogirls`: - -> **Nota**: Verifique o seu diretório de trabalho atual com um `pwd` (OSX/Linux) ou o comando `cd` (Windows) antes de inicializar o repositório. Você deve estar na pasta `djangogirls`. +{% filename %}command-line{% endfilename %} $ git init Initialized empty Git repository in ~/djangogirls/.git/ - $ git config user.name "Your Name" - $ git config user.email you@example.com + $ git config --global user.name "Seu Nome" + $ git config --global user.email voce@exemplo.com + +Só é necessário iniciar o repositório Git uma vez por projeto (e você não vai precisar preencher seu nome de usuário e e-mail nunca mais). -Inicializar o repositório git é algo que só precisamos fazer uma vez por projeto (e você não terá que re-introduzir o nome de usuário e e-mail nunca mais) +O Git irá controlar as alterações em todos os arquivos e pastas neste diretório, mas existem alguns arquivos que queremos que ele ignore. Fazemos isso através da criação de um arquivo chamado `.gitignore` no diretório base. Abra seu editor e crie um novo arquivo com o seguinte conteúdo: -Git irá controlar as alterações para todos os arquivos e pastas neste diretório, mas existem alguns arquivos que queremos ignorar. Fazemos isso através da criação de um arquivo chamado `.gitignore` no diretório base. Abra seu editor e crie um novo arquivo com o seguinte conteúdo: +{% filename %}.gitignore{% endfilename %} *.pyc + *~ __pycache__ myvenv db.sqlite3 + /static .DS_Store + +E salve-o como `.gitignore` na pasta "djangogirls". -E salve como `.gitignore` na pasta de nível superior "djangogirls". +> **Observação:** O ponto no início do nome do arquivo é importante! Se você estiver tendo alguma dificuldade em criá-lo (Macs, por exemplo, não gostam quando você tenta criar arquivos que começam com um ponto por meio do Finder), use a função "Salvar Como..." no seu editor; não tem como errar. E certifique-se de não adicionar *.txt *, *.py *, ou qualquer outra extensão ao nome do arquivo - ele só será reconhecido pelo Git se o nome for apenas *.gitignore *. +> +> **Observação:** Um dos arquivos especificados no seu `.gitignore` é o `db.sqlite3`. Este arquivo é o seu banco de dados local, onde todos os seus posts ficarão guardados. Seguiremos a prática padrão de programação na web, o que significa que usaremos bancos de dados separados para o seu site de teste local e seu site ao vivo no PythonAnywhere. Esse banco poderia ser SQLite, como na sua máquina de desenvolvimento, mas normalmente você utilizará um chamado MySQL, que consegue lidar com bem mais visitantes ao site do que o SQLite. De qualquer forma, ignorando o seu banco de dados SQLite para a cópia do GitHub, todos os posts criados até agora vão estar disponíveis apenas no seu ambiente local, e você vai ter que criá-los novamente em produção. Pense no seu banco de dados local como um bom parque de diversões onde você pode testar coisas diferentes e não ter medo de apagar os posts reais do seu blog. -> **Nota**: O ponto no início do nome do arquivo é importante! Se você está tendo alguma dificuldade em criá-la (Macs não gostam de criar arquivos que começam com um ponto através do Finder, por exemplo), use o recurso "Save As" no seu editor que sempre funciona. +É uma boa idéia usar um comando `git status` antes de `git add` ou sempre que você não tiver certeza do que mudou. Isso evitará quaisquer surpresas, como os arquivos errados serem adicionados ou "commitados". O comando `git status` mostra informações sobre arquivos que não estão sendo controlados, arquivos que foram modificados ou preparados (staged), o status do branch, e muito mais. A saída do comando deve ser parecida com o seguinte: -É uma boa idéia para usar um comando de `git status` antes de `git add` ou sempre que você não tiver certeza de que será feito, para evitar surpresas (por exemplo, serão adicionados arquivos errados ou commitados). O comando `git status` retorna informações sobre todos os arquivos controlado/modificado/encenado, status de ramo e muito mais. O output deve ser semelhante a: +{% filename %}linha de comando{% endfilename %} $ git status On branch master - - Initial commit - + + No commits yet + Untracked files: (use "git add ..." to include in what will be committed) - - .gitignore - blog/ - manage.py - mysite/ - + + .gitignore + blog/ + manage.py + mysite/ + requirements.txt + nothing added to commit but untracked files present (use "git add" to track) + +E finalmente salvamos nossas alterações. Vá para o seu console e execute estes comandos: -E finalmente nós salvamos nossas alterações, Vá para o seu console e execute estes comandos: +{% filename %}linha de comando{% endfilename %} $ git add --all . $ git commit -m "My Django Girls app, first commit" @@ -93,225 +83,138 @@ E finalmente nós salvamos nossas alterações, Vá para o seu console e execute create mode 100644 .gitignore [...] create mode 100644 mysite/wsgi.py + +## Subindo o seu código para o GitHub -## Empurrando o nosso código para GitHub - -Vá para [GitHub.com][4] e cadastre uma nova e gratuita conta de usuário. Em seguida, crie um novo repositório, e dê o nome "my-first-blog". Deixe o "initialise with a README" desmarcado, deixe a opção .gitignore em branco (já fizemos isso manualmente) e a licença como None. +Vá para [GitHub.com](https://www.github.com) e cadastre uma conta de usuário. (Se você já fez isso em preparação para a oficina, ótimo!) Certifique-se de lembrar da sua senha (adicione-a ao seu gerenciador de senhas, se usar um). - [4]: https://www.github.com' +Em seguida, crie um novo repositório chamado "my-first-blog". Deixe a caixa "Initialize with a README" desmarcada, deixe a opção do .gitignore em branco (nós já fizemos isso manualmente) e deixe a licença como "None". -![][5] +![](images/new_github_repo.png) - [5]: images/new_github_repo.png +> **Observação:** O nome `my-first-blog` é importante - você poderia escolher qualquer outra coisa, mas ele vai aparecer várias vezes nas instruções abaixo, e você teria que substituir todas as vezes. É mais fácil simplesmente manter o nome `my-first-blog`. -> **Nota** O nome `my-first-blog` é importante --você poderia escolher outra coisa, mas vamos usá-lo muitas vezes nas instruções abaixo e você teria que substituí-lo cada vez. É provavelmente mais fácil ficar com o nome `my-first-blog`. +Na próxima tela, você verá a URL de clonagem do seu repositório, que utilizará em alguns dos comandos a seguir: -Na tela seguinte, você será mostrada a clone URL do seu repo. Escolha a versão "HTTPS",copie, e vamos colá-lo no terminal em breve: +![](images/github_get_repo_url_screenshot.png) -![][6] +Agora precisamos conectar o repositório Git no seu computador com o que existe no GitHub. - [6]: images/github_get_repo_url_screenshot.png +Digite o seguinte no seu terminal (substitua `` pelo nome de usuário que você escolheu quando criou sua conta no GitHub, mas sem os sinais de menor e maior): -Agora precisamos ligar o repositório Git no seu computador com o no GitHub. +{% filename %}linha de comando{% endfilename %} $ git remote add origin https://github.com//my-first-blog.git $ git push -u origin master + +Quando você enviar para o GitHub, seu nome de usuário e senha do GitHub serão solicitados (na própria janela de linha de comando ou em uma janela pop-up), e depois de inserir suas credenciais, você deverá ver algo assim: -Digite seu GitHub username e senha, e você deve ver algo como isto: +{% filename %}linha de comando{% 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 + To https://github.com/ola/my-first-blog.git + * [new branch] master -> master Branch master set up to track remote branch master from origin. + + - - -Seu código agora está no GitHub. Vá e confira! Você saberá que está em boa companhia - [Django][7], o [Django Girls Tutorial][8] e muitos outros grandes projetos de software de fonte aberta também hospedam seu código no GitHub :) - - [7]: https://github.com/django/django - [8]: https://github.com/DjangoGirls/tutorial - -# Criação de nosso blog em PythonAnywhere - -Em seguida, é hora de se inscrever para uma conta gratuita de "Beginner" na PythonAnywhere. - -* [www.pythonanywhere.com][9] - - [9]: https://www.pythonanywhere.com/ - -> **Nota**: ao escolher seu nome de utilizador aqui, tenha em mente que a URL do seu blog terá o formulário `yourusername.pythonanywhere.com`, então escolha seu nickname ou o nome do que é o blog. - -## Pulling our code down on PythonAnywhere - -Quando você se inscreve para PythonAnywhere, você é levado ao seu painel de controle ou página "Consoles". Escolha a opção iniciar o console "Bash"--que é a versão PythonAnywhere de um console, como aquela no seu PC - -> **Nota**: PythonAnywhere é baseado em Linux, assim se você estiver no Windows o console vai parecer um pouco diferente do que está no seu computador. - -Vamos puxar nosso código de GitHub em PythonAnywhere através da criação de um "clone" do repo. Digite o seguinte para o console na PythonAnywhere: +O seu código agora está no GitHub. Vai lá ver! Você perceberá que ele esta em ótima companhia - o [Django](https://github.com/django/django), o [Tutorial Django Girls](https://github.com/DjangoGirls/tutorial) e vários outros incríveis projetos open source também hospedam seu código no GitHub. :) - $ git clone https://github.com//my-first-blog.git +# Configurando o seu blog no PythonAnywhere +## Crie uma conta no PythonAnywhere -Isto puxará uma cópia do seu código para PythonAnywhere. Confira digitando: +> **Observação:** Você talvez já tenha criado uma conta no PythonAnywhere durante os passos de instalação. Nesse caso, não precisa criar outra. - $ 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 +{% include "/deploy/signup_pythonanywhere.md" %} +## Configurando o seu site no PythonAnywhere -### Criando um virtualenv na PythonAnywhere +Navegue para a [Dashboard do PythonAnywhere](https://www.pythonanywhere.com/) clicando no logo e escolha a opção de iniciar um console "Bash" -- essa é a versão do PythonAnywhere da linha de comando, igual à que existe no seu computador. -Assim como fez em seu próprio computador, você pode criar um virtualenv na PythonAnywhere. No console Bash, digite: +![A seção 'New Console' na interface web do PythonAnywhere, com o botão para abrir o 'bash'](images/pythonanywhere_bash_console.png) - 20:20 ~ $ cd my-first-blog +> **Observação:** O PythonAnywhere é baseado em Linux, então se você estiver no Windows, o console terá uma cara um pouco diferente do que aparece no seu computador. - 20:20 ~ $ virtualenv --python=python3.4 myvenv - Running virtualenv with interpreter /usr/bin/python3.4 - [...] - Installing setuptools, pip...done. +Fazer o deploy de uma aplicação web no PythonAnywhere envolve baixar o seu código do GitHub e configurar o PythonAnywhere para reconhecê-lo e começar a servi-lo como uma aplicacão web. Existem formas manuais de fazer isso, mas o PythonAnywhere fornece uma ferramenta que vai fazer tudo pra você. Vamos instalar ela primeiro: - 20:20 ~ $ source myvenv/bin/activate +{% filename %}linha de comando do PythonAnywhere{% endfilename %} - (mvenv)20:20 ~ $ pip install django whitenoise - Collecting django - [...] - Successfully installed django-1.8.5 whitenoise-2.0 + $ pip3.6 install --user pythonanywhere + +Isso deve mostrar na tela coisas como `Collecting pythonanywhere`, e depois de algum tempo finalizar com uma linha dizendo `Successfully installed (...) pythonanywhere (...)`. - +Agora vamos executar a ferramenta para configurar a nossa aplicação a partir do GitHub automaticamente. Digite os seguintes comandos no console do PythonAnywhere (não se esqueça de usar o seu nome de usuário do GitHub ao invés de ``): -### Coleta de arquivos estáticos. +{% filename %}linha de comando do PythonAnywhere{% endfilename %} -Você estava imaginando o que é "whitenoise"? É uma ferramenta para servir os chamados "arquivos estáticos". Arquivos estáticos funcionam de forma diferente nos servidores em comparação com nosso próprio computador, e precisamos de uma ferramenta como o "whitenoise" para atendê-los. + $ pa_autoconfigure_django.py https://github.com//my-first-blog.git + -Vamos descobrir um pouco mais sobre arquivos estáticos mais tarde no tutorial, quando vamos editar o CSS para o nosso site. +Enquanto assiste a execução da ferramenta, você pode ver o que ela está fazendo: -Por enquanto só precisamos executar um comando extra chamado "collectstatic" no servidor. Isso diz pro Django reunir todos os arquivos estáticos que ele precisa no servidor. Em sua maioria, estes são os arquivos estáticos que fazem o site do admin bonito no momento. +- Baixando o seu código do GitHub; +- Criando um virtualenv no PythonAnywhere, igual ao que existe no seu computador +- Atualizando o seu arquivo de configuração com algumas configurações sobre o deploy; +- Criando um banco de dados no PythonAnywhere usando o comando `manage.py migrate`; +- Criando os seus arquivos estáticos (nós aprenderemos sobre eles mais tarde) +- E configurando o PythonAnywhere para servir a sua web app através da sua API. - 20:20 ~ $ python manage.py collectstatic +No PythonAnywhere, todos esses passos são automatizados, mas são os mesmos que você executaria ao utilizar qualquer outro provedor. - You have requested to collect static files at the destination - location as specified in your settings: +Agora, é importante notar que o seu banco de dados no PythonAnywhere é completamente separado do banco de dados no seu computador — isso significa que eles têm posts e contas de admin diferentes. Por causa disso, da mesma forma que fizemos nos nossos computadores, precisamos iniciar a conta de admin com o comando *createsuperuser*. O PythonAnywhere já ativou o seu virtualenv automaticamente, então tudo o que você precisa fazer é executar o comando: - /home/edith/my-first-blog/static +{% filename %}linha de comando do PythonAnywhere{% endfilename %} - This will overwrite existing files! - Are you sure you want to do this? + (ola.pythonanywhere.com) $ python manage.py createsuperuser + - Type 'yes' to continue, or 'no' to cancel: yes +Digite as informações sobre a sua conta de admin. É mais fácil usar as mesmos que usou no seu computador pra evitar qualquer confusão, a menos que você queira criar uma senha mais segura para a conta no PythonAnywhere. +Agora, se quiser, você pode dar uma olhada no seu código no PythonAnywhere usando `ls`: -Digite "yes" (Sim) e vai embora! Você não adora fazer computadores imprimir páginas e páginas de texto? Sempre faço pequenos ruídos para acompanhá-lo. Brp, brp brp... +{% filename %}linha de comando do PythonAnywhere{% endfilename %} - Copying '/home/edith/.virtualenvs/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/actions.min.js' - Copying '/home/edith/.virtualenvs/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/inlines.min.js' - [...] - Copying '/home/edith/.virtualenvs/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/css/changelists.css' - Copying '/home/edith/.virtualenvs/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'. + (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 + +Você também pode visitar a aba "Files" e dar uma olhada usando o gerenciador de arquivos do PythonAnywhere. (Da página do console, você pode navegar para outras páginas do PythonAnywhere utilizando o botão menu no canto superior direito. Quando você estiver em uma dessas páginas, outros links serão exibidos perto do topo.) -### Criando o banco de dados em PythonAnywhere +## Estamos no ar! -Aqui está outra coisa que é diferente entre seu computador e o servidor -- ele usa um banco de dados diferente. Então as contas de usuário e mensagens podem ser diferentes no servidor e no seu computador. +Agora, seu site deve estar no ar! Clique na aba "Web" do PythonAnywhere para pegar o link dele. Você pode compartilhar esse link com quem quiser :) -Então nós vamos inicializar o banco de dados no servidor tal como fizemos no seu próprio computador, com `migrate` e `createsuperuser`: +> **Observação:** Este é um tutorial para iniciantes e ao fazer o deploy do site desta forma, nós tomamos alguns atalhos que não são ideais do ponto de vista de segurança. Se e quando você decidir continuar trabalhando nesse projeto ou começar um novo, você deve revisar a [checklist de implantação do Django](https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/) para pegar algumas dicas de como tornar seu site seguro. - (mvenv)20:20 ~ $ python manage.py migrate - Operations to perform: - [...] - Applying sessions.0001_initial... OK - - - (mvenv)20:20 ~ $ python manage.py createsuperuser - - -## Publicação do nosso blog como um aplicativo web - -Agora nosso código está na PythonAnywhere, nossa virtualenv está pronta, os arquivos estáticos estão recolhidos e o banco de dados está inicializado, estamos prontos para publicá-lo como um aplicativo da web. - -Clique em voltar para o PythonAnywhere dashboard clicando no seu logotipo e clique na guia **Web** e vá em **Add a new web app**. - -Na caixa de diálogo, após a confirmação de seu nome de domínio, escolha **manual configuration** (NB *não* a opção "Django"). Em seguida, escolha **Python 3.4** e clique em Next para concluir o assistente. - -> **Nota** certifique-se você escolheu a opção "Manual configuration", não a "Django". Nós somos demais para o padrão de configuração Django da PythonAnywhere ;-) - -### Definindo o virtualenv - -Você será levado para a tela de configuração de PythonAnywhere para seu webapp que é onde você precisará de ir quando quiser fazer alterações para o aplicativo no servidor. - -![][10] - - [10]: images/pythonanywhere_web_tab_virtualenv.png - -Na seção "Virtualenv", clique no texto vermelho que diz "Enter the path to a virtualenv" e digite: `/home//my-first-blog/myvenv/` - -> **Nota**: substitua seu próprio nome de usuário conforme apropriado. Se você cometer um erro, PythonAnywhere irá mostrar um pequeno aviso. - -### Configurando o arquivo WSGI - -Django funciona usando o WSGI protocol, um padrão para servir sites usando Python, que oferece suporte a PythonAnywhere. A maneira que configuramos PythonAnywhere para reconhecer nosso blog Django é editando um arquivo de configuração do WSGI. - -Clique no link "WSGI configuration file" (na seção "Code" perto do topo da página - -ele vai ser nomeado algo como `/var/www/_pythonanywhere_com_wsgi.py`), e você será levado para um editor. - -Exclua todo o conteúdo atual e substitua com algo parecido com isto: - -```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()) -``` - -> **Nota** não se esqueça de substituir em seu próprio nome de usuário onde diz `` - -O que esse arquivo faz é dizer PythonAnywhere onde mora a nossa aplicação web e qual o nome do arquivo de configurações Django. Ele também define a ferramenta de arquivos estáticos "whitenoise". +## Dicas de debugging -Aperte **Save** e então volte para a guia **Web**. +Se você vir um erro ao rodar o script `pa_autoconfigure_django.py`, aqui vão algumas causas comuns: -Já terminamos! Aperte o botão grande verde de **Reload**e você será capaz de ir ver os seu aplicativo. Você encontrará um link para ele no topo da página. +- Esquecer de criar um token de API do PythonAnywhere. +- Digitar a URL do seu GitHub incorretamente. +- Se você vir um erro dizendo *"Could not find your settings.py"* (settings.py não encontrado), você provavelmente não adicionou todos os seus arquivos ao Git e/ou você não fez o push deles para o GitHub. Dê uma revisada na sessão sobre Git acima -## Dicas de debugging +Se você vir um erro ao visitar o seu site, o primeiro lugar para procurar informações sobre ele é o **log de erros**. Você vai encontrar um link para o log na aba [Web](https://www.pythonanywhere.com/web_app_setup/) do PythonAnywhere. Verifique se há alguma mensagem de erro no log; as mais recentes estarão no final. -Se você vir um erro quando você tenta visitar o seu site, o primeiro lugar para procurar alguma informação de debugging é no seu **error log** -- você encontrará um link para isso na guia web PythonAnywhere. Ver se há mensagens de erro lá. As mais recentes estão na parte inferior. Problemas comuns incluem +Há também algumas [dicas de debugging no site de ajuda da PythonAnywhere](http://help.pythonanywhere.com/pages/DebuggingImportError). -* esquecer um dos passos que fizemos no console: criando o virtualenv, ativá-lo, instalando o Django, collectstatic, inicializando o banco de dados -* cometer um erro no caminho do virtualenv na guia web -- haverá geralmente uma pequena mensagem de erro vermelho lá, se há um problema -* cometer um erro no arquivo de configuração WSGI..--você usou o caminho para a pasta do my-first-blog certinho? +E lembre-se, a sua monitora está aí pra ajudar! -O treinador está aqui para ajudar! +# Visite o seu site! -# Você está live! +A página padrão no seu site deverá dizer "It worked!" ("Funcionou!"), igual ao seu ambiente local. Adicione `/admin` ao final da URL e você será levada ao site de administração. Faça o login com o nome de usuário e a senha, e você verá que pode adicionar novas postagens no servidor -- lembre-se de que as postagens do banco de dados de teste local não foram enviadas para o seu blog no ar. -A página padrão para seu site deve dizer "Bem-vindo ao Django", como acontece no seu PC local. Tente adicionar `/admin/` para o final da URL, e você será levado ao site admin. Fazer login com o nome de usuário e senha, e você verá que você pode adicionar novas mensagens no servidor. +Depois de criar alguns posts, você pode voltar para o seu ambiente local (não o PythonAnywhere). Daqui pra frente você deve trabalhar no seu ambiente local para fazer alterações. Este workflow é comum no desenvolvimento web – fazer alteracões locais, subir essas alteracões pro GitHub, e baixar essas alterações para o seu servidor web de produção. Isto permite que você desenvolva e experimente sem quebrar o seu site que está no ar. Bem legal, né? -Dê em você mesma um *enorme* tapinha nas costas - implantações de servidor são uma das partes mais difíceis do desenvolvimento web, e muitas vezes leva as pessoas vários dias antes de fazer funcionar. Mas você tem seu site publicado, na internet, assim! +Você merece *MUITOS* parabéns! Deploys em servidores são uma das partes mais complicadas do desenvolvimento web e não é incomum levar vários dias até conseguir fazer com que isso funcione. Mas você já tem seu site publicado na internet! \ No newline at end of file diff --git a/pt/deploy/images/github_get_repo_url_screenshot.png b/pt/deploy/images/github_get_repo_url_screenshot.png index 62a29f5f8d7..ee1560b1e85 100644 Binary files a/pt/deploy/images/github_get_repo_url_screenshot.png and b/pt/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/pt/deploy/images/new_github_repo.png b/pt/deploy/images/new_github_repo.png index 64011e59a52..d1f82e5d863 100644 Binary files a/pt/deploy/images/new_github_repo.png and b/pt/deploy/images/new_github_repo.png differ diff --git a/pt/deploy/images/pythonanywhere_account.png b/pt/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/pt/deploy/images/pythonanywhere_account.png differ diff --git a/pt/deploy/images/pythonanywhere_bash_console.png b/pt/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..458b43f5d0d Binary files /dev/null and b/pt/deploy/images/pythonanywhere_bash_console.png differ diff --git a/pt/deploy/images/pythonanywhere_beginner_account_button.png b/pt/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/pt/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/pt/deploy/images/pythonanywhere_create_api_token.png b/pt/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..6e617d0a53e Binary files /dev/null and b/pt/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/pt/deploy/images/pythonanywhere_web_tab_virtualenv.png b/pt/deploy/images/pythonanywhere_web_tab_virtualenv.png deleted file mode 100644 index 97e87e7b07b..00000000000 Binary files a/pt/deploy/images/pythonanywhere_web_tab_virtualenv.png and /dev/null differ diff --git a/pt/deploy/install_git.md b/pt/deploy/install_git.md new file mode 100644 index 00000000000..17adb503794 --- /dev/null +++ b/pt/deploy/install_git.md @@ -0,0 +1,52 @@ +O Git é um "sistema de controle de versão" usado por muitos programadores. Este software pode acompanhar mudanças em arquivos ao longo do tempo para que você possa recuperar versões específicas mais tarde. É parecido com o recurso "Controlar Alterações" dos processadores de texto (e.x Microsoft Word ou Libre Writer), mas muito mais poderoso. + +## Instalando o Git + + + +Você pode baixar o Git em [git-scm.com](https://git-scm.com/). Você pode clicar "próximo" em todas as etapas seguintes, exceto em duas delas: na etapa onde se pede para que escolha o seu editor, você deve escolher Nano, e na etapa "Ajustando o seu ambiente PATH", escolha "Usar Git e ferramentas opcionais Unix para Prompt de comando Windows" (a opção de baixo). Fora isso, as configurações padrão estão ótimas. "Checkout Windows-style, commit Unix-style line endings" está bom. + +Não se esqueça de reiniciar o prompt de comando ou o PowerShell depois que a instalação terminar com sucesso. + + + +Baixe o Git em [git-scm.com](https://git-scm.com/) e siga as instruções. + +> **Observação:** Se estiver rodando o OS X 10.6, 10.7, ou 10.8, você precisará instalar essa versão do git: [Instalado Git para o OS X Snow Leopard](https://sourceforge.net/projects/git-osx-installer/files/git-2.3.5-intel-universal-snow-leopard.dmg/download) + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo apt install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo dnf install git +``` + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo zypper install git +``` + + \ No newline at end of file diff --git a/pt/deploy/signup_pythonanywhere.md b/pt/deploy/signup_pythonanywhere.md new file mode 100644 index 00000000000..64c2a821bf5 --- /dev/null +++ b/pt/deploy/signup_pythonanywhere.md @@ -0,0 +1,19 @@ +PythonAnywhere é um serviço para execução de código Python em servidores "na nuvem". Nós vamos utilizá-lo para hospedar nosso site e deixá-lo no ar na internet. + +Vamos hospedar o blog que estamos construindo no PythonAnywhere. Cadastre uma conta "Begginer" (de iniciante) no PythonAnywhere (o pacote gratuito é suficiente, você não precisa de um cartão de crédito). + +* [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +![Página do PythonAnywhere mostrando o botão para criar a conta "Beginner" (iniciante)](../deploy/images/pythonanywhere_beginner_account_button.png) + +> ** Observação ** Quando escolher seu nome de usuário no PythonAnywhere, lembre que a URL do blog será `seunomedeusuário.pythonanywhere.com `, então use algo como o seu apelido ou um nome que descreva o assunto do blog. Além disso, certifique-se de lembrar sua senha (adicione-a ao seu gerenciador de senhas, se você usar um). + +## Criando um token de API do PythonAnywhere + +Você só precisará fazer isso uma vez. Depois de se registrar no PythonAnywhere, você será levada ao seu painel de controle. Encontre o link para a página de "Account" (conta, em português) próximo ao topo no lado direito: + +![Link para a conta no topo direito na página](../deploy/images/pythonanywhere_account.png) + +em seguida, selecione a guia chamada "API Token" e aperte o botão que diz "Create new API token" (criar novo token API"). + +![Aba de token da API na página da conta](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/pt/django/README.md b/pt/django/README.md index d7d1904c403..d1253c5e18a 100755 --- a/pt/django/README.md +++ b/pt/django/README.md @@ -1,27 +1,27 @@ # O que é Django? -Django é um framework gratuito e de código aberto para a criação de aplicações web, escrito em Python. É um framework web, ou seja, é um conjunto de componentes que ajuda a desenvolver sites de forma mais rápida e mais fácil. +Django (/ˈdʒæŋɡoʊ/ *jang-goh*) é um framework para aplicações web gratuito e de código aberto, escrito em Python. Um web framework é um conjunto de componentes que ajuda você a desenvolver sites de forma mais rápida e fácil. -Veja, quando você está construindo um site, você sempre precisa um conjunto similar de componentes: uma maneira de lidar com a autenticação do usuário (inscrever-se, realizar login, realizar logout), painel de gerenciamento para o seu site, formulários, upload de arquivos, etc. +Quando você está construindo um site, sempre precisa de um conjunto similar de componentes: uma maneira de lidar com a autenticação do usuário (inscrever-se, fazer login, fazer logout), um painel de gerenciamento para o seu site, formulários, uma forma de upload de arquivos, etc. -Felizmente para você, há muito tempo, outras pessoas notaram várias semelhanças nos problemas enfrentados pelos desenvolvedores web quando estão criando um novo site, então eles uniram-se e criaram os frameworks (Django é um deles) que lhe dão componentes prontos, que você pode usar. +Felizmente, outras pessoas perceberam muito tempo atrás que desenvolvedores web enfrentam problemas similares quando estão construindo um novo site, então elas se juntaram e criaram frameworks (Django é um deles) que te dão componentes já prontos para usar. -Frameworks existem para salvá-lo de ter que reinventar a roda e ajudam a aliviar a sobrecarga quando você está construindo um novo site. +Frameworks existem para evitar que você tenha que reinventar a roda e para ajudar a aliviar parte do trabalho extra quando você está construindo um novo site. ## Por que você precisa de um framework? -Para entender o que Django é na verdade, precisamos olhar mais de perto os servidores. A primeira coisa é que o servidor precisa saber o que você quer para servi-lo uma página da Web. +Para entender para quê o Django de fato serve, precisamos olhar os servidores mais de perto. Primeiramente, o servidor precisa saber que você quer que ele te sirva uma página web. -Imagine uma caixa de correio (porta) que é monitorada por cartas recebidas (requisição). Isso é feito por um servidor web. O servidor web lê a carta e envia uma resposta com uma página web. Mas, quando você quer enviar alguma coisa você precisa ter um conteúdo. E o Django é aquilo que vai lhe ajudar a criar esse conteúdo. +Imagine uma caixa de correio (porta) que monitora cartas recebidas (requisição). Isso é feito por um servidor web. O servidor web lê a carta e então envia a resposta com uma página web. Mas quando quer enviar alguma coisa, você precisa ter um conteúdo. O Django vai te ajudar a criar esse conteúdo. ## O que acontece quando alguém solicita um site do seu servidor? -Quando chega uma requisição para o servidor web ela é passada para o Django que tenta descobrir do que ela se trata. Primeiro ele pega um endereço web e tenta descobrir o que fazer. Essa parte é feita pelo **urlresolver** do Django. (Note que o endereço de um site se chama URL - Uniform Resource Locator, em português Localizador de Recursos Uniforme, dessa forma o nome *urlresolver*, ou resolvedor de urls, faz sentido). Isso não é muito inteligente - leva à uma lista de padrões e tenta corresponder a URL. O Django verifica padrões de cima para baixo e se algo é correspondido, passa a solicitação para a função associada (que é chamada *view*). +Quando uma requisição chega a um servidor web, ela é passada para o Django, que tenta entender o que está sendo requisitado de fato. Primeiro, ele pega um endereço de página web e tenta descobrir o que fazer. Isso parte é feito pelo **urlresolver** do Django (note que um endereço de website é chamado de URL - Uniform Resource Locator -- Localizador de Recursos Uniforme, em tradução livre --, então o nome *urlresolver* faz sentido). Ele não é muito inteligente - ele pega uma lista de padrões e tenta achar em qual deles a URL se encaixa. O Django checa os padrões de cima pra baixo, e se algum se encaixa, ele passa a requisição para a função associada (que é chamada de *view*). -Imagine um carteiro com uma carta. Ela está andando pela rua e verifica cada número de casa com a que está na carta. Se ele corresponder, ela coloca a carta lá. É assim que funciona o urlresolver! +Imagine uma funcionária dos Correios com uma carta. Ela está andando pela rua e compara cada número de casa com o que está na carta. Se os números forem correspondentes, ela entrega a carta lá. É assim que funciona o urlresolver! -Todas as coisas interessantes são feitas dentro da *view*: podemos dar uma olhada no banco de dados para procurar algumas informações. Talvez o usuário queira mudar algo nos dados? Como uma carta dizendo: "Por favor mude a descrição do meu emprego." - a *view* checa se você tem permissão para fazer isso e então atualiza a descrição do emprego pra você, enviando em seguida uma mensagem: "Feito!". Então a *view* gera uma resposta e o Django pode enviá-la para o navegador do cliente. +Todas as coisas interessantes são feitas dentro da função *view*: podemos dar uma olhada no banco de dados para procurar algumas informações. O usuário solicitou alguma mudança nos dados? Como uma carta dizendo "Por favor mude a descrição do meu emprego." A *view* pode checar se você tem permissão para fazer isso, e então atualizar a descrição do emprego e enviar de volta a mensagem: "Pronto!" Então a *view* gera uma resposta e o Django pode enviá-la para o navegador web do usuário. -Claro, a descrição acima é muito simplificada, mas você não precisa saber detalhes técnicos ainda. Ter uma ideia geral já é suficiente. +A descrição acima é um pouco simplificada, mas você não precisa saber todos os detalhes técnicos ainda. Uma ideia geral já é o suficiente. -Então em vez de mergulhar em muitos detalhes, nós simplesmente vamos começar criando algo com o Django e aprenderemos todas as partes importantes ao longo do caminho! +Então, ao invés de mergulharmos fundo nos detalhes, vamos começar criando algo com o Django e ir aprendendo as partes importantes durante o caminho! \ No newline at end of file diff --git a/pt/django_admin/README.md b/pt/django_admin/README.md index 9281a7d8afb..41606b38d1b 100755 --- a/pt/django_admin/README.md +++ b/pt/django_admin/README.md @@ -1,8 +1,10 @@ -# Administração +# Django Admin -Para adicionar, editar e remover postagens que nós criamos usaremos o Django admin. +Para adicionar, editar e deletar os posts que acabamos de modelar, nós usaremos o admin do Django. -Vamos abrir o arquivo `blog/admin.py` e substituir seu conteúdo por: +Vamos abrir o arquivo `blog/admin.py` no editor de código e substituir o conteúdo pelo seguinte: + +{% filename %}blog/admin.py{% endfilename %} ```python from django.contrib import admin @@ -11,38 +13,45 @@ from .models import Post admin.site.register(Post) ``` -Como você pode ver, nós importamos (incluímos) o modelo Post definido no capítulo anterior. Para tornar nosso modelo visível na página de administração, nós precisamos registrá-lo com: `admin.site.register(Post)`. +Como você pode ver, nós importamos (incluímos) o modelo Post definido no capítulo anterior. Para tornar nosso modelo visível na página de administração, precisamos registrá-lo com `admin.site.register(Post)`. + +OK, hora de olhar para o nosso modelo de Post. Lembre-se de executar `python manage.py runserver` no console para iniciar o servidor web. Vá para o seu navegador e digite o endereço http://127.0.0.1:8000/admin/. Você verá uma página de login como essa: -OK, hora de olhar para o nosso modelo de Post. Lembre-se de executar `python manage.py runserver` no console para executar o servidor web. Vá para o navegador e digite o endereço http://127.0.0.1:8000/admin/ Você verá uma página de login assim: +![Página de login](images/login_page2.png) -![Página de login][1] +Para fazer login, você precisa criar um *superusuário (superuser)* - uma conta de usuário que pode controlar tudo no site. Volte à linha de comando, digite `python manage.py createsuperuser` e aperte Enter. - [1]: images/login_page2.png +> Lembre-se: para escrever novos comandos enquanto o servidor web estiver rodando, abra uma nova janela do terminal e ative seu virtualenv. Nós revisamos como escrever novos comandos no capítulo **Seu primeiro projeto Django!**, na seção **Iniciando o servidor web**. -Para fazer login você precisa criar um *superuser* - um usuário que possui controle sobre tudo do site. Volte para o terminal e digite `python manage.py createsuperuser`, pressione enter e digite seu nome de usuário (caixa baixa, sem espaço), endereço de e-mail e password quando eles forem requisitados. Não se preocupe que você não pode ver a senha que você está digitando - é assim que deve ser. Só digitá-la e pressione 'Enter' para continuar. A saída deve parecer com essa (onde Username e Email devem ser os seus): +{% filename %}macOS ou 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 + + +Quando for solicitado, insira seu nome de usuário (letras minúsculas, sem espaços), e-mail e senha. **Não se preocupe por não conseguir ver a senha que está digitando - é assim mesmo.** Digite a senha e aperte a tecla `enter` para continuar. A saída deve parecer com isso (onde o nome de usuário e o email devem ser os seus): + + Username: ola + Email address: ola@example.com Password: Password (again): Superuser created successfully. -Volte para a o navegador e faça login com as credenciais de superuser que você escolheu, você deve visualizar o painel de controle do Django admin. - -![Administração][2] - - [2]: images/django_admin3.png +Volte ao seu navegador. Faça login com as credenciais de superusuário que você escolheu; você deverá ver o painel de controle de administração do Django. -Vá para as postagens e experimente um pouco com elas. Adicione cinco ou seis postagens. Não se preocupe com o conteúdo - você pode copiar e colar algum texto deste tutorial para o conteúdo para economizar tempo :). +![Django Admin](images/django_admin3.png) -Certifique-se que pelo menos duas ou três postagens (mas não todas) têm a data de publicação definida. Isso será útil depois. +Vá para as postagens e experimente um pouco com elas. Adicione cinco ou seis postagens. Não se preocupe com o conteúdo -- ele só é visível para você no seu computador local -- você pode copiar e colar algum texto deste tutorial para economizar tempo. :) -![Administração][3] +Certifique-se de que pelo menos duas ou três postagens (mas não todas) têm a data de publicação definida. Isso será útil depois. - [3]: images/edit_post3.png +![Django admin](images/edit_post3.png) -Se você quiser saber mais sobre o Django admin, você deve conferir a documentação do Django: https://docs.djangoproject.com/en/1.8/ref/contrib/admin/ +Se você quiser saber mais sobre o Django admin, confira a documentação do Django: https://docs.djangoproject.com/en/2.0/ref/contrib/admin/ -Este é provavelmente um bom momento para tomar um café (ou chocolate) ou algo para comer para repor as energias. Você criou seu primeiro modelo de Django - você merece um pouco de descanso! +Esse provavelmente é um bom momento para pegar um café (ou chá) ou algo para comer para recuperar as energias. Você criou seu primeiro modelo em Django e merece uma pausa! \ No newline at end of file diff --git a/pt/django_admin/images/django_admin3.png b/pt/django_admin/images/django_admin3.png index a450b4f9630..fb221bd18e1 100644 Binary files a/pt/django_admin/images/django_admin3.png and b/pt/django_admin/images/django_admin3.png differ diff --git a/pt/django_admin/images/edit_post3.png b/pt/django_admin/images/edit_post3.png index c8572a73e7d..57299b6f5af 100644 Binary files a/pt/django_admin/images/edit_post3.png and b/pt/django_admin/images/edit_post3.png differ diff --git a/pt/django_admin/images/login_page2.png b/pt/django_admin/images/login_page2.png index 47153ef6960..c16d1aa4289 100644 Binary files a/pt/django_admin/images/login_page2.png and b/pt/django_admin/images/login_page2.png differ diff --git a/pt/django_forms/README.md b/pt/django_forms/README.md index af4c937e580..54caf1b1ce0 100755 --- a/pt/django_forms/README.md +++ b/pt/django_forms/README.md @@ -1,20 +1,22 @@ -# Formulários +# Formulários do Django -Por último queremos uma forma legal de adicionar e editar as postagens do nosso blog. A `ferramenta de administração` do Django é legal, mas ela é um pouco difícil de customizar e de deixar mais bonita. Se usarmos `formulários` teremos controle absoluto sobre nossa interface - podemos fazer qualquer coisa que imaginarmos! +Por último, queremos uma forma legal de adicionar e editar as postagens do nosso blog. A `ferramenta de administração` do Django é legal, mas é um pouco difícil de personalizar e de deixar mais bonita. Com `formulários`, temos poder absoluto sobre nossa interface - podemos fazer quase tudo que pudermos imaginar! -Uma coisa legal do Django é que nós podemos tanto criar um formulário do zero como podemos criar um `ModelForm` que salva o resultado do formulário para um determinado modelo. +Uma coisa legal do Django é que podemos tanto criar um formulário do zero, como criar um `ModelForm` que salva o resultado do formulário em um determinado modelo. -Isso é exatamente o que nós queremos fazer: criaremos um formulário para o nosso modelo `Post`. +É exatamente isso que queremos fazer: criar um formulário para o nosso modelo `Post`. -Assim como toda parte importante do Django, forms tem seu próprio arquivo: `forms.py`. +Assim como todas as partes importantes do Django, forms têm seu próprio arquivo: `forms.py`. Precisamos criar um arquivo com este nome dentro da pasta `blog`. blog └── forms.py + +Agora vamos abri-lo no editor de código e digitar o seguinte: -Ok, vamos abri-lo e escrever nele o seguinte: +{% filename %}blog/forms.py{% endfilename %} ```python from django import forms @@ -28,33 +30,36 @@ class PostForm(forms.ModelForm): fields = ('title', 'text',) ``` +Primeiro, precisamos importar o módulo de formulários do Django (*from django import forms*) e, obviamente, o nosso modelo *Post* (*from .models import Post*). -Primeiro precisamos importar o módulo de formulários do Django (`from django import forms`) e, obviamente, nosso modelo `Post` (`from .models import Post`). +`PostForm`, como você já deve suspeitar, é o nome do nosso formulário. Precisamos dizer ao Django que esse form é um `ModelForm` (pro Django fazer algumas mágicas para nós) – `forms.ModelForm` é o responsável por essa parte. -`PostForm`, como você já deve suspeitar, é o nome do nosso formulário. Precisamos dizer ao Django que este formulário é um `ModelForm` (assim o Django pode fazer a mágica pra gente) - o `forms.ModelForm` é o responsável por isso. +Em seguida, temos a `class Meta` em que dizemos ao Django qual modelo deverá ser usado para criar este formulário (`model = Post`). -Segundo, nós temos a classe `Meta` onde dizemos ao Django qual modelo deveria ser usado para criar este formulário (`model = Post`). +Por fim, podemos dizer quais campos devem entrar no nosso formulário. Neste cenário, queremos que apenas o `title` e o `text` sejam expostos -- `author` deve ser a pessoa que está logada no sistema (nesse caso, você!) e `created_date` deve ser configurado automaticamente quando criamos um post (no código), correto? -Finalmente, nós podemos dizer qual(is) campo(s) deveriam entrar em nosso formulário. Nesse cenário nós queremos apenas o `title` e `text` para ser exposto - `author` deveria ser a pessoa que está logada no sistema (nesse caso, você!) e `created_date` deveria ser setado automaticamente quando nós criamos um post (no código), correto? +E é isso! Tudo o que precisamos fazer agora é usar o formulário em uma *view* e mostrá-lo em um template. -E é isso aí! Tudo o que precisamos fazer agora é usar o formulário em uma *view* e mostrá-lo em um template. - -Então, mais uma vez, nós iremos criar: um link para a página, uma URL, uma view e um template. +Novamente, criaremos um link para a página, uma URL, uma view e um template. ## Link para a página com o formulário -É hora de abrir `blog/templates/blog/base.html`. Nós iremos adicionar um link em `div` nomeado `page-header`: +É hora de abrir *blog/templates/blog/base.html*. Nós iremos adicionar um link em *div* nomeado *page-header*: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + ``` -Note que nós queremos chamar nossa nova visão `post_new`. +Note que queremos chamar nossa nova view de `post_new`. A classe `"glyphicon glyphicon-plus"` é fornecida pelo tema (bootstrap) que estamos usando, e nos mostrará um sinal de mais. -Depois de adicionar a linha, seu html deve se parecer com isso: +Depois de adicionar essa linha, o seu HTML vai ficar assim: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} Django Girls blog @@ -65,7 +70,7 @@ Depois de adicionar a linha, seu html deve se parecer com isso:
@@ -80,293 +85,365 @@ Depois de adicionar a linha, seu html deve se parecer com isso: ``` -Depois de salvar e recarregar a página `http://127.0.0.1:8000` você verá, obviamente, um erro familiar `NoReverseMatch` certo? +Depois de salvar e recarregar a página *http://127.0.0.1:8000* você verá um erro familiar `NoReverseMatch` certo? É isso! ## URL -Vamos abrir o arquivo `blog/urls.py` e escrever: +Vamos abrir o arquivo *blog/urls.py* e escrever: + +{% filename %}blog/urls.py{% endfilename %} ```python -url(r'^post/new/$', views.post_new, name='post_new'), +path('post/new/', views.post_new, name='post_new'), ``` O código final deve se parecer com isso: -``` python -from django.conf.urls import url +{% filename %}blog/urls.py{% endfilename %} + +```python +from django.urls import path from . import views urlpatterns = [ - url(r'^$', views.post_list), - url(r'^post/(?P[0-9]+)/$', views.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'), ] ``` -Após recarregar o site, nós veremos um `AttributeError`, desde que nós não temos a visão `post_new` implementada. Vamos adicioná-la agora. +Após recarregar a página, veremos um `AttributeError` por que não temos a view `post_new` implementada. Vamos adicioná-la agora. -## post_new view +## View post_new -Hora de abrir o arquivo `blog/views.py` e adicionar as linhas seguintes com o resto das linhas `from`: +Hora de abrir o arquivo *blog/views.py* e adicionar o seguinte às linhas *from*: -``` python +{% filename %}blog/views.py{% endfilename %} + +```python from .forms import PostForm ``` -e nossa *view*: +E então a nossa *view*: -``` python +{% filename %}blog/views.py{% endfilename %} + +```python def post_new(request): form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) ``` -Para criar um novo formulario `Post`, nós devemos chamar `PostForm()` e passá-lo para o template. Nós iremos voltar para esta *view*, mas por agora vamos criar rapidamente um template para o formulário. +Para criar um novo formulario `Post`, devemos chamar `PostForm()` e passá-lo para o template. Voltaremos a esta *view* depois, mas por enquanto, vamos criar um template para o formulário. -## Template(modelos) +## Template -Precisamos criar um arquivo `post_edit.html` na pasta `blog/templates/blog`. Pra fazer o formulário funcionar precisamos de muitas coisas: +Precisamos criar um arquivo *post_edit.html* na pasta *blog/templates/blog*. Para fazer o formulário funcionar, precisamos de várias coisas: -* Temos que exibir o formulário. Podemos fazer isso simplesmente com um `{{ form.as_p }}`. -* A linha acima precisa estar dentro de uma tag HTML form: `...` -* Precisamos de um botão `Salvar`. Fazemos isso com um botão HTML: `` -* E finalmente, depois de abrir a tag `
` precisamos adicionar um `{% raw %}{% csrf_token %}{% endraw %}`. Isso é muito importante, pois é isso que faz o nosso formulário ficar seguro! O DJango vai reclamar se você esquecer de adicionar isso e simplesmente salvar o formulário: +* Temos que exibir o formulário. Podemos fazer isso com (por exemplo) {% raw %}`{{ form.as_p }}`{% endraw %}. +* A linha acima precisa estar dentro de uma tag HTML form: `...
`. +* Precisamos de um botão `Salvar`. Fazemos isso com um botão HTML: ``. +* E finalmente, depois de abrir a tag `
`, precisamos adicionar {% raw %}`{% csrf_token %}`{% endraw %}. Isso é muito importante, pois é isso que torna o nosso formulário seguro! Se você esquecer esta parte, o Django vai reclamar quando você tentar salvar o formulário: -![CSFR Página proíbida][1] +![CSFR Página proibida](images/csrf2.png) - [1]: images/csrf2.png +Legal, então vamos ver como ficou o HTML `post_edit.html`: -Beleza, então vamos ver como ficou o 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 %} ``` -Hora de atualizar! Há! Seu formulário apareceu! +Hora de atualizar! Uhuu! Seu formulário apareceu! -![Novo formulário][2] +![Novo formulário](images/new_form2.png) - [2]: images/new_form2.png +Mas espere um minuto! O que vai acontecer quando você digitar alguma coisa nos campos `title` e `text` e tentar salvar? -Mas, espere um minuto! Quando você digita alguma coisa nos campos `title` e `text` e tenta salvar o que acontece? - -Nada! Estamos novamente na mesma página e nosso texto sumiu... E nenhum post foi adicionado. Então o que deu errado? +Nada! Estamos novamente na mesma página e nosso texto sumiu... e nenhum post foi adicionado. Então o que deu errado? A resposta é: nada. Precisamos trabalhar um pouco mais na nossa *view*. ## Salvando o formulário -Abra `blog/views.py` mais uma vez. Atualmente tudo que temos na visão `post_new` é: +Abra *blog/views.py* no editor de código mais uma vez. No momento, tudo que temos na view *post_new* é: + +{% filename %}blog/views.py{% endfilename %} -``` python +```python def post_new(request): form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) ``` -Quando nós enviamos o formulário, somos trazidos de volta para a mesma visão, mas desta vez temos mais alguns dados no `request`, mais especificamente em `request.POST` (o nome não tem nada com "post" de blog , tem a ver com o fato de que estamos "postando" dados). Você se lembra que no arquivo HTML nossa definição de `
` tem a variável `method="POST"`? Todos os campos vindos do "form" estarão disponíveis agora em `request.POST`. Você não deveria renomear `POST` para nada diferente disso (o único outro valor válido para `method` é `GET`, mas nós não temos tempo para explicar qual é a diferença). +Quando enviamos o formulário, somos trazidas de volta à mesma view, mas desta vez temos mais alguns dados no `request`, especificamente em `request.POST` (o nome não tem nada a ver com "post" de blog; tem a ver com o fato que estamos "postando" dados). Lembra que no arquivo HTML, nossa definição de `form` incluiu a variável `method="POST"`? Todos os campos vindos do "form" estarão disponíveis agora em `request.POST`. Não renomeie `POST` para nada diferente disso (o único outro valor válido para `method` é `GET`, mas não temos tempo para explicar a diferença). + +Então em nossa *view* temos duas situações diferentes com as quais lidar: primeiro, quando acessamos a página pela primeira vez e queremos um formulário em branco e segundo, quando voltamos para a *view* com todos os dados do formulário que acabamos de digitar. Desse modo, precisamos adicionar uma condição (usaremos `if` para isso): -Então na nossa *view* nós temos duas situações separadas para lidar. A primeira é quanto acessamos a página pela primeira vez e queremos um formulário em branco. E a segunda, é quando nós temos que voltar para a *view* com todos os dados do formulário que nós digitamos. Desse modo, precisamos adicionar uma condição (usaremos `if` para isso). +{% filename %}blog/views.py{% endfilename %} -``` python +```python if request.method == "POST": [...] else: form = PostForm() ``` -Está na hora de preencher os pontos`[...]`. Se `method` é `POST` então nós queremos construir o `PostForm` com os dados que veem do formulário, certo? Nós iremos fazer assim: +É hora de preencher os pontos `[...]`. Se `method` é `POST`, queremos construir o `PostForm` com dados do formulário, certo? Faremos assim: + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(request.POST) ``` -Fácil! Próxima coisa é verificar se o formulário está correto(todos os campos requeridos são definidos e valores incorretos não serão salvos). Fazemos isso com `form.is_valid()`. +O próximo passo é checar se o formulário está correto (todos os campos requeridos estão prontos e valores incorretos não serão salvos). Fazemos isso com `form.is_valid()`. Verificamos se o formulário é válido e se estiver tudo certo, podemos salvá-lo! +{% filename %}blog/views.py{% endfilename %} + ```python if form.is_valid(): - post = form.save(commit=False) - post.author = request.user - post.published_date = timezone.now() - post.save() + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() ``` -Basicamente, temos duas coisas aqui: Salvamos o formulário com `form.save` e adicionados um autor(desde que não haja o campo `author` em `PostForm`, e este campo é obrigatório!). `commit=False` significa que não queremos salvar o modelo `Post` ainda - queremos adicionar autor primeiro. Na maioria das vezes você irá usar `form.save()`, sem `commit=False`, mas neste caso, precisamos fazer isso. `post.save()` irá preservar as alterações(adicionando autor) e é criado um novo post no blog! +Basicamente, temos duas coisas aqui: salvamos o formulário com `form.save` e adicionamos um autor (já que houve um campo `author` em `PostForm`, e este campo é obrigatório). `commit=False` significa que não queremos salvar o modelo de `Post` ainda - queremos adicionar o autor primeiro. Na maioria das vezes você irá usar `form.save()`, sem `commit=False`, mas neste caso, precisamos fazer isso. `post.save()` vai preservar as alterações (adicionando o autor) e é criado um novo post no blog! + +Finalmente, seria fantástico se pudéssemos ir à página `post_detail`, direto para o nosso recém-criado post no blog, né? Para fazer isso, precisaremos de mais uma importação: -Finalmente, não seria fantástico se nós pudéssemos imediatamente ir à página de `post_detail` para o recém-criado blog post, certo? Para fazer isso nós precisaremos de mais uma importação: +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import redirect ``` -Adicione-o logo no início do seu arquivo. E agora podemos dizer: vá para a página `post_detail` para um recém-criado post. +Adicione isso logo no início do seu arquivo. Agora podemos dizer: "vá para a página `post_detail` para o post recém-criado": + +{% filename %}blog/views.py{% endfilename %} ```python -return redirect('blog.views.post_detail', pk=post.pk) +return redirect('post_detail', pk=post.pk) ``` -`blog.views.post_detail` é o nome da view que queremos ir. Lembre-se que essa *view* exige uma variável `pk`? Para passar isso nas `views` usamos `pk=post.pk`, onde post é o recém-criado blog post. +`post_detail` é o nome da visualização (view) à qual queremos ir. Lembra que essa *view* exige uma variável `pk`? Para passar isso para as `views`, usamos `pk=post.pk`, em que post é o recém-criado post do blog! + +Ok, nós falamos muito, e agora queremos ver a cara da *view* completa, né? -Ok, nós falamos muito, mas provavelmente queremos ver o que toda a *view* irá parecer agora, certo? +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): - if request.method == "POST": - form = PostForm(request.POST) - if form.is_valid(): - post = form.save(commit=False) - post.author = request.user - post.published_date = timezone.now() - post.save() - return redirect('blog.views.post_detail', pk=post.pk) - else: - form = PostForm() - return render(request, 'blog/post_edit.html', {'form': form}) + if request.method == "POST": + form = PostForm(request.POST) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) ``` -Vamos ver se funciona. Vá para o página http://127.0.0.1:8000/post/new/, adicione um `title` e o `text`, salve... e voilà! O novo blog post é adicionado e nós somos redirecionados para a página de `post_detail`! +Vamos ver se funciona. Vá para a página http://127.0.0.1:8000/post/new/, adicione um `title` e o `text`, salve... e pronto! O novo post do blog é adicionado e somos redirecionadas à página de `post_detail`! -Você provavelmente notou que nós não estamos definindo a data de publicação em tudo. Vamos introduzir um *botão de publicação* em **Django Girls Tutorial: Extensões**. +Você deve ter percebido que estamos estabelecendo a data de publicação antes de salvar o post. Mais tarde, vamos introduzir um botão de *Publicar* em **Django Girls Tutorial: Extensões**. Isso é incrível! -## Validação de formulários - -Agora, nós lhe mostraremos como os fórmularios são legais. O post do blog precisa ter os campos `title` e `text`. Em nosso modelo `Post` não dissemos (em oposição a `published_date`) que esses campos não são necessários, então Django, por padrão, espera-os a ser definido. - -Tente salvar o formulário sem `title` e `text`. Adivinhe o que vai acontecer! +> Como recentemente usamos a interface de administração do Django, o sistema entende que estamos logadas. Existem algumas situações que poderiam nos desligar do sistema (fechar o navegador, reiniciar banco de dados etc.). Se ao criar um post você receber erros que se referem à ausência de um usuário logado, vá até a página de admin http://127.0.0.1:8000/admin e faça login novamente. Isso vai resolver o problema temporariamente. Há um ajuste permanente esperando por você em **lição de casa: adicionar segurança ao seu site!**, um capítulo posterior ao tutorial principal. -![Validação de formulários][3] +![Erro de usuário logado](images/post_create_error.png) - [3]: images/form_validation2.png +## Validação de formulários -Django está tomando conta de validar se todos os campos de nosso formulário estão corretos. Não é incrível? +Agora, mostraremos como os fórmularios do Django são legais. O post do blog precisa ter os campos `title` e `text`. Em nosso modelo `Post` não dissemos (em oposição a `published_date`) que esses campos são opcionais, então o Django, por padrão, espera que sejam definidos. -> Como recentemente usamos a interface de administração do Django o sistema entende que estamos logados. Existem algumas situações que poderiam levar a sermos deslogados do sistema (fechar o navegador, reiniciar banco de dados etc.). Se você perceber que erros estão aparecendo ao criar um post que referencia um usuário que não está logado, vá para a página admin http://127.0.0.1:8000 e logue novamente. Isso vai resolver o problema temporariamente. Há um ajuste permanente esperando por você em **lição de casa: adicionar segurança no seu site!**, capítulo após o tutorial principal. +Tente salvar o formulário sem `title` e `text`. Adivinhe o que vai acontecer! -![Erro de usuário logado][4] +![Validação de formulários](images/form_validation2.png) - [4]: images/post_create_error.png +Django está confirmando que todos os campos de nosso formulário estão corretos. Não é incrível? ## Editando o formulário -Agora sabemos como adicionar um novo formulário. Mas e se quisermos editar um já existente? É muito semelhante ao que fizemos. Vamos criar algumas coisas importantes rapidamente (se você não entender alguma coisa - você deve perguntar a seu professor ou veja os capítulos anteriores, já cobrimos todas essas etapas anteriormente). +Agora sabemos como adicionar um novo formulário. Mas e se quisermos editar um que já existe? É muito parecido com o que acabamos de fazer. Vamos criar algumas coisas importantes rapidinho. (Se você não entender alguma coisa, pergunte para a sua monitora ou veja os capítulos anteriores -- já cobrimos todas essas etapas anteriormente.) + +Abra *blog/templates/blog/post_detail.html* e adicione esta linha -Abra `blog/templates/blog/post_detail.html` e adicione a linha: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html ``` +agora, o template estará parecido com: -Agora o modelo estará parecido com: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html {% extends 'blog/base.html' %} {% block content %} -
- {% if post.published_date %} - {{ post.published_date }} - {% endif %} - +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} + +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

{% endblock %} ``` +Abra o arquivo *blog/urls.py* no editor de código e digite: -Em `blog/urls.py` adicionamos esta linha: +{% 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'), ``` -Nós reutilizaremos o modelo `blog/templates/blog/post_edit.html`, então a última coisa que falta é uma *view*. +Vamos reutilizar o template `blog/templates/blog/post_edit.html`, então a última coisa que falta é uma *view*. -Vamos abrir `blog/views.py` e adicionar no final do arquivo: +Vamos abrir *blog/views.py* no editor de código e adicionar o seguinte ao final do arquivo: + +{% filename %}blog/views.py{% endfilename %} ```python def post_edit(request, pk): - post = get_object_or_404(Post, pk=pk) - if request.method == "POST": - form = PostForm(request.POST, instance=post) - if form.is_valid(): - post = form.save(commit=False) - post.author = request.user - post.published_date = timezone.now() - post.save() - return redirect('blog.views.post_detail', pk=post.pk) - else: - form = PostForm(instance=post) - return render(request, 'blog/post_edit.html', {'form': form}) + post = get_object_or_404(Post, pk=pk) + if request.method == "POST": + form = PostForm(request.POST, instance=post) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm(instance=post) + return render(request, 'blog/post_edit.html', {'form': form}) ``` -Isso é quase exatamente igual a nossa view de `post_new`, certo? Mas não totalmente. Primeira coisa: passamos um parâmetro extra da url `pk`. Em seguida: pegamos o modelo `Post` que queremos editar com `get_object_or_404 (Post, pk=pk)` e então, quando criamos um formulário passamos este post como uma `instância`, tanto quando salvamos o formulário: +Isso é quase igual à nossa view de `post_new`, né? Mas não inteiramente. Primeira coisa: passamos um parâmetro extra `pk` a partir da url. Em seguida, pegamos o modelo `Post` que queremos editar com `get_object_or_404 (Post, pk=pk)` e então, quando criamos um formulário, passamos este post como uma `instância` tanto quando salvamos o formulário… + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(request.POST, instance=post) ``` -como quando nós apenas abrimos um formulário com este post para editar: +... como quando apenas abrimos um formulário para editar esse post: + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(instance=post) ``` -Ok, vamos testar se funciona! Vamos para a página `post_detail`. Deve haver um botão editar no canto superior direito: +Ok, vamos testar para ver se funciona! Vamos para a página `post_detail`. Deve haver um botão editar no canto superior direito: -![Botão editar][5] +![Botão editar](images/edit_button2.png) - [5]: images/edit_button2.png +Quando você clicar nesse botão, verá o formulário com a nossa postagem: -Quando você clicar nele você verá o formulário com a nossa postagem: +![Editando o formulário](images/edit_form2.png) -![Editando o formulário][6] +Sinta-se livre para mudar o título ou o texto e salvar as alterações! - [6]: images/edit_form2.png +Parabéns! Sua aplicação está ficando cada vez mais completa! -Sinta-se livre para mudar o título ou o texto e salvar as mudanças! +Se precisar de mais informações sobre formulários do Django, leia a documentação: https://docs.djangoproject.com/en/2.0/topics/forms/ -Parabéns! Sua aplicação está ficando cada vez mais completa! +## Segurança -Se você precisar de mais informações sobre formulários do Django você deve ler a documentação: https://docs.djangoproject.com/en/1.8/topics/forms/ +Poder criar novos posts apenas clicando em um link é ótimo! Mas nesse momento, qualquer um que visitar nosso site poderá criar um novo post, e você isso provavelmente não quer isso. Vamos fazer com que o botão apareça apenas para você e para mais ninguém. -## Mais uma coisa: hora de implantar! +Em `blog/templates/blog/base.html`, procure nossa `div` `page-header` e a tag de link que você colocou mais cedo. Deve se parecer com: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html + +``` + +Vamos incluir outra tag `{% if %}` que irá apresentar o link somente para os usuários que estiverem logados como admin. No momento, é apenas você! Mude a tag `` para que fique assim: + +{% filename %}blog/templates/blog/base.html{% endfilename %} + +```html +{% if user.is_authenticated %} + +{% endif %} +``` + +Este `{% if %}` fará com que o link seja enviado ao navegador se o usuário que requisitou a página estiver logado. Isso não protege o blog completamente da criação de um novo post, mas é um bom começo. Vamos falar mais sobre segurança nas próximas lições. + +Lembra do ícone Editar que acabamos de adicionar à nossa página de detalhes? Queremos fazer a mesma coisa com ele para que outras pessoas não possam editar as mensagens já existentes. -Vamos ver se tudo isso funciona na PythonAnywhere. Tempo para outro deploy! +Abra `blog/templates/blog/post_detail.html` e encontre esta linha: -* Primeiro, commit o seu novo código e coloque no Github +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} -```bash -$ git status -$ git add --all . -$ git status -$ git commit -m "Added views to create/edit blog post inside the site." -$ git push +```html + ``` -* Então, em um [console PythonAnywhere Bash][7]: +Altere-a para: -```bash -$ cd my-first-blog -$ git pull +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% if user.is_authenticated %} + +{% endif %} ``` -* Finalmente, pule para a [Web tab][8] e aperte **Reload**. +Você provavelmente está logada, então se atualizar a página, não verá nada de diferente. Carregue a página em um navegador novo ou em uma janela anônima (chamada "InPrivate" no Windows Edge), e então você verá que o link não aparece, e o ícone também não! + +## Mais uma coisa: hora de implantar! + +Vamos ver se tudo isso funciona no PythonAnywhere. Hora de fazer outro deploy! + +* Primeiro, faça o commit do seu novo código e dê o comando push para colocá-lo no Github: + +{% filename %}command-line{% endfilename %} + + $ git status + $ git add --all . + $ git status + $ git commit -m "Added views to create/edit blog post inside the site." + $ git push + + +* Então, em um [console Bash do PythonAnywhere](https://www.pythonanywhere.com/consoles/): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Lembre de substituir `` pelo seu subdomínio PythonAnywhere, sem os símbolos < e >.) - [7]: https://www.pythonanywhere.com/consoles/ - [8]: https://www.pythonanywhere.com/web_app_setup/ +* Finalmente, vá para a [página "Web"](https://www.pythonanywhere.com/web_app_setup/) (use o botão de menu no canto superior direito do console) e pressione **Recarregar**. Atualize seu blog https://subdominio.pythonanywhere.com para ver as mudanças. -E deve ser isso! Parabéns :) +E deve ser isso! Parabéns :) \ No newline at end of file diff --git a/pt/django_forms/images/csrf2.png b/pt/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/pt/django_forms/images/csrf2.png and b/pt/django_forms/images/csrf2.png differ diff --git a/pt/django_forms/images/drafts.png b/pt/django_forms/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/pt/django_forms/images/drafts.png and b/pt/django_forms/images/drafts.png differ diff --git a/pt/django_forms/images/edit_button2.png b/pt/django_forms/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/pt/django_forms/images/edit_button2.png and b/pt/django_forms/images/edit_button2.png differ diff --git a/pt/django_forms/images/edit_form2.png b/pt/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/pt/django_forms/images/edit_form2.png and b/pt/django_forms/images/edit_form2.png differ diff --git a/pt/django_forms/images/form_validation2.png b/pt/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/pt/django_forms/images/form_validation2.png and b/pt/django_forms/images/form_validation2.png differ diff --git a/pt/django_forms/images/new_form2.png b/pt/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/pt/django_forms/images/new_form2.png and b/pt/django_forms/images/new_form2.png differ diff --git a/pt/django_forms/images/post_create_error.png b/pt/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/pt/django_forms/images/post_create_error.png and b/pt/django_forms/images/post_create_error.png differ diff --git a/pt/django_installation/README.md b/pt/django_installation/README.md index 34f22f79e98..8c58074b145 100755 --- a/pt/django_installation/README.md +++ b/pt/django_installation/README.md @@ -1,113 +1,7 @@ # Instalação do Django -> Parte deste capítulo é baseado nos tutoriais do Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> **Observação:** Se você está usando um Chromebook, pule este capítulo e certifique-se de seguir as instruções para [ Configuração do Chromebook](../chromebook_setup/README.md). > -> Parte deste capítulo é baseado no [django-marcador tutorial][1] licenciado sobre Creative Commons Attribution-ShareAlike 4.0 International License. O tutorial do django-marcador é protegido por direitos autorais por Markus Zapke-Gründemann et al. +> **Observação:** Se você já seguiu o passo a passo da instalação, pode ignorar essa seção - vá direto para o próximo capítulo! - [1]: http://django-marcador.keimlink.de/ - -## Ambiente virtual - -Antes de instalarmos o Django, nós iremos instalar uma ferramenta extremamente útil que irá ajudar a manter seu ambiente de desenvolvimento arrumado em seu computador. É possível ignorar este passo, mas ele é altamente recomendado. Começar com a melhor configuração possível te salvará de muitos problemas no futuro! - -Então, vamos criar um **ambiente virtual**(também chamado um *virtualenv*). Isso isolará sua configuração Python/Django em uma base por projeto, significa que quaisquer mudanças que fizer em um website não afetará quaisquer outras aplicações que estiver desenvolvendo a parte. Arrumado, certo? - -Tudo o que você precisa fazer é encontrar um diretório no qual você deseja criar o `virtualenv`; Seu diretório Home, por exemplo. No Windows pode parecer como `C:\Usuário\Nome` (onde `Nome` é o nome do seu login). - -Para este tutorial usaremos um novo diretório`djangogirls` do seu diretório home: - - mkdir djangogirls - cd djangogirls - - -Nós vamos fazer um virtualenv chamado `myvenv`. O formato geral desse comando é: - - python3 -m venv myvenv - - -### Windows - -Para criar um novo `virtualenv`, você precisa abrir o console(Nós falamos sobre isso alguns capítulos atrás, lembra-se?) e executar `C:\Python34\python -m venv myvenv`. Será algo parecido com isto: - - C:\Usuário\Nome\djangogirls> C:\Python34\python -m venv myvenv - - -onde `C:\Python34\python` é o diretório em que você previamente instalou Python e `myvenv` é o nome da sua `virtualenv`. Você pode usar qualquer outro nome, mas sempre use minúsculas e sem espaços, acentos ou caracteres especiais. Também é uma boa ideia manter o nome curto - você irá referenciar muito a ele! - -### Linux e OS X - -Criar um `virtualenv` tanto no Linux como OS X é simples como executar `python3 -m venv myvenv`. Será algo parecido com isto: - - ~/djangogirls$ python3 -m venv myvenv - - -`myvenv` é o nome da sua `virtualenv`. Você pode usar qualquer outro nome, mas permaneça em caixa baixa(minúsculas) e não use espaços entre os nomes. Também é uma boa ideia manter o nome curto - você irá referenciar muito a ele! - -> **NOTA:**Iniciar o ambiente virtual no Ubuntu 14.04 assim retornará o seguinte erro: -> -> Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 -> -> -> Para contornar esse problema, use o comando `virtualenv`. -> -> ~/djangogirls$ sudo apt-get install python-virtualenv -> ~/djangogirls$ virtualenv --python=python3.4 myvenv -> - -## Trabalhando com o virtualenv - -O comando acima criará um diretório chamado `myvenv` (ou seja o nome que você escolheu) que contém o nosso ambiente virtual(basicamente um conjunto de diretórios e arquivos). Tudo o que queremos por enquanto é iniciá-lo executando: - - C:\Usuário\Nome\djangogirls> myvenv\Scripts\activate - - -no Windows, ou: - - ~/djangogirls$ source myvenv/bin/activate - - -no OS X e no Linux. - -Lembre-se de substituir `myvenv` com seu nome escolhido do `virtualenv`! - -> **NOTE:** às vezes `source(fonte)` pode não estar disponível. Nesses casos, tente fazer isso: -> -> ~/djangogirls$ . myvenv/bin/activate -> - -Você vai saber que tem um `virtualenv` funcionando quando ver o prompt no seu console se parecer com: - - (myvenv) C:\Usuário\Nome\djangogirls> - - -ou: - - (myvenv) ~/djangogirls$ - - -Perceba que o prefixo `(myvenv)` aparece! - -Ao trabalhar dentro de um ambiente virtual, `python` irá automaticamente se referir a versão correta para que possa utilizar `python` em vez de `python3`. - -Ok, nós temos todas as dependências importantes no lugar. Finalmente podemos instalar o Django! - -## Instalando o Django - -Agora que você tem a sua `virtualenv` iniciado, você pode instalar Django usando `pip`. No console, execute `pip install django==1.8.5` (Perceba que usamos um duplo sinal de igual: `==`). - - (myvenv) ~$ pip install django==1.8.5 - Downloading/unpacking django==1.8.5 - Installing collected packages: django - Successfully installed django - Cleaning up... - - -no Windows - -> Se você receber um erro ao chamar o pip na plataforma Windows por favor, verifique se o caminho do projeto contém espaços, acentos ou caracteres especiais (exemplo, `C:\Users\User Name\djangogirls`). Se sim por favor mova para outro lugar sem espaços, acentos ou caracteres especiais (sugestão é: `C:\djangogirls`). Após a mudança, por favor tente novamente o comando acima. - -No Linux - -> Se você receber um erro ao chamar pip no Ubuntu 12.04 por favor execute `python -m pip install -U --force-reinstall pip` para corrigir a instalação do pip no virtualenv. - -É isso! Agora você está (finalmente) pronto para criar uma aplicação Django! +{% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/pt/django_installation/instructions.md b/pt/django_installation/instructions.md new file mode 100644 index 00000000000..6fba8429b47 --- /dev/null +++ b/pt/django_installation/instructions.md @@ -0,0 +1,225 @@ +> Esta seção baseia-se em tutoriais da Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> +> Parte deste capítulo é baseada em [tutorial django-marcador](http://django-marcador.keimlink.de/) licenciado sob Creative Commons Attribution-ShareAlike 4.0 International License. O tutorial do django-marcador é protegido por direitos autorais por Markus Zapke-Gründemann et al. + +## Ambiente virtual + +Antes de instalar o Django, vamos instalar uma ferramenta muito útil para ajudar a manter o ambiente de trabalho no nosso computador organizado. Você pode pular esse passo, mas ele é altamente recomendado. Começar com a melhor instalação possível poupará você de muito trabalho no futuro! + +Vamos criar um **ambiente virtual** (também chamado um *virtualenv*). O virtualenv isolará seu código Python/Django em um ambiente organizado por projetos. Isso significa que as alterações que você fizer em um website não afetarão os outros projetos que você estiver desenvolvendo ao mesmo tempo. Legal, né? + +Tudo o que você precisa fazer é encontrar o diretório em que você quer criar o `virtualenv`; seu diretório Home, por exemplo. No Windows, pode aparecer como `C:\Users\Name` (onde `Nome` é seu usuário de login). + +> ** Observação:** No Windows, certifique-se de que esse diretório não contém palavras acentuadas ou caracteres especias; se o seu usuário contém caracteres acentuados, use um diretório diferente, por exemplo: ` C:\djangogirls`. + +Para este tutorial, usaremos um novo diretório `djangogirls` no seu diretório home: + +{% filename %}command-line{% endfilename %} + + $ mkdir djangogirls + $ cd djangogirls + + +Vamos fazer um virtualenv chamado `meuenv`. O formato geral desse comando é: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + + + +Para criar um novo `virtualenv`, você deve abrir o terminal e executar `python -m venv myvenv`. Deve ficar assim: + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls> python -m venv myvenv + + +Onde `myvenv` é o nome do seu `virtualenv`. Você pode usar qualquer outro nome, mas sempre use minúsculas e não use espaços, acentos ou caracteres especiais. Também é uma boa ideia manter o nome curto - você irá referenciá-lo muitas vezes! + + + + + +Podemos criar um `virtualenv` no Linux ou no macOS executando `python3 -m venv myvenv`. Deve ficar assim: + +{% filename %}command-line{% endfilename %} + + $ python3 -m venv myvenv + + +`myvenv` é o nome do seu `virtualenv`. Você pode usar qualquer outro nome, mas use sempre letras minúsculas e não use espaços entre as palavras. Também é uma boa ideia manter o nome curto pois você vai escrevê-lo muitas vezes! + +> **Observação:** Em algumas versões do Debian/Ubuntu, você pode receber o seguinte erro: +> +> {% 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. +> +> +> Caso você receba esse erro, siga as instruções acima e instale o pacote `python3-venv`: {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python3-venv +> +> +> **Observação:** Em algumas versões do Debian/Ubuntu, iniciar o ambiente virtual com este comando gera o seguinte erro: +> +> {% filename %}command-line{% endfilename %} +> +> Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 +> +> +> Para contornar esse problema, use o comando `virtualenv`. +> +> {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python-virtualenv +> $ virtualenv --python=python3.6 myvenv +> +> +> **Oservação:** Se você obtiver um erro como +> +> {% filename %}command-line{% endfilename %} +> +> E: Unable to locate package python3-venv +> +> +> no lugar do comando mostrado acima, execute esse: +> +> {% filename %}command-line{% endfilename %} +> +> sudo apt install python3.6-venv +> + + + +## Trabalhando com o virtualenv + +O comando acima criará um diretório chamado `myvenv` (ou qualquer que seja o nome que você escolheu) que contém o nosso ambiente virtual (basicamente um conjunto de diretórios e arquivos). + + + +Inicie o seu ambiente virtual executando: + +{% filename %}command-line{% endfilename %} + + C:\Users\Name\djangogirls> myvenv\Scripts\activate + + +> **Observação:** no Windows 10, você pode obter um erro no Windows PowerShell que diz `execution of scripts is disabled on this system`. Neste caso, abra uma outra janela do Windows PowerShell com a opção de "Executar como Administrador". Assim, execute o comando abaixo antes de iniciar o seu ambiente virtual: +> +> {% 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 +> + +> **NOTA:** Para usuários do editor popular Código VS, que vem com um terminal baseado em janelas, se você deseja manter-se com o terminal integrado, você pode executar o seguinte comando para ativar seu ambiente virtual: +> +> $ . myvenv\Scripts\activate.ps1 +> +> +> A vantagem é que você não precisa alternar entre janelas do editor e janelas de linha de comando + + + + + +Inicie o seu ambiente virtual executando: + +{% filename %}command-line{% endfilename %} + + $ source myvenv/bin/activate + + +Lembre-se de substituir `myvenv` pelo nome que você escolheu para o `virtualenv`! + +> **Observação:** às vezes `source` pode não estar disponível. Nesses casos, tente fazer isso: +> +> {% filename %}command-line{% endfilename %} +> +> $ . myvenv/bin/activate +> + + + +Você vai saber que tem um `virtualenv` funcionando quando vir que a linha de comando no seu console tem o prefixo `(myvenv)`. + +Ao trabalhar em de um ambiente virtual, o comando `python` irá automaticamente se referir à versão correta para que você possa digitar `python` em vez de `python3`. + +Pronto, já temos todas as dependências importantes no lugar. Finalmente podemos instalar o Django! + +## Instalando o Django + +Agora que você tem seu `virtualenv` ativo, pode instalar o Django. + +Antes de fazer isto, devemos garantir que temos instalada a última versão do `pip`, que é o software que usamos para instalar o Django: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~$ python -m pip install --upgrade pip + + +### Instalando pacotes com requisitos + +O arquivo "requirements.txt" guarda as depenências que serão instaladas utilizando o `pip install`: + +Primeiro, crie um arquivo `requirements.txt` dentro da sua pasta `djangogirls/` usando o editor de código que você instalou mais cedo. Para fazer isso, abra um novo arquivo no editor e salve-o como `requirements.txt` na pasta `djangogirls`. O seu diretório vai parecer com isso: + + djangogirls + └───requirements.txt + + +E adicione o seguinte texto ao arquivo `djangogirls/requirements.txt`: + +{% filename %}djangogirls/requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +Agora, execute `pip install -r requirements.txt` para instalar o Django. + +{% filename %}command-line{% endfilename %} + + (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.1MB) + Installing collected packages: Django + Successfully installed Django-{{ book.django_version }} + + + + +> Se você receber um erro ao chamar o pip na plataforma Windows, verifique se o caminho do projeto contém espaços, acentos ou caracteres especiais (exemplo, `C:\Users\User Name\djangogirls`). Se sim, considere movê-lo para outro lugar sem espaços, acentos ou caracteres especiais (sugestão: `C:\djangogirls`). Crie um novo virtualenv no diretório recém-criado, exclua o mais velho e tente novamente executar o comando acima. (Mover o diretório de virtualenv não vai funcionar pois o virtualenv usa caminhos absolutos.) + + + + + +> Sua linha de comando pode congelar depois de você tentar instalar o Django. Neste caso, ao invés do comando acima, use: +> +> {% filename %}command-line{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> + + + + + +> Se você receber um erro ao chamar pip no Ubuntu 12.04, por favor execute `python -m pip install -U --force-reinstal pip` para corrigir a instalação de pip no virtualenv. + + + +É isto! Você agora (finalmente) está pronta para criar uma aplicação Django! \ No newline at end of file diff --git a/pt/django_models/README.md b/pt/django_models/README.md index b62a01e1e0b..92472447de2 100755 --- a/pt/django_models/README.md +++ b/pt/django_models/README.md @@ -1,40 +1,40 @@ # Modelos do Django -Agora o que nós queremos criar é algo que armazene todos os posts no nosso blog. Mas para fazer isso precisamos aprender um pouco mais sobre coisas chamadas `objetos`. +Queremos criar algo que armazene todos os posts em nosso blog. Mas para fazer isto, temos que falar um pouco sobre `objects`. ## Objetos -Existe um conceito na programação chamado `Programação Orientada à Objetos (POO)`. A ideia é que ao invés de escrever tudo como uma chata sequência de instruções de programação podemos modelar as coisas e definir como elas interagem umas com as outras. +Existe um conceito em programação chamado `programação orientada a objetos`. A ideia é que ao invés de escrever tudo como uma sequência entediante de instruções de programação, possamos modelar as coisas e definir como elas interagem umas com as outras. -Então o que é um objeto? É uma coleção de propriedades e ações. Isto pode parecer estranho, mas vamos lhe dar um exemplo. +Então o que é um objeto? É uma coleção de propriedades e ações. Isto pode parecer estranho, mas vamos mostrar um exemplo. -Se queremos modelar um gato nós criaremos um objeto `Gato` que possui algumas propriedades, por exemplo `cor`, `idade`, `humor` (bom, mau, sonolento ;)), `dono` (que é um objeto da classe `Pessoa` ou, caso seja um gato de rua, essa propriedade é vazia). +Se quisermos modelar um gato, podemos criar um objeto `Gato` que possui propriedades como `cor`, `idade`, `humor` (como bom, mal ou sonolento ;)), e `dono` (que seria atribuído a um objeto de `Pessoa` – ou talvez, no caso de um gato de rua, essa propriedade seja vazia). -E então o `Gato` tem algumas ações: `ronronar`, `arranhar` ou `comer` (no qual vamos dar ao gato alguma `ComidaDeGato `, que poderia ser um objeto separado com propriedades, como `sabor`). +`Gato` também realiza algumas ações: `ronronar`, `arranhar` ou `alimentar`-se (em que podemos dar ao gato alguma `ComidaDeGato`, que poderia ser um objeto separado com propriedades como `sabor`). Gato -------- cor idade - humor + temperamento dono ronronar() arranhar() - comer(comida_de_gato) - + alimentar(comida_de_gato) + ComidaDeGato - -------- + ------------ sabor -Então, basicamente, a ideia é descrever coisas reais no código com propriedades(chamadas de `propriedades do objeto`) e ações (chamadas de `métodos`). +A ideia básica é descrever coisas reais em código a partir de suas propriedades (chamadas de `atributos`) e ações (chamadas de `métodos`). -Como nós iremos modelar as postagens do blog então? Queremos construir um blog, certo? +Como vamos modelar as postagens do blog, então? Queremos construir um blog, certo? -Precisamos responder à pergunta: o que é uma postagem de blog? Que propriedades deve ter? +Para isto, precisamos responder as questões: O que é um post de blog? Que propriedades (atributos) ele deve ter? -Bem, com certeza nosso blog precisa de alguma postagem com o seu conteúdo e um título, certo? Também seria bom saber quem a escreveu - então precisamos de um autor. Finalmente, queremos saber quando a postagem foi criada e publicada. +Bem, com certeza uma postagem precisa de um texto com seu conteúdo e um título, certo? Também seria legal saber quem a escreveu – então precisamos de um autor. Finalmente, queremos saber quando a postagem foi criada e publicada. Para ficar chique, vamos fazer em inglês. Post -------- @@ -45,50 +45,63 @@ Bem, com certeza nosso blog precisa de alguma postagem com o seu conteúdo e um published_date -Que tipo de coisa pode ser feita com uma postagem? Seria legal ter algum `método` que publique a postagem, não é mesmo? +Que tipo de ações podem ser feitas com uma postagem? Seria legal ter um `método` que publique a postagem, não é mesmo? -Então precisamos de um método chamado `publicar`. +Então, nós precisaremos de um método para publicar (`publish`). -Como já sabemos o que queremos alcançar, podemos começar a modelagem em Django! +Como já sabemos o que queremos alcançar, podemos começar a modelar em Django! -## Modelo do Django +## Modelos do Django -Sabendo o que um objeto é, nós criaremos um modelo no Django para a postagem do blog. +Sabendo o que um objeto é, criamos um modelo no Django para a postagem do blog. -Um modelo no Django é um tipo especial de objeto - ele é salvo em um `banco de dados`. Um banco de dados é uma coleção de dados. O banco de dados é um local em que você vai salvar dados sobre usuários, suas postagens, etc. Usaremos um banco de dados chamado SQLite para armazenar as nossas informações. Este é o adaptador de banco de dados padrão Django -- ele vai ser o suficiente para nós neste momento. +Um modelo no Django é um tipo especial de objeto -- ele é salvo em um `banco de dados`. Um banco de dados é uma coleção de dados. Ele é um local em que você vai salvar dados sobre usuários, suas postagens, etc. Usaremos um banco de dados chamado SQLite para armazenar as nossas informações. Este é o banco de dados padrão do Django -- e ele será suficiente neste primeiro momento. Você pode pensar em um modelo de banco de dados como uma planilha com colunas (campos) e linhas (dados). ### Criando uma aplicação -Para manter tudo arrumado vamos criar um aplicativo separado dentro do nosso projeto. É muito bom ter tudo organizado desde o início. Para criar um aplicativo precisamos executar o seguinte comando no console (a partir do diretório `djangogirls` onde está o arquivo `manage.py`): +Para manter tudo arrumado, vamos criar uma aplicação separada dentro do nosso projeto. É muito bom ter tudo organizado desde o início. Para criar uma aplicação, precisamos executar o seguinte comando no prompt (a partir do diretório `djangogirls` onde está o arquivo `manage.py`): + +{% filename %}macOS and Linux:{% endfilename %} (myvenv) ~/djangogirls$ python manage.py startapp blog -Você vai notar que um novo diretório `blog` é criado e que ele agora contém um número de arquivos. Nossos diretórios e arquivos no nosso projeto devem se parecer com este: +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + + +Você vai notar que um novo diretório `blog` foi criado e que ele contém vários arquivos. Algo como a lista abaixo: djangogirls - ├── mysite - | __init__.py - | settings.py - | urls.py - | wsgi.py + ├── blog + │   ├── __init__.py + │   ├── admin.py + │   ├── apps.py + │   ├── migrations + │   │   └── __init__.py + │   ├── models.py + │   ├── tests.py + | ├── urls.py + │   └── views.py + ├── db.sqlite3 ├── manage.py - └── blog - ├── migrations - | __init__.py - ├── __init__.py - ├── admin.py - ├── models.py - ├── tests.py - └── views.py + ├── mysite + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + └── requirements.txt -Depois de criar um aplicativo também precisamos dizer ao Django que deve usá-lo. Fazemos isso no arquivo `mysite/settings.py`. Precisamos encontrar o `INSTALLED_APPS` e adicionar uma linha com `'blog',` logo acima do `)`. É assim que o produto final deve ficar assim: +Depois de criar uma aplicação, também precisamos dizer ao Django que ele deve usá-la. Fazemos isso no arquivo `mysite/settings.py` -- abra-o no seu editor de código. Precisamos encontrar o `INSTALLED_APPS` e adicionar uma linha com `'blog',` logo acima do `]`. O resultado final ficará assim: + +{% filename %}mysite/settings.py{% endfilename %} ```python -INSTALLED_APPS = ( +INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -96,27 +109,29 @@ INSTALLED_APPS = ( 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', -) +] ``` -### Criando o modelo Post do nosso blog +### Criando um modelo de postagem para o nosso blog + +No arquivo `blog/models.py` definimos todos os objetos chamados `Modelos` -- este é um lugar em que vamos definir nossa postagem do blog. -No arquivo `blog/models.py` definimos todos os objetos chamados `Modelos` - este é um lugar em que vamos definir nossa postagem do blog. +Vamos abrir `blog/models.py` no editor de código, apagar tudo dele e escrever o seguinte código: -Vamos abrir `blog/models.py`, remova tudo dele e escreva o código como este: +{% filename %}blog/models.py{% endfilename %} ```python +from django.conf import settings from django.db import models from django.utils import timezone + class Post(models.Model): - author = models.ForeignKey('auth.User') + 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() @@ -126,44 +141,53 @@ class Post(models.Model): return self.title ``` -> Certifique-se de ter usado dois caracteres (`_`) em cada lado do `str`. Aqueles caracteres são usados freqüentemente em Python e às vezes os chamamos de "dunder" (abreviação de "double-underscore" ou "duplo sublinhado"). +> Certifique-se de que usou dois caracteres de sublinhado (`_`) em cada lado de `str`. Esta convenção é utilizada frequentemente em Python e, muitas vezes, a chamamos de "dunder" (vem da expressão em inglês "double-underscore" - sublinhado duplo em português). -É assustador, não? Mas não se preocupe, vamos explicar o que estas linhas significam! +Parece assustador, né? Mas não se preocupe, vamos explicar o que essas linhas significam! -Todas as linhas começando com `from` ou `import` são linhas que adicionam alguns pedaços de outros arquivos. Então ao invés de copiar e colar as mesmas coisas em cada arquivo, podemos incluir algumas partes com `from... import ...`. +Todas as linhas começando com `from` ou `import` são linhas que adicionam pedaços de outros arquivos. Então ao invés de copiar e colar as mesmas coisas em cada arquivo, podemos incluir algumas partes com `from... import ...`. `class Post(models.Model):` - esta linha define o nosso modelo (é um `objeto`). -* `class` é uma palavra-chave especial que indica que estamos definindo um objeto. -* `Post` é o nome do nosso modelo, podemos lhe dar um nome diferente (mas é preciso evitar os espaços em branco e caracteres especiais). Sempre comece um nome de classe com uma letra maiúscula. -* `models.Model` significa que o Post é um modelo de Django, então o Django sabe ele que deve ser salvo no banco de dados. +- `class` é uma palavra-chave especial que indica que estamos definindo um objeto. +- `Post` é o nome do nosso modelo. Nós podemos dar um nome diferente (mas precisamos evitar caracteres especiais e espaços em branco). Sempre inicie o nome de uma classe com uma letra em maiúsculo. +- `models.Model` significa que o Post é um modelo de Django, então o Django sabe que ele deve ser salvo no banco de dados. + +Agora definiremos as propriedades comentadas acima: `title`, `text`, `created_date`, `published_date` e `author`. Para fazer isso, é necessário definir um tipo para cada campo (É um texto? Um número? Uma data? Uma relação com outro objeto, por exemplo, um usuário?) -Agora podemos definir as propriedades que discutimos: `titulo`, `texto`, `data_criacao`, `data_publicacao` e `autor`. Para isso precisamos definir um tipo de campo (é um texto? É um número? Uma data? Uma relação com outro objeto, por exemplo, um usuário?). +- `models.CharField` - é assim que definimos um texto com um número limitado de caracteres. +- `models.TextField` - este campo é para textos sem um limite fixo. Parece ideal para o conteúdo de um blog, né? +- `models.DateTimeField` - este é uma data e hora. +- `models.ForeignKey` - este é um link para outro modelo. -* `models.CharField` - assim é como você define um texto com um número limitado de caracteres. -* `models.TextField` - este é para textos longos sem um limite. Será ideal para um conteúdo de post de blog, certo? -* `models.DateTimeField` - este é uma data e hora. -* `models.ForeignKey` - este é um link para outro modelo. +Nós não explicaremos cada pedaço de código aqui pois isso levaria muito tempo. Você deve dar uma olhada na documentação do Django se quiser saber mais sobre campos de modelos e como definir outras coisas além das descritas acima (https://docs.djangoproject.com/en/2.0/ref/models/fields/#field-types). -Nós não vamos explicar cada pedaço de código aqui, pois isso levaria muito tempo. Você deve olhar a documentação do DJango se você quiser saber mais sobre campos do Model e como definir coisas além destas descritas acima (https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-types). +E `def publish(self):`? Esse é justamente o método `publish` de que falamos anteriormente. `def` significa que se trata de uma função/método e que `publish` é seu nome. Você pode mudar o nome do método, se quiser. A regra para nomes é sempre usar letras minúsculas e no lugar dos espaços em branco, usar o caractere sublinhado (_). Por exemplo, um método que calcula o preço médio poderia se chamar `calculate_average_price` (do inglês, calcular_preco_medio). -Que tal `def publish(self):`? É exatamente o nosso método de `publish` que falávamos antes. `def`, significa que se trata de um função/método. `publish` é o nome do método. Você pode alterar, se quiser. A regra é que usamos letras minúsculas e sublinhados em vez de espaços em branco (ou seja, se você quer ter um método que calcula o preço médio, você poderia chamá-lo `calculate_average_price`). +Métodos muitas vezes retornam (`return`) algo. Um exemplo disto é o método `__str__`. Neste caso, quando chamarmos `__str__()`, obteremos um texto (**string**) com o título do Post. -Métodos muitas vezes `return` algo. Há um exemplo de que, no método `__str__`. Nesse cenário, quando chamamos `__str__()` teremos um texto (**string**), com um título do Post. +Lembre-se também de que tanto `def publish(self):` quanto `def __str__(self):` são endentados para dentro da classe. E porque Python é sensível a espaços em branco, precisamos endentar todos os nossos métodos para dentro da classe. Caso contrário, os métodos não pertencerão à classe e você poderá obter um comportamento inesperado. -Se algo ainda não está claro sobre modelos, sinta-se livre para pedir o seu treinador! Sabemos que é muito complicado, especialmente quando você aprender o que são objetos e funções ao mesmo tempo. Mas espero que ele se parece um pouco menos mágica para você agora! +Se algo ainda não está claro sobre modelos, sinta-se livre para perguntar para sua monitora! Sabemos que é complicado, especialmente porque você está aprendendo o que são objetos e funções ao mesmo tempo. Mas esperamos que isto se pareça um pouco menos com mágica agora! ### Criando tabelas para nossos modelos no banco de dados -O último passo é adicionar nosso novo modelo para nosso banco de dados. Primeiro temos que fazer o Django saber que nós temos algumas mudanças em nosso modelo (só criamos isso), digite `python manage.py makemigrations blog`. Será algo parecido com isto: +O último passo é adicionar nosso novo modelo ao banco de dados. Primeiramente, precisamos fazer com que o Django entenda que fizemos algumas alterações nos nossos modelos. (Acabamos de criar um modelo de Post!) Vá para o console e digite `python manage.py makemigrations blog`. Deve ficar assim: + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py makemigrations blog Migrations for 'blog': - 0001_initial.py: + blog/migrations/0001_initial.py: + - Create model Post -Django prepara um arquivo de migração que temos de aplicar agora para nosso banco de dados, tipo `python manage.py migrate blog`, a saída deve ser: +**Observação:** Lembre-se de salvar os arquivos que você editar. Caso contrário, o computador executará uma versão antiga que pode gerar mensagens de erro inesperadas. + +O Django preparou um arquivo de migração que precisamos aplicar ao nosso banco de dados. Digite `python manage.py migrate blog` e a saída deve ser: + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py migrate blog Operations to perform: @@ -172,4 +196,4 @@ Django prepara um arquivo de migração que temos de aplicar agora para nosso ba Applying blog.0001_initial... OK -Viva! Nosso modelo de Post está agora em nosso banco de dados, seria um prazer vê-lo, certo? Saltar para o próximo capítulo para ver o aspecto do seu Post! +Uhuu! Nosso modelo Post já está no banco de dados! Seria legal vê-lo, né? Vá para o próximo capítulo para descobrir como nosso Post se parece! \ No newline at end of file diff --git a/pt/django_orm/README.md b/pt/django_orm/README.md index 9de06ce256d..b6ba8d76d66 100755 --- a/pt/django_orm/README.md +++ b/pt/django_orm/README.md @@ -1,146 +1,221 @@ # QuerySets e ORM do Django -Neste capítulo você vai aprender como Django se conecta ao banco de dados e como ele armazena dados. Vamos nessa! +Neste capítulo você vai aprender como o Django se conecta ao banco de dados e como ele armazena dados. Vamos nessa! ## O que é um QuerySet? -Um QuerySet (conjunto de pesquisa), no fundo, é uma lista de objetos de um dado modelo. Um QuerySet permite que você leia os dados do banco, filtre e ordene o mesmo. +Um QuerySet (conjunto de busca) é, em essência, uma lista de objetos de um dado modelo. QuerySet permite que você leia os dados a partir de uma base de dados, filtre e ordene. -É mais fácil aprender por exemplos. Vamos tentar? +É mais fácil aprender usando exemplos. Vamos lá? ## O Shell do Django -Abra o terminal e digite: +Abra o seu terminal (não o PythonAnywhere) e digite o seguinte comando: + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py shell O resultado deve ser: - (InteractiveConsole) - >>> - +{% filename %}command-line{% endfilename %} + +```python +(InteractiveConsole) +>>> +``` -Agora você está no console interativo do Django. Ele é como o prompt do Python só que com umas mágicas a mais :). Você pode usar todos os comandos do Python aqui também, é claro. +Agora você está no console interativo do Django. Ele é como o prompt do Python, só que com umas mágicas adicionais ;). Você pode usar todos os comandos do Python aqui também, é claro. ### Todos os objetos -Antes, vamos tentar mostrar todas as nossas postagens. Podemos fazer isso com o seguinte comando: +Primeiro, vamos tentar mostrar todas as nossas postagens. Podemos fazer isso com o seguinte comando: - >>> Post.objects.all() - Traceback (most recent call last): - File "", line 1, in - NameError: name 'Post' is not defined - +{% filename %}command-line{% endfilename %} -Oops! Um erro apareceu. Ele nos diz que não existe algo chamado Post. É verdade -- nós esquecemos de importá-lo primeiro! +```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! Um erro apareceu. Ele nos diz que não existe algo chamado Post. É verdade -- nós esquecemos de importá-lo antes! -Isso é simples: importamos o modelo `Post` de dentro do `blog.models`. Vamos tentar mostrar todas as postagens novamente: +{% filename %}command-line{% endfilename %} - >>> Post.objects.all() - [, ] - +```python +>>> from blog.models import Post +``` -É uma lista dos posts que criamos anteriormente! Criamos esses posts usando a interface de administração do Django. No entanto, agora queremos criar novas mensagens utilizando o python, então como é que fazemos isso? +Mas isso é simples: basta importar o modelo `Post` de dentro do `blog.models`. Vamos tentar mostrar todas as postagens novamente: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, ]> +``` + +É uma lista dos posts que criamos mais cedo! Nós criamos estes posts utilizando a interface do Django admin. No entanto, agora queremos criar novos posts utilizando Python. Como fazemos isso? ### Criando um objeto -É assim que você cria um objeto Post no banco de dados: +É assim que se cria um objeto Post no banco de dados: - >>> 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') +``` -Mas aqui temos um ingrediente que faltava: `me`. Precisamos passar uma instância de `User` modelo como autor. Como fazer isso? +Mas aqui temos um ingrediente faltando: `me`. Precisamos passar uma instância do modelo `User` como autor. Como fazemos isso? Primeiro vamos importar o modelo User: - >>> from django.contrib.auth.models import User - +{% filename %}command-line{% endfilename %} + +```python +>>> from django.contrib.auth.models import User +``` Quais usuários temos no nosso banco de dados? Experimente isso: - >>> User.objects.all() - [] - +{% filename %}command-line{% endfilename %} -É o superusuário que criamos anteriormente! Vamos obter uma instância de usuário agora: +```python +>>> User.objects.all() +]> +``` - me = User.objects.get(username='ola') - +Este é o superusuário que criamos anteriormente! Vamos pegar uma instância do usuário agora (ajuste esta linha para usar seu próprio nome de usuário): -Como você pode ver, nós agora usamos um `get` a `User` with a `username` igual a 'ola'. Claro, você tem que adaptar a seu nome de usuário. +{% filename %}command-line{% endfilename %} -Agora finalmente podemos criar nossa primeira postagem: +```python +>>> me = User.objects.get(username='ola') +``` - >>> Post.objects.create(author=me, title='Sample title', text='Test') - +Como você pode ver, agora `obtém` um `Usuário` com um `nome de usuário` que é igual a 'ola'. Arrumado! -Viva! Quer ver se funcionou? +Agora finalmente podemos criar nosso post: - >>> Post.objects.all() - [] - +{% filename %}command-line{% endfilename %} -### Adicione mais postagens +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') + +``` -Agora, você pode se divertir um pouco e adicionar mais postagens para ver como funciona. Adicione mais 2-3 e siga para a próxima parte. +Uhuu! Quer ver se funcionou? -### Filtrar objetos +{% filename %}command-line{% endfilename %} -Uma grande parte de QuerySets é a habilidade de filtrá-los. Digamos que queremos encontrar todos as postagens escritas pelo usuário ola. Nós usaremos o `filter` em vez de `all` em `Post.objects.all()`. Entre parênteses indicamos que as condições precisam ser atendidas por um postagem de blog para acabar em nosso queryset. Em nosso caso é `author` que é igual a `me`. A maneira de escrever isso no Django é: `author=me`. Agora o nosso trecho de código parece com este: +```python +>>> Post.objects.all() +, , ]> +``` - >>> Post.objects.filter(author=me) - [, , , ] - +É isso aí, mais um post na lista! -Ou talvez nós queremos ver todos os posts que contenham a palavra 'title' no campo de `title`? +### Adicionando mais postagens - >>> Post.objects.filter(title__contains='title') - [, ] - +Agora você pode se divertir um pouco e adicionar algumas postagens para ver como funciona. Adicione mais uns 2 ou 3 posts pelo Python e siga para a próxima parte. -> **Nota** Existem dois caracteres de sublinhado (`_`) entre o `title` e `contains`. Django ORM usa esta sintaxe para separar nomes de campo ("title") e operações ou filtros ("contains"). Se você usar apenas um sublinhado, você obterá um erro como "FieldError: Cannot resolve keyword title_contains". +### Filtrando objetos -Você também pode obter uma lista de todos os posts publicados. Fazemos isso filtrando todos os posts com `published_date` definido no passado: +Um recurso importante dos QuerySets é a possibilidade de filtrá-los. Digamos que queremos encontrar todos as postagens escritas pela usuária ola. Para isto, usamos `filter` ao invés de `all` em `Post.objects.all()`. Entre parênteses, indicamos quais condições precisam ser atendidas por um post para que ele entre no nosso queryset. No nosso caso, a condição é: `author` é igual a `me`. A maneira de escrever isso no Django é: `author=me`. Agora o nosso trecho de código ficará assim: - >>> from django.utils import timezone - >>> Post.objects.filter(published_date__lte=timezone.now()) - [] +{% filename %}command-line{% endfilename %} -Infelizmente, nenhum dos nossos posts estão publicados ainda. Nós podemos mudar isso! Primeiro obtenha uma instância de um post que queremos publicar: +```python +>>> Post.objects.filter(author=me) +, , , ]> +``` - >>> post = Post.objects.get(id=1) - +E se quisermos ver todos os posts que contenham a palavra 'title' no campo `title`? -E então publicá-lo com o nosso método de `publish`! +{% filename %}command-line{% endfilename %} - >>> post.publish() - +```python +>>> Post.objects.filter(title__contains='title') +, ]> +``` -Agora tente obter a lista de posts publicados novamente (pressione a seta para cima botão 3 vezes e tecle Enter): +> **Observação:** Existem dois caracteres de sublinhado (`_`) entre `title` e `contains`. O ORM do Django utiliza esta sintaxe para separar nomes de campo ("title") e operações ou filtros (como "contains"). Se você usar apenas um sublinhado, obterá um erro como "FieldError: Cannot resolve keyword title_contains". - >>> Post.objects.filter(published_date__lte=timezone.now()) - [] - +Você também pode obter uma lista de todos os posts publicados. Fazemos isso filtrando todos os posts com uma `published_date` definida no passado: + +{% filename %}command-line{% endfilename %} + +```python +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) + +``` + +Infelizmente, o post que nós criamos pelo console do Python não está publicado ainda. Podemos mudar isso! Primeiro, busque a instância do post que queremos publicar: + +{% filename %}command-line{% endfilename %} + +```python +>>> post = Post.objects.get(title="Sample title") +``` + +Então vamos publicá-lo com o nosso método `publish`: + +{% filename %}command-line{% endfilename %} + +```python +>>> post.publish() +``` + +Agora, busque novamente a lista de posts publicados (aperte a seta para cima algumas vezes e pressione `enter`): + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +]> +``` ### Ordenando objetos Um QuerySet também nos permite ordenar a lista de objetos. Vamos tentar ordenar as postagens pelo campo `created_date`: - >>> Post.objects.order_by('created_date') - [, , , ] - +{% filename %}command-line{% endfilename %} -Você também pode inverter a ordem adicionando `-` no início: +```python +>>> Post.objects.order_by('created_date') +, , , ]> +``` - >>> Post.objects.order_by('-created_date') - [, , , ] - +Também podemos inverter a ordem adicionando `-` no início: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.order_by('-created_date') +, , , ]> +``` + +### Consultas Complexas com Encadeamento de Métodos + +Como você viu, alguns métodos em `Post.objects` retornam um QuerySet. Esses mesmos métodos podem, por sua vez, ser invocados num QuerySet, o que resultará num novo QuerySet. Dessa forma, você pode combinar seus efeitos **encadeando-los** juntos: + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> +``` + +Isso é muito poderoso e nos permite criar consultas bastante complexas. + +Legal! Você já está pronta para a próxima parte! Para fechar o terminal, digite: -Legal! Você já está pronto para a próxima parte! Para fechar o terminal digite: +{% filename %}command-line{% endfilename %} - >>> exit() - $ +```python +>>> exit() +$ +``` \ No newline at end of file diff --git a/pt/django_start_project/README.md b/pt/django_start_project/README.md index cb4caab2eaf..a78c3cad7b6 100755 --- a/pt/django_start_project/README.md +++ b/pt/django_start_project/README.md @@ -1,118 +1,205 @@ # Seu primeiro projeto Django! -> Parte deste capítulo é baseado nos tutoriais do Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> Parte deste capítulo é baseada nos tutoriais da Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). > -> Parte deste capítulo é baseado no [django-marcador tutorial][1] licenciado sobre Creative Commons Attribution-ShareAlike 4.0 International License. O tutorial do django-marcador é protegido por direitos autorais por Markus Zapke-Gründemann et al. - - [1]: http://django-marcador.keimlink.de/ +> Parte deste capítulo é baseado no [django-marcador tutorial](http://django-marcador.keimlink.de/) licenciado sobre Creative Commons Attribution-ShareAlike 4.0 International License. O tutorial do django-marcador é protegido por direitos autorais por Markus Zapke-Gründemann et al. Nós vamos criar um blog simples! -O primeiro passo para criá-lo é começar um novo projeto de Django. Basicamente, isto significa que vamos executar alguns scripts fornecidos pelo Django que irá criar o esqueleto de um projeto Django para nós: um bando de diretórios e arquivos que usaremos mais tarde. +O primeiro passo é iniciar um novo projeto Django. Basicamente, isso significa que devemos rodar alguns scripts providos pelo Django que vão criar um esqueleto de projeto Django para nós. O resultado é um conjunto de diretórios e arquivos que nós iremos utilizar e modificar mais tarde. -Os nomes de alguns arquivos e diretórios são muito importantes para o Django. Não renomeie os arquivos que estamos prestes a criar. Mover para um lugar diferente também não é uma boa idéia. Django precisa manter uma determinada estrutura para ser capaz de encontrar coisas importantes. +Os nomes de alguns arquivos e diretórios são muito importantes para o Django. Você não deve renomear os arquivos que estamos prestes a criar. Mover para um lugar diferente também não é uma boa idéia. O Django precisa manter uma certa estrutura para conseguir encontrar algumas coisas importantes. -> Lembre-se que tudo no virtualenv. Se você não vê um prefixo `(myvenv)` em seu console, você precisa ativar o virtualenv. Nós explicamos como fazer isso no capítulo **instalação do Django** na parte **trabalhando com virtualenv**. Você pode fazer isso digitando o seguinte comando: `myvenv\Scripts\activate` no Windows ou `myvenv/bin/activate` no Mac OS / Linux. -> -> **Nota** Verifique que você incluiu o ponto (`.`) no final do comando, é importante porque diz o script para instalar o Django em seu diretório atual. +> Lembre-se de rodar tudo no virtualenv. Se você não vê um prefixo `(myvenv)` em seu console, é necessário ativar o virtualenv. Nós explicamos como fazer isso no capítulo **Instalação do Django** na parte **Ambiente Virtual**. Digitar `myvenv\Scripts\activate` no Windows ou `source myvenv/bin/activate` no Mac OS / Linux fará isso para você. + + -No console, você deve executar (Lembre-se de que você não pode digitar `~/djangogirls$ (myvenv)`, OK?): +No MacOS ou no console do Linux, rode o comando abaixo (**não esqueça de adicionar o ponto `.` no final):

+ +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ django-admin startproject mysite . -no Windows: +> O ponto `.` é crucial por que ele diz para o script instalar o Django no diretório atual (o ponto `.` é um atalho para referenciar este diretório). +> +> **Observação:** Quando digitar o comando acima, lembre-se de digitar apenas a parte que começa em `django-admin`. A parte `(myvenv) ~/djangogirls$` apresentada aqui é apenas um exemplo do que pode aparecer no seu terminal quando você digitar seus comandos. + + - (myvenv) C:\Users\Name\djangogirls> python myvenv\Scripts\django-admin.py startproject mysite . + + +No Windows, rode o seguinte comando (**não esqueça de adicionar o ponto `.` no final!**): + +{% filename %}command-line{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . -`Django-admin` é um script que irá criar os diretórios e arquivos para você. Agora, você deve ter um diretório estrutura que se parece com isso: +> O ponto `.` é crucial por que ele diz para o script instalar o Django no diretório atual (o ponto `.` é um atalho para referenciar este diretório). +> +> **Observação:** Quando digitar o comando acima, lembre-se de digitar apenas a parte que começa em `django-admin.exe`. A parte `(myvenv) C:\Users\Name\djangogirls>` apresentada aqui é apenas um exemplo do que pode aparecer no seu terminal quando você digitar seus comandos. + + + +`django-admin` é um script que criará os diretórios e arquivos para você. Agora, você deve ter uma estrutura de diretório parecida com isso: djangogirls ├───manage.py - └───mysite - settings.py - urls.py - wsgi.py - __init__.py + ├───mysite + │ settings.py + │ urls.py + │ wsgi.py + │ __init__.py + └───requirements.txt -`manage.py` é um script que ajuda com a gestão do site. Com isso seremos capazes de iniciar um servidor de web no nosso computador sem instalar nada, entre outras coisas. +> **Observação:** em sua estrutura de diretórios, você também verá o o diretório do virtualenv, `myvenv`, que criamos antes. + +`manage.py` é um script que ajuda com a gestão do site. Com ele, podemos iniciar um servidor de web no nosso computador sem instalar nada, entre outras coisas. O arquivo `settings.py` contém a configuração do seu site. -Lembra quando falamos sobre um carteiro verificando onde entregar uma carta? arquivo `urls.py` contém uma lista dos padrões usados por `urlresolver`. +Lembra de quando falamos sobre um carteiro verificando onde entregar uma carta? O arquivo `urls.py` contém uma lista dos padrões usados por `urlresolver`. -Vamos ignorar os outros arquivos por agora - nós não vamos mudá-los. A única coisa a lembrar é não excluí-los por acidente! +Vamos ignorar os outros arquivos por enquanto pois não vamos modificá-los. Só precisamos lembrar de não excluí-los por acidentalmente! -## Configurando +## Mudando as configurações Vamos fazer algumas alterações no `mysite/settings.py`. Abra o arquivo usando o editor de código que você instalou anteriormente. -Seria bom ter a hora correta no nosso site. Vá para a <[wikipedia timezones list][2] e copie seu fuso horário. (por exemplo. `America/Sao_Paulo`) +**Observação:** Lembre-se de que o `settings.py` é um arquivo comum, como qualquer outro. Você pode abri-lo de dentro do editor de código usando as ações de menu "Arquivo-> Abrir". Assim, você deve encontrá-lo na janela usual para selecionar arquivos e abri-lo. Ou então, é possível abrir o arquivo navegando até o diretório do djangogirls e abrindo o arquivo com o botão direito. Uma vez clicado, selecione o seu editor de código preferido da lista. Selecionar o editor apropriado é importante uma vez que você pode ter outros programas instalados que podem abrir o arquivo, mas não editá-lo. + +Para começar, seria bom ter a hora correta no nosso site. Para isto, você configurar o fuso horário correto de onde está. Se você estiver no Brasil, é bem provável que o fuso horário seja `America/Sao_Paulo` (aqui conhecido como horário de Brasília). Caso queira saber mais, vá para [Wikipedia's list of time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) e copie e cole o fuso horário correspondende à sua localização. - [2]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +Em `settings.py`, localize a linha que contém `TIME_ZONE` e modifique para escolher seu próprio fuso horário: -Em settings.py, localize a linha que contém `TIME_ZONE` e modifique para escolher seu próprio fuso horário: +{% filename %}mysite/settings.py{% endfilename %} ```python TIME_ZONE = 'America/Sao_Paulo' -``` +``` + +Um código de idioma se refere à língua, por exemplo, `en` para inglês ou `pt` para português e o código do país, por exemplo, `br` para Brasil ou `pt` para a Portugal. Já que o inglês provavelmente não é sua língua nativa, você pode pode adicionar um novo código de país para deixar os botões padrão e notificações de Django em seu idioma. Assim, você teria por exemplo um botão "Cancel" traduzido para a língua da sua escolha (ex: "Cancelar" em português). O [Django vem com um monte de traduções já preparadas](https://docs.djangoproject.com/en/2.0/ref/settings/#language-code). + +Se você quiser um idioma diferente do inglês, especifique o código de idioma alterando a seguinte linha: + +{% filename %}mysite/settings.py{% endfilename %} -Modifique "America/Sao_Paulo", conforme o caso +```python +LANGUAGE_CODE = 'pt-BR' +``` + +Também precisamos adicionar o caminho para os arquivos estáticos. (Discutiremos tudo sobre arquivos estáticos e CSS mais adiante no tutorial.) Vá até o *final* do arquivo e, logo abaixo da linha com `STATIC_URL`, adicione uma nova variável chamada `STATIC_ROOT`: -Nós também precisaramos adicionar um caminho para arquivos estáticos (nós vamos descobrir tudo sobre arquivos estáticos e CSS mais tarde no tutorial). Desça até o *final* do arquivo e logo abaixo da entrada `STATIC_URL`, adicione um novo um chamado `STATIC_ROOT`: +{% filename %}mysite/settings.py{% endfilename %} ```python STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') -``` +STATIC_ROOT = BASE_DIR / 'static' +``` -## Instalação de um banco de dados +Quando `DEBUG` for `True` e `ALLOWED_HOSTS` estiver vazia, o domínio do site será validado como `['localhost', '127.0.0.1', '[::1]']`. Isso não corresponderá ao nosso domínio no PythonAnywhere quando implantarmos a nossa aplicação, então vamos mudamos a seguinte configuração: -Há vários softwares de banco de dados diferentes que pode armazenar dados para o seu site. Nós vamos usar o padrão, `sqlite3`. +{% filename %}mysite/settings.py{% endfilename %} + +```python +ALLOWED_HOSTS = ['127.0.0.1', '.pythonanywhere.com'] +``` + +> **Observação:** Se você estiver utilizando um Chromebook, adicione esta linha ao final do arquivo settings.py: `MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'` +> +> Também inclua `.c9users.io` à lista de `ALLOWED_HOSTS` se você estiver utilizando o cloud9 + +## Configurando um banco de dados + +Existem vários software de banco de dados diferentes que podem armazenar dados para o seu site. Nós vamos usar o padrão do Django, o `sqlite3`. Isto já está configurado nesta parte do seu arquivo `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', } } ``` -Para criar um banco de dados para o nosso blog, vamos fazer o seguinte no console. Digite: `python manage.py migrate` (precisamos estar no diretório que contém o arquivo `manage.py` `djangogirls`). Se isso der certo, você deve ver algo como isto: +Para criar um banco de dados para o nosso blog, vamos executar o seguinte comando no console. Digite: `python manage.py migrate` (precisamos estar no diretório que contém o arquivo `manage.py` `djangogirls`). Se isso der certo, você deve ver algo assim: + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py migrate - Operations to perform: - Apply all migrations: admin, contenttypes, auth, sessions - Running migrations: + Operations to perform: + Apply all migrations: auth, admin, 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 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 sessions.0001_initial... OK -E está pronto! Hora de iniciar o servidor web e ver se nosso site está funcionando! +Pronto! Hora de iniciar o servidor web e ver se nosso site está funcionando! + +## Iniciando o servidor web Você precisa estar no diretório que contém o arquivo `manage.py` (o diretório `djangogirls`). No console, nós podemos iniciar o servidor web executando o `python manage.py runserver`: +{% filename %}command-line{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py runserver -Agora tudo que você precisa fazer é verificar se seu site está sendo executado - abra seu navegador (Firefox, Chrome, Safari, Internet Explorer ou o que você usa) e digite o endereço: +Se você usa um Chromebook, execute este comando: + +{% filename %}Cloud 9{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0.0.0.0:8080 + + +Se você estiver no Windows e o comando falhar com `UnicodeDecodeError`, use o comando alternativo: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + + +Agora você precisa checar se o o seu site está funcionando. Abra o seu navegador (Firefox, Chrome, Safari, Internet Explorer ou qualquer outro que você usa) e coloque esse endereço: + +{% filename %}browser{% endfilename %} http://127.0.0.1:8000/ -O servidor web vai assumir seu prompt de comando até você pará-lo: para digitar mais comandos ou abrir uma nova janela do terminal (e não se esqueça de ativar seu virtualenv nele também), ou parar o servidor de web, alternando de volta para a janela na qual está executando e pressionando CTRL + C - botões de controle e C juntos (no Windows, você pode ter que pressionar Ctrl + Break). +Se você esta usando um Chromebook e o Cloud9, em vez disso clique no URL na janela "pop-up" que deve ter aparecido no canto superior direito da janela de comando onde o servidor está funcionando. A URL vai ser algo como: + +{% filename %}browser{% endfilename %} + + https://.vfs.cloud9.us-west-2.amazonaws.com + + +Parabéns! Você criou seu primeiro site e o executou usando um servidor web! Não é impressionante? + +![Instalação funcionou!](images/install_worked.png) -Parabéns! Você criou seu primeiro site e o executou usando um servidor de web! Não é impressionante? +Note que a janela de comando só pode rodar uma coisa de cada vez, e a janela de comando que você abriu anteriormente já está rodando o servidor. Enquanto o servidor web estiver executando e esperando por solicitações de entrada, o terminal vai aceitar o novo testo mas não executará novos comandos. -![Funcionou!][3] +> Nós revisamos como servidores web funcionam no capítulo **Como a Internet funciona**. - [3]: images/it_worked2.png +Para digitar comandos adicionais enquanto o servidor está rodando, abra uma nova janela de terminal e ative seu ambiente virtual, para revisar as instruções de como abrir uma segunda janela de terminal, veja [Introdução à linha de comando](../intro_to_command_line/README.md). Para interromper o seu servidor, volte para a janela onde ele está rodando e pressione CTRL+C -- botões Control e C juntos (no Windows; tente Ctrl+Break se o primeiro não funcionar). -Pronto para o próximo passo? Está na hora de criar algum conteúdo! +Pronta para o próximo passo? Está na hora de criar conteúdo! \ No newline at end of file diff --git a/pt/django_start_project/images/install_worked.png b/pt/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..4354c634ddb Binary files /dev/null and b/pt/django_start_project/images/install_worked.png differ diff --git a/pt/django_start_project/images/it_worked2.png b/pt/django_start_project/images/it_worked2.png deleted file mode 100644 index 4412ecfc49e..00000000000 Binary files a/pt/django_start_project/images/it_worked2.png and /dev/null differ diff --git a/pt/django_templates/README.md b/pt/django_templates/README.md index 8d024330f15..3fd9d73f18c 100755 --- a/pt/django_templates/README.md +++ b/pt/django_templates/README.md @@ -1,35 +1,40 @@ -# Templates +# Templates do Django -Hora de exibir algum dado! Django nos dá ** tags de templates** embutidas bastante úteis para isso. +Hora de exibir dados! O Django já vem com algumas **tags de template** que são úteis pra isso. ## O que são tags de template? -Como pode ver, você não pode colocar código Python no HTML, porque os navegadores não irão entender. Eles apenas conhecem HTML. Nós sabemos que HTML é bastante estático, enquanto Python é muito mais dinâmico. +Sabe, em HTML não podemos incluir código Python porque os browsers só entendem HTML. Sabemos que o HTML é bem estático, enquanto o Python é muito mais dinâmico. -**Tags de template Django** nos permite transformar objetos Python em código HTML, para que você possa construir sites dinâmicos mais rápido e mais fácil. Uhuu! +**Tags de template Django** nos permitem transformar código similar a Python em código HTML para que você possa construir sites dinâmicos mais rápido e mais facilmente. Legal! -## Modelo de lista de post de exibição +## Templates para lista de posts -No capitulo anterior, nós fornecemos ao nosso template uma lista de postagens e a variável posts. Agora vamos exibir em nosso HTML. +No capítulo anterior, fornecemos para o nosso template uma lista de postagens e a variável posts. Agora vamos exibi-las em HTML. -Para exibir uma variável no Django template, nós usamos colchetes duplos com o nome da variável dentro, exemplo: +Pra mostrar uma variável em um template do Django, usamos chaves duplas com o nome da variável, assim: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {{ posts }} ``` -Tentar fazer isso no seu template `blog/templates/blog/post_list.html` (substituia o segundo e o terceiro par de tags `< div >< / div >` pela linha `{{ posts }}`), salve o arquivo e atualize a página para ver os resultados: +Tente fazer isso no seu template `blog/templates/blog/post_list.html`. Abra-o no editor de código e substitua tudo desde o segundo `
` até o terceiro `
` com `{{ posts }}`. Salve o arquivo e atualize a página para ver o resultado: -![Figura 13.1][1] +![Figura 13.1](images/step1.png) - [1]: images/step1.png +Como você pode ver, obtivemos apenas: -Você pode ver, tudo que temos é: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} - [, ] - +```html +, ]> +``` -Isto significa que o Django a entende como uma lista de objetos. Lembre-se de **introdução ao Python** como podemos exibir listas? Sim, com os loops! Em um template Django, fazemos isso da seguinte maneira: +Isto significa que o Django entende essa variável como uma lista de objetos. Em **Introdução ao Python** aprendemos como exibir listas, lembra? Sim, com laços "for"! Em um template do Django você pode criá-los assim: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %} @@ -39,11 +44,11 @@ Isto significa que o Django a entende como uma lista de objetos. Lembre-se de ** Tente fazer isso no seu template. -![Figura 13.2][2] +![Figura 13.2](images/step2.png) - [2]: images/step2.png +Funciona! Mas nós queremos que eles sejam exibidos como os posts estáticos que criamos anteriormente no capítulo de **Introdução a HTML**. Nós podemos misturar HTML com tags de template. O conteúdo da tag `body` ficará assim: -Funciona! Mas nós queremos que eles sejam exibidos como os posts estáticos, como os que criamos anteriormente no capítulo de **Introdução a HTML**. Nós podemos misturar HTML com tags de template. O conteúdo da tag `body` ficará assim: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html
@@ -53,50 +58,51 @@ Funciona! Mas nós queremos que eles sejam exibidos como os posts estáticos, co {% for post in posts %} {% endfor %} ``` -Tudo que você põe entre `{% for %}` e `{% endfor %}` será repetido para cada objeto na lista. Atualize sua página: - -![Figura 13.3][3] +{% raw %}Tudo o que você colocar entre `{% for %}` e `{% endfor %}` será repetido para cada objeto na lista. Atualize a página:{% endraw %} - [3]: images/step3.png +![Figura 13.3](images/step3.png) -Você notou que dessa vez nós usamos uma notação um pouco diferente `{{ post.title }}` ou `{{ post.text }}`? Nós estamos acessando os dados em cada um dos campos que definimos no model do `Post`. Além disso, `|linebreaksbr` está passando o texto do post por um filtro, convertendo quebras de linha em parágrafos. +Você notou que dessa vez nós usamos uma notação um pouco diferente (`{{ post.title }}` ou `{{ post.text }}`)? Estamos acessando os dados em cada um dos campos que definimos no modelo do `Post`. Além disso, `|linebreaks` está passando o texto do post por um filtro, convertendo quebras de linha em parágrafos. ## Mais uma coisa -Seria bom ver se seu site ainda estará funcionando na internet, certo? Vamos tentar implantar a PythonAnywhere novamente. Aqui está um resumo dos passos... +Seria bom ver se seu site ainda funciona na internet, né? Vamos tentar implantar a PythonAnywhere novamente. Aqui está um resumo dos passos… -* Primeiro, envie seu código para o Github - - ``` - $ git status - $ git add --all . - $ git status - $ git commit -m "Added views to create/edit blog post inside the site." - $ git push - ``` +* Primeiro, envie seu código para o Github + +{% filename %}command-line{% endfilename %} -* Em seguida, faça login em [PythonAnywhere][4] e vá para seu **Bash console** (ou comece um novo) e execute: + $ git status + [...] + $ git add --all . + $ git status + [...] + $ git commit -m "Modified templates to display posts from database." + [...] + $ git push - ``` - $ cd my-first-blog - $ git pull - `` -* Finalmente, pule para a [Web tab][5] e aperte **Reload** em seu aplicativo web. Sua atualização deve estar live! +* Em seguida, faça login em [PythonAnywhere](https://www.pythonanywhere.com/consoles/) e vá para seu **console de Bash** (ou comece um novo) e execute: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd .pythonanywhere.com + $ git pull + [...] + - [4]: https://www.pythonanywhere.com/consoles/ - [5]: https://www.pythonanywhere.com/web_app_setup/ +(Lembre-se de substituir `` pelo seu subdomínio PythonAnywhere, mas sem os colchetes angulares, ou seja, sem < e >). -Parabéns! Agora vá em frente e tente adicionar um novo post em seu Django admin (Lembre-se de adicionar published_date!), em seguida, atualize a página para ver se o post aparece por lá. +* Finalmente, pule para a aba ["Web" page](https://www.pythonanywhere.com/web_app_setup/) e aperte **Reload** em sua aplicação. (Para acessar outras páginas do PythonAnywhere a partir do console, utilize o botão do menu na parte superior direita). A sua atualização deve estar ativa em https://subdomain.pythonanywhere.com - confira pelo navegador! Tudo bem se as postagens em seu site PythonAnywhere não coincidirem com as postagens que aparecem no blog hospedado no seu servidor local. Os bancos de dados em seu computador local e no Python Anywhere não sincronizam com o resto de seus arquivos. -Funciona como mágica? Estamos orgulhosos! Afaste-se do seu computador um pouco, você ganhou uma pausa. :) +Parabéns! Agora vá em frente e tente adicionar um novo post no seu administrador Django (lembre-se de adicionar published_data!). Assegure-se que você está no administrador Django do seu site pythonanywhere, https://subdomain.pythonanywhere.com/admin. E então, recarregue a página para verificar se o seu post é mostrado. -![Figura 13.4][6] +Funciona? Estamos orgulhosas! Saia do seu computador um pouquinho - você merece um descanso. :3 - [6]: images/donut.png +![Figura 13.4](images/donut.png) \ No newline at end of file diff --git a/pt/django_templates/images/donut.png b/pt/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/pt/django_templates/images/donut.png and b/pt/django_templates/images/donut.png differ diff --git a/pt/django_templates/images/step1.png b/pt/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/pt/django_templates/images/step1.png and b/pt/django_templates/images/step1.png differ diff --git a/pt/django_templates/images/step2.png b/pt/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/pt/django_templates/images/step2.png and b/pt/django_templates/images/step2.png differ diff --git a/pt/django_templates/images/step3.png b/pt/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/pt/django_templates/images/step3.png and b/pt/django_templates/images/step3.png differ diff --git a/pt/django_urls/README.md b/pt/django_urls/README.md index a63fbe1105c..39e13e6d146 100755 --- a/pt/django_urls/README.md +++ b/pt/django_urls/README.md @@ -1,123 +1,103 @@ -# Urls +# URLs -Estamos prestes a construir nossa primeira Web page - uma página inicial para o seu blog! Mas primeiro, vamos aprender um pouco mais sobre Django urls. +Estamos prestes a construir nossa primeira página Web: uma página inicial para o seu blog! Mas primeiro, vamos aprender um pouco mais sobre as URLs do Django. ## O que é uma URL? -Uma URL é simplesmente um endereço da web, você pode ver uma URL toda vez que você visita qualquer site - é visível na barra de endereços do seu navegador (Sim! `127.0.0.1:8000` é uma URL! E http://djangogirls.org também é uma URL): +Uma URL é um endereço da web. Você pode ver uma URL toda vez que você visita um website - ela aparece na barra de endereços do seu navegador. (Sim! `127.0.0.1:8000` é uma URL! E `https://djangogirls.org` também é uma URL.) -![URL][1] +![URL](images/url.png) - [1]: images/url.png - -Cada página na Internet precisa de sua própria URL. Desta forma seu aplicativo sabe o que deve mostrar a um usuário que abre uma URL. Em Django, nós usamos algo chamado `URLconf` (configuração de URL), que é um conjunto de padrões que Django vai tentar coincidir com a URL recebida para encontrar a visão correta. +Cada página na Internet precisa de sua própria URL. Desta forma, sua aplicação sabe o que deve mostrar a um usuário que abre uma URL. Em Django, usamos algo chamado `URLconf` (configuração de URLs). URLconf é um conjunto de padrões que o Django vai usar para comparar com a URL recebida para encontrar a resposta correta. ## Como funcionam as URLs em Django? -Vamos abrir o arquivo `mysite/urls.py` e ver com que ele se parece: +Abra o arquivo `mysite/urls.py` no seu editor de código preferido e veja o que aparece: + +{% 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), ] ``` -Como você pode ver, o Django já colocou alguma coisa lá pra nós. +Como você pode ver, o Django já colocou alguma coisa aqui para nós. + +Linhas entre aspas triplas (`'''` ou `"""`) são chamadas de docstrings -- você pode escrevê-las no topo de um arquivo, classe ou método para descrever o que ele faz. Elas não serão executadas pelo Python. -As linhas que começam com `#` são comentários - isso significa que essas linhas não serão executadas pelo Python. Muito útil, não? +A URL do admin, que você visitou no capítulo anterior, já está aqui: -A URL do admin, que você visitou no capítulo anterior já está aqui: +{% filename %}mysite/urls.py{% endfilename %} ```python - url(r'^admin/', include(admin.site.urls)), + path('admin/', admin.site.urls), ``` -Isso significa que para cada URL que começa com `admin /` o Django irá encontrar um correspondente *modo de exibição*. Neste caso nós estamos incluindo um monte de admin URLs para que isso não fique tudo embalado neste pequeno arquivo..--é mais legível e mais limpo. - -## Regex - -Você quer saber como o Django coincide com URLs para views? Bem, esta parte é complicada. o Django usa o `regex` -- expressões regulares. Regex tem muito (muito!) de normas que formam um padrão de pesquisa. Como regexes são um tópico avançado, nós veremos em detalhes como elas funcionam. - -Se você ainda quiser entender como criamos os padrões, aqui está um exemplo do processo - só precisamos um subconjunto limitado de regras para expressar o padrão que procuramos, ou seja: - - ^ para o início do texto - $ para o final do texto - \d para um dígito - + para indicar que o item anterior deve ser repetido pelo menos uma vez - () para capturar parte do padrão - - -Qualquer outra coisa na definição de url será levada literalmente. +Isso significa que para cada URL que começa com `admin/`, o Django irá encontrar uma *view* correspondente. Neste caso nós estamos incluindo várias URLs de admin de uma vez a partir de uma lista criada pelo próprio Django em <0>admin.site.urls. Desta forma, não temos que repetir todas URLs no nosso modesto arquivo -- é mais legível e mais limpo. -Agora imagine que você tem um site com o endereço assim: `http://www.mysite.com/post/12345/`, onde `12345` é o número do seu post. +## Sua primeira URL no Django! -Escrever views separadas para todos os números de post seria muito chato. Com expressões regulares podemos criar um padrão que irá coincidir com a url e extrair o número para nós: `^ post/(\d+) / $`. Vamos aos poucos ver o que estamos fazendo aqui: +É hora de criar nossa primeira URL! Queremos que http://127.0.0.1:8000 / seja a página inicial do nosso blog e exiba uma lista de posts. -* **^ post /** está dizendo ao Django para pegar tudo que tenha `post /` no início da url (logo após o `^`) -* **(\d+)** significa que haverá um número (um ou mais dígitos) e que queremos o número capturado e extraído -* **/** diz para o Django que deve seguir outro `/` -* **$** indica o final da URL significando que apenas sequências terminando com o `/` irão corresponder a esse padrão +Também queremos manter o arquivo de `mysite/urls.py` limpo, e portanto importaremos as URLS da nossa aplicação `blog` no arquivo principal `mysite/urls.py`. -## Sua primeira url Django! - -É hora de criar nossa primeira URL! Queremos http://127.0.0.1:8000 / para ser uma página inicial do nosso blog e exibir uma lista de posts. - -Também queremos manter o arquivo de `mysite/urls.py` limpo, aí nós importaremosurls da nossa aplicação `blog` para o arquivo principal `mysite/urls.py`. - -Vá em frente, apague as linhas comentadas (as linhas que começam com `#`) e adicione uma linha que vai importar `blog.urls` para a url principal (`''`). +Vá em frente, adicione uma linha que importará `blog.urls` Você também irá precisar alterar a linha `from django.urls...` porque nós estamos utilizando a função `include` aqui, então você precisará adicionar aquele import para a linha. O seu arquivo `mysite/urls.py` deve agora se parecer com isto: +{% 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')), ] ``` O Django agora irá redirecionar tudo o que entra em 'http://127.0.0.1:8000 /'para `blog.urls` e procurar por novas instruções lá. -Ao escrever as expressões regulares em Python é sempre feito com `r` na frente da sequência - isso é só uma dica útil para Python que a seqüência pode conter caracteres especiais que não são destinadas para Python em si, mas em vez disso são parte da expressão regular. - ## blog.urls -Crie um novo arquivo vazio `blog/urls.py`. Tudo bem! Adicione estas duas primeiras linhas: +Crie um novo arquivo vazio chamado `urls.py` no diretório `blog`. É fácil! Basta adicionar essas duas linhas: + +{% filename %}blog/urls.py{% endfilename %} ```python -from django.conf.urls import include, url +from django.urls import path from . import views ``` -Aqui nós estamos apenas importando métodos do Django e todos os nossos `views` do aplicativo `blog` (ainda não temos nenhuma, mas teremos em um minuto!) +Aqui, estamos importando do Django a função `url` e todas as nossas `views` do aplicativo `blog`. (Não temos nenhuma ainda, mas chegaremos a isso em um minuto!) + +Depois disso podemos adicionar nosso primeiro padrão de URLs: -Depois disso nós podemos adicionar nosso primeira URL padrão: +{% filename %}blog/urls.py{% endfilename %} ```python urlpatterns = [ - url(r'^$', views.post_list), + path('', views.post_list, name='post_list'), ] -``` - -Como você pode ver, estamos agora atribuindo uma `view` chamada `post_list` para `^ $` URL. Essa expressão regular corresponderá a `^` (um começo) seguido por `$` (fim) - então somente uma seqüência vazia irá corresponder. E isso é correto, porque em resolvedores de Django url, ' http://127.0.0.1:8000 /' não é uma parte da URL. Este padrão irá mostrar o Django que `views.post_list` é o lugar certo para ir, se alguém entra em seu site no endereço 'http://127.0.0.1:8000 /'. +``` -Tudo certo? Abra http://127.0.0.1:8000 no seu navegador pra ver o resultado. +Como você pode ver, estamos agora atribuindo uma `view` chamada `post_list` à URL raiz. Este padrão de URL corresponde a uma sequência de caracteres vazia, e o resolvedor de URLs do Django irá ignorar o nome de domínio (ou seja, http://127.0.0.1:8000 /) que antecede o caminho completo da URL. Este padrão dirá ao Django que `views.post_list` é o lugar correto aonde ir se alguém entra em seu site pelo endereço 'http://127.0.0.1:8000 /'. -![Erro][2] +A última parte, `name='post_list'`, é o nome da URL que será usado para identificar a view. Pode ser o mesmo nome da view, mas também pode ser algo completamente diferente. Nós vamos usar URLs nomeadas mais à frente, então é importante nomearmos agora todas as URLs de nossa aplicação. Também devemos fazer com que os nomes das URLs sejam únicos e fáceis de lembrar. - [2]: images/error1.png +Se você tentar visitar http://127.0.0.1:8000 / agora, vai encontrar alguma mensagem do tipo 'página web não disponível'. Isso ocorre porque o servidor (lembre-se de digitar `runserver`?) não está mais funcionando. Dê uma olhada na sua janela de console do servidor para descobrir o porquê. -Não tem mais "It Works!' mais ein? Não se preocupe, é só uma página de erro, nada a temer! Elas são na verdade muito úteis: +![Erro](images/error1.png) -Você pode ler que não há **no attribute 'post_list'**. O *post_list* te lembra alguma coisa? Isto é como chamamos o nosso view! Isso significa que está tudo no lugar, só não criamos nossa *view* ainda. Não se preocupe, nós chegaremos lá. +Seu console está mostrando um erro, mas não se preocupe -- este erro é bastante útil: ele está dizendo que não existe nenhum atributo **post_list** no módulo de views. Esse é o nome da *view* que Django está tentando encontrar e usar, mas ainda não a criamos. Por enquanto, seu `/admin/` também não funcionará. Mas não se preocupe, nós chegaremos lá. Se você vir uma mensagem de erro diferente, tente reiniciar seu servidor da web. Entre na linha de comando, interrompa o servidor pressionando Ctrl+C (Control seguido da tecla C, juntas) e reinicie-o rodando `python manage.py runserver`. -> Se você quer saber mais sobre Django URLconfs, veja a documentação oficial: https://docs.djangoproject.com/en/1.8/topics/http/urls/ +> Se você quer saber mais sobre a configuração de URLs no Django, veja a documentação oficial: https://docs.djangoproject.com/en/2.0/topics/http/urls/ \ No newline at end of file diff --git a/pt/django_urls/images/error1.png b/pt/django_urls/images/error1.png index cc17593d19d..50618fca3fe 100644 Binary files a/pt/django_urls/images/error1.png and b/pt/django_urls/images/error1.png differ diff --git a/pt/django_urls/images/url.png b/pt/django_urls/images/url.png index 6cd1bd96291..c22441e930e 100644 Binary files a/pt/django_urls/images/url.png and b/pt/django_urls/images/url.png differ diff --git a/pt/django_views/README.md b/pt/django_views/README.md index 077726964df..c5ef7b5f467 100755 --- a/pt/django_views/README.md +++ b/pt/django_views/README.md @@ -1,38 +1,44 @@ -# Views - hora de criar! +# Django views -- hora de criar! -É hora de resolver o bug que criamos no capítulo anterior :) +É hora de resolver o bug que criamos no capítulo anterior! :) -Uma *view* é colocada onde nós colocamos a "lógica" da nossa aplicação. Ele irá solicitar informações a partir do `model` que você criou antes e passá-lo para um `template` que você vai criar no próximo capítulo. Views, no fundo, não passam de métodos escritos em Python que são um pouco mais complicados do que aquilo que fizemos no capítulo **Introdução ao Python**. +Uma *view* é o lugar onde nós colocamos a "lógica" da nossa aplicação. Ela vai extrair informações do `model` que você criou e entregá-las a um `template`. Nós vamos criar um template no próximo capítulo. Views são apenas funções Python um pouco mais complicadas do que aquelas que criamos no capítulo **Introdução ao Python**. -As views são postas no arquivo `views.py`. Nós vamos adicionar nossas *views* no arquivo `blog/views.py`. +As views são colocadas no arquivo `views.py`. Nós vamos adicionar nossas *views* ao arquivo `blog/views.py`. ## blog/views.py OK, vamos abrir o arquivo e ver o que tem nele: +{% filename %}blog/views.py{% endfilename %} + ```python from django.shortcuts import render # Create your views here. ``` -Não tem muita coisa. A *view* mais básica se parece com isto. +Ainda não tem muita coisa aqui. + +Lembre-se de que as linhas começando com `#` são comentários -- isto significa que elas não serão executadas pelo Python. + +Vamos criar uma *view* (como o comentário em inglês acima sugere). Vamos criar uma view simples agora: + +{% filename %}blog/views.py{% endfilename %} ```python def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -Como você pode ver, nós criamos um método (`def`) chamado `post_list` que aceita o `pedido` e `retornar` um método `render` será processado (para montar) nosso modelo `blog/post_list.html`. - -Salve o arquivo, vá para http://127.0.0.1:8000 / e veja o que temos agora. +Como você pode ver, nós criamos uma função (`def`) chamada `post_list` que leva a `solicitação` e irá `retornar` o valor que recebe ao chamar outra função `render` que irá renderizar (montar) nosso modelo `blog/post_list.html`. -Outro erro! Leia o que está acontecendo agora: +Salve o arquivo e abra a página http://127.0.0.1:8000/ para ver o que acontece. -![Erro][1] +Outro erro! Veja o que está acontecendo agora: - [1]: images/error.png +![Erro](images/error.png) -Esta é fácil: *TemplateDoesNotExist*. Vamos corrigir este bug e criar um modelo no próximo capítulo! +O erro mostra que o servidor pelo menos está sendo executado, mas ainda não parece certo, né? Não se preocupe, é apenas uma página de erro: nada a temer! Como as mensagens de erro no console, estas também são muito úteis. Você pode ler *TemplateDoesNotExist*, que significa "template não existe", em inglês. Vamos corrigir este bug e criar um modelo no próximo capítulo! -> Aprenda mais sobre as views do Django lendo a documentação oficial: https://docs.djangoproject.com/en/1.8/topics/http/views/ +> Aprenda mais sobre as views do Django lendo a documentação oficial: https://docs.djangoproject.com/en/2.0/topics/http/views/ \ No newline at end of file diff --git a/pt/django_views/images/error.png b/pt/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/pt/django_views/images/error.png and b/pt/django_views/images/error.png differ diff --git a/pt/domain/README.md b/pt/domain/README.md index ade0d9b6d17..23248d0a4f4 100755 --- a/pt/domain/README.md +++ b/pt/domain/README.md @@ -1,8 +1,8 @@ # Domínio -PythonAnywhere te deu um domínio gratuito, mas talvez você não queira ter ". pythonanywhere.com" no final da URL do seu blog. Talvez você queira seu blog apenas "www.infinite-kitten-pictures.org" ou "www.3d-printed-steam-engine-parts.com" ou "www.antique-buttons.com" ou "www.mutant-unicornz.net", ou seja o que vai ser. +PythonAnywhere te deu um domínio gratuito, mas talvez você não queira ter ". pythonanywhere.com" no final da URL do seu blog. Talvez você queira que o endereço seja algo como "www.fotos-infinitas-de-gatinhos.org" ou "www.pecas-de-maquinas-a-vapor-em-3D.com" ou "www.colecionando-antiguidades.com" ou "www.unicornioz-mutantez.net" ou qualquer outro nome que você quiser. -Aqui vamos falar um pouco sobre onde obter um domínio e como ligá-lo a seu aplicativo da web em PythonAnywhere. No entanto, você deve saber que a maioria dos domínios custam dinheiro e PythonAnywere também cobra uma taxa mensal para usar seu próprio nome de domínio -- não é muito dinheiro, no total, mas isso provavelmente é algo que você só quer fazer se você está realmente comprometido! +Aqui vamos falar um pouco sobre onde obter um domínio e como ligá-lo a seu aplicativo da web em PythonAnywhere. No entanto, você deve saber que a maioria dos domínios custam dinheiro e PythonAnywere também cobra uma taxa mensal para usar seu próprio nome de domínio -- não é muito dinheiro, no total, mas isso provavelmente é algo que você só quer fazer se estiver realmente comprometida! ## Onde registrar um domínio? @@ -14,7 +14,7 @@ O nosso favorito é o [I want my name][2] (eu quero meu nome). Eles anunciam seu [2]: https://iwantmyname.com/ -Você também pode obter domínios gratuitamente. [dot.tk][3] é um lugar para pegar um, mas você deve estar ciente de que domínios grátis às vezes parecem muito baratos -- se seu site vai ser para um profissional de negócios, você deve pensar em pagar por um domínio "correto" que termina em `.com`. +Você também pode obter domínios gratuitamente. [dot.tk][3] é um lugar para obter um, mas você deve estar ciente de que domínios grátis às vezes parecem muito baratos -- se seu site vai ser para uma profissional de negócios, você deve pensar em pagar por um domínio "correto" que termina em `.com`. [3]: http://www.dot.tk @@ -42,35 +42,35 @@ Clique no botão Adicionar e salve as mudanças na parte de baixo. > **Nota** Se você usou um provedor de domínio diferente, o UI exata para encontrar o seu DNS / configurações de CNAME será diferente, mas seu objetivo é o mesmo: para configurar um CNAME que aponta seu novo domínio no `yourusername.pythonanywhere.com`. -Pode levar alguns minutos para o seu domínio começar a trabalhar, então seja paciente! +Pode levar alguns minutos para o seu domínio funcionar, então seja paciente! ## Configure o domínio através de um web app na PythonAnywhere. -Você também precisa dizer PythonAnywhere que você deseja usar o seu domínio personalizado. +Você também precisa dizer para o PythonAnywhere que você deseja usar o seu domínio personalizado. -Vá para a [página PythonAnywhere contas][7] e upgrade sua conta. A opção mais barata (um plano de "Hacker") é bom para começar, você pode sempre atualizá-lo mais tarde quando você ficar super famoso e tiver milhões de acessos. +Vá para a [página PythonAnywhere contas][7] e atualize sua conta. A opção mais barata (um plano de "Hacker") é bom para começar, você pode sempre atualizá-lo mais tarde quando você ficar super famosa e tiver milhões de acessos. [7]: https://www.pythonanywhere.com/account/ -Em seguida,vá na [Web tab][8] e anote algumas coisas: +Em seguida, vá na [Web tab][8] e anote algumas coisas: [8]: https://www.pythonanywhere.com/web_app_setup/ * Copie o **caminho para seu virtualenv** e coloque em um lugar seguro -* Clique para seu **arquivo de configuração do wsgi**, copie o conteúdo e cole em um lugar seguro. +* Clique para seu **arquivo de configuração do wsgi**, copie o conteúdo e cole em um lugar seguro Em seguida, **exclua** seu antigo web app. Não se preocupe, isso não vai excluir nada do seu código, ele apenas irá se desligar do domínio *yourusername.pythonanywhere.com*. Em seguida, crie um novo aplicativo web e siga estes passos: * Digite seu nome de domínio novo * Escolha "manual configuration" -* Escolha Python 3.4 +* Escolha Python 3.5 * E é isso! -Quando você tiver voltado para a web tab. +Quando você tiver voltado para a web tab: * Colar o caminho virtualenv que você salvou antes * Clicar no arquivo de configuração wsgi e colar o conteúdo do seu arquivo de configuração antigo Clique em reload web app e você deve encontrar seu site live no novo domínio! -Se você tiver qualquer problema, clique no link "Enviar feedback" no site PythonAnywhere, e um dos seus administradores amigáveis vai estar lá para ajudá-lo. \ No newline at end of file +Se você tiver qualquer problema, clique no link "Enviar feedback" no site PythonAnywhere, e um dos seus administradores amigáveis vai estar lá para ajudá-la. diff --git a/pt/domain/images/1.png b/pt/domain/images/1.png index 97a06e28f2a..2564b209b25 100644 Binary files a/pt/domain/images/1.png and b/pt/domain/images/1.png differ diff --git a/pt/domain/images/2.png b/pt/domain/images/2.png index 604fd5b02c8..b97fe785c46 100644 Binary files a/pt/domain/images/2.png and b/pt/domain/images/2.png differ diff --git a/pt/domain/images/3.png b/pt/domain/images/3.png index c941c0d231d..8c5030b918a 100644 Binary files a/pt/domain/images/3.png and b/pt/domain/images/3.png differ diff --git a/pt/domain/images/4.png b/pt/domain/images/4.png index dcbe145b271..443f243c0d4 100644 Binary files a/pt/domain/images/4.png and b/pt/domain/images/4.png differ diff --git a/pt/domain/images/5.png b/pt/domain/images/5.png index 778765053e5..571f92877ae 100644 Binary files a/pt/domain/images/5.png and b/pt/domain/images/5.png differ diff --git a/pt/domain/images/6.png b/pt/domain/images/6.png index 52a0bb87c4c..1a20ea5beb3 100644 Binary files a/pt/domain/images/6.png and b/pt/domain/images/6.png differ diff --git a/pt/dynamic_data_in_templates/README.md b/pt/dynamic_data_in_templates/README.md index ae15a38fe96..6ae56ba438d 100755 --- a/pt/dynamic_data_in_templates/README.md +++ b/pt/dynamic_data_in_templates/README.md @@ -1,12 +1,14 @@ -# Django Querysets +# Dados dinâmicos em templates -Nós temos diferentes peças aqui: o model `Post` está definido em `models.py`, nós temos `post_list` no `views.py` e o template adicionado. Mas como nós faremos de fato para fazer com que as nossas postagens apareçam no nosso template em HTML? Porque é isso que nós queremos: pegar algum conteúdo (models salvos no banco de dados) e exibi-lo de uma maneira bacana no nosso template, certo? +Até o momento, temos diferentes peças: o modelo `Post` está definido em `models.py`, temos `post_list` em `views.py` e o template adicionado. Mas como faremos de fato para que as postagens apareçam no nosso template em HTML? Porque é isso que nós queremos: pegar algum conteúdo (modelos salvos no banco de dados) e exibi-lo de uma maneira bacana no nosso template, certo? -E isso é exatamente o que as *views* devem fazer: conectar models e templates. Na nossa view `post_list` *view* nós vamos precisar pegar os models que queremos exibir e passá-los para o template. Então, basicamente, em uma *view* nós decidimos o que (um model) será exibido no template. +E isso é exatamente o que as *views* devem fazer: conectar modelos e templates. Vamos precisar pegar os modelos que queremos exibir e passá-los para o template na nossa lista de postagens `post_list` *view*. Em uma *view*, nós decidimos o que (qual modelo) será exibido em um template. -Certo, e como nós faremos isso? +Tudo bem, e como vamos fazer isso? -Precisamos abrir o nosso `blog/views.py`. Até agora a *view*`post_list` se parece com isso: +Precisamos abrir o nosso `blog/views.py`. Até agora, a *view* `post_list` se parece com isso: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -15,58 +17,67 @@ def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -Lembra quando falamos sobre a inclusão de código escrito em arquivos diferentes? Agora é o momento em que temos de incluir o model que temos escrito em `models.py`. Vamos adicionar esta linha `from .models import Post` como este: +Lembra de quando falamos sobre a inclusão de código que foi escrito em arquivos diferentes? Agora é o momento em que precisamos que incluir o modelo que temos escrito em `models.py`. Vamos adicionar a linha `from .models import Post` assim: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render from .models import Post ``` -O ponto depois de `from` significa o *diretório atual* ou o *aplicativo atual*. Como `views.py` e `models.py` estão no mesmo diretório podemos simplesmente usar `.` e o nome do arquivo (sem `.py`). Então nós importamos o nome do modelo (`Post`). +O ponto antes de `models` significa *diretório atual* ou *aplicativo atual*. Tanto `views.py` como `models.py` estão no mesmo diretório. Isto significa que podemos usar `.` e o nome do arquivo (sem `py`). Em seguida, importamos o nome do modelo (`Post`). -E o que vem agora? Para pegar os posts reais do model `Post` nós precisamos de uma coisa chamada `QuerySet`. +E o que vem agora? Para pegar os posts reais do modelo `Post`, precisamos de uma coisa chamada `QuerySet`. ## QuerySet -Você já deve estar familiarizado com o modo que os QuerySets funcionam. Nós conversamos sobre isso no [capítulo ORM do Django (QuerySets)][2]. -Agora nós estamos interessados em uma lista de posts que são publicados e classificados por `published_date`, certo? Nós já fizemos isso no capítulo QuerySets! +Você já deve estar familiarizada com o modo que os QuerySets funcionam. Nós conversamos sobre isso no [capítulo QuerySets e ORM do Django](../django_orm/README.md).

+ +Agora queremos classificar as postagens publicadas por `published_date`, certo? Nós já fizemos isso no capítulo sobre QuerySets! + +{% filename %}blog/views.py{% endfilename %} ```python Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') -``` +``` + +Agora vamos colocar esse pedaço de código dentro do arquivo `blog.views.py` adicionando-o à função `def post_list(request)`. Não esqueça de adicionar `from django.utils import timezone` antes! -Agora nós colocamos este pedaço de código dentro do arquivo `blog/views.py` adicionando-o à função `def post_list(request)`: +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render from django.utils import timezone from .models import Post -def post_list(request): - posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') return render(request, 'blog/post_list.html', {}) ``` -Note que criamos uma *variável* para nosso o QuerySet: `posts`. Trate isto como o nome do nosso QuerySet. De agora em diante nós podemos nos referir a ele por este nome. +A última parte que falta é passar a QuerySet `posts` para o template. Não se preocupe com isso agora, vamos falar sobre como exibi-lo em um próximo capítulo. + +Note que criamos uma *variável* para nosso o QuerySet: `posts`. Esse é o nome do nosso QuerySet. De agora em diante, podemos nos referir a ele por este nome. -A última parte que falta é passar o QuerySet `posts` para o template (veremos como exibi-lo em um próximo capítulo). +Na função `render` já temos um parâmetro `request` (tudo o que recebemos do usuário através da Internet) e um arquivo de template (`'blog/post_list.html'`). O último parâmetro -- `{}` -- é um lugar em que podemos acrescentar algumas coisas para o template usar. Precisamos nomear os parâmetros (continuaremos com `'posts'`, por enquanto). :) Deve ficar assim: `{'posts': posts}`. Note que a parte antes de `:` é uma string; por isso você precisa colocá-la entre aspas: `"`. -Na função `render` já temos o parâmetro `request` (tudo o que recebemos do usuário através da Internet) e um arquivo de template `'blog/post_list.html'`. O último parâmetro, que se parece com isso: `{}` é um lugar em que podemos acrescentar algumas coisas para que o template use. Precisamos nomeá-los (ficaremos com `'posts'` por enquanto :)). Deve ficar assim: `{'posts': posts}`. Observe que a parte antes de `:` está entre aspas `''`. +Agora, nosso arquivo `blog/views.py` deve ter essa cara: -Então finalmente nosso arquivo `blog/views.py` deve se parecer com isto: +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render from django.utils import timezone from .models import Post + def post_list(request): - posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') return render(request, 'blog/post_list.html', {'posts': posts}) ``` -Feito! Hora de voltar para o nosso template e exibir essa QuerySet! - -Se quiser ler mais sobre QuerySets no Django você deve dar uma olhada aqui: https://docs.djangoproject.com/en/1.8/ref/models/querysets/ +Pronto! Hora de voltar para o nosso template e exibir essa QuerySet! - [2]: /django_orm/README.html +Se quiser ler mais sobre QuerySets no Django, você deve dar uma olhada aqui: https://docs.djangoproject.com/en/2.0/ref/models/querysets/ \ No newline at end of file diff --git a/pt/extend_your_application/README.md b/pt/extend_your_application/README.md index 7def24c838c..dbfc325c305 100755 --- a/pt/extend_your_application/README.md +++ b/pt/extend_your_application/README.md @@ -1,16 +1,18 @@ +{% set warning_icon = '' %} + # Amplie sua aplicação -Já concluímos todos os passos necessários para a criação do nosso site: sabemos como criar um modelo, uma url, uma view e um template. Também sabemos como melhorar a aparência do nosso website. +Já concluímos todos os passos necessários para a criação do nosso site: sabemos como criar um modelo, uma url, uma view e um template. Também sabemos como deixá-lo bonitinho. Hora de praticar! -A primeira coisa que precisamos no nosso blog é, obviamente, uma página para mostrar uma postagem, certo? +A primeira coisa que precisamos em nosso blog é, obviamente, uma página para mostrar uma postagem, né? Já temos um modelo de `Post`, então não precisamos adicionar nada ao `models.py`. -## Criar um link no template +## Criando um link para os detalhes de um post -Vamos começar com a adição de um link dentro do arquivo `blog/templates/blog/post_list.html`. Neste momento ele deve se parecer com: +Vamos começar com a adição de um link dentro do arquivo `blog/templates/blog/post_list.html`. Neste momento ele deve se parecer com: Abra-o no editor de código e, até agora, deve ficar assim:{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% extends 'blog/base.html' %} @@ -21,113 +23,126 @@ Vamos começar com a adição de um link dentro do arquivo `blog/templates/blog/
{{ post.published_date }}
-

{{ post.title }}

+

{{ post.title }}

{{ post.text|linebreaksbr }}

{% endfor %} -{% endblock content %} +{% endblock %} ``` -Queremos ter um link para uma página de detalhe no título do post. Vamos transformar `< h1 >< href = "" >{{ post.title }} < /a >< / h1 >` em um link: +{% raw %} Queremos um link no título do post dentro da página de lista de posts apontando para a página de detalhes do post respectivo. Vamos mudar `

{{ post.title }}

` e adicionar um link para a página de detalhe:{% endraw %} + +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} ```html -

{{ post.title }}

+

{{ post.title }}

``` -{% raw %}Tempo para explicar o misterioso `{% url 'blog.views.post_detail' pk=post.pk %}`. Como você pode suspeitar, a notação de `{% %}` significa que estamos usando as tags de template do Django. Desta vez vamos usar uma que vai criar uma URL para nós!{% endraw %} +{% raw %}Hora de explicar o misterioso `{% url 'post_detail' pk=post.pk %}`. Como você deve suspeitar, a notação `{% %}` significa que estamos usando as tags de template do Django. Dessa vez, usamos uma que cria uma URL para nós!{% endraw %} -`blog.views.post_detail` é um caminho para um `post_detail` *Vista* que queremos criar. Preste atenção: `blog` é o nome da sua aplicação (o diretório `blog`), `views` vem do nome do arquivo `views.py` e, a última parte - `post_detail` - é o nome da *view*. +A parte `post_detail` significa que o Django espera uma URL no arquivo `blog/urls.py` com o nome definido como name='post_detail' -Agora quando formos para: http://127.0.0.1:8000/ teremos um erro (como esperado, já que não temos uma URL ou uma *view* para `post_detail`). Vai se parecer com isso: +E quanto ao `pk=post.pk`? `pk` é uma abreviação de "primary key" (do inglês chave primária), que é um identificador único de cada entrada em um banco de dados. Uma vez que não especificamos a chave primária em nosso modelo de `Post`, o Django cria uma para nós (que por padrão, é um número que incrementa sequencialmente a partir de 1, 2, 3, etc) e a adiciona como um campo chamado `pk` em cada um dos nossos posts. Acessamos a chave primária escrevendo `post.pk`, do mesmo modo que podemos acessar outros campos (`title`, `author`, etc.) no nosso objeto de `Post`! -![NoReverseMatch error][1] +Agora, quando formos para: http://127.0.0.1:8000/, veremos um erro (como esperado, já que existe uma URL, mas não uma *view* para `post_detail`). Vai se parecer com isso: - [1]: images/no_reverse_match2.png +![erro NoReverseMatch](images/no_reverse_match2.png) -Vamos criar a URL em `urls.py` para a nossa`post_detail` *view*! +## Criando uma URL para a página de detalhes de um post -### URL: http://127.0.0.1:8000/post/1/ +Vamos criar uma URL em `urls.py` para a nossa `post_detail` *view*! + +Queremos que a página de detalhes do nosso primeiro post seja exibida por essa **URL**: http://127.0.0.1:8000/post/1/ + +Vamos criar uma URL no arquivo `blog/urls.py` que aponta para uma *view* chamada `post_detail`, que vai nos mostrar o post completo. Abra o arquivo `blog/urls.py` no editor de código e adicione a linha `path('post//', views.post_detail, name='post_detail'),` para que o arquivo fique assim: + +{% filename %}{{ warning_icon }} blog/urls.py{% endfilename %} -Queremos criar uma URL para guiar o Django para a *view* chamada `post_detail`, que irá mostrar um post completo do blog. Adicione a linha `url(r'^post/(?P[0-9]+)/$', views.post_detail),` ao arquivo `blog/urls.py`. Deve ficar assim: - ```python -from django.conf.urls import url +from django.urls import path from . import views urlpatterns = [ - url(r'^$', views.post_list), - url(r'^post/(?P[0-9]+)/$', views.post_detail), + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), ] ``` -Parece assustador, mas não se preocupe - vamos explicar ele para você: - começa com `^` de novo... "o início" - `post /` significa apenas que após o começo, da URL deve ter a palavra **post** e **/**. Até aqui, tudo bem. - `(?P[0-9]+)` - essa parte é mais complicada. Isso significa que o Django vai levar tudo que você colocar aqui e transferir para uma view como uma variável chamada `pk`. `[0-9]` também nos diz que só pode ser um número, não uma letra (tudo entre 0 e 9). `+` significa que precisa existir um ou mais dígitos. Então algo como `http://127.0.0.1:8000/post//` não é válido, mas `http://127.0.0.1:8000/post/1234567890/` é perfeitamente ok! -`/` - então precisamos de **/** outra vez - `$` - "o fim"! - -Isso significa que se você digitar `http://127.0.0.1:8000/post/5/` em seu navegador, Django vai entender que você está procurando uma *view* chamada `post_detail` e transferir a informação de que `pk` é igual a `5` para aquela *view*. +A parte `post//` especifica um padrão de URL – vamos explicar: -`pk` é uma abreviação para `primary key` (chave primária). Esse nome geralmente é usado nos projetos feitos em Django. Mas você pode dar o nome que quiser às variáveis (lembre-se: minúsculo e `_` ao invés de espaços em branco!). Por exemplo em vez de `(?P[0-9]+)` podemos ter uma variável`post_id`, então esta parte ficaria como: `(?P[0-9]+)`. +- `post/` significa apenas que a URL deve começar com a palavra **post** seguida por **/**. Até aqui, tudo bem. +- `` – essa parte é um pouco mais complicada. Ela nos diz que o Django espera um objeto do tipo inteiro e que vai transferi-lo para a view como uma variável chamada `pk`. +- `/` – por fim, precisamos adicionar uma **/** ao final da nossa URL. -Razoável! Vamos atualizar a página: http://127.0.0.1:8000 / Boom! Ainda outro erro! Como esperado! +Isso significa que se você digitar `http://127.0.0.1:8000/post/5/` em seu navegador, o Django vai entender que você está procurando uma *view* chamada `post_detail` e vai transferir a informação de que `pk` é igual a `5` para essa *view*. -![AttributeError][2] +Legal, adicionamos um novo padrão de URL para `blog/urls.py`! Vamos atualizar a página: http://127.0.0.1:8000 / Boom! O servidor parou de funcionar de novo. Dê um olhada no console -- como esperado, há ainda outro erro! - [2]: images/attribute_error2.png +![AttributeError](images/attribute_error2.png) -Você se lembra qual é o próximo passo? Claro: adicionando uma view! +Você se lembra qual é o próximo passo? Claro: adicionar uma view! -## post_detail view +## Adicionando a view de detalhes do post -Desta vez a nossa *view* recebe um parâmetro extra `pk`. Nossa *view* precisa pegá-la, certo? Então vamos definir nossa função como `def post_detail (request, pk):`. Observe que precisamos usar exatamente o mesmo nome que especificamos em urls (`pk`). Omitir essa variável é errado e resultará em um erro! +Desta vez, a nossa *view* recebe um parâmetro extra: `pk`. Nossa *view* precisa pegá-lo, certo? Então vamos definir nossa função como `def post_detail (request, pk):`. Precisamos usar exatamente o mesmo nome que especificamos em urls (`pk`). Omitir essa variável é incorreto e resultará em um erro! -Agora queremos receber apenas um post do blog. Para isso podemos usar querysets como este: +Agora, queremos receber apenas um post do blog. Para isso, podemos usar queries (buscas) como esta: - Post.objects.get(pk=pk) - +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} -Mas este código tem um problema. Se não houver nenhum `Post` com a `chave primária` (`pk`) fornecida teremos um erro horroroso! +```python +Post.objects.get(pk=pk) +``` -![DoesNotExist error][3] +Mas este código tem um problema. Se não houver nenhum `Post` com a `chave primária` (`pk`) fornecida, teremos um erro horroroso! - [3]: images/does_not_exist2.png +![erro DoesNotExist](images/does_not_exist2.png) -Não queremos isso! Mas, claro, o Django vem com algo que vai lidar com isso para nós: `get_object_or_404`. Caso não haja nenhum `Post` com o dado `pk` exibirá uma página muito mais agradável (chamada `Page Not Found 404` - página não encontrada). +Não queremos isso! Mas, claro, o Django vem com algo que vai lidar com isso para nós: `get_object_or_404`. Caso não haja nenhum `Post` com o `pk`, o Django exibirá uma página muito mais agradável que aquela mensagem de erro -- `Page Not Found 404` (página não encontrada). -![Page not found][4] +![Página não encontrada](images/404_2.png) - [4]: images/404_2.png +A boa notícia é que você pode criar sua própria página de `Page not found` e torná-la tão bonita quanto quiser. Mas isso não é super importante agora, então vamos deixar pra lá. -A boa notícia é que você realmente pode criar sua própria página de `Page not found` e torná-lo tão bonita quanto você quiser. Mas isso não é super importante agora, então nós vamos ignorá-la. +Hora de adicionar uma *view* ao nosso arquivo `views.py`! -Ok, hora de adicionar uma *view* ao nosso arquivo `views.py`! +Em `blog/urls.py`, criamos uma regra de URL chamada `post_detail` que se refere a uma view chamada `views.post_detail`. Isto significa que o Django espera uma função chamada `post_detail` dentro de `blog/views.py`. -Devemos abrir `blog/views.py` e adicionar o seguinte código: +Vamos abrir `blog/views.py` e adicionar o seguinte código perto das outras linhas `from`: - from django.shortcuts import render, get_object_or_404 - +{% filename %}blog/views.py{% endfilename %} -Perto de outras linhas `from`. E no final do arquivo, adicionaremos a nossa *view*: +```python +from django.shortcuts import render, get_object_or_404 +``` - def post_detail(request, pk): - post = get_object_or_404(Post, pk=pk) - return render(request, 'blog/post_detail.html', {'post': post}) - +E no final do arquivo, vamos adicionar a nossa *view*: -Sim. Está na hora de atualizar a página: http://127.0.0.1:8000 / +{% filename %}blog/views.py{% endfilename %} -![Post list view][5] +```python +def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) +``` - [5]: images/post_list2.png +É isso aí, está na hora de atualizar a página: http://127.0.0.1:8000/ -Funcionou! Mas o que acontece quando você clica em um link no título do post do blog? +![View da lista de posts](images/post_list2.png) -![TemplateDoesNotExist error][6] +Funcionou! Mas o que acontece quando você clica em um link no título de um post do blog? - [6]: images/template_does_not_exist2.png +![erro TemplateDoesNotExist](images/template_does_not_exist2.png) Ah não! Outro erro! Mas nós já sabemos como lidar com isso, né? Precisamos adicionar um template! +## Criando um template para os detalhes do post + Vamos criar um arquivo em `blog/templates/blog` chamado `post_detail.html`. -Será algo parecido com isto: +Ele vai ter essa cara: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html {% extends 'blog/base.html' %} @@ -139,45 +154,61 @@ Será algo parecido com isto: {{ post.published_date }}
{% endif %} -

{{ post.title }}

+

{{ post.title }}

{{ post.text|linebreaksbr }}

{% endblock %} ``` -Mais uma vez estamos estendendo `base.html`. No bloco de `content` queremos exibir o published_date (data de publicação) do post (se houver), título e texto. Mas devemos discutir algumas coisas importantes, certo? +Mais uma vez estamos estendendo `base.html`. No bloco `content`, queremos exibir a data de publicação (published_date) do post (se houver), título e texto. Mas ainda temos algumas coisas importantes para discutir, certo? -{% raw %}`{% if ... %} ... {% endif %}` é uma tag de template que podemos usar quando queremos verificar algo (Lembre-se `if ... else...` do **capítulo introdução ao Python**?). Neste cenário, queremos verificar se `published_date` de um post não está vazia.{% endraw %} +{% raw %}`{% if ... %} ... {% endif %}` é uma tag de template que podemos usar quando queremos conferir alguma coisa. (Lembra de `if ... else ...` do capítulo **Introdução ao Python**?). Neste cenário nós queremos conferir se a `published_date` de um post não está vazia.{% endraw %} -Ok, podemos atualizar nossa página e ver se `Page not found` já se foi. +Pronto, podemos atualizar nossa página e ver se aquele `Page not found` sumiu. -![Post detail page][7] +![Página de detalhes da postagem](images/post_detail2.png) - [7]: images/post_detail2.png +Uhuu! Funcionou! -Yay! Funciona! +# Hora do Deploy! -## Mais uma coisa: hora de implantar! +Seria bom ver se seu site ainda estará trabalhando no PythonAnywhere, né? Vamos tentar fazer a implantação novamente. -Seria bom ver se seu site ainda estará trabalhando em PythonAnywhere, certo? Vamos tentar fazer deploy novamente. -```bash -$ 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 %} -* Então, em um [console PythonAnywhere Bash][8]: + $ 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 + + +Agora, em um [console Bash do PythonAnywhere](https://www.pythonanywhere.com/consoles/): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Lembre-se de substituir `` com o nome do seu subdomínio PythonAnywhere, sem os colchetes angulares, ou seja, sem < e >). + +## Atualizando os arquivos estáticos no servidor + +Servidores como o PythonAnywhere tratam arquivos estáticos (como os arquivos CSS) de forma diferente dos arquivos em Python, por que assim podem otimizar para que eles carreguem mais rápido. Como resultado, sempre que alteramos nossos arquivos CSS, precisamos rodar um comando extra no servidor para dizer a ele que os atualize. O comando se chama `collectstatic`. + +Comece ativando seu virtualenv, se ele já não estiver ativo (para isso, o PythonAnywhere usa um comando chamado `workon` que é bem parecido com o comando `source myenv/bin/activate` que vosê usa no seu computador): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ workon .pythonanywhere.com + (ola.pythonanywhere.com)$ python manage.py collectstatic + [...] -``` -$ cd my-first-blog -$ git pull -``` -* Finalmente, pule para a [Web tab][9] e aperte **Reload**. +O comando `manage.py collectstatic` é mais ou menos como `manage.py migrate`. Agora, fazemos algumas mudanças no nosso código e dizemos ao Django que as aplique (*apply*) à coleção de arquivos estáticos, ou ao banco de dados. - [8]: https://www.pythonanywhere.com/consoles/ - [9]: https://www.pythonanywhere.com/web_app_setup/ +Em qualquer caso, nós agora estamos prontos para saltar para a ["Web" page](https://www.pythonanywhere.com/web_app_setup/) (do botão menu à direita do console) e pressionar **Reload**, checando a página https://subdomain.pythonanywhere.com para ver o resultado. -E deve ser isso! Parabéns :) +Deve estar pronto! Arrasou :) \ No newline at end of file diff --git a/pt/extend_your_application/images/404_2.png b/pt/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/pt/extend_your_application/images/404_2.png and b/pt/extend_your_application/images/404_2.png differ diff --git a/pt/extend_your_application/images/attribute_error2.png b/pt/extend_your_application/images/attribute_error2.png index 6edcd9933c3..4b8262476d9 100644 Binary files a/pt/extend_your_application/images/attribute_error2.png and b/pt/extend_your_application/images/attribute_error2.png differ diff --git a/pt/extend_your_application/images/does_not_exist2.png b/pt/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/pt/extend_your_application/images/does_not_exist2.png and b/pt/extend_your_application/images/does_not_exist2.png differ diff --git a/pt/extend_your_application/images/no_reverse_match2.png b/pt/extend_your_application/images/no_reverse_match2.png index db65a5dc70a..aba1c9c8980 100644 Binary files a/pt/extend_your_application/images/no_reverse_match2.png and b/pt/extend_your_application/images/no_reverse_match2.png differ diff --git a/pt/extend_your_application/images/post_detail2.png b/pt/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/pt/extend_your_application/images/post_detail2.png and b/pt/extend_your_application/images/post_detail2.png differ diff --git a/pt/extend_your_application/images/post_list2.png b/pt/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/pt/extend_your_application/images/post_list2.png and b/pt/extend_your_application/images/post_list2.png differ diff --git a/pt/extend_your_application/images/template_does_not_exist2.png b/pt/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/pt/extend_your_application/images/template_does_not_exist2.png and b/pt/extend_your_application/images/template_does_not_exist2.png differ diff --git a/pt/how_the_internet_works/README.md b/pt/how_the_internet_works/README.md index c7b35a20ec4..4ef0d0a6203 100755 --- a/pt/how_the_internet_works/README.md +++ b/pt/how_the_internet_works/README.md @@ -1,45 +1,47 @@ -# Como funciona a internet +# Como a Internet funciona +> Para leitoras em casa: este capítulo é abordado no vídeo [How the Internet Works](https://www.youtube.com/watch?v=oM9yAA09wdc). +> > Este capítulo é inspirado na palestra "Como a Internet funciona" de Jessica McKellar (http://web.mit.edu/jesstess/www/). -Apostamos que você usa a Internet todos os dias. Mas você sabe realmente o que acontece quando você digita um endereço como https://djangogirls.org em seu navegador e pressiona 'Enter'? +Apostamos que você usa a Internet todos os dias. Mas você sabe realmente o que acontece quando digita um endereço como https://djangogirls.org em seu navegador e aperta `Enter`? -A primeira coisa que você precisa entender é que um site é só um monte de arquivos salvos em um disco rígido. Assim como seus filmes, músicas ou fotos. No entanto, existe uma parte que é exclusiva para sites: essa parte inclui código de computador chamado HTML. +A primeira coisa que você precisa entender é que um site é só um monte de arquivos salvos em um disco rígido. No entanto, há uma parte que é exclusiva para sites: ela inclui códigos de computador chamados HTML. -Se você não estiver familiarizada com programação, pode ser difícil compreender o HTML no começo, mas seu navegador web (como o Chrome, Safari, Firefox, etc) ama ele. Navegadores Web são projetados para entender esse código, seguir suas instruções e apresentar todos esses arquivos de que seu site é feito, exatamente do jeito que você quer que eles sejam apresentados. +Se você não estiver familiarizada com a programação, pode ser difícil compreender o HTML no começo, mas seus navegadores da web (como o Chrome, Safari, Firefox, etc) amam ele. Os navegadores da Web são projetados para entender esse código, seguir suas instruções e apresentar os arquivos de que um site é feito, exatamente como deve. -Igual à todos os arquivos, os arquivos HTML precisam ser armazenados em um disco rígido. Para a internet, nós usamos especiais e poderosos computadores chamados de *servidores*. Eles não têm tela, mouse ou teclado, porque sua finalidade principal é armazenar dados e servi-los. É por isso que eles são chamados de *servidores*..--porque eles *servem* a você, dados. +Como qualquer arquivo, os arquivos HTML precisam ser armazenados num disco rígido. Para a internet, usamos poderosos computadores especiais chamados *servidores*. Eles não têm uma tela, um mouse ou um teclado, porque sua finalidade principal é armazenar dados e servi-los. É por isso que eles são chamados de *servidores* - eles *servem* dados a você. OK, mas você quer saber com o quê a internet se parece, certo? -Fizemos um desenho pra você! Veja: +Fizemos um desenho para ajudar! Veja: ![Figura 1.1](images/internet_1.png) -Parece uma bagunça, não é? Na verdade é uma rede de máquinas conectadas (os *servidores* mencionados acima). Centenas de milhares de máquinas! Muitos, muitos quilômetros de cabos por todo o mundo! Para ver o quão complicada a internet é, você pode visitar um site (http://submarinecablemap.com/) que mostra um mapa com os cabos submarinos. Aqui está um screenshot do site: +Que bagunça, né? Na verdade, a internet é uma rede de máquinas conectadas (os *servidores* mencionados acima). São centenas de milhares de máquinas! Muitos, muitos quilômetros de cabos em todo o mundo! Para ver o quão complicada a internet é, você pode visitar um site (http://submarinecablemap.com/) que mostra o mapa com dos cabos submarinos. Aqui está um screenshot do site: ![Figura 1.2](images/internet_3.png) -Fascinante, não? Mas, obviamente, não é possível ter um fio conectado a toda máquina ligada na internet. Logo, para chegar em uma máquina (por exemplo aquela onde https://djangogirls.org está salva) nós precisamos passar uma requisição através de muitas e muitas máquinas diferentes. +Fascinante, né? Mas não é possível ter um fio ligando todas as máquinas que estão conectadas à internet. Logo, para alcançar uma máquina (por exemplo aquela onde https://djangogirls.org está salva), precisamos passar uma requisição por muitas máquinas diferentes. -Se parece com isso: +É algo assim: ![Figura 1.3](images/internet_2.png) -Imagine que quando você digita https://djangogirls.org, você envia uma carta que diz: "Querido Django Girls, eu desejo ver o site djangogirls.org. Envie ele pra mim, por favor!" +Imagine que quando digita http://djangogirls.org, você envia uma carta que diz: "Queridas Django Girls, eu desejo ver o site djangogirls.org. Enviem-no para mim, por favor!" -Sua carta vai para a agência dos correios mais próxima de você. Depois vai para outra que é um pouco mais perto de seu destinatário, depois para outra e outra, até que ela seja entregue ao seu destino. O único diferencial é que se você enviar cartas (*pacotes de dados*) com freqüência para o mesmo lugar, cada carta pode passar por diferentes agências de correios (*roteadores*), dependendo de como elas são distribuídas em cada agência. +Sua carta vai para a agência dos correios mais próxima de você. Então, ela vai para outra agência um pouco mais perto do destinatário e, em seguida, para outra e outra até ser entregue. A única coisa diferente é que se você enviar muitas cartas (*pacotes de dados*) para o mesmo lugar, elas podem passar por agências totalmente diferentes (*roteadores*). Isso depende de como elas são distribuídas em cada agência. ![Figura 1.4](images/internet_4.png) -Sim, é simples assim. Você envia mensagens e espera alguma resposta. Claro, ao invés de papel e caneta você usa bytes de dados, mas a ideia é a mesma! +Funciona assim - voê envia mensagens e espera alguma resposta. Ao invés de papel e caneta, você usa bytes de dados, mas a ideia é a mesma! -Ao invés de endereços com o nome da rua, cidade, código postal e nome do país, nós usamos endereços IP. Primeiro seu computador pede ao DNS (Domain Name System - Sistema de Nome de Domínio) para traduzir djangogirls.org para um endereço IP. O funcionamento dele se parece um pouco com as antigas listas telefônicas onde você pode olhar para o nome da pessoa que quer entrar em contato e achar o seu número de telefone e endereço. +Ao invés de endereços com o nome da rua, cidade, código postal e nome do país, na internet usamos endereços de IP. Primeiro seu computador pergunta pelo DNS (Domain Name System - Sistema de Nome de Domínio) para traduzir djangogirls.org para um endereço de IP. Isso funciona mais ou menos como as antigas listas telefônicas em que você podia procurar o número e endereço da pessoa que queria contactar. -Quando você envia uma carta, ela precisa ter certas características para ser entregue corretamente: um endereço, selo, etc. Você também usa uma linguagem que o receptador compreende, certo? O mesmo acontece com *pacotes de dados* que você envia para ver um site: você usa um protocolo chamado HTTP (Hypertext Transfer Protocol - Protocolo de Transferência de Hipertexto). +Quando você envia uma carta, ela precisa ter certas características para ser entregue corretamente: um endereço, um selo, etc. E você usa uma linguagem que o destinatário compreende, certo? O mesmo se aplica aos *pacotes de dados* que você envia para acessar um site. Nós usamos um protocolo chamado HTTP (Hypertext Transfer Protocol). -Então, basicamente, quando você tem um site, você precisa ter um *servidor* (máquina) onde ele fica hospedado. O *servidor* está à espera de quaisquer *requisições* recebidas (cartas que solicitam ao servidor o envio do seu site) e ele envia de volta seu site (em outra carta). +Então, de forma simplificada, um site precisa ter um *servidor* (máquina) onde ele vive. Quando o *servidor* recebe uma *solicitação* de entrada (numa carta), ele envia em respota seu website (em outra carta). -Como este é um tutorial de Django você vai perguntar o que o Django faz. Quando você envia uma resposta nem sempre você quer enviar a mesma coisa para todo mundo. Será muito melhor se suas cartas forem personalizadas, diferenciada para a pessoa que acabou de escrever para você, certo? O Django ajuda você a criar essas personalizadas e interessantes cartas :). +Este é um tutorial de Django, então você deve estar imaginando o que o Django faz. Quando envia uma resposta, nem sempre você quer mandar a mesma coisa para todo mundo. É muito melhor que as cartas sejam personalizadas, especialmente para a pessoa que acabou de nos escrever, né? O Django nos ajuda a criar essas cartas personalizadas. :) -Chega de falar, é hora de criar! +Chega de falar, é hora de criar! \ No newline at end of file diff --git a/pt/how_the_internet_works/images/internet_1.png b/pt/how_the_internet_works/images/internet_1.png index 21bf592af8e..e289eac2b23 100644 Binary files a/pt/how_the_internet_works/images/internet_1.png and b/pt/how_the_internet_works/images/internet_1.png differ diff --git a/pt/how_the_internet_works/images/internet_2.png b/pt/how_the_internet_works/images/internet_2.png index 726d432fc03..e8cf8b77999 100644 Binary files a/pt/how_the_internet_works/images/internet_2.png and b/pt/how_the_internet_works/images/internet_2.png differ diff --git a/pt/how_the_internet_works/images/internet_3.png b/pt/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/pt/how_the_internet_works/images/internet_3.png and b/pt/how_the_internet_works/images/internet_3.png differ diff --git a/pt/how_the_internet_works/images/internet_4.png b/pt/how_the_internet_works/images/internet_4.png index ddadf75d984..d4748ac48ef 100644 Binary files a/pt/how_the_internet_works/images/internet_4.png and b/pt/how_the_internet_works/images/internet_4.png differ diff --git a/pt/html/README.md b/pt/html/README.md index fb788da123f..109028027ca 100755 --- a/pt/html/README.md +++ b/pt/html/README.md @@ -1,73 +1,75 @@ -# Introdução a HTML +# Introdução ao HTML -Você pode se perguntar: e o que é um template? +Você pode se perguntar: o que é um template? -Um template é um arquivo que nós podemos reutilizar para apresentar diferentes informações de uma forma consistente. Por exemplo, você poderia usar um template para te ajudar a escrever uma carta, pois, embora cada carta possua uma mensagem e um destino diferente, todas terão sempre o mesmo formato. +Template é um arquivo que nós podemos reutilizar para apresentar diferentes informações em um formato consistente – por exemplo, você pode usar um template para te ajudar a escrever uma carta, pois mesmo que cada carta contenha mensagens diferentes e possa estar endereçada a pessoas diferentes, elas compartilharão o mesmo formato. -O formato do template do Django é descrito em uma linguagem chamada HTML (esse é o mesm HTML que mencionamos no primeiro capítulo **Como a Internet funciona**). +O formato do template do Django é descrito em uma linguagem chamada HTML (esse é o mesm HTML que mencionamos no primeiro capítulo -- **Como a Internet funciona**). ## O que é HTML? -HTML é um simples código que é interpretado pelo seu navegador web - como o Chrome, o Firefox ou o Safari - para exibir uma página da web para o usuário. +HTML é um código interpretado pelo seu navegador - como Chrome, Firefox ou Safari - para exibir uma página web ao usuário. -HTML significa "HyperText Markup Language". **HiperText** significa que é um tipo de texto que suporta hiperlinks entre páginas. **Marcação** nada mais é que marcar um documento com códigos que dizem para alguém (nesse caso, o navegador web) como a página deverá ser interpretada. Código em HTML é feito com **tags**, cada uma começando com `<` e terminando com `>`. Essas tags marcam os **elementos**. +HTML significa "HyperText Markup Language". **HiperText** significa que é um tipo de texto que suporta hiperlinks entre páginas. **Marcação** nada mais é que marcar um documento com códigos que dizem para alguém (nesse caso, o navegador web) como a página deverá ser interpretada. Códigos em HTML são feitos com **tags**, cada uma começando com `<` e terminando com `>`. Estas tags representam **elementos de marcação**. ## Seu primeiro template! Criar um template significa criar um arquivo de template. Tudo é um arquivo, certo? Provavelmente você já deve ter notado isso. -Os templates são salvos no diretório `blog/templates`. Logo, crie um diretório chamado `templates` dentro do diretório do seu blog. Em seguida, crie outro diretório chamado `blog` dentro da diretório templates: +Os templates são salvos no diretório `blog/templates`. Então, crie um diretório chamado `templates` dentro do diretório do seu blog. Em seguida, crie outro diretório chamado `blog` dentro do diretório templates: blog └───templates └───blog -(Você deve estar se perguntando porque nós precisamos de dois diretórios chamados `blog` - como você descobrirá mais para frente, essa é uma simples e útil convenção que facilita a vida quando as coisas começarem a ficar mais complicadas.) +(Você deve estar se perguntando porque nós precisamos de dois diretórios chamados `blog` - como você descobrirá mais para frente, essa é uma convenção que facilita a nossa vida quando as coisas começam a ficar mais complicadas.) -E agora nós criamos o arquivo `post_list.html` (deixe-o em branco por agora) dentro do diretório `blog/templates/blog`. +E agora nós criamos o arquivo `post_list.html` (deixe-o em branco por enquanto) dentro do diretório `blog/templates/blog`. -Veja como o nosso site está se parecendo agora: http://127.0.0.1:8000/ +Veja como o nosso site está agora: http://127.0.0.1:8000/ -> Se ocorrer um erro de `TemplateDoesNotExists` tente reiniciar o seu servidor. Entre na linha de comando, pare o servidor pressionando Ctrl+C (Control seguido da tecla C, juntas) e reinicie-o rodando `python manage.py runserver`. +> Se você ainda tem um erro `TemplateDoesNotExist`, tente reiniciar o seu servidor. Entre na linha de comando, interrompa o servidor pressionando Ctrl+C (Control seguido da tecla C, juntas) e reinicie-o rodando `python manage.py runserver`. -![Figura 11.1][1] +![Figura 11.1](images/step1.png) - [1]: images/step1.png +Acabaram-se os erros! Uhuu :) Entretanto, nosso site não mostra nada a não ser uma página em branco. Isso acontece porque o nosso template está vazio. Precisamos consertar isso. -Acabaram-se os erros! Parabéns :) Entretanto, nosso site não mostra nada a não ser uma página em branco. Isso porque o nosso template está vazio. Então precisamos consertar isso. +Abra o novo arquivo no editor de código e adicione o seguinte: -Adicione a seguinte linha dentro do template: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html +

Hi there!

It works!

+ ``` -Como nosso site se parece agora? Clique para descobrir: http://127.0.0.1:8000/ +Como está o nosso site agora? Visite a página descobrir: http://127.0.0.1:8000/ -![Figura 11.2][2] - - [2]: images/step3.png +![Figura 11.2](images/step3.png) Funcionou! Bom trabalho :) -* A tag mais básica, ``, estará sempre no começo de qualquer página da web, assim como, `` sempre estará no fim. Como você pode ver, todo o conteúdo de um website se encontra entre a tag de início `` e entre a tag de fim `` -* `

` é a tag que denomina parágrafos; `

` determina o fim de cada parágrafo +* A tag mais básica, ``, estará sempre no começo de qualquer página da web, assim como, `` sempre estará no fim. Todo o conteúdo de um website se encontra entre a tag de início `` e a tag de fim `` +* `

` é a tag que inicia um parágrafos; `

` determina o fim de um parágrafo + +## "Head" e "body" -## Head & body +Cada página HTML também é dividida em dois elementos: **head** (cabeçalho) e **body** (corpo). -Cada página HTML também é dividida em dois elementos: **head** (cabeça) e **body** (corpo). +* **head** é um elemento que contém informações sobre o documento que não são mostradas na tela. -* **head** é um elemento que contém informações sobre o documento que não são mostradas na tela. +* **body** é um elemento que contém tudo o que é exibido como parte de uma página da web. -* **body** é um elemento que contém tudo o que é exibido como parte de uma página de um site. +Nós usamos a tag `` para dizer ao navegador quais são as configurações da página. Por sua vez, a tag `` diz ao navegador qual é o conteúdo de fato da página. -Nós usamos a tag `` para dizer ao navegador sobre as configurações da página. Por sua vez, a tag `` diz ao navegador o que há de verdade na página. +Por exemplo, você pode incluir o elemento título de uma página web dentro da tag ``. Veja: -Por exemplo, você pode por o elemento título de uma página web dentro da tag ``. Veja: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html @@ -79,57 +81,58 @@ Por exemplo, você pode por o elemento título de uma página web dentro da tag

It works!

-``` +``` -Salve o arquivo e atualize sua página. +Salve o arquivo e atualize a página. -![Figura 11.3][3] +![Figura 11.3](images/step4.png) - [3]: images/step4.png +Viu como o navegador entendeu que "Ola's blog" é o título da página? Ele interpretou `Ola's blog` e colocou o texto na barra de título do seu navegador (o texto também será usado nos favoritos e outras coisas mais). -Viu como o navegador entendeu que "Ola's blog" é o título da página? Ele interpretou `Ola's blog` e colocou o texto na barra de título do seu navegador (e também será usado para os favoritos e outras coisas mais). +Provavelmente você já deve ter notado que cada tag de abertura casa com uma *tag de fechamento*, com uma `/`, e que os elementos estão *aninhados* (ex.: você não pode fechar uma tag específica antes que todas as outras tags dentro dela estejam fechadas). -Provavelmente você já deve ter notado que cada tag de abertura casa com uma *tag de fechamento*, com uma `/`, e que os elementos estão *aninhados* (ex.: você não pode fechar um tag em particular antes que todas as outras tags que estiverem dentro dela já estejam fechadas). +É como colocar coisas dentro de caixas. Você tem uma grande caixa, ``; dentro dela há ``, e esta contém caixas ainda menores: `

`. -É como colocar coisas dentro de caixas. Você tem uma grande caixa, ``; dentro dela há ``, sendo que esta ainda contém caixas menors: `

`. +Você precisa seguir essas regras de *fechamento* de tags, e de *aninhamento* de elementos - se não fizer isso, o navegador provavelmente não interpretará seu código da maneira correta e sua página será exibida incorretamente. -Você precisa seguir essas regras de *fechamento* de tags, e de *aninhamento* de elementos - se você não fizer isso, o navegador poderá não estar apto para interpretar seu código de maneira correta e sua página será exibida de maneira incorreta. +## Personalize seu template -## Customize seu template +Agora você pode se divertir um pouco tentando personalizar o seu template! Aqui estão algumas tags úteis para isso: -Agora você pode se divertir um pouco tentando customizar o seu template! Aqui estão algumas tags úteis para isso: +* `

Um título

` para o título da seção principal exibido na página +* `

Um sub-título

` para um título um nível abaixo +* `

Um sub-sub-título

` ... e por aí vai, até `
` +* `

Um parágrafo de texto

` +* `texto` enfatiza seu texto +* `text` enfatiza fortemente seu texto +* `
` quebra a linha (você não pode digitar nada dentro da tag br e ela não possui uma tag de fechamento correspondente) +* `link` cria um link +* `
  • primeiro item
  • segundo item
` cria uma lista, exatamente como essa! +* `
` define uma seção da página -* `

Um título

` - para o título mais importante -* `

Um sub-título

` para um título um nível abaixo -* `

Um sub-sub-título

` ... e por aí vai, até `
` -* `texto` enfatiza seu texto -* `text` enfatiza fortemente seu texto -* `
` pula para a próxima linha (você não pode colocar nada dentro de br) -* `link` cria um link -* `
  • primeiro item
  • segundo item
` cria uma lista, exatamente como essa! -* `
` define uma seção da página +Aqui vai um exemplo de um template completo; copie e cole dentro de `blog/templates/blog/post_list.html`: -Aqui está um exemplo de um template completo: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - Django Girls blog + Blog Django Girls
-

published: 14.06.2014, 12:14

-

My first post

+

publicado: 14.06.2014, 12:14

+

Meu primeiro 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

+

publicado: 14.06.2014, 12:14

+

Meu segundo 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.

@@ -138,73 +141,77 @@ Aqui está um exemplo de um template completo: Nós criamos três seções `div` aqui. -* O primeiro elemento `div` possui o título do nosso blog - é um título e um link -* Os outros dois elementos `div` possuem nossas postagens com a data de publicação, `h2` com o título da postagem que é clicável e dois `p`s (parágrafos) de texto, um para a data e outro para o texto da postagem. +* O primeiro elemento `div` possui o título do nosso blog - é um título que contêm um link +* Os outros dois elementos `div` possuem nossas postagens com a data de publicação, `h2` com o título clicável da postagem e dois `p`s (parágrafos) de texto, um para a data e outro para o texto da postagem. Isso nos dá o seguinte efeito: -![Figura 11.4][4] +![Figura 11.4](images/step6.png) - [4]: images/step6.png +Uhuu! Mas, até o momento, nosso template mostra **sempre a mesma informação** - sendo que, anteriormente, nós falávamos sobre templates como uma maneira para exibir informações **diferentes** em um **mesmo formato**. -Yaaay! Mas, até agora, nosso template mostra exatamante **sempre a mesma informação** - sendo que, anteriormente, nós falávamos sobre templates como uma maneira para exibir informações **diferentes** em um **mesmo formato**. +O que nós realmente queremos fazer é exibir as postagens reais que foram adicionadas no Django admin - e isso é o que faremos em seguida. -O que nós realmente queremos fazer é exibir postagens reais que foram adicionadas no Django admin - e isso é o que faremos em seguida. +## Mais uma coisa: implantação (deploy)! -## Mais uma coisa: deploy! +Seria bom ver tudo isto na Internet, certo? Vamos fazer mais um deploy no PythonAnywhere: -Seria bom ver tudo isto na Internet, certo? Vamos fazer outro deploy PythonAnywhere: +### Commit, e dê push para subir seu código no GitHub -### Commit, e ponha seu código no GitHub +Antes de tudo, vamos ver que arquivos foram modificados desde que nós fizemos a última implantação (execute esses comandos localmente, não no PythonAnywhere): -Primeiro de tudo, vejamos quais arquivos foram alterados desde a última implantação: +{% filename %}command-line{% endfilename %} $ git status -Verifique se você está no diretório `djangogirls` e vamos dizer ao `git` para incluir todas as mudanças dentro deste diretório: +Assegure-se de que você está no diretório `djangogirls` e vamos dizer ao `git` para incluir todas as mudanças feitas nele: + +{% filename %}command-line{% endfilename %} $ git add --all . -> **Nota** `-A` (abreviação de "all", tudo em inglês) significa que o `git` também reconhecerá se você deletou algum arquivo (por padrão, o git apenas reconhece arquivos criados/modificados). Lembre-se também (do capítulo 3) que `.` significa o diretório atual. +> **Observação:** `..--all` significa que o `git` também vai reconhecer se você tiver excluído arquivos (por padrão, ele só reconhece arquivos novos/modificados). Lembre-se também (do capítulo 3) que `.` significa o diretório atual. -Antes de nós fazermos o upload de todos os aqruivos, chequemos o que o `git` enviará (todos os arquivos que o `git` for enviar deverá aparece em verde): +Antes de fazermos o upload de todos os arquivos, vamos verificar quais deles o `git` enviará (todos os arquivos marcados para upload pelo `git` aparecerão em verde): + +{% filename %}command-line{% endfilename %} $ git status -Estamos quase lá! Agora é hora de dizer a ele para salvar essa modificação em seu histórico. Nós daremos a ele uma "mensagem de commit" onde nós descrevemos as modificações que fizemos. Você pode escrever o que você quiser agora, mas será mais útil se você escrever alguma coisa mais descritiva, algo para você poder se lembrar das coisas que você fez futuramente. +Estamos quase lá! Agora é hora de dizer ao git para salvar essa modificação em seu histórico. Daremos a ele uma "mensagem de commit" em que descrevemos as modificações que foram feitas. Você pode escrever o que quiser agora, mas é mais útil escrever algo descritivo que te ajude no futuro a lembrar das coisas que fez. + +{% filename %}command-line{% endfilename %} $ git commit -m "Changed the HTML for the site." -> **Note** Certifique-se que você usou aspas duplas para delimitar a mensagem do commit. +> **Observação:** Certifique-se de que você usou aspas duplas para delimitar a mensagem do commit. -Quando fizermos isso, nós fazemos upload (envio) das nossas mudanças para o PythonAnywhere: +Uma vez feito isso, faremos o upload (push) das nossas mudanças para o Github: - git push +{% filename %}command-line{% endfilename %} + + $ git push -### Bote deu novo código no PythonAnywhere e recarregue o seu aplicativo da web +### Baixe seu novo código no PythonAnywhere e recarregue o seu aplicativo da web -* Abra a [página de consoles de PythonAnywhere][5] e vá para o seu **console Bash** (ou começar um novo). Em seguida, execute: - -``` - $ cd ~/my-first-blog - $ source myvenv/bin/activate - (myvenv)$ git pull - [...] - (myvenv)$ python manage.py collectstatic - [...] -``` +* Abra a [página de consoles do PythonAnywhere](https://www.pythonanywhere.com/consoles/) e vá para o seu **console do Bash** (ou inicie um novo). Em seguida, execute: - [5]: https://www.pythonanywhere.com/consoles/ +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + -Eveja seu código sendo baixado. Se você deseja verificar se já chegou, pode ir para a **Files tab** e ver seu código no PythonAnywhere. +Você precisará substituir `` com o seu subdomínio PythonAnywhere, sem os colchetes angulares (< >). O nome do seu subdomínio normalmente é o mesmo nome de usuário do seu PythonAnywhere, mas em alguns casos este pode ser um pouco diferente (por exemplo, se o nome possuir letras maísculas). Sendo assim, caso o comando não funcione, utilize o comando `ls` (lista de arquivos) para encontrar o seu subdomínio/nome da pasta e então execute `cd` para acessá-lo. -* Finalmente, pule para a [Web tab][6] e aperte **Reload** em seu aplicativo web. +Agora veja o seu código ser baixado. Se você quiser verificar se ele chegou, você pode pular para a **página "Arquivos"**e visualizar seu código no PythonAnywhere (você pode acessar outras páginas do PythonAnywhere a partir do botão de menu na página do console). - [6]: https://www.pythonanywhere.com/web_app_setup/ +* Finalmente, pule para a aba ["Web" page](https://www.pythonanywhere.com/web_app_setup/) e aperte **Reload** em sua aplicação. -Sua atualização deve estar live! Vá em frente e atualize seu site no navegador. As alterações devem ser visíveis :) +Sua atualização deve estar no ar! Vá em frente e atualize seu site no navegador. As alterações devem estar visíveis. :) \ No newline at end of file diff --git a/pt/html/images/step1.png b/pt/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/pt/html/images/step1.png and b/pt/html/images/step1.png differ diff --git a/pt/html/images/step3.png b/pt/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/pt/html/images/step3.png and b/pt/html/images/step3.png differ diff --git a/pt/html/images/step4.png b/pt/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/pt/html/images/step4.png and b/pt/html/images/step4.png differ diff --git a/pt/html/images/step6.png b/pt/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/pt/html/images/step6.png and b/pt/html/images/step6.png differ diff --git a/pt/images/application.png b/pt/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/pt/images/application.png and b/pt/images/application.png differ diff --git a/pt/installation/README.md b/pt/installation/README.md new file mode 100644 index 00000000000..799ead7434b --- /dev/null +++ b/pt/installation/README.md @@ -0,0 +1,69 @@ +# Se você estiver fazendo o tutorial em casa + +Se você estiver fazendo o tutorial em casa e não em um dos [eventos Django Girls](https://djangogirls.org/events/), pode pular este capítulo e ir direto para o capítulo [Como a internet funciona](../how_the_internet_works/README.md). + +Isso porque nós cobrimos a instalação dos itens a medida que eles são necessários no tutorial -- Essa é apenas uma página adicional que reúne todas as instruções de instalação em um só lugar (que é útil para alguns formatos de oficinas). Você pode escolher instalar tudo que está nessa página nesse momento se você quiser. Mas se você quer começar a aprender coisas antes de instalar um monte de coisas no seu computador, pule este capítulo e nós explicaremos os componentes de instalação para você mais tarde, a medida que são necessários. + +Boa sorte! + +# Se você está participando de uma oficina + +Se você está participando de uma oficina de um [ Evento Django Girls ](https://djangogirls.org/events/): + +* Sua oficina pode ter um "grupo de instalação" antes da oficina principal. Se você está com um grupo de instalação, essa página é para você! Siga as instruções aqui contidas para ter tudo que precisa para a oficina instalada, com a ajuda de instrutores, se necessário. Então, no workshop principal, poderás saltar as intruções de instalação que encontrares no tutorial principal, quando aparecerem. +* A organização do workshop poderá ter-te perguntado se tentaste reslizar a instalação no computador, em casa antes de vires para o workshop. Se te oriposeram a isso, esta página é para ti! Siga as instruções. Então, no workshop principal, quando chegar à etapa de instalação, se você ainda for capaz de prosseguir você poderá pedir ajuda para a sua monitora. +* Se o seu workshop não tem uma seção de instalação (ou você não a consegue localizar) e os organizadores não lhe pedirem para tentar instalar tudo antes que você chegue, pule esta página e vá direto para [Como a internet funciona](../how_the_internet_works/README.md). Você irá instalar tudo o que precisa no seguimento do tutorial. + +# Instalação + +Neste tutorial, você irá criar um blog. Para fazer isso, ao longo do tutorial você receberá instruções de como instalar diversos programas no seu computador e configurar algumas contas online conforme necessário. Esta página reune as instruções de instalação e registro em um só lugar (o que vai ser útil para a alguns formatos de workshop). + + {% include "/chromebook_setup/instructions.md" %} + + + +# Breve introdução à linha de comando + +Vários dos passos abaixos referenciam o "console", "terminal", "janela de comandos", ou "linha de comandos" - todos significam a mesma coisa: uma janela no seu computador onde você pode inserir comandos. Quando você chegar ao tutorial principal, você irá aprender mais sobre a linha de comandos. Por agora, a coisa principal que você precisará saber é como abrir uma janela de comandos e como ela se parece: +{% include "/intro_to_command_line/open_instructions.md" %} + +# Instale o Python + +{% include "/python_installation/instructions.md" %} + +# Instale um editor de código + +{% include "/code_editor/instructions.md" %} + +# Configure o virtualenv e instale o Django + +{% include "/django_installation/instructions.md" %} + +# Instale o Git + +{% include "/deploy/install_git.md" %} + +# Crie uma conta no GitHub + +Vá para [GitHub.com](https://www.github.com) e registre uma nova conta, de graça. Assegure-se de lembrar a sua senha (e a adicione ao seu gerenciador de senhas, caso você tenha um). + +# Crie uma conta no PythonAnywhere + +{% include "/deploy/signup_pythonanywhere.md" %} + +# Comece a ler + +Parabéns, você tem tudo configurado e pronto para começar! Se você ainda tem algum tempo antes do workshop, seria útil começar a ler alguns dos capítulos de início: + +* [Como a internet funciona](../how_the_internet_works/README.md) + +* [Introdução à linha de comando](../intro_to_command_line/README.md) + +* [Introdução ao Python](../python_introduction/README.md) + +* [O que é Django?](../django/README.md) + +# Aproveite o workshop! + +Quando você começar a oficina, já será capaz de ir direto para o [seu primeiro projeto Django!](../django_start_project/README.md) porque já vai ter visto todo o material dos capítulos anteriores. diff --git a/pt/intro_to_command_line/README.md b/pt/intro_to_command_line/README.md index 002553086da..842ca198d1c 100755 --- a/pt/intro_to_command_line/README.md +++ b/pt/intro_to_command_line/README.md @@ -1,98 +1,154 @@ # Introdução à linha de comando -É emocionante, não?! Você vai escrever sua primeira linha de código em poucos minutos :) +> Para as leitoras em casa: este capítulo é coberto no vídeo [Sua nova amiga: a linha de comando](https://www.youtube.com/watch?v=jvZLWhkzX-8). -**Deixe-nos apresentá-lo ao seu primeiro novo amigo: a linha de comando!** +É emocionante, não?! Em poucos minutos você vai escrever sua primeira linha de código! :) -As etapas a seguir mostrarão a você como usar a janela preta que todos os hackers usam. Pode parecer um pouco assustador no começo, mas realmente é apenas um prompt esperando por comandos de você. +**Vamos apresentá-la à sua primeira nova amiga: a linha de comando!** -## Qual é a linha de comando? +As etapas a seguir mostrarão como usar a janela preta que todos os hackers usam. Pode parecer um pouco assustador no começo, mas é apenas um prompt esperando por comandos. -A janela, que normalmente é chamada de **linha de comando** ou **interface de linha de comando**, é um aplicativo baseado em texto para visualização, manipulação e manuseio de arquivos em seu computador (como por exemplo, o Windows Explorer ou o Finder no Mac, mas sem interface gráfica). Outros nomes para a linha de comando são: *cmd*, *CLI*, *prompt*, *console* ou *terminal*. +> **Observação:** Note que ao longo deste tutorial, intercalamos o uso dos termos 'diretório' e 'pasta', mas eles significam a mesma coisa. -## Abra a interface de linha de comando - -Para começar alguns experimentos, precisamos abrir a nossa interface de linha de comando primeiro. - -### Windows +## O que é a linha de comando? -Vá em Iniciar → Todos os Programas → Acessórios → Prompt de comando. +A janela, que geralmente é chamada de **linha de comando** ou **interface de linha de comando**, é uma aplicação de texto para ver e manipular arquivos em seu computador. É como o Windows Explorer ou o Finder no Mac, mas sem a interface gráfica. Outros nomes para a linha de comando são: *cmd*, *CLI*, *prompt*, *console* ou *terminal*. -### Mac OS X - -Applications → Utilities → Terminal. +## Abra a interface de linha de comando -### Linux +Para começar alguns experimentos, precisamos abrir a nossa interface de linha de comando. -Provavelmente você vai achar em Applications → Accessories → Terminal, mas isso depende do seu sistema operacional. Qualquer coisa é só procurar no Google :) +{% include "/intro_to_command_line/open_instructions.md" %} ## Prompt Agora você deve ver uma janela branca ou preta que está à espera de seus comandos. -Se você estiver em Mac ou num Linux, você provavelmente verá um `` $, como este: + + +Se você está usando Mac ou Linux, você provavelmente verá um `$`, como esse: + +{% filename %}command-line{% endfilename %} $ -No Windows, é um sinal de `>`, como este: + + + + +No Windows, você provavelmente verá um `>`, assim: + +{% filename %}command-line{% endfilename %} > -Cada comando será antecedido por este sinal e um espaço, mas você não precisa digitá-lo. Seu computador fará isso por você :) +Dê uma olhada na seção Linux logo acima -- você verá algo mais como isso quando você chegar ao PythonAnywhere depois no tutorial. + + + +Cada comando vai ser precedido por um `$` ou `>` e um espaço, mas você não deve digitar isso. Seu computador vai fazer isso por você. :) -> Apenas uma pequena nota: no seu caso, talvez há algo como `C:\Users\ola>` ou `Olas-MacBook Air: ~ ola$` antes do sinal do prompt isto estará 100% correto. Neste tutorial nós apenas simplificaremos ele para o mínimo. +> Uma pequena observação: pode ser que apareça algo como `C:\Users\ola>` ou `Olas-MacBook-Air:~ ola$` antes do cursor e isso está 100% correto. -## Seu primeiro comando (YAY!) +A parte que vai até e inclui o `$` ou o `>` é chamada de *prompt de linha de comando*, ou *prompt*, de forma breve. Ele está pedindo que você digite algo. -Vamos começar com algo simples. Digite o seguinte comando: +No tutorial, quando quisermos que você digite um comando, incluiremos o `$` ou `>` e, algumas vezes, algum texto adicional à esquerda. Ignore o que está à esquerda e apenas digite o comando que inicia após o prompt. + +## Seu primeiro comando (Uhuu!) + +Vamos começar digitando este comando: + + + +{% filename %}command-line{% endfilename %} $ whoami -ou + + + + +{% filename %}command-line{% endfilename %} > whoami -Depois tecla Enter. Essa é nossa saída: + + +E então pressione a tecla `enter`. Este é o resultado: + +{% filename %}command-line{% endfilename %} $ whoami olasitarska -Como você pode ver, o computador só apresentou seu nome de usuário. Elegante, né?:) +Como você pode ver, o computador acabou de mostrar seu nome de usuário na tela. Legal, né? :) -> Tente digitar cada comando, não copiar e colar. Você vai se lembrar mais dessa forma! +> Tente escrever cada comando, não copie e cole. Assim você vai se lembrar melhor deles! ## O Básico -Cada sistema operacional tem o seu próprio conjunto de instruções para a linha de comando, então se certifique que você está seguindo as instruções do seu sistema operacional. Vamos tentar, certo? +Cada sistema operacional tem o seu próprio conjunto de instruções para a linha de comando, então certifique-se de que você está seguindo as instruções do seu sistema operacional. Vamos tentar, certo? ### Pasta atual -Seria legal saber em que pasta estamos agora, certo? Vamos ver. Digite o seguinte comando seguido de um enter: +Quer saber em que diretório está agora? Digite o seguinte comando e clique `enter`: + + + +{% filename %}command-line{% endfilename %} $ pwd /Users/olasitarska -Se você estiver no Windows: +> Observação: 'pwd' significa 'print working directory' (imprima/mostre o diretório de trabalho). + + + + + +{% filename %}command-line{% endfilename %} > cd C:\Users\olasitarska -Provavelmente você vai ver algo parecido na sua máquina. Um vez que você abre a linha de comando você já começa na pasta Home. +> Observação: 'cd' significa 'change directory' em inglês, o que se traduz para 'mudar de diretório'. Com o PowerShell, você pode utilizar pwd da mesma forma como no Linux ou macOS. + + -> Nota: 'pwd' significa 'print working directory'. +Você provavelmente vai ver algo parecido em seu computador. A linha de comando geralmente inicia no diretório principal do usuário, também chamado de diretório "home", em Inglês. * * * +### Aprenda mais sobre um comando + +Muitos comandos que você digita no Prompt de comand possuem um painel de ajuda integrada que você pode abrir e ler! Por exemplo, para entender melhor sobre o comando do diretório atual: + + + +SO X e Linux tem um comando `man`, que ajuda você nos comandos. Tente `man pwd` e veja o que ele diz, ou coloque `man` antes de outros comandos para ver seus menus de ajuda. A saída `man` é normalmente paginada. Use a barra de espaço para ir para a próxima página, e `q` para sair do menu de ajuda. + + + + + +Colocando um sufixo `/?` para a maioria dos comandos, irá imprimir uma página de ajuda. Você pode precisar rolar a janela do seu comando para ver tudo. Tente `cd /?`. + + + ### Listando arquivos e pastas -Então o que tem nele? Seria legal descobrir. Vamos ver: +Então, o que tem no seu computador? Vamos descobrir: + + + +{% filename %}command-line{% endfilename %} $ ls Applications @@ -102,7 +158,11 @@ Então o que tem nele? Seria legal descobrir. Vamos ver: ... -Windows: + + + + +{% filename %}command-line{% endfilename %} > dir Directory of C:\Users\olasitarska @@ -113,165 +173,269 @@ Windows: ... +> Observação: No PowerShell, você também pode usar 'ls' como no Linux e macOS. + * * * -### Entrar em outra pasta +### Mudar a pasta atual + +Agora vamos para a pasta Desktop: + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + + -Talvez a gente queira entrar na nossa pasta Desktop? + + +{% filename %}command-line{% endfilename %} $ cd Desktop -Windows: +Note que o nome do diretório "Desktop" pode estar traduzido para a linguagem da sua conta Linux. Se for o caso, você irá precisar mudar `Desktop` para o nome traduzido; como exemplo, `Área de trabalho` em português. + + + + + +{% filename %}command-line{% endfilename %} > cd Desktop -Veja se realmente entramos na pasta: + + +Verifique se realmente mudamos de pasta: + + + +{% filename %}command-line{% endfilename %} $ pwd /Users/olasitarska/Desktop -Windows: + + + + +{% filename %}command-line{% endfilename %} > cd C:\Users\olasitarska\Desktop + + Aqui está! -> Dica de profissional: se você digitar `cd D` e apertar a tecla `tab` no seu teclado, a linha de comando irá preencher automaticamente o resto do nome para que você possa navegar rapidamente. Se houver mais de uma pasta que comece com "D", aperte a tecla `tab` duas vezes para obter uma lista de opções. +> Dica de profissional: se você digitar `cd D` e apertar a tecla `tab` no seu teclado, a linha de comando preencherá automaticamente o resto do nome para que você possa navegar rapidamente. Se houver mais de uma pasta cujo nome comece com "D", aperte a tecla `tab` duas vezes para obter uma lista de opções. * * * -### Criando uma pasta +### Criando Pastas + +Que tal criar uma pasta para praticarmos em sua área de trabalho? Você pode fazer assim: + + -Que tal criar um diretório Django Girls na sua área de trabalho? Você pode fazer assim: +{% filename %}command-line{% endfilename %} - $ mkdir djangogirls + $ mkdir practice -Windows: + - > mkdir djangogirls + + +{% filename %}command-line{% endfilename %} + + > mkdir practice -Este comando vai criar uma pasta com o nome `djangogirls` no nosso desktop. Você pode verificar se ele está lá, só de olhar na sua área de trabalho ou executando um comando `ls` (Mac ou Linux) ou `dir` (Windows)! Experimente :) + + +Esse pequeno comando criará uma pasta com o nome `practice` na sua área de trabalho. Você pode verificar se está lá ao olhar na sua Área de trabalho ou executando o comando `ls` ou `dir`! Experimente. :) > Dica de profissional: Se você não quiser digitar o mesmo comando várias vezes, tente pressionar `seta para cima` e `seta para baixo` no teclado para percorrer comandos usados recentemente. * * * -### Exercite-se! +### Pratique! -Um pequeno desafio para você: na sua mais nova pasta criada `djangogirls` crie uma outra pasta chamada `teste`. Use os comandos `cd` e `mkdir`. +Um pequeno desafio para você: em sua recém criada pasta `practice`, crie uma pasta chamada `test`. (Use os comandos `cd` e `mkdir`.) #### Solução: - $ cd djangogirls - $ mkdir teste + + +{% filename %}command-line{% endfilename %} + + $ cd practice + $ mkdir test $ ls - teste + test -Windows: + + + - > cd djangogirls - > mkdir teste +{% filename %}command-line{% endfilename %} + + > cd practice + > mkdir test > dir - 05/08/2014 07:28 PM teste + 05/08/2014 07:28 PM test -Parabéns! :) + + +Boa! :) * * * -### Limpando +### Arrumando + +Nós não queremos que você deixe uma bagunça, então vamos remover tudo que fizemos até aqui. -Não queremos deixar uma bagunça, então vamos remover tudo o que fizemos até agora. +Primeiro, precisamos voltar para a Área de trabalho: -Primeiro precisamos voltar para a pasta Desktop: + + +{% filename %}command-line{% endfilename %} $ cd .. -Windows: + + + + +{% filename %}command-line{% endfilename %} > cd .. -Fazendo `cd` para `..` nós mudaremos do diretório atual para o diretório pai (que significa o diretório que contém o diretório atual). + + +Usando o comando `..` com o `cd` irá mudar sua pasta atual para o diretório pai (ou seja, a pasta que contém sua pasta atual). + +Verifique onde você está: -Veja onde você está: + + +{% filename %}command-line{% endfilename %} $ pwd /Users/olasitarska/Desktop -Windows: + + + + +{% filename %}command-line{% endfilename %} > cd C:\Users\olasitarska\Desktop -Agora é hora de excluir o diretório `djangogirls`. + -> **Atenção**: A exclusão de arquivos usando `del`, `rmdir` ou `rm` é irrecuperável, significando *Arquivos excluídos vão embora para sempre*! Então, tenha cuidado com este comando. +Agora é hora de deletar a pasta `practice`: - $ rm -r djangogirls +> **Atenção**: A exclusão de arquivos usando `del`, `rmdir` ou `rm` é irreversível; ou seja, os *arquivos excluídos são perdidos para sempre*! Então, tenha cuidado com este comando. + + + +{% filename %}command-line{% endfilename %} + + $ rm -r practice -Windows: + - > rmdir /S djangogirls - djangogirls, Tem certeza ? S + + +{% filename %}command-line{% endfilename %} + + > rmdir /S practice + practice, Are you sure ? Y -Pronto! Para ter certeza que a pasta foi excluída, vamos checar: + + +Pronto! Para ter certeza de que a pasta foi excluída, vamos checar: + + + +{% filename %}command-line{% endfilename %} $ ls -Windows: + + + + +{% filename %}command-line{% endfilename %} > dir + + ### Saindo -Por enquanto é isso! Agora você fechar a linha de comando com segurança. Vamos fazer do jeito hacker, certo?:) +Isso é tudo por agora! Você pode fechar a janela da sua linha de comando agora sem medo. Vamos fazer isso do jeito hacker, certo? :) + + + +{% filename %}command-line{% endfilename %} $ exit -Windows: + + + + +{% filename %}command-line{% endfilename %} > exit -Legal, né?:) + -## Sumário +Massa, né? :) -Aqui vai uma lista de alguns comandos úteis: +## Sumário -| Comando (Windows) | Comando (Mac OS / Linux) | Descrição | Exemplo | -| ----------------- | ------------------------ | ----------------------------- | ------------------------------------------------- | -| exit | exit | Fecha a janela | **exit** | -| cd | cd | Muda a pasta | **cd test** | -| dir | ls | Lista as pastas e os arquivos | **dir** | -| copy | cp | Copia um arquivo | **copy c:\test\test.txt c:\windows\test.txt** | -| move | mv | Move um arquivo | **move c:\test\test.txt c:\windows\test.txt** | -| mkdir | mkdir | Cria uma pasta | **mkdir testdirectory** | -| del | rm | Deleta uma pasta e/ou arquivo | **del c:\test\test.txt** | +Aqui vai uma lista com alguns comandos úteis: -Estes são apenas alguns dos poucos comandos que você pode executar em sua linha de comando, mas você não vai usar mais nada do que isto hoje. +| Comando (Windows) | Comando (Mac OS / Linux) | Descrição | Exemplo | +| ----------------- | ------------------------ | ----------------------------- | -------------------------------------------------- | +| exit | exit | Fecha a janela | **exit** | +| cd | cd | Muda a pasta | **cd test** | +| cd | pwd | Mostra o diretório atual | **cd** (Windows) ou **pwd** (Mac OS / Linux) | +| dir | ls | Lista as pastas e/ou arquivos | **dir** | +| copy | cp | Copia um arquivo | **copy c:\test\test.txt c:\windows\test.txt** | +| move | mv | Move um arquivo | **move c:\test\test.txt c:\windows\test.txt** | +| mkdir | mkdir | Cria uma pasta | **mkdir testdirectory** | +| rmdir (ou del) | rm | Exclui arquivo | **del c:\test\test.txt** | +| rmdir /S | rm -r | Exclui diretório | **rm -r testdirectory** | +| [CMD] /? | man [CMD] | obtém ajuda para um comando | **cd /?** (Windows) or **man cd** (Mac OS / Linux) | -Se você estiver curioso, [ss64.com][1] contém uma referência completa de comandos para todos os sistemas operacionais. +Esses são apenas alguns dos comandos que você pode executar na sua linha de comandos, mas você não irá utilizar outros por hoje. - [1]: http://ss64.com +Se estiver com curiosidade, [ss64.com](http://ss64.com) contém uma referência completa dos comandos de todos os sistemas operacionais. -## Pronto? +## Pronta? -Vamos mergulhar no Python! +Vamos mergulhar no mundo do Python! diff --git a/pt/intro_to_command_line/open_instructions.md b/pt/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..ab7d2379721 --- /dev/null +++ b/pt/intro_to_command_line/open_instructions.md @@ -0,0 +1,29 @@ + + + +Dependendo da sua versão do Windows e do seu teclado, um dos seguintes deverá abrir uma janela de comando (você talvez tenha que experimentar um pouco, mas não precisa tentar todas essas sugestões): + +- Vá para o menu ou tela de iniciar, e digite "Prompt de comando" no campo de busca. +- Vá para o menu Iniciar → Sistema Windows → Prompt de comando. +- Vá em Iniciar → Todos os Programas → Acessórios → Prompt de comando. +- Vá para a tela Iniciar, passe o mouse sobre o canto inferior esquerdo da tela, e clique na seta para baixo que aparecerá (Em touch screen, passe o dedo sobre a parte inferior da tela). A página "Aplicativos" deve abrir. Clique em Prompt de comando na seção Sistema Windows. +- Pressione a tecla Windows no seu teclado e aperte a tecla "X" em seguida. Escolha "Prompt de comando" no menu pop-up. +- Mantenha pressionada a tecla Windows e pressione a tecla "R" para obter uma janela de "Executar". Digite "cmd" na caixa e clique no botão OK. + +![Digite "cmd" na janela "Run"](../python_installation/images/windows-plus-r.png) + +Ainda neste tutorial, você precisará ter duas janelas de comando abertas ao mesmo tempo. Entretanto, em algumas versões do Windows, se você já tem uma janela de comando aberta e tentar abrir uma segunda usando o mesmo método, Ao invés de abrir o sistema apontará para a que você já tem aberto. Agora tente no seu computador e veja o que acontece! Se você só obter uma janela de comando, tente um dos outros métodos listados acima. Ao menos um deles deve resultar em uma nova janela de comando. + + + + + +Vá para Aplicações → Utilidades → Terminal. + + + + + +Provavelmente está em aplicações → Acessórios → Terminal, ou Aplicativos → Sistema → Terminal, mas isso pode depender do seu sistema. Se não estiver lá, você pode tentar utilizar o Google. :) + + diff --git a/pt/python_installation/README.md b/pt/python_installation/README.md index 465ef8a0713..8a2845ab154 100755 --- a/pt/python_installation/README.md +++ b/pt/python_installation/README.md @@ -1,72 +1,15 @@ -# Vamos começar com Python +# Vamos começar com o Python Finalmente chegamos aqui! -Mas primeiro, vamos falar um pouco sobre o que o Python é. Python é uma linguagem de programação muito popular que pode ser usada para criar sites, jogos, softwares científicos, gráficos e muito, muito mais. +Mas primeiro, vamos falar sobre o que é Python. Python é uma linguagem de programação muito popular que pode ser usada para criar sites, jogos, software científicos, gráficos e muito, muito mais. -O Python é originário da década de 1980 e seu principal objetivo é ser legível por seres humanos (não apenas máquinas!), por isso ele parece muito mais simples do que outras linguagens de programação. Isso faz ele mais fácil de aprender, mas não se engane, Python também é muito poderoso! +O Python foi criado na década de 1980 e seu principal objetivo é ser legível por seres humanos (e não apenas pelas máquinas!). Por isso ele parece mais simples que outras linguagens de programação, mas não se preocupe - o Python também é muito poderoso! # Instalação do Python -> Este subcapítulo é baseado em um tutorial criado por Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) +> **Observação:** Se você está usando um Chromebook, pule este capítulo e certifique-se de seguir as instruções para [ Configuração do Chromebook](../chromebook_setup/README.md). +> +> **Observação:** Se você já passou pelas etapas de Instalação, não precisa fazer isso novamente - pode seguir em frente e ir para o próximo capítulo! -Django é escrito em Python. Nós precisamos dele para fazer qualquer coisa em Django. Vamos começar com sua instalação! Nós queremos que você instale o Python 3.4, então se você tem qualquer versão anterior, você vai precisar atualizá-la. - -### Windows - -Você pode baixar o Python para Windows no website https://www.python.org/downloads/release/python-343/. Depois de fazer o download do arquivo ***.msi**, você precisa executá-lo (dando um duplo-clique nele) e seguir as instruções. É importante lembrar o caminho (a pasta) onde você instalou o Python. Ela será útil depois! - -Cuidado com uma coisa: na segunda tela do assistente de instalação, marcado "Customize", certifique-se você rolar para baixo e escolha a opção "Adicionar python.exe para o caminho", como em - -![Não se esqueça de adicionar o Python para o Path][1] - - [1]: images/add_python_to_windows_path.png - -### Linux - -É muito provável que você já tenha o Python instalado e configurado. Para ter certeza se ele está instalado (e qual a sua versão), abra um terminal e digite o seguinte comando: - - $ python3 --version - Python 3.4.2 - - -Se você não tem o Python instalado ou quer uma versão diferente, você pode instalá-lo da seguinte maneira: - -#### Ubuntu - -Digite o seguinte comando no terminal: - - sudo apt-get install python3.4 - - -#### Fedora - -Use o seguinte comando no terminal: - - sudo yum install python3.4 - - -#### openSUSE - -Use o seguinte comando no terminal: - - sudo zypper install python3 - - -### OS X - -Você precisa acessar o site https://www.python.org/downloads/release/python-342/ e baixar o instalador do Python: - -* download do *instalador Mac OS X 64-bit/32-bit* *DMG*, -* Dê um duplo-clique para abri-lo, -* Dê um duplo-clique no *Python.mpkg* para executar o instalador. - -Verifique se a instalação foi bem sucedida abrindo o *Terminal* e digitando o comando `python3`: - - $ python3 --version - Python 3.4.2 - - -* * * - -Se você tiver qualquer dúvida ou se alguma coisa deu errado e você não sabe o que fazer - por favor pergunte ao seu instrutor! Às vezes, as coisas não estão indo bem e é melhor pedir ajuda a alguém com mais experiência. +{% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/pt/python_installation/images/add_python_to_windows_path.png b/pt/python_installation/images/add_python_to_windows_path.png index 9510d6f2176..3266efb6177 100644 Binary files a/pt/python_installation/images/add_python_to_windows_path.png and b/pt/python_installation/images/add_python_to_windows_path.png differ diff --git a/pt/python_installation/images/python-installation-options.png b/pt/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..a0a6c65d81d Binary files /dev/null and b/pt/python_installation/images/python-installation-options.png differ diff --git a/pt/python_installation/images/windows-plus-r.png b/pt/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/pt/python_installation/images/windows-plus-r.png differ diff --git a/pt/python_installation/instructions.md b/pt/python_installation/instructions.md new file mode 100644 index 00000000000..5ef658caa77 --- /dev/null +++ b/pt/python_installation/instructions.md @@ -0,0 +1,121 @@ +> Para leitoras em casa: esse capítulo é abordado no vídeo [Instalando Python & Editor de Código](https://www.youtube.com/watch?v=pVTaqzKZCdA). +> +> Esta seção baseia-se em tutoriais das Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) + +Django é escrito em Python. Precisamos de Python para fazer qualquer coisa no Django. Vamos começar por instalá-lo! Queremos que você instale a versão mais recente do Python 3, então, se você tiver uma versão anterior, precisará atualizá-la. Se você já tem versão 3.4 ou superior, deve estar bem. + +Por favor, instale o Python normal da seguinte maneira, mesmo tenha o Anaconda instalado no seu computador. + + + +Primeiramente, verifique se o seu computador está rodando uma versão 32-bit ou 64-bit do Windows, na linha "Tipo de Sistema" na página de informação do Sistema. Para chegar a essa página, tente um desses métodos: + +* Aperte as teclas do Windows e "Pause/Break" ao mesmo tempo +* Abra o seu Painel de Controle pelo menu do Windows, e navegue para "Sistema e Segurança", depois "Sistema" +* Aperte o botão do Windows no seu teclado, então navegue para Configurações > Sistema > Sobre + +Você pode baixar Python para Windows do site https://www.python.org/downloads/windows/. Clique no link "Versão mais recente do Python 3 - Python x.x.x". Se o seu computador está executando uma versão **64-bit** do Windows, baixe o instalador executável **Windows x86-64**. Caso contrário, baixe o instalador executável **Windows x86**. Depois de baixar o instalador, você deve executá-lo (com clique duplo) e seguir as instruções fornecidas. + +Uma coisa para prestar atenção: durante a instalação, você notará uma janela marcada "Setup". Certifique-se de marcar a caixa "Adicionar Python 3.6 ao PATH" ou "Adicionar Python às suas variáveis de ambiente" e clicar em "Instalar Agora", como mostrado aqui (pode aparecer um pouco diferente se você estiver instalando uma outra versão): + +![Não se esqueça de adicionar o Python ao Path](../python_installation/images/python-installation-options.png) + +Quando a instalação for concluída, pode aparecer uma caixa de diálogo com um link que você pode seguir para saber mais sobre Python ou sobre a versão que instalou. Feche ou cancele essa caixa de diálogo -- você vai aprender mais neste tutorial! + +Observação: se você estiver usando uma versão antiga do Windows (7, Vista, ou qualquer outra mais antiga) e o instalador do 3.6. x Python falhar com um erro, você pode tentar: + +1. instalar todas as atualizações do Windows e tentar instalar o Python novamente; ou +2. instalar uma [versão mais antiga do Python](https://www.python.org/downloads/windows/), por exemplo, [3.4.6](https://www.python.org/downloads/release/python-346/). + +Se você instalar uma versão mais antiga do Python, a tela de instalação pode parecer um pouco diferente da mostrada. Se certifique de rolar o botão do meio do mouse para baixo, até ver "Add python.exe to Path", então clique no botão à esquerda e selecione "Will be installed on local hard drive". + +![Adicione o Python ao PATH, versões mais antigas](../python_installation/images/add_python_to_windows_path.png) + + + + + +> **Observação:** Antes de instalar o Python no macOS, você deve garantir que suas configurações permitam a instalação de pacotes que não estejam na App Store. Vá para preferências do sistema (dentro da pasta Aplicativos), clique em "Segurança & Privacidade" e depois na guia "Geral". Se a configuração "Permitir que apps baixados:" estiver definida como "Mac App Store," mude para "Mac App Store e desenvolvedores identificados." + +Você precisa visitar https://www.python.org/downloads/release/python-361/ e baixar o instalador do Python: + +* Faça o download do arquivo *macOS 64-bit/32-bit installer*, +* Dê um duplo clique no arquivo *python-3.6.1-macosx10.6.pkg* para executar o instalador. + + + + + +É muito provável que você já tenha o Python instalado e configurado. Para ter certeza se ele está instalado (e qual a sua versão), abra o terminal e digite o seguinte comando: + +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python 3.6.1 + + +Se você tem instalada uma outra "versão micro" do Python, por exemplo, 3.6.0, não precisa atualizá-la. Se você não tem Python instalado, ou se você quer uma versão diferente, primeiro verifique qual distribuição Linux você está usando o seguinte comando: + +{% filename %}command-line{% endfilename %} + + $ grep ^NAME= /etc/os-release + + +Depois, dependendo do resultado, siga um dos seguintes guias de instalação abaixo desta seção. + + + + + +Digite o seguinte comando no terminal: + +{% filename %}command-line{% endfilename %} + + $ sudo apt install python3 + + + + + + +Use o seguinte comando no terminal: + +{% filename %}command-line{% endfilename %} + + $ sudo dnf install python3 + + +Se você estiver em versões mais antigas do Fedora, pode receber um erro dizendo que o comando `dnf` não foi encontrado. Nesse caso, você precisa usar o `yum` em vez disso. + + + + + +Use o seguinte comando no terminal: + +{% filename %}command-line{% endfilename %} + + $ sudo zypper install python3 + + + + +Verifique se a instalação foi bem sucedida abrindo o terminal e digitando o comando `python3`: + +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python 3.6.1 + + +A versão mostrada pode ser diferente da versão 3.6.1 -- deve corresponder à versão que você instalou. + +**Observação:** Se você estiver no Windows e receber uma mensagem de erro dizendo que o `python3` não foi encontrado, tente utilizar `python` (sem o `3`) e verifique se ela corresponde à versão Python 3.4. + +* * * + +Se você tem alguma dúvida ou se alguma coisa deu errado e você não tem a menor ideia do que fazer, pergunte à sua monitora! Nem sempre tudo sai conforme o esperado e é melhor pedir ajuda a alguém mais experiente. \ No newline at end of file diff --git a/pt/python_introduction/README.md b/pt/python_introduction/README.md index a59a336203e..e9049b81fa2 100755 --- a/pt/python_introduction/README.md +++ b/pt/python_introduction/README.md @@ -1,410 +1,569 @@ +{% set warning_icon = '' %} + # Introdução ao Python -> Parte deste capítulo é baseado nos Tutoriais de Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> Parte deste capítulo é baseada no tutorial das Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). Vamos escrever um pouco de código! -## Interpretador Python +## Interpretador de Python + +> Para leitoras em casa: esta parte é abordada no vídeo [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U). + +Para começar a trabalhar com Python, precisamos abrir uma * linha de comando* (ou prompt) no computador. Você provavelmente já sabe como fazer isso - aprendeu no capítulo [ Introdução à Linha de Comando ](../intro_to_command_line/README.md). -Para começar a brincar com Python nós precisamos abrir uma *linha de comando* no seu computador. Você já deve saber como fazer isso -- você aprendeu isso no capítulo [Introdução à Linha de Comando][2]. -Assim que estiver pronto, siga as instruções abaixo. +Assim que estiver pronta, siga as instruções abaixo. -Nós queremos abrir o Python num terminal, então digite `python3` e tecle Enter. +Para abrir um prompt de comando do Python, digite `python` no Windows ou `python3` no Mac OS/Linux e clique `enter`. + +{% filename %}command-line{% endfilename %} $ python3 - Python 3.4.2 (...) - Type "copyright", "credits" or "license" for more information. + Python 3.6.1 (...) + Digite "ajuda", "direitos autorais", ou "licença" para mais informações. >>> -## Seu primeiro comando Python! +## Seu primeiro comando em Python! -Depois de executar o comando Python, o prompt mudou para `>>>`. Para nós, isso significa que por enquanto só utilizaremos comandos na linguagem Python. Você não precisa digitar `>>>` - O Python fará isso por você. +Depois de executar o comando python, o prompt mudou para `>>>`. Isso significa que, por enquanto, só podemos executar comandos na linguagem Python. Você não precisa digitar `>>>` - o Python fará isso por você. -Se você deseja sair do console do Python, apenas digite `exit()` ou use o atalho `Ctrl + Z` no Windows e `Ctrl + D` no Mac/Linux. Então você não vai ver mais o `>>>`. +Se a qualquer momento você quiser sair do prompt do Python, digite `exit()` ou use o atalho `Ctrl + Z` no Windows e `Ctrl + D` no Mac ou Linux. Fazendo isso, você não vai mais ver o `>>>`. -Mas agora não queremos sair da linha de comando do Python. Queremos aprender mais sobre ele. Vamos, então, fazer algo muito simples. Por exemplo, tente digitar alguma operação matemática, como `2 + 3` e aperte Enter. +Por enquanto, não vamos sair do prompt do Python. Queremos aprender mais sobre ele. Para começar, vamos digitar um pouco de matemática, como `2 + 3`, e clicar `enter`. - >>> 2 + 3 - 5 - +{% filename %}command-line{% endfilename %} + +```python +>>> 2 + 3 +5 +``` -Incrível! Vê como a resposta simplesmente aparece? O Python conhece matemática! Você pode tentar outros comandos como: - `4 * 5` - `5 - 1` - `40 / 2` +Legal! Viu como a resposta apareceu? O Python sabe matemática! Você pode tentar outros comandos: -Divirta-se com isso por um tempo e depois volte aqui :). +- `4 * 5` +- `5 - 1` +- `40 / 2` -Como você pode ver, o Python é uma ótima calculadora. Se você está se perguntando o que mais você pode fazer... +Para executar cálculo exponencial, como 2 elevado a 3, digitamos: {% filename %}command-line{% endfilename %} + +```python +>>> 2 ** 3 +8 +``` + +Brinque um pouco com isso e depois volte aqui. :) + +Como você pode ver, o Python é uma ótima calculadora. Se você está se perguntando o que mais pode fazer… ## Strings Que tal o seu nome? Digite seu primeiro nome entre aspas, desse jeito: - >>> "Ola" - 'Ola' - +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" +'Ola' +``` -Você acabou de criar sua primeira string! String é um sequência de caracteres que podem ser processada pelo computador. A string sempre precisa iniciar e terminar com o mesmo caractere. Este pode ser aspas duplas(`'`) ou simples(`"`) - elas dizem ao Python que o que está dentro delas é uma string. +Você acabou de criar sua primeira string! Uma string é uma sequência de caracteres que pode ser processada pelo computador. Ela deve sempre começar e terminar com o mesmo caractere. Este caractere pode ser aspas duplas (`"`) ou simples (`'`) (não há nenhuma diferença!). Elas dizem ao Python que o que está entre elas é uma string. Strings podem ser juntadas. Tente isto: - >>> "Oi " + "Ola" - 'Oi Ola' - +{% filename %}command-line{% endfilename %} -Você também pode multiplicar strings por um número: +```python +>>> "Olá " + "Ola" +'Olá Ola' +``` - >>> "Ola" * 3 - 'OlaOlaOla' - +(Ola é o nome das duas criadoras do Django Girls!). Você também pode multiplicar strings por um número: -Se você precisa colocar uma apóstrofe dentro de sua string, existem duas maneiras de fazer. +{% filename %}command-line{% endfilename %} + +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` + +Se você precisa colocar uma apóstrofe dentro de uma string, pode fazê-lo de duas maneiras. Usando aspas duplas: - >>> "Correndo' ladeira abaixo" - "Correndo' ladeira abaixo" - +{% filename %}command-line{% endfilename %} -ou escapando apóstrofo com uma barra invertida (`\`): +```python +>>> "Roda d'água" +"Roda d'água" +``` - >>> "Correndo\' ladeira abaixo" - "Correndo' ladeira abaixo" - +ou "escapando" a aspa simples (o que sinaliza para o Python que aquele sinal é uma apóstrofe, e não uma aspa marcando o final da string) com uma contra-barra (``): + +{% filename %}command-line{% endfilename %} + +```python +>>> "Roda d\'água" +"Roda d'água" +``` Legal, hein? Para ver seu nome em letras maiúsculas, basta digitar: - >>> "Ola".upper() - 'OLA' - +{% filename %}command-line{% endfilename %} -Você acabou de usar a **função** `upper` na sua string! Uma função (como `upper()`) é um conjunto de instruções que o Python realiza em um determinado objeto (`"Ola"`), sempre que você chamar por ele. +```python +>>> "Ola".upper() +'OLA' +``` -Se você quer saber o número de letras do seu nome, existe uma função para isso também! +Você acabou de usar a **função** `upper` na sua string! Uma função (como `upper()`) é um conjunto de instruções que o Python tem que realizar em um determinado objeto (`"Ola"`) sempre que você o chamar. - >>> len("Ola") - 3 - +Se você quer saber o número de letras contidas em seu nome, há uma **função** para isso também! -Se perguntando porque algumas vezes você chama funções com um `.` no fim de uma string (como `"Ola".upper()`) e algumas vezes você primeiro chama a função colocando a string nos parênteses? Bem, em alguns casos, funções pertencem a objetos, como `upper()`, que só pode ser utilizada em strings. Nesse caso, nós chamamos a função de **método**. Outras vezes, funções não pertencem a nada específico e podem ser usadas em diferentes tipos de objetos, assim como `len()`. É por isso que nós estamos fornecendo `"Ola"` como um parâmetro para a função `len`. +{% filename %}command-line{% endfilename %} + +```python +>>> len("Ola") +3 +``` + +Talvez você esteja se perguntando porque algumas vezes chamamos funções com um `.` depois de uma string (como `"Ola".upper()`) e outras vezes primeiro chamamos a função e depois colocamos a string entre parênteses. Bem, em alguns casos, funções pertencem a objetos - como `upper()`, que só pode ser utilizada em strings. Nesse caso, nós chamamos a função de **método**. Outras vezes, elas não pertencem a nada específico e podem ser usadas em diferentes tipos de objetos, como a função `len()`. É por isso que fornecemos `"Ola"` como parâmetro para a função `len`. ### Sumário -OK, chega de strings. Até agora você aprendeu sobre: +OK, chega de strings. Até agora, você aprendeu sobre: -* **o prompt** - digitar comandos (códigos) no interpretador Python resulta em respostas em Python -* **números e strings** - no Python, números são usados para matemática e strings para objetos de texto -* **operadores** - como + e *, combinam valores para produzir um novo valor -* **funções** - como upper() e len(), executam ações nos objetos. +- **o prompt** - digitar comandos (códigos) no interpretador de Python resulta em respostas em Python +- **números e strings** - no Python, números são usados para matemática e strings, para objetos de texto +- **operadores** - como `+` e `*`, combinam valores para produzir um novo valor +- **funções** - como `upper()` e `len()`, executam ações nos objetos. -Isso é o básico sobre todas as linguagens de programação que você aprende. Pronto para algo mais difícil? Apostamos que sim! +Esse é o básico de todas as linguagens de programação. Pronta para algo mais difícil? Apostamos que sim! ## Erros -Vamos tentar algo novo. Podemos obter o tamanho de um número da mesma forma que podemos encontrar o tamanho do nosso nome? Digite `len(304023)` e pressione Enter: +Vamos tentar algo novo. Será que conseguimos saber a extensão de um número da mesma forma que descobrimos a dos nossos nomes? Digite `len(304023)` e clique `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 %} -Temos nosso primeiro erro! Ele diz que objetos do tipo "int" (inteiros, apenas números) não têm nenhum comprimento. Então o que podemos fazer agora? Talvez possamos escrever nosso número como uma string? Strings têm um comprimento, certo? +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` - >>> len(str(304023)) - 6 - +Temos nosso primeiro erro! O ícone {{ warning_icon }} é a forma que o Pyhton tem para avisar que o código que você está prestes a executar não vai funcionar conforme o esperado. Cometer erros (inclusive intencionalmente) é uma parte importante da aprendizagem! -Funcionou! Usamos a função `str` dentro da função `len`. `str ()` converte tudo para strings. +Nossa primeira mensagem de erro nos diz que objetos do tipo "int" (inteiros, naturais) não têm comprimento algum. O que podemos fazer agora? Podemos escrever nosso número como string? Strings têm comprimento, certo? -* A função `str` converte as coisas em **strings** -* A função `int` converte as coisas em **números inteiros** +{% filename %}command-line{% endfilename %} -> Importante: podemos converter números em texto, mas nós não podemos, necessariamente, converter texto em números - o que `int('hello')` quer dizer? +```python +>>> len(str(304023)) +6 +``` + +Funcionou! Usamos a função `str` dentro da função `len`. A função `str ()` converte tudo em strings. + +- A função `str` converte as coisas em **strings** +- A função `int` converte as coisas em **números inteiros** + +> Importante: podemos converter números em texto, mas nem sempre é possível converter texto em números - o que `int('hello')` quer dizer? ## Variáveis -Um conceito importante na programação é o conceito de variáveis. Uma variável não é nada mais do que um nome para alguma coisa, de tal forma que você possa usá-la mais tarde. Os programadores usam essas variáveis para guardar dados, para fazer seus códigos mais legíveis e para não ter que se lembrar sempre o que algumas coisas significam. +Variáveis são um conceito importante em programação. Uma variável é apenas um nome que você atribui a um objeto. Programadores armazenam dados nelas para tornar seus códigos mais legíveis e para não ter que lembrar a todo momento o que são certas coisas. -Digamos que queremos criar uma nova variável chamada `nome`: +Se quisermos criar uma nova variável chamada `name`: - >>> nome = "Ola" - +{% filename %}command-line{% endfilename %} -Vê? É fácil! É só fazer: nome igual a Ola. +```python +>>> name = "Ola" +``` -Como você percebeu, seu programa não retornou nada como fez anteriormente. Então como sabemos que a variável realmente existe? Simplesmente digite `nome` e tecle Enter: +Digitamos: name igual Ola. - >>> nome - 'Ola' - +Como você deve ter percebido, a última linha de código não retornou nada como nos exemplos anteriores. Então como vamos saber se a variável realmente existe? Basta digitar `name` e clicar `enter`: -Yippee! Sua primeira variável! :) Você sempre pode mudar o seu valor: +{% filename %}command-line{% endfilename %} - >>> nome = "Sonja" - >>> nome - 'Sonja' - +```python +>>> name +'Ola' +``` + +Uhuuu! Sua primeira variável! :) Você pode mudar o valor dela: + +{% filename %}command-line{% endfilename %} + +```python +>>> name = "Sonja" +>>> name +'Sonja' +``` Você pode usá-la também em funções: - >>> len(nome) - 5 - +{% filename %}command-line{% endfilename %} -Incrível não? Claro, variáveis podem ser qualquer coisa, então podem ser números também! Tente isso: +```python +>>> len(name) +5 +``` - >>> a = 4 - >>> b = 6 - >>> a * b - 24 - +Incrível, né? Variáveis podem ser qualquer coisa, então podem ser números também! Tente isso: -Mas, e se digitarmos o nome errado? Você consegue adivinhar o que aconteceria? Vamos tentar! +{% filename %}command-line{% endfilename %} - >>> city = "Tokyo" - >>> ctiy - Traceback (most recent call last): - File "", line 1, in - NameError: name 'ctiy' is not defined - +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` -Um erro! Como você pode ver, Python tem diferentes tipos de erros e este é chamado **NameError**. Python dará este erro se você tentar usar uma variável que não foi definida ainda. Se você encontrar esse erro depois, veja se no seu código se você não digitou o nome de uma variável errado. +E se digitarmos errado o nome da variável? Você consegue imaginar o que aconteceria? Vamos tentar! -Brinque com isso por um tempo e veja o que você consegue fazer! +{% 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 +``` + +Um erro! O Python tem diferentes tipos de erros e este é chamado **NameError**. Ele mostrará esta mensagem se você tentar usar uma variável que ainda não foi definida. Se encontrar esse erro mais tarde, confira no seu código se você não digitou errado o nome de uma variável. + +Brinque com isso por um tempo e veja o que consegue fazer! ## A função print -Tente isso: +Tente o seguinte: - >>> nome = 'Maria' - >>> nome - 'Maria' - >>> print(nome) - Maria - +{% filename %}command-line{% endfilename %} -Quando você apenas digita `nome`, o interpretador Python responde com a *representação* como string da variável 'name', que são as letras M-a-r-i-a, entre aspas simples. Quando você diz `print(nome)`, Python vai "imprimir" o conteúdo da variável na tela, sem as aspas, o que é mais puro. +```python +>>> name = 'Maria' +>>> name +'Maria' +>>> print(name) +Maria +``` + +Quando você digita `name`, o interpretador de Python responde com a *representação* da variável 'name' na forma de string, que é sequência de letras M-a-r-i-a, entre aspas simples. Quando você disser para o Python `print(name)`, ele vai "imprimir" (ou mostrar) na tela o conteúdo da variável sem as aspas. -Como veremos mais tarde, `print()` também é útil quando queremos imprimir algo dentro de funções, ou quando queremos imprimir algo em várias linhas. +Como veremos mais tarde, `print()` também é útil quando queremos imprimir algo dentro de funções ou quando queremos imprimir algo em várias linhas. ## Listas -Além de strings e inteiros, o Python tem todos os tipos diferentes de objetos. Vamos apresentar um chamado **lista**. Listas são exatamente o que você acha que elas são: elas são objetos que são listas de outros objetos :) +Além de strings e números inteiros, o Python tem muitos tipos diferentes de objetos. Agora, vamos apresentar um chamado **lista**. Listas são objetos que são listas de outros objetos. :) Vá em frente e crie uma lista: - >>> [] - [] - +{% filename %}command-line{% endfilename %} -Sim, esta é uma lista vazia. Não é muito, não é? Vamos criar uma lista dos números da loteria. Como não queremos ficar repetindo o código todo o tempo vamos criar uma variável para ela: +```python +>>> [] +[] +``` - >>> loteria = [3, 42, 12, 19, 30, 59] - +Sim, esta é uma lista vazia. Não é muito útil, né? Vamos criar uma outra composta por números de loteria. Para não precisar repetir o código o tempo todo, vamos atribuí-la a uma variável: -Tudo certo, nós temos uma lista! O que podemos fazer com isso? Vamos ver quantos números de loteria existem nesta lista. Você tem ideia de qual função deve usar para isso? Você já sabe disso! +{% filename %}command-line{% endfilename %} - >>> len(loteria) - 6 - +```python +>>> lottery = [3, 42, 12, 19, 30, 59] +``` -Sim! `len()` pode te dar o número de objetos que fazem parte de uma lista. Uma mão na roda, não? Vamos organizar isso agora: +Legal, criamos uma lista! O que podemos fazer com ela? Vamos ver quantos números de loteria ela contém. Você tem ideia de que a função deve usar para isso? Você já aprendeu ;) - >>> loteria.sort() - +{% filename %}command-line{% endfilename %} -Isso não retorna nada, apenas troca a ordem em que os números aparecem na lista. Vamos imprimir isso outra vez e ver o que acontece: +```python +>>> len(lottery) +6 +``` - >>> print(loteria) - [3, 12, 19, 30, 42, 59] - +Sim! `len()` pode te dizer o número de objetos que fazem parte de uma lista. Uma mão na roda, né? Agora vamos organizá-los: -Como você pode ver, os números na nossa lista estão ordenados do menor para o maior. Parabéns! +{% filename %}command-line{% endfilename %} -Talvez a gente queira inverter essa ordem? Vamos fazer isso! +```python +>>> lottery.sort() +``` - >>> loteria.reverse() - >>> print(loteria) - [59, 42, 30, 19, 12, 3] - +Isso não retorna nada, apenas muda a ordem em que os números aparecem na lista. Vamos imprimi-la outra vez e ver o que acontece: -Moleza né? Se você quiser adicionar alguma coisa à sua lista, você pode fazer isto digitando o seguinte comando: +{% filename %}command-line{% endfilename %} - >>> loteria.append(199) - >>> print(loteria) - [59, 42, 30, 19, 12, 3, 199] - +```python +>>> print(lottery) +[3, 12, 19, 30, 42, 59] +``` -Se você quiser mostrar apenas o primeiro número você pode usar **índices**. Um índice é um número que diz onde um item da lista está. Os computadores gostam de iniciar a contagem por 0, então o primeiro objeto tem índice 0, o próximo tem índice 1 e por aí vai. Tente isso: +Agora os números estão ordenados do menor para o maior. Parabéns! - >>> print(loteria[0]) - 59 - >>> print(loteria[1]) - 42 - +E se quisermos inverter a ordem? Vamos fazer isso! + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery.reverse() +>>> print(lottery) +[59, 42, 30, 19, 12, 3] +``` + +Moleza, né? Se quiser adicionar alguma coisa à sua lista, digite o seguinte comando: -Como você pode ver, você pode acessar diferentes objetos na sua lista usando o nome da lista e o índice do objeto dentro dos colchetes. +{% filename %}command-line{% endfilename %} -Por diversão extra, tente alguns outros índices: 6, 7, 1000, -1, -6 ou -1000. Veja se você consegue prever o resultado antes de tentar o comando. Os resultados fazem sentido? +```python +>>> lottery.append(199) +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +``` + +Se quiser ver apenas o primeiro número da lista, pode usar **índices**. Um índice é o número que diz onde na lista um item está. Programadores preferem começar a contar a partir do zero, então o primeiro objeto em sua lista está no índice 0, o segundo no 1 e assim por diante. Tente isso: + +{% filename %}command-line{% endfilename %} + +```python +>>> print(lottery[0]) +59 +>>> print(lottery[1]) +42 +``` + +Como você pode ver, podemos acessar diferentes objetos na lista usando o nome da lista e o índice do objeto entre colchetes. + +Para apagar algum objeto da sua lista, você precisa usar **índices**, como aprendemos acima, e o método `pop()`. Vamos usar um exemplo para reforçar o que já aprendemos: vamos deletar o primeiro número de nossa lista. -Você pode encontrar uma lista de todos os métodos disponíveis neste capítulo na documentação do Python: https://docs.python.org/3/tutorial/datastructures.html +{% filename %}command-line{% 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] +``` + +Funcionou perfeitamente! + +Agora, tente alguns outros índices, como: 6, 7, 1000, -1, -6 ou -1000. Veja se consegue prever o resultado antes de executar o comando. Os resultados fazem sentido para você? + +Uma lista de todos os métodos disponíveis nesta seção pode ser encontrada na documentação do Python: https://docs.python.org/3/tutorial/datastructures.html ## Dicionários -Um dicionário é semelhante a uma lista, mas você pode acessar valores através de uma chave ao invés de um índice. Uma chave pode ser qualquer string ou número. A sintaxe para definir um dicionário vazio é: +> Para leitoras em casa: esta seção é abordada no vídeo [Python Basics: Dictionaries](https://www.youtube.com/watch?v=ZX1CVvZLE6c). - >>> {} - {} - +Um dicionário é similar a uma lista, mas para acessar seus valores você usa uma chave ao invés de um índice. Uma chave pode ser qualquer string ou número. A sintaxe para definir um dicionário vazio é: -Isso mostra que você acabou de criar um dicionário vazio. Hurra! +{% filename %}command-line{% endfilename %} -Agora, tente escrever o seguinte comando (tente substituir com as suas próprias informações também): +```python +>>> {} +{} +``` - >>> participante = {'nome': 'Ola', 'pais': 'Polonia', 'numeros_favoritos': [7, 42, 92]} - +Você acabou de criar um dicionário vazio. Uhuuu! -Com esse comando, você acabou de criar uma variável chamada `participant` com três pares de chave-valor: +Agora escreva o seguinte comando (e tente colocar suas próprias informações): -* A chave `nome` aponta para o valor `'Ola'` (um objeto `string`), -* `pais` aponta para `'Polonia'` (outra `string`), -* e `numeros_favoritos` apontam para `[7, 42, 92]` (uma `list` com três números nela). +{% filename %}command-line{% endfilename %} -Você pode checar o conteúdo de chaves individuais com a sintaxe: +```python +>>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} +``` - >>> print(participante['nome']) - Ola - +Com esse comando, você criou uma variável chamada `participant` com três pares de chave-valor: -Veja, é similar a uma lista. Mas você não precisa lembrar o índice - apenas o nome. +- A chave `name` aponta para o valor `'Ola'` (um objeto do tipo `string`), +- a chave `country` aponta para `'Poland'` (outra `string`), +- e a chave `favorite_numbers` aponta para `[7, 42, 92]` (uma `lista` de três números). -O que acontece se pedirmos ao Python o valor de uma chave que não existe? Você consegue adivinhar? Vamos tentar e descobrir! +Você pode verificar o conteúdo de chaves individuais com a sintaxe: - >>> participante['idade'] - Traceback (most recent call last): - File "", line 1, in - KeyError: 'idade' - +{% filename %}command-line{% endfilename %} -Olha, outro erro! Esse é um **KeyError**. Python é bastante prestativo e te diz que a chave `'idade'` não existe nesse dicionário. +```python +>>> print(participant['name']) +Ola +``` -Quando usar um dicionario ou uma lista? Bem, um bom ponto para refletir. Pense em uma solução antes de olhar a resposta na próxima linha. +É similar a uma lista, mas você não precisa lembrar o índice - apenas o nome. -* Você precisa de uma sequência ordenada de itens? Use uma list. -* Você precisa associar valores com chaves, assim você pode procurá-los eficientemente (pela chave) mais tarde? Use um dictionary. +O que acontece se perguntarmos ao Python qual é o valor de uma chave que não existe? Você consegue adivinhar? Vamos testar e descobrir! -Dicionários, como listas, são *mutáveis*, ou seja, que podem ser mudados depois que são criados. Você pode adicionar novos pares de chave/valor para o dicionário após sua criação, como: +{% filename %}{{ warning_icon }} command-line{% endfilename %} - >>> participante['linguagem_favorita'] = 'Python' - +```python +>>> participant['age'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'age' +``` -Como as lists, usar o método `len()` em dicionários retorna o número de pares chave-valor no dicionario. Vá em frente e digite o comando: +Olha, outro erro! Esse é um **KeyError**. O Python é bastante prestativo e te diz que a chave `'age'` não existe no nesse dicionário. - >>> len(participante) - 4 - +Você deve estar se perguntando quando deveria usar um dicionário ou uma lista. Essa é uma questão importante. Pense sobre ela antes de ver a resposta nas próximas linhas. -Espero que agora faça sentido até agora. :) Pronta para mais diversão com dicionários? Pule na próxima linha para coisas incríveis. +- Você precisa de uma sequência ordenada de itens? Use uma lista. +- Você precisa associar valores a chaves para poder procurá-los eficientemente (pela chave) mais tarde? Use um dicionário. -Você pode usar o comando `pop()` para deletar um item no dicionario. Digamos, se você quer excluir a entrada correspondente a chave `'numeros_favoritos'`, basta digitar o seguinte comando: +Dicionários, assim como listas, são *mutáveis*. Isso significa que eles podem ser alterados depois de criados. Você pode adicionar um novo par chave-valor a um dicionário depois de ele ser criado, por exemplo: - >>> participante.pop('numeros_favoritos') - >>> participante - {'pais': 'Polonia', 'linguagem_favorita': 'Python', 'nome': 'Ola'} +{% filename %}command-line{% endfilename %} -Como você pode ver no retorno, o par chave-valor correspondente à chave 'numeros_favoritos' foi excluído. +```python +>>> participant['favorite_language'] = 'Python' +``` -Além disso você pode mudar o valor associado com uma chave já criada no dicionário. Digite: +Como nas listas, usar a função `len()` em dicionários retorna o número de pares chave-valor que ele contém. Vá em frente e digite o comando: - >>> participante['pais'] = 'Alemanha' - >>> participante - {'pais': 'Alemanha', 'linguagem_favorita': 'Python', 'nome': 'Ola'} +{% filename %}command-line{% endfilename %} -Como você pode ver, o valor da chave `'pais'` foi alterado de `'Polonia'` para `'Alemanha'`. :) Emocionante? Hurra! Você acabou de aprender outra coisa incrível. +```python +>>> len(participant) +4 +``` + +Esperamos que esteja fazendo sentido até agora. :) Pronta para mais diversão com dicionários? + +Você pode usar o método `pop()` para deletar um item do dicionário. Se quiser excluir a entrada correspondente à chave `'favorite_numbers'`, por exemplo, basta digitar o seguinte comando: + +{% filename %}command-line{% endfilename %} + +```python +>>> participant.pop('favorite_numbers') +[7, 42, 92] +>>> participant +{'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +Como você pode ver no resultado, o par chave-valor correspondente à chave 'favorite_numbers' foi excluído. + +Além disso, você pode mudar o valor associado a uma chave já criada no dicionário. Digite: + +{% filename %}command-line{% endfilename %} + +```python +>>> participant['country'] = 'Germany' +>>> participant +{'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +Agora, o valor da chave `'country'` foi alterado de `'Poland'` para `'Germany'`. :) Emocionante? Uhu! Você acabou de aprender outra coisa incrível. ### Sumário -Incrível! Agora você sabe muito sobre programação. Nesta última parte você aprendeu sobre: +Legal! Agora você sabe muito sobre programação. ;) Nesta última parte, você aprendeu sobre: -* **erros** - agora você sabe como ler e entender erros que aparecem se o Python não entender um comando que você deu -* **variáveis** - nomes para objetos que permitem você programar facilmente e deixar seu código mais legível -* **listas** - listas de objetos armazenados em uma ordem específica -* **dicionários** - objetos armazenados como pares chave-valor +- **erros** - você já sabe como ler e entender mensagens de erro que aparecem quando o Python não entende um comando que você deu; +- **variáveis** - são nomes para objetos que permitem que você programe facilmente e deixam seu código mais legível; +- **listas** - são listas de objetos armazenados em uma ordem específica; +- **dicionários** - contêm objetos armazenados como pares chave-valor. -Empolgado(a) para o próximo passo? :) +Animada para a próxima parte? :) ## Compare coisas -Grande parte da programação consiste em comparar coisas. O que é mais fácil de comparar? Números, é claro. Vamos ver como isso funciona: - - >>> 5 > 2 - True - >>> 3 < 1 - False - >>> 5 > 2 * 2 - True - >>> 1 == 1 - True - >>> 5 != 2 - True - +> Para leitoras em casa: esta seção é abordada no vídeo [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4). -Demos ao Python alguns números para comparar. Como você pode ver, Python pode comparar não só números mas também resultados de métodos. Legal, hein? +Grande parte da programação consiste em comparar coisas. O que é mais fácil comparar? Números! Vamos ver como funciona: -Você está se perguntando por que colocamos dois sinais de igual `==` lado a lado para comparar se os números são iguais? Nós usamos um único `=` para atribuir valores a variáveis. Você sempre, **sempre** precisa colocar dois `==` se quiser verificar se as coisas são iguais. Também é possível afirmar que as coisas são desiguais entre si. Para isso, usamos o símbolo `! =`, conforme mostrado no exemplo acima. +{% filename %}command-line{% endfilename %} + +```python +>>> 5 > 2 +True +>>> 3 < 1 +False +>>> 5 > 2 * 2 +True +>>> 1 == 1 +True +>>> 5 != 2 +True +``` + +Demos ao Python alguns números para comparar. Como você pode ver, ele pode comparar não apenas números, mas também resultados de métodos. Legal, né? + +Você deve estar se perguntando por que colocamos dois sinais de igual `==` lado a lado para verificar se os números são iguais. Nós usamos um único `=` para atribuir valores a variáveis. Você sempre, **sempre**, precisa colocar dois `==` se quiser verificar se as coisas são iguais. Também é possível afirmar que as coisas são diferentes. Para isso, usamos o símbolo `!=`, como mostrado no exemplo acima. Dê ao Python mais duas tarefas: - >>> 6 >= 12 / 2 - True - >>> 3 <= 2 - False - +{% filename %}command-line{% endfilename %} -`>` e `<` são fáceis, mas o que `>=` e `<=` significam? Leia eles da seguinte forma: +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` -* x `>` y significa: x é maior que y -* x `<` y significa: x é menor que y -* x `< =` y significa: x é menor ou igual a y -* x `>=` y significa: x é maior ou igual a y +Já vimos `>` e `<`, mas o que significam `>=` e `<=`? Leia da seguinte forma: -Fantástico! Quer mais? Tente isto: +- x `>` y significa: x é maior que y +- x `<` y significa: x é menor que y +- x `<=` y significa: x é menor ou igual a y +- x `>=` y significa: x é maior ou igual a y - >>> 6 > 2 and 2 < 3 - True - >>> 3 > 2 and 2 < 1 - False - >>> 3 > 2 or 2 < 1 - True - +Fantástico! Quer fazer mais? Tente isto: + +{% filename %}command-line{% endfilename %} + +```python +>>> 6 > 2 and 2 < 3 +True +>>> 3 > 2 and 2 < 1 +False +>>> 3 > 2 or 2 < 1 +True +``` -Você pode dar ao Python quantos números para comparar quanto você quiser, e ele vai te dar uma resposta! Espertinho, certo? +Você pode pedir ao Python para comprar quantos números quiser e ele vai te dar uma resposta! Espertinho, não é? -* **and** - se você usar o operador `and`, ambas as comparações terão que ser verdadeiras para que todo o comando seja verdadeiro -* **or** - se você usar o operador `or`, apenas uma das comparações precisa ser verdadeira para que o comando todo seja verdadeiro +- **and** - se você usar o operador `and`, as duas comparações terão que ser verdadeiras para que a expressão seja verdadeira (True) +- **or** - se você usar o operador `or`, apenas uma das comparações precisa ser verdadeira para que a expressão seja verdadeira (True) -Já ouviu a expressão "comparar maçãs com laranjas"? Vamos tentar o equivalente em Python: +Já ouviu a expressão "comparar alhos com bugalhos"? Vamos tentar o equivalente em Python: - >>> 1 > 'django' - Traceback (most recent call last): - File "", line 1, in - TypeError: unorderable types: int() > str() - +{% filename %}{{ warning_icon }} command-line{% endfilename %} -Aqui vemos que assim como na expressão, Python não é capaz de comparar um número (`int`) e uma string (`str`). -Em vez disso, ele mostrou um TypeError e nos disse que os dois tipos não podem ser comparados juntos.

+```python +>>> 1 > 'django' +Traceback (most recent call last): + File "", line 1, in +TypeError: '>' not supported between instances of 'int' and 'str' +``` -

Booleano

+Aqui, vemos que assim como não podemos comparar alhos com bugalhos, o Python não é capaz de comparar um número (`int`) e uma string (`str`). Em vez de retornar um resultado, ele mostrou um **TypeError** e nos disse que os dois tipos não podem ser comparados um ao outro. -

Acidentalmente, você aprendeu sobre um novo tipo de objeto em Python. É chamado de booleano -- e provavelmente o tipo mais fácil que existe.

+## Booleanos -

Existem apenas dois objetos booleanos: - True (verdadeiro) - False (falso)

+Aliás, você acabou de aprender sobre um novo tipo de objeto em Python. Ele se chama **booleano**. -

Mas para o Python entender isso, você precisa sempre escrever True (primeira letra maiúscula, com o resto das letras em minúsculo). true, TRUE, tRUE não vai funcionar -- só True é correto. (O mesmo se aplica ao False, claro.)

+Existem apenas dois objetos booleanos: -

Booleanos podem ser variáveis também! Veja:

+- True (verdadeiro) +- False (falso) -``` +Para que o Python entenda, você precisa escrever exatamente 'True' (primeira letra maiúscula e as outras minúsculas - mas sem as aspas). **true, TRUE ou tRUE não vão funcionar - só True está correto.** (A mesma coisa vale para 'False'). + +Booleanos também podem ser variáveis! Veja: + +{% filename %}command-line{% endfilename %} + +```python >>> a = True >>> a True @@ -412,89 +571,146 @@ True Você também pode fazer desse jeito: -``` +{% filename %}command-line{% endfilename %} + +```python >>> a = 2 > 5 >>> a False ``` -Pratique e divirta-se com os valores booleanos, tentando executar os seguintes comandos: +Pratique e divirta-se com os valores booleanos tentando executar os seguintes comandos: -* `True and True` -* `False and True` -* `True or 1 == 1` -* `1 != 2` +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` Parabéns! Booleanos são um dos recursos mais interessantes na programação, e você acabou de aprender como usá-los! -# Salvá-lo! +# Salve! -Até agora nós escrevemos todo nosso código em um interpretador python, que nos limita a uma linha de código em um momento. Programas normais são salvos em arquivos e executados pelo nosso **interpretador** de linguagem de programação ou **compilador**. Até agora já corremos nossos programas de uma linha de cada vez no **interpretador** Python. Nós vamos precisar de mais de uma linha de código para as próximas tarefas, então precisaremos rapidamente: +> Para leitoras em casa: esta seção é abordada no vídeo [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk). -* Sair do interpretador Python -* Abrir o editor de código de sua escolha -* Salvar algum código em um novo arquivo python -* Executá-lo! +Até agora, escrevemos todos os códigos no interpretador de Python, que nos limita a digitar uma linha por vez. Programas normais são salvos em arquivos e executados pelo nosso **interpretador** de linguagem de programação ou **compilador**. Até aqui, executamos nossos programas uma linha de cada vez no **interpretador** de Python. Vamos precisar de mais de uma linha de código para as próximas tarefas, então vamos rapidamente: -Para sair do interpretador Python que estamos usando, simplesmente digite a função `exit()`: +- Sair do interpretador de Python +- Abrir o editor de código que escolhemos antes +- Salvar algum código em um novo arquivo de Python +- Executar o código! - >>> exit() - $ - +Para sair do interpretador de Python, use a função `exit()`. -Isso vai colocá-la no prompt de comando. +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` + +Isso vai levá-la de volta ao prompt de comando. + +Mais cedo, nós escolhemos um editor de código da seção [code editor](../code_editor/README.md). Vamos precisar abrir o editor agora e escrever algum código em um novo arquivo (ou se você estiver utilizando um Chromebook, crie um novo arquivo no IDE da nuvem e o abra, que será incluso ao editor): + +{% filename %}editor{% endfilename %} -Anteriormente, nós escolhemos um editor de código da seção do [editor de código][4]. Nós precisamos abrir o editor agora e escrever algum código em um novo arquivo: ```python print('Hello, Django girls!') ``` -> **Nota** Você deve observar que uma das coisas mais legais sobre editores de código: cores! No console do Python, tudo era da mesma cor, mas agora você deve ver que a função de `Imprimir` é uma cor diferente da sequência de caracteres no seu interior. Isso é chamado de "realce de sintaxe", e é uma ajuda muito útil quando está programando. Perceba a cor das coisas e você vai obter uma dica para quando você esquecer de fechar uma seqüência de caracteres, ou fazer um erro de digitação em um nome de palavra-chave (como `def` em uma função, que veremos abaixo). Esta é uma das razões pelas quais que nós usamos um editor de código :) +Você já é uma desenvolvedora Python bastante experiente, então sinta-se livre para escrever códigos com o que aprendeu hoje. ;) + +Agora, precisamos salvar o arquivo e dar a ele um nome descritivo. Vamos nomear o arquivo **python_intro.py** e salvá-lo na sua área de trabalho. Podemos chamá-lo como quisermos, mas é importante que o nome termine com **.py**. A extensão **.py** diz ao sistema operacional que esse é um **arquivo Python executável** e o interpretador de Python pode rodá-lo. + +> **Observação**: Você deve reparar numa das coisas mais legais nos editores de código: cores! No interpretador de Python, tudo é da mesma cor, mas no editor você deve estar vendo que a função `print` tem uma cor diferente da string que ela recebe como argumento. Isso se chama destaque de sintaxe ("syntax highlightning", do Inglês) e é uma funcionalidade muito útil quando escrevemos código. As cores de cada elemento nos dão dicas importantes. Elas avisam, por exemplo, sobre strings que esquecemos de fechar ou palavras reservadas que digitamos errado (como a palavra `def` na definição de uma função, que veremos adiante). Esta é uma das razões pelas quais usamos um editor de código. :) -Obviamente, você é um desenvolvedor python bastante experiente agora, então sinta-se livre para escrever um código que você aprendeu hoje. +O arquivo está salvo, então é hora de executá-lo! Com as habilidades que você aprendeu na seção sobre linhas de comando, use o terminal para **ir para os diretórios no desktop**. -Agora temos de salvar o arquivo e dê um nome descritivo. Vamos chamar o arquivo **python_intro.py** e salve-o em seu desktop. Podemos nomear o arquivo tudo o que quisermos, o importante aqui é ter certeza que o arquivo termina no **py**, isto diz nosso computador, que é um **arquivo executável de python** e Python pode executá-lo. + -Com o arquivo salvo, é hora de executá-lo! Usando as habilidades que você aprendeu na seção de linha de comando, use o terminal **altere os diretórios** para o desktop. +Em um Mac, o comando é esse: -Em um Mac, o comando será parecido com isto: +{% filename %}command-line{% endfilename %} - cd ~/Desktop + $ cd ~/Desktop -No Linux, será assim (a palavra "Desktop" pode ser traduzido para seu idioma): + - cd ~/Desktop + + +No Linux, ficará assim: + +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop -E no windows, vai ser assim: +(Lembre-se de que a palavra "Desktop" pode estar traduzida para o seu idioma local.) + + + + + +No prompt de comando Windows, é assim: + +{% filename %}command-line{% endfilename %} + + > cd %HomePath%\Desktop + + + + + + +E no Windows Powershell, é assim: - cd %HomePath%\Desktop +{% filename %}command-line{% endfilename %} + + > cd $Home\Desktop -Se você ficar preso, só pedir ajuda. + + +Se você tiver alguma dificuldade, é só pedir ajuda. Sua monitora está aqui para isso! + +Agora, use o interpretador de Python para executar o código que está no arquivo, assim: -Em seguida, usar o Python para executar o código no arquivo assim: +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hello, Django girls! -Tudo bem! Você acabou de executar seu primeiro programa em python que foi salvo em um arquivo. Se sente ótima? +Observação: no Windows, 'python3' não é reconhecido como um comando. Em vez disso, use 'python' para executar o arquivo: + +{% filename %}command-line{% endfilename %} + +```python +> python python_intro.py +``` + +Muito bom! Você acabou de rodar o seu primeiro programa Python que foi salvo a um arquivo. Sente-se incrível? + +Agora, você pode começar a aprender uma ferramenta essencial na programação: -Você pode agora passar para uma ferramenta essencial na programação: +## If … elif … else -## if...elif...else +Várias coisas em um código só podem ser executadas se determinadas condições forem atendidas. É por isso que o Python tem um comando chamado **if**. -Muitas coisas no código só podem ser executadas se determinadas condições forem atendidas. É por isso que o Python tem alguma coisa chamada **declaração if**. +Substitua o código no arquivo **python_intro.py** pelo seguinte: -Substitua o código no arquivo **python_intro.py** para isto: +{% filename %}python_intro.py{% endfilename %} ```python if 3 > 2: -``` +``` + +Se você salvar e executar esse código, verá um erro como este: -Se salvou este e ele foi executado, nós veríamos um erro como este: +{% filename %}{{ warning_icon }} command-line{% endfilename %} $ python3 python_intro.py File "python_intro.py", line 2 @@ -502,114 +718,194 @@ Se salvou este e ele foi executado, nós veríamos um erro como este: SyntaxError: unexpected EOF while parsing -Python espera que nós forneçamos mais instruções que serão supostamente executadas caso a condição `3 > 2` venha a ser verdadeira (ou `True` nesse caso). Vamos tentar fazer o Python imprimir "It works!". Altere o seu código no seu arquivo **python_intro.py** para isto: +O Python espera que lhe demos instruções que devem ser executadas caso a condição `3 > 2` seja verdadeira (ou `True`). Vamos tentar fazer o Python mostrar na tela o texto "Funciona!". Altere o seu código no seu arquivo **python_intro.py** para isto: + +{% filename %}python_intro.py{% endfilename %} ```python if 3 > 2: - print('It works!') + print('Funciona!') ``` -Você percebeu que identamos a próxima linha com 4 espaços? Precisamos fazer isso para que o Python saiba qual código será executado se o resultado for True. Você pode fazer com 1 espaço, mas quase todos os programadores Python fazem com 4 para deixar as coisas arrumadas. Um único tab também vai contar como 4 espaços. -Salvá-lo e execute novamente: +Notou que a linha após o "if" começa com 4 espaços? Precisamos dessa endentação para que o Python saiba quais linhas executar se a condição dentro do if for verdadeira. Você pode quantos espaços quiser, mas por convenção os programadores Python usam 4, para que os códigos fiquem mais uniformes. Uma tabulação conta como quatro espaços se você configurar seu editor de texto assim. Quando escolher quantos espaços usar, não mude! Se começou a endentar com quatro espaços, siga esse padrão em todo o código - ou você poderá encontrar problemas. - $ python3 python_intro.py - It works! - +Salve-o e execute novamente: + +{% filename %}command-line{% endfilename %} + +```python +$ python3 python_intro.py +Funciona! +``` -### E se não? +Observação: Lembre-se que no Windows 'python3' não é reconhecido como um comando. Se você usa esse sistema operacional, de agora em diante, substitua 'python3' 'python' para executar o arquivo. -Nos exemplos anteriores, o código foi executado somente quando as condições eram verdade. Mas o Python também tem instruções `elif` e `else`: +### E se uma condição não for verdadeira? + +Nos exemplos anteriores, o código foi executado somente quando as condições eram verdadeiras, mas o Python também tem as instruções `elif` e `else`: + +{% filename %}python_intro.py{% endfilename %} ```python if 5 > 2: - print('5 é realmente maior que 2') + print('5 é maior que 2') else: print('5 não é maior que 2') ``` -Quando for executado irá imprimir: +Quando esse código for executado, o Python mostrará: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py - 5 é realmente maior que 2 + 5 é maior que 2 -Se 2 for um número maior do que 5, então o segundo comando será executado. Fácil, né? Vamos ver como funciona o `elif`: +Se 2 fosse um número maior que 5, o segundo comando seria executado. Fácil, né? Vamos ver como funciona o `elif`: + +{% filename %}python_intro.py{% endfilename %} ```python name = 'Sonja' if name == 'Ola': - print('Hey Ola!') + print('Olá Ola!') elif name == 'Sonja': - print('Hey Sonja!') + print('Olá Sonja!') else: - print('Hey anonymous!') -``` + print('Olá estranho!') +``` + +e executando: + +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Olá Sonja! + + +Viu o que aconteceu? O `elif` possibilita adicionar uma condição que só vai ser executada se a primeira condição for falsa. + +Você pode adicionar quantos `elif` quiser depois do `if`. Por exemplo: + +{% filename %}python_intro.py{% endfilename %} + +```python +volume = 57 +if volume < 20: + print("Está um pouco baixo") +elif 20 <= volume < 40: + print("Está bom para música ambiente") +elif 40 <= volume < 60: + print("Perfeito, posso ouvir todos os detalhes") +elif 60 <= volume < 80: + print("Ótimo para festas!") +elif 80 <= volume < 100: + print("Está muito alto!") +else: + print("Meus ouvidos doem! :(") +``` + +O Python testa cada condição na sequência em que aparece no código e então mostra: -e executado: +{% filename %}command-line{% endfilename %} $ python3 python_intro.py - Hey Sonja! + Perfeito, posso ouvir todos os detalhes -Viu o que aconteceu? +## Comentários + +Comentários são linhas que começam com `#`. Você pode escrever o que quiser após o # `` e o Python vai ignorar. Comentários podem tornar seu código mais fácil para outras pessoas entenderem. + +Vamos ver como funciona: + +{% filename %}python_intro.py{% endfilename %} + +```python +# Mudar o volume se estiver muito alto ou muito baixo +if volume < 20 or volume > 80 + volume = 50 + print("Bem melhor!") +``` + +Você não precisa escrever um comentário para cada linha de código, mas eles são úteis para explicar porque o seu código faz alguma coisa ou para fornecer um breve resumo de algo mais complexo. ### Sumário -Nos últimos três exercícios você aprendeu: +Nos últimos exercícios você aprendeu: -* **comparar as coisas** - em Python, você pode comparar as coisas usando os operadores `>`, `>=`, `==`, `<=`, `<` e o `and`, `or` -* **Booleano** - um tipo de objeto que só tem um dos dois valores: `True` ou `False` -* **Salvando arquivos** - armazenamento de código em arquivos assim você pode executar programas maiores. -* **if... elif... else** - instruções que permitem que você execute o código somente se determinadas condições forem atendidas. +- a **comparar coisas** - em Python, você pode comparar objetos usando os operadores `>`, `>=`, `==`, `<=`, `<` e `and`, `or`; +- **booleano** - um tipo de objeto que só tem dois valores possíveis: `True` ou `False`; +- a **salvar arquivos** - armazenar código em arquivos para que você possa executar programas maiores; +- **if... elif... else** - instruções que permitem que você execute o código somente se determinadas condições forem atendidas; +- **comentários** - linhas que o Python não executa e que permitem que você documente seu código. É hora da última parte deste capítulo! ## Suas próprias funções! -Se lembra de funções como `len()` que você pode executar no Python? Bem, boas notícias, agora você vai aprender a escrever suas próprias funções! +> Para leitoras em casa: esta parte do capítulo é abordada no vídeo [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0). + +Lembra de funções como `len()`? Boas notícias: agora você vai aprender como escrever suas próprias funções! + +Uma função é um sequência de instruções que o Python deve executar. Cada função em Python se inicia com a palavra reservada `def`, possui um nome e pode ter parâmetros. Vamos fazer uma tentativa. Substitua o código no **python_intro.py** com o seguinte: -Uma função é uma sequência de instruções que o Python deve executar. Cada função em Python começa com a palavra-chave `def`, seguido de um nome para a função e opcionalmente uma lista de parâmetros. Vamos começar com uma função simples. Substitua o código no **python_intro.py** com o seguinte: +{% filename %}python_intro.py{% endfilename %} ```python def hi(): - print('Hi there!') - print('How are you?') + print('Olá!') + print('Tudo bem?') hi() -``` +``` Ok, nossa primeira função está pronta! -Você pode se perguntar por que escrevemos o nome da função na parte inferior do arquivo. Isto é porque Python lê o arquivo e executa de cima para baixo. Então, para usar a nossa função, temos de escrevê-lo na parte inferior. +Você pode se perguntar por que escrevemos o nome da função na parte inferior do arquivo. Isto é porque Python lê o arquivo e executa-lo de cima para baixo. Então, para usar a nossa função, temos re-escrevê-lo na parte inferior. + +Vamos executá-lo agora e ver o que acontece: -Vamos executa-lo agora e ver o que acontece: +{% filename %}command-line{% endfilename %} $ python3 python_intro.py - Hi there! - How are you? + Olá! + Tudo bem? -Isso foi fácil! Vamos construir nossa primeira função com parâmetros. Usaremos o exemplo anterior - uma função que diz 'hi' para quem o executa - com um name: +Observação: se não funcionou, não entre em pânico! A saída (o output) vai te ajudar a entender o que aconteceu: + +- Se você recebeu uma mensagem `NameError`, provavelmente foi um erro de digitação, então confira se usou o mesmo nome ao criar a função com `def hi()` e quando a chamou no final com `hi()`. +- Se recebeu uma mensagem `IdentationError`, confira se as duas linhas de `print` têm o mesmo recuo no começo: o Python precisa que o código dentro da função esteja bem alinhado. +- Se a função não retornou nenhum resultado, certifique-se de que o útlimo `hi()`*não* esteja endentado - se ele estiver, essa linha vai se tornar parte da função e o Python não vai receber nenhum comando para executar. + +Foi fácil, né? Vamos construir nossa primeira função com parâmetros. Usaremos o exemplo anterior - uma função que diz 'olá' para quem o executa - com o nome dessa pessoa: + +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): -``` +``` Como você pode ver, agora demos um parâmetro chamado `name` para nossa função: +{% filename %}python_intro.py{% endfilename %} + ```python def hi(name): if name == 'Ola': - print('Hi Ola!') + print('Olá Ola!') elif name == 'Sonja': - print('Hi Sonja!') + print('Olá Sonja!') else: - print('Hi anonymous!') + print('Olá estranho!') hi() -``` +``` + +Não esqueça: a função `print` está endentada com 4 espaços depois do `if`. Isso é necessário porque a função só rodará se a condição for verdadeira. Vamos ver como isso funciona: -Como você pode ver, nós precisamos colocar dois espaços antes da função `print`, porque `if` precisa saber o que deve acontecer quando a condição for atendida. Vamos ver como isso funciona agora: +{% filename %}{{ warning_icon }} command-line{% endfilename %} $ python3 python_intro.py Traceback (most recent call last): @@ -620,109 +916,137 @@ Como você pode ver, nós precisamos colocar dois espaços antes da função `pr Oops, um erro. Felizmente, Python nos fornece uma mensagem de erro bastante útil. Ela diz que a função `hi()` (aquela que declaramos) tem um argumento obrigatório (chamado `name`) e que nós esquecemos de passá-lo ao chamar a função. Vamos corrigi-lo na parte inferior do arquivo: +{% filename %}python_intro.py{% endfilename %} + ```python hi("Ola") ``` -e execute novamente: +E rode novamente: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py - Hi Ola! + Olá Ola! E se mudarmos o nome? +{% filename %}python_intro.py{% endfilename %} + ```python hi("Sonja") -``` +``` + +E rode novamente: -e executá-lo: +{% filename %}command-line{% endfilename %} $ python3 python_intro.py - Hi Sonja! + Olá Sonja! -Agora, o que acha que vai acontecer se você escrever outro nome lá? (Sem ser Ola ou Sonja) Experimentá-lo e ver se você está certo. Ele deve imprimir isto: +Agora, o que você acha que aconteceria se escrevesse um outro nome (diferente de "Ola" ou "Sonja")? Faça um teste e veja se estava certa. Deve aparecer o seguinte: - Hi anonymous! +{% filename %}command-line{% endfilename %} + + Olá estranho! -Isto é incrível, não? Dessa maneira você não precisa se repetir (DRY - don't repeat yourself, ou em português, não se repita) cada vez que for mudar o nome da pessoa que a função pretende cumprimentar. E é exatamente por isso que precisamos de funções - você nunca quer repetir seu código! +Legal, né? Dessa maneira você não precisa se repetir (Dry - don't repeat yourself) cada vez que for mudar o nome da pessoa que a função pretende cumprimentar. E é exatamente por isso que precisamos de funções - você não quer precisar repetir seu código! + +Vamos fazer algo mais inteligente - há mais de dois nomes e escrever uma condição para cada um seria difícil, certo? Modifique o conteúdo do seu arquivo com o seguinte: -Vamos fazer algo mais inteligente..--existem mais que dois nomes, e escrever uma condição para cada um seria difícil, certo? +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): - print('Hi ' + name + '!') + print('Olá ' + name + '!') hi("Rachel") -``` +``` Vamos chamar o código agora: +{% filename %}command-line{% endfilename %} + $ python3 python_intro.py - Hi Rachel! + Olá Rachel! -Parabéns! Você acabou de aprender a criar funções :)! +Parabéns! Você acabou de aprender como criar funções. :) ## Laços -Já é a última parte. Foi rápido, não? :) +> Para leitoras em casa: esta parte do capítulo é abordada no vídeo [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0). -Como mencionamos, os programadores são preguiçosos, não gostam de repetir as mesmas coisas. Programação fala sobre como automatizar as coisas, então não queremos cumprimentar cada pessoa pelo seu nome manualmente, certo? É aí onde os laços vem a calhar. +Essa já é a última parte do capítulo! Rápido, né? :) + +Programadores não gostam de repetir código. Programar é automatizar coisas, então não queremos cumprimentar cada pessoa manualmente, certo? É aí que entram os laços (ou "loops", em Inglês). Ainda se lembra das listas? Vamos fazer uma lista de garotas: +{% filename %}python_intro.py{% endfilename %} + ```python -girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'você'] ``` -Queremos cumprimentar todas elas pelos seus nomes. Temos a função `hi` para fazer isso, então vamos usá-la em um loop: +Queremos cumprimentar todas elas pelos seus nomes. Temos a função `hi` para fazer isso, então vamos usá-la em um laço: + +{% filename %}python_intro.py{% endfilename %} ```python for name in girls: ``` -O `for` se comporta da mesma forma que o `if`, o código abaixo esses dois precisam ser recuados quatro espaços. +A instrução `for` se comporta de maneira similar ao `if`; o código abaixo de qualquer uma destas instrução deve ser endentado com quatro espaços. Aqui está o código completo que será salvo no arquivo: +{% filename %}python_intro.py{% endfilename %} + ```python def hi(name): - print('Hi ' + name + '!') + print('Olá ' + name + '!') -girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'você'] for name in girls: hi(name) - print('Next girl') + print('Próxima') ``` -e quando executá-lo: +E quando rodamos: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py - Hi Rachel! - Next girl - Hi Monica! - Next girl - Hi Phoebe! - Next girl - Hi Ola! - Next girl - Hi You! - Next girl + Olá Rachel! + Próxima + Olá Monica! + Próxima + Olá Phoebe! + Próxima + Olá Ola! + Próxima + Olá você! + Próxima -Como você pode ver, tudo o que você vai colocar dentro de uma instrução `for` com espaço será repetido para cada elemento da lista `girls`. +Como você pode ver, tudo o que colocar dentro de uma instrução `for` com endentação será repetido para cada elemento da lista `girls`. Você também pode usar o `for` em números usando a função `range`: +{% filename %}python_intro.py{% endfilename %} + ```python for i in range(1, 6): print(i) -``` +``` + +Que deve imprimir: -Que iria imprimir: +{% filename %}command-line{% endfilename %} 1 2 @@ -731,17 +1055,16 @@ Que iria imprimir: 5 -`range` é uma função que cria uma lista de números que se seguem um após o outro (esses números são dados por você como parâmetros). +`range` é uma função que cria uma lista de números que se seguem um após o outro (os números são dados por você como parâmetros). -Note que o segundo desses dois números não está incluído na lista que o Python mostrou (em `range(1, 6)`, conta de 1 a 5, mas o 6 não é incluído). +Note que o segundo desses dois números não está incluído na lista que o Python mostrou (em `range(1, 6)`, conta de 1 a 5, mas o 6 não é incluído). Isso porque o intervalo é semiaberto, o que significa que ele inclui o primeiro valor, mas não o último. ## Sumário -É isso. **Você é totalmente demais!** Não é tão fácil, então você deve se sentir orgulhosa de si mesma. Estamos definitivamente orgulhosas de você por ter chegado até aqui! +É isso. **Arrasou!** Esse foi um capítulo difícil, então você deve estar orgulhosa. Nós estamos orgulhosas de você por ter conseguido ir tão longe! -Talvez você queira brevemente fazer algo mais - espreguiçar, andar um pouco, descansar os olhos - antes de ir para o próximo capítulo. :) +Para um tutorial de Python oficial e completo, visite https://docs.python.org/3/tutorial/. Lá você encontrará um guia da linguagem mais exaustivo e completo. Até lá :) -![Cupcake](images/cupcake.png) +Talvez você queira fazer uma breve pausa - se espreguiçar, andar um pouco, descansar os olhos - antes de ir para o próximo capítulo. :) - [2]: /intro_to_command_line/README.html - [4]: ../code_editor/README.md +![Cupcake](images/cupcake.png) \ No newline at end of file diff --git a/pt/python_introduction/images/cupcake.png b/pt/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/pt/python_introduction/images/cupcake.png and b/pt/python_introduction/images/cupcake.png differ diff --git a/pt/template_extending/README.md b/pt/template_extending/README.md index a888a3ec111..dae006b6b08 100755 --- a/pt/template_extending/README.md +++ b/pt/template_extending/README.md @@ -1,12 +1,12 @@ # Estendendo os templates -Outra coisa boa que o Django tem pra você é o **template extending**. O que isso significa? Isso significa que você pode usar as mesmas partes do seu HTML em diferentes páginas do seu site. +Outra coisa boa que o Django tem para você é o **template extending** - extensão de templates. O que isso significa? Significa que você pode usar as mesmas partes do seu HTML em diferentes páginas do seu site. -Dessa forma você não precisa ficar se repetindo em cada arquivo quando quiser usar a mesma informação/layout. E se você quiser mudar alguma coisa não precisa fazer isso em todo template, só uma vez! +Templates ajudam quando você quer usar a mesma informação ou layout em mais de um lugar. Você não precisa se repetir em todos os arquivos. E, caso queira mudar algo, você não precisa fazê-lo em todos os templates, apenas em um! -## Criar template base +## Criando um template base -Um template base é o template mais básico que você estenderá em cada página do seu site. +Um template base é o template mais básico sobre o qual você construirá em cada página do seu site. Vamos criar um arquivo `base.html` na pasta `blog/templates/blog/`: @@ -17,10 +17,12 @@ Vamos criar um arquivo `base.html` na pasta `blog/templates/blog/`: post_list.html -Abra-o e copie tudo que está no arquivo `post_list.html` para `base.html`, desse jeito: +Em seguida, abra o arquivo no editor de código e copie tudo de `post_list.html` para `base.html`, desse jeito: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} Django Girls blog @@ -53,7 +55,9 @@ Abra-o e copie tudo que está no arquivo `post_list.html` para `base.html`, dess ``` -Então em `base.html`, substitua todo seu `` (tudo entre `` e ``) com isso: +Então, em `base.html`, substitua todo o seu `` (tudo entre `` e ``) por isso: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html @@ -71,16 +75,20 @@ Então em `base.html`, substitua todo seu `` (tudo entre `` e ` ``` -{% raw %}Basicamente nós substituimos tudo entre `{% for post in posts %}{% endfor %}` por:{% endraw %} +{% raw %}Você pode ver que essa ação substituiu tudo a partir de `{% for post in posts %}` até `{% endfor %}` por: {% endraw %} + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% block content %} {% endblock %} ``` -O que isso significa? Você acabou de criar um `block` (bloco), que é uma tag de template que te permite inserir HTML neste bloco em outros templates que estendem `base.html`. Nós vamos te mostrar como fazer isso já já. +Mas por quê? Você acabou de criar um `bloco`! Você usou o a etiqueta de template (template tag) `{% block %}` para criar uma área que terá HTML inserido nela. Esse HTML virá de outro template que vai estender este template (`base.html`). Nós vamos te mostrar como fazer isso já já. -Salve e abra o arquivo `blog/templates/blog/post_list.html` novamente. Apague exatamente tudo que não estiver dentro da tag body e apague também ``, de forma que o arquivo fique da seguinte maneira: +Agora, salve `base.html` e abra novamente o seu `blog/templates/blog/post_list.html` no editor de código. {% raw %} Remova tudo acima de `{% for post in posts %}` e abaixo de `{% endfor %}`. Quando terminar, o arquivo deve estar parecido com isso: {% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %} @@ -88,19 +96,35 @@ Salve e abra o arquivo `blog/templates/blog/post_list.html` novamente. Apague ex
{{ post.published_date }}
-

{{ post.title }}

+

{{ post.title }}

{{ post.text|linebreaksbr }}

{% endfor %} ``` -Agora adicione esta linha ao início do arquivo: +Queremos usar isso como parte do nosso template para todos os blocos de conteúdo. É hora de adicionar as tags (etiquetas) de blocos neste arquivo! + +{% raw %}Você quer que sua etiqueta de bloco coincida com a etiqueta no seu arquivo `base.html`. Você também quer que inclua todo o código que pertence aos seus blocos de conteúdo. Para isso, coloque tudo entre `{% block content %}` e `{% endblock %}`. Assim:{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -{% extends 'blog/base.html' %} +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} ``` -Isso significa que, agora, nós estamos estendendo o template `base.html` em `post_list.html`. Uma última coisa: colocar tudo (exceto pela linha que acabamos de adicionar) entre `{% block content %}` e `{% endblock content %}`. Como a seguir: +Só falta uma coisa. Precisamos juntar estes dois templates. Isto é o que significa 'estender templates'! Vamos fazer isso adicionando uma etiqueta de extensão ao início do arquivo. Assim: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% extends 'blog/base.html' %} @@ -111,13 +135,13 @@ Isso significa que, agora, nós estamos estendendo o template `base.html` em `po
{{ post.published_date }}
-

{{ post.title }}

+

{{ post.title }}

{{ post.text|linebreaksbr }}

{% endfor %} -{% endblock content %} +{% endblock %} ``` -É isso! Veja se o seu site ainda está funcionando direito :) +É isso! Salve o arquivo e veja se o seu site ainda está funcionando corretamente. :) -> Se ocorrer um erro de `TemplateDoesNotExists`, que diz que não existe nenhum arquivo chamado `blog/base.html` e se você tiver o `runserver` executando no terminal, tenta interrompê-lo (precionando Ctrl+C - o botão Control mais o botão C juntos) e reinicie ele rodando o comando `python manage.py runserver`. +> Se você receber o erro `TemplateDoesNotExist`, significa que não há um arquivo em `blog/base.html` e você está rodando o `runserver` na janela do terminal. Tente encerrá-lo (apertando Ctrl+C -- as teclas Control e C juntas) e reiniciá-lo rodando o comando `python manage.py runserver`. \ No newline at end of file diff --git a/pt/whats_next/README.md b/pt/whats_next/README.md index fb97dbb3627..988ea4e715f 100755 --- a/pt/whats_next/README.md +++ b/pt/whats_next/README.md @@ -1,39 +1,42 @@ -# O que vem depois? +# O que vem agora? -Parabéns! Você é **demais**. Estamos orgulhosos! <3 +Parabéns! Você **arrasou**. Estamos orgulhosas! <3 ### O que fazer agora? -Faça uma pausa e relaxe. Você acabou de fazer algo realmente grande. +Tire uma pausa e relaxe! Você acabou de fazer algo realmente grande. -Depois disso: +Depois disso, certifique-se de seguir o Django Girls no [Facebook](http://facebook.com/djangogirls) ou no [Twitter](https://twitter.com/djangogirls) para se manter atualizada. -* Siga Django girls no [Facebook][1] ou [Twitter][2] para ficar atualizada +### Vocês podem recomendar outras fontes de informação? - [1]: http://facebook.com/djangogirls - [2]: https://twitter.com/djangogirls +Sim! Existem *muitos* recursos online para aprender todos os tipos de habilidade de programação – pode ser bastante assustador decidir para onde prosseguir, mas nos te damos cobertura. Quaisquer que fossem seus interesses antes de vir à Django Girls, e quaisquer interesses você tenha adquirido ao longo do tutorial, aqui estão alguns recursos gratuitos (ou recursos com grandes partes gratuitas) que você pode usar para chegar até onde deseja estar. -### Você pode recomendar outras fontes? +#### Django -Sim! Primeiro, vá em frente e tente nosso outro livro, chamado [Django Girls Tutorial: Extensions][3]. +- Nosso outro livro: [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org/) +- [Tutorial oficial do Django](https://docs.djangoproject.com/en/2.0/intro/tutorial01/) +- [Começando com as aulas de vídeo do Django](http://www.gettingstartedwithdjango.com/) - [3]: http://djangogirls.gitbooks.io/django-girls-tutorial-extensions/ +#### HTML, CSS and JavaScript -Depois você pode tentar as fontes listadas abaixo. Todas elas são recomendadas! -- [Django's official tutorial][4] -- [New Coder tutorials][5] -- [Code Academy Python course][6] -- [Code Academy HTML & CSS course][7] -- [Django Carrots tutorial][8] -- [Learn Python The Hard Way book][9] -- [Getting Started With Django video lessons][10] -- [Two Scoops of Django: Best Practices for Django][11] book +- [Curso de desenvolvimento web do Codecademy](https://www.codecademy.com/learn/paths/web-development) +- [freeCodeCamp](https://www.freecodecamp.org/) - [4]: https://docs.djangoproject.com/en/1.8/intro/tutorial01/ - [5]: http://newcoder.io/tutorials/ - [6]: https://www.codecademy.com/en/tracks/python - [7]: https://www.codecademy.com/tracks/web - [8]: https://github.com/ggcarrots/django-carrots/ - [9]: http://learnpythonthehardway.org/book/ - [10]: http://gettingstartedwithdjango.com/ - [11]: https://twoscoopspress.org/products/two-scoops-of-django-1-6 +#### Python + +- [Curso de Python do Code Academy](https://www.codecademy.com/learn/learn-python) +- [Curso Python do Google](https://developers.google.com/edu/python/) +- Livro [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) - os exercícios iniciais são grátis +- [Tutoriais New Coder](http://newcoder.io/tutorials/) - uma variedade de exemplos práticos que você pode usar Python +- [edX](https://www.edx.org/course?search_query=python) – você pode assistir a maior parte dos cursos de graça, porem se você quiser um certificado ou créditos para validação em curso superior, então haverá um custo +- [Especialização em Python do Coursera](https://www.coursera.org/specializations/python) - alguns videos podem ser assistidos de graça e você pode ganhar um certificado por atender aos cursos +- [Python para todos](https://www.py4e.com/) - uma versão gratuita e aberta do Coursera Python para especialização de todo mundo + +#### Trabalhando com dados + +- [Codecademy curso de data science](https://www.codecademy.com/learn/paths/data-science) +- [edX](https://www.edx.org/course/?search_query=python&subject=Data%20Analysis%20%26%20Statistics) – você pode assistir a maior parte dos cursos de graça, porem se você quiser um certificado ou créditos para validação em curso superior, então haverá um custo +- [Dataquest](https://www.dataquest.io/) – as primeiras 30 "missões" são gratuitas + +Mal podemos esperar para ver o que você vai construir da próxima vez! \ No newline at end of file diff --git a/ru/README.md b/ru/README.md index 434fc3b8ab2..397afd30aa4 100755 --- a/ru/README.md +++ b/ru/README.md @@ -1,8 +1,16 @@ # Руководство 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) +[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -> Это руководство распространяется под международной лицензией Creative Commons Attribution-ShareAlike 4.0 Чтобы ознакомиться с содержанием этой лицензии, посети: https://creativecommons.org/licenses/by-sa/4.0/ +> Это руководство распространяется под международной лицензией Creative Commons Attribution-ShareAlike 4.0 +Чтобы ознакомиться с содержанием этой лицензии, посети: https://creativecommons.org/licenses/by-sa/4.0/ + +## Вступительное слово + +Добро пожаловать в руководство Django Girls! Мы рады тебя здесь видеть :) В этом руководстве мы заглянем за кулисы веб-технологий и дадим +базовое представление о тех вещах, которые собираются в общую картину веба таким, каким мы его знаем. + +Как и с любой незнакомой темой – это будет приключением. Но не волнуйся, тебе уже хватило смелости оказаться здесь, так что всё будет хорошо :) ## Введение @@ -22,12 +30,18 @@ ![Рисунок 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?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge). Мы попросили наших тренеров и успешно прошедших обучение участников заглядывать туда время от времени и помогать остальным! Не стесняйся задавать там свои вопросы! Хорошо, [давай начнем с начала...][3] [3]: ./how_the_internet_works/README.md +## Прохождение руководства дома + +Принимать участие в воркшопе Django Girls – это потрясающе, но мы понимаем, что не всегда есть такая возможность. Поэтому мы приветствуем прохождение +данного руководства дома. В настоящий момент мы готовим видео, которое поможет следовать руководству самостоятельно. Работа над ними ещё не закончена, +но все больше и больше тем скоро будут разобраны на YouTube-канале [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed). + ## Сотрудничество и дополнительная информация Это руководство поддерживается [DjangoGirls][4]. Если ты нашла ошибки или хочешь обновить информацию, пожалуйста, [следуй этим рекомендациям][5]. diff --git a/ru/SUMMARY.md b/ru/SUMMARY.md index 9fc224ba38a..9d90c4e53dc 100755 --- a/ru/SUMMARY.md +++ b/ru/SUMMARY.md @@ -2,6 +2,7 @@ * [Введение](README.md) * [Установка](installation/README.md) +* [Установка (chromebook)](chromebook_setup/README.md) * [Как работает Интернет](how_the_internet_works/README.md) * [Знакомство с командной строкой](intro_to_command_line/README.md) * [Установка Python](python_installation/README.md) @@ -12,7 +13,7 @@ * [Твой первый проект на Django!](django_start_project/README.md) * [Модели Django](django_models/README.md) * [Администрирование Django](django_admin/README.md) -* [Публикация!](deploy/README.md) +* [Публикация в Интернет!](deploy/README.md) * [URL-адреса Django](django_urls/README.md) * [Представления в Django – время создавать!](django_views/README.md) * [Введение в HTML](html/README.md) diff --git a/ru/chromebook_setup/README.md b/ru/chromebook_setup/README.md new file mode 100644 index 00000000000..e72aa319db3 --- /dev/null +++ b/ru/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# Настройка Chromebook + +> **Примечание** Если ты уже прошла раздел Установка, не нужно делать это снова – можно перейти прямо к [Введению в Python](../python_introduction/README.md) + +{% include "/chromebook_setup/instructions.md" %} diff --git a/ru/chromebook_setup/instructions.md b/ru/chromebook_setup/instructions.md new file mode 100644 index 00000000000..b2a16f03a76 --- /dev/null +++ b/ru/chromebook_setup/instructions.md @@ -0,0 +1,98 @@ +Если ты не используешь Chromebook, можешь пропустить эту секцию. +В противном случае процесс установки будет немного другим, и тебе нужно будет пройти только эту инструкцию по установке. + + +### Облачная IDE (PaizaCloud Cloud IDE, AWS Cloud9) + +Облачная IDE — это инструмент, который предоставляет тебе редактор кода и доступ к компьютеру, +запущенному в интернете. На этом удалённом компьютере ты можешь устанавливать, создавать и запускать программы. +На время прохождения этого руководства облачная IDE будет вести себя как _локальный компьютер_. +Ты будешь так же, как и другие участницы с macOS, Ubuntu или Windows, выполнять команды в командной строке, +но она будет подключена к компьютеру облачной IDE, который находится где-то в другом месте. + +Ниже ты увидишь инструкции для настройки облачных IDE (PaizaCloud Cloud IDE, AWS Cloud9). +Ты можешь выбрать одну из них и выполнить соответствующие действия. + +#### PaizaCloud Cloud IDE + +1. Перейди на сайт [PaizaCloud Cloud IDE](https://paiza.cloud/) +2. Войди в свой аккаунт +3. Нажми _New Server_ +4. Нажми кнопку Terminal (в левой части окна) + +Теперь ты должна увидеть интерфейс с боковой панелью, кнопки расположены слева. +Нажми кнопку "Terminal", чтобы открыть командную строку. Ты увидишь приглашение командной строки: + +{% filename %}Terminal{% endfilename %} +``` +$ +``` + +Командная строка в PaizaCloud Cloud IDE готова к твоим командам. +Ты можешь изменить размер этого окна, чтобы сделать его немного больше. + + +#### AWS Cloud9 + +1. Перейди на сайт [AWS Cloud9](https://aws.amazon.com/cloud9/) +2. Войди в свой аккаунт +3. Нажми _Create Environment_ + +Теперь ты должна увидеть интерфейс с боковой панелью, большим основным окном с текстом, +а также маленьким окошком снизу, которое выглядит как-то так: + +{% filename %}bash{% endfilename %} +``` +yourusername:~/workspace $ +``` + +Эта область внизу и есть твоя командная строка. Ты можешь использовать её, чтобы давать команды +удалённому компьютеру в Cloud9. Ты можешь изменить размер этого окна, чтобы сделать его немного больше. + + +### Виртуальное окружение + +Виртуальное окружение (его также называют virtualenv) похоже на личную коробку, куда мы можем +сложить полезный код для проекта, над которым работаем. Виртуальные окружения нужны нам, чтобы держать отдельно +разные кусочки кода для наших проектов — так они не перемешаются между разными проектами. + +В твоей командной строке в нижней части интерфейса Cloud 9 запусти следующие команды: + +{% filename %}Cloud 9{% endfilename %} +``` +sudo apt update +sudo apt install python3.6-venv +``` + +Если они не сработают, попроси своего тренера помочь. + +Далее запусти: + +{% filename %}Cloud 9{% endfilename %} +``` +mkdir djangogirls +cd djangogirls +python3.6 -mvenv myvenv +source myvenv/bin/activate +pip install django~={{ book.django_version }} +``` + +(обрати внимание, что в последней строчке мы используем сочетание тильды и знака равенства: `~=`). + +### GitHub + +Создай аккаунт на [GitHub](https://github.com). + +### PythonAnywhere + +Руководство Django Girls включает в себя раздел «Публикация». Этим словом описывается процесс, +когда ты переносишь код, запускающий твоё новое веб-приложение, на публично доступный компьютер +(он называется сервер), чтобы другие люди могли видеть результаты твоей работы. + +Если ты проходишь это руководство на Chromebook, этап публикации может выглядеть немного нетипично, так как +для разработки мы уже используем удалённый компьютер где-то в интернете (а, например, не мощности своего ноутбука). +Тем не менее, будет полезно пройти раздел «Публикация», ведь мы можем рассматривать наше рабочее пространство +в Cloud9 или PaizaCloud как место для незавершенной работы, а PythonAnywhere как место +для демонстрации законченных дел. + +Так что тебе нужно будет завести аккаунт на сайте [www.pythonanywhere.com](https://www.pythonanywhere.com). diff --git a/ru/code_editor/README.md b/ru/code_editor/README.md index 5a63261e934..326200c4c9a 100755 --- a/ru/code_editor/README.md +++ b/ru/code_editor/README.md @@ -1,7 +1,11 @@ # Текстовый редактор -Приступаем к написанию первых строк кода - пора загрузить текстовый редактор! +> Для проходящих курс дома: эта глава рассмотрена в видео [Installing Python & Code Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s). -> **Примечание**: Если ты уже все сделала в главе, посвященной установке, то можешь смело переходить к следующей главе! +Приступаем к написанию первых строк кода — пора загрузить текстовый редактор! -{% include "/code_editor/instructions.md" %} \ No newline at end of file +> **Примечание:** Если ты используешь Chromebook, пропусти эту главу и следуй инструкциям в [Chromebook Setup](../chromebook_setup/README.md). Облачная IDE, которую ты выбрала (PaizaCloud Cloud IDE или AWS Cloud9), включает в себя редактор кода, и когда ты откроешь файл в IDE из файлового меню, редактор будет использоваться автоматически. + +> **Примечание:** если ты уже все сделала в главе, посвященной установке, то можешь смело переходить к следующей главе! + +{% include "/code_editor/instructions.md" %} diff --git a/ru/code_editor/instructions.md b/ru/code_editor/instructions.md index e37368ddbb4..ab2aea568ad 100755 --- a/ru/code_editor/instructions.md +++ b/ru/code_editor/instructions.md @@ -1,6 +1,6 @@ -Существует много различных редакторов и в основном все сводится к личным предпочтениям. Большинство Python программистов используют сложные, но чрезвычайно мощные IDE (англ. Integrated Development Environments - Интегрированные среды разработки), такие как PyCharm. Однако они, вероятно, не очень подходят для начинающих; мы предлагаем столь же мощные, но куда более простые варианты. +Существует много различных редакторов, и в основном все сводится к личным предпочтениям. Большинство Python-программистов используют сложные, но чрезвычайно мощные IDE (англ. Integrated Development Environments — Интегрированные среды разработки), такие как PyCharm. Однако они, вероятно, не очень подходят для начинающих; мы предлагаем столь же мощные, но куда более простые варианты. -Ниже приведен перечень наших предпочтений, но также можешь попросить совета у своего тренера - будет проще получить помощь от него. +Ниже приведен перечень наших предпочтений, но также можешь попросить совета у своего тренера — будет проще получить помощь от него. ## Gedit @@ -8,24 +8,24 @@ Gedit является открытым, бесплатным редакторо [Скачать его можно здесь](https://wiki.gnome.org/Apps/Gedit#Download) -## Sublime Text 3 +## Sublime Text -Sublime Text - это очень популярный текстовый редактор с бесплатным пробным периодом. Он легко устанавливается и прост в использовании, а также доступен для всех операционных систем. +Sublime Text — это очень популярный текстовый редактор с бесплатным пробным периодом. Он легко устанавливается и прост в использовании, а также доступен для всех операционных систем. -[Скачать его можно здесь](https://www.sublimetext.com/3) +[Скачать его можно здесь](https://www.sublimetext.com/) ## Atom -Atom - это новейший текстовый редактор от [GitHub](https://github.com/). Он является бесплатным, открытым, легко устанавливается и прост в использовании. Доступен для Windows, OSX и Linux. +Atom — это новейший текстовый редактор от [GitHub](https://github.com/). Он является бесплатным, открытым, легко устанавливается и прост в использовании. Доступен для Windows, OSX и Linux. [Скачать его можно здесь](https://atom.io/) ## Зачем нам нужен редактор кода? -Ты можешь спросить - зачем устанавливать отдельную программу для редактирования кода, если можно использовать Word или Notepad. +Ты можешь спросить — зачем устанавливать отдельную программу для редактирования кода, если можно использовать Word или Notepad? -Во-первых, код должен должен храниться в виде **простого текста**, а проблема таких программ, как Word или Textedit в том, что они не сохраняют файлы в этом виде, а используют "обогащенный" текст (с форматированием и шрифтами), например, [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format). +Во-первых, код должен должен храниться в виде **простого текста**, а проблема таких программ, как Word или Textedit в том, что они не сохраняют файлы в этом виде, а используют "обогащённый" текст (с форматированием и шрифтами), например, [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format). -Вторая причина в том, что специализированные редакторы предоставляют множество полезных для программирования возможностей, такие как цветную подсветку кода в зависимости от его смысла и автоматически закрывающиеся кавычки. +Вторая причина в том, что специализированные редакторы предоставляют множество полезных для программирования возможностей, таких как цветная подсветка кода в зависимости от его смысла и автоматически закрывающиеся кавычки. -Позже мы увидим все это в действии. Скоро ты начнешь думать о своем редакторе кода как о проверенном любимом инструменте :) \ No newline at end of file +Позже мы увидим всё это в действии. Скоро ты начнешь думать о своем редакторе кода как о проверенном любимом инструменте :) diff --git a/ru/css/README.md b/ru/css/README.md index 64fc384a1fe..99c70cd6adf 100755 --- a/ru/css/README.md +++ b/ru/css/README.md @@ -1,26 +1,27 @@ -# CSS - сделай это красиво! +# CSS — сделай это красиво! -Наш блог все еще выглядит довольно скверно, не так ли? Пора сделать его красивым! Для этого будем использовать CSS. +Наш блог всё ещё выглядит довольно скверно, не так ли? Пора сделать его красивым! Для этого будем использовать CSS. ## Что такое CSS? -Каскадные таблицы стилей (англ. Cascading Style Sheets или сокращенно CSS) - специальный язык, используемый для описания внешнего вида и форматирования сайта, написанного на языке разметки (как HTML). Воспринимай это, как своего рода макияж для нашей веб-страницы ;). +Каскадные таблицы стилей (англ. Cascading Style Sheets, или сокращённо CSS) — специальный язык, используемый для описания внешнего вида и форматирования сайта, написанного на языке разметки (как HTML). Воспринимай это как своего рода макияж для нашей веб-страницы ;) -Но мы же не хотим начинать все с нуля, правда? Мы просто снова возьмем что-то, что уже было создано программистами и опубликовано в Интернете для свободного пользования. Ты же знаешь, заново изобретать велосипед совсем не весело. +Но мы же не хотим начинать всё с нуля, правда? Мы просто снова возьмём что-то, что уже было создано программистами и опубликовано в Интернете для свободного пользования. Ты же знаешь, заново изобретать велосипед совсем не весело. ## Давай использовать Bootstrap! -Bootstrap - один из наиболее популярных HTML и CSS фреймворков для разработки красивых сайтов: https://getbootstrap.com/ +Bootstrap — один из наиболее популярных HTML и CSS фреймворков для разработки красивых сайтов: https://getbootstrap.com/ -Он был написан программистами, которые работали в Twitter, а сейчас совершенствуется волонтерами со всего мира. +Он был написан программистами, которые работали в Twitter, а сейчас совершенствуется волонтёрами со всего мира. ## Установка Bootstrap Для установки Bootstrap тебе нужно добавить следующие строки в `` твоего `.html` файла (`blog/templates/blog/post_list.html`): +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - - + + ``` Это не добавит ни одного файла к твоему проекту. Эти строки просто указывают на файлы, опубликованные в Интернете. Просто продолжай, открой свой веб-сайт и обнови страницу. Вот и результат! @@ -37,104 +38,109 @@ Bootstrap - один из наиболее популярных HTML и CSS фр ### Куда поместить статические файлы в Django -Как ты видела при выполнении команды `collectstatic` на сервере, Django уже знает где искать статические файлы для встроенного приложения "admin". Теперь нам нужно добавить статические файлы для своего приложения `blog`. +Django уже знает, где искать статические файлы для встроенного приложения "admin". Теперь нам нужно добавить статические файлы для своего приложения `blog`. Мы сделаем это, создав папку `static` внутри каталога с нашим приложением: ``` - djangogirls - ├── blog - │ ├── migrations - │ └── static - └── mysite +djangogirls +├── blog +│ ├── migrations +│ ├── static +│   └── templates +└── mysite ``` -Django будет автоматически находить папки "static" внутри всех каталогов твоих приложений и сможет использовать их содержимое в качестве статических файлов. +Django будет автоматически находить папки `static` внутри всех каталогов твоих приложений и сможет использовать их содержимое в качестве статических файлов. ## Твой первый CSS файл! -Давай создадим CSS файл, чтобы добавить свой собственный стиль для твоей web-страницы. Создай новую папку под названием `css` внутри твоей папки `static`. Затем создайте новый файл под названием `blog.css` внутри папки `css`. Готова? +Давай создадим CSS файл, чтобы добавить свой собственный стиль для твоей веб-страницы. Создай новую папку под названием `css` внутри твоей папки `static`. Затем создай новый файл под названием `blog.css` внутри папки `css`. Готово? ``` - djangogirls - └─── blog - └─── static - └─── css - └─── blog.css +djangogirls +└─── blog + └─── static + └─── css + └─── blog.css ``` Пришло время написать несколько строк CSS! Открой файл `blog/static/css/blog.css` в своем редакторе кода. -Мы не будем здесь погружаться слишком глубоко в процесс настройки и изучения CSS, поскольку это так просто, что ты сможешь изучить этот материал самостоятельно после этого руководства. Мы настоятельно рекомендуем пройти этот курс [Codeacademy HTML & CSS course][2], чтобы изучить все, что тебе нужно знать об оформлении веб-сайтов с помощью CSS. +Мы не будем здесь погружаться слишком глубоко в процесс настройки и изучения CSS, поскольку это так просто, что ты сможешь изучить этот материал самостоятельно после этого руководства. В конце этой главы мы порекомендуем тебе бесплатный курс для дальнейшего изучения. - [2]: https://www.codecademy.com/tracks/web - -Но давай сделаем хотя бы немного. Возможно, мы могли бы изменить цвет заголовка? Чтобы понимать цвета, компьютеры используют специальные коды. Они начинаются с `#` и далее следуют 6 букв (A-F) и цифр (0-9). Ты можешь найти коды цветов, например, здесь: http://www.colorpicker.com/. Также можешь пользоваться [предопределенными цветами][3], такими как `red` и `green`. +Но давай сделаем хотя бы немного. Возможно, мы могли бы изменить цвет заголовка? +Чтобы понимать цвета, компьютеры используют специальные коды. Они начинаются с `#` и далее следуют 6 букв (A-F) и цифр (0-9). Ты можешь найти коды цветов, например, здесь: http://www.colorpicker.com/. Также можешь пользоваться [предопределенными цветами][3], такими как `red` и `green`. [3]: http://www.w3schools.com/cssref/css_colornames.asp В файле `blog/static/css/blog.css` тебе нужно добавить следующий код: +{% filename %}blog/static/css/blog.css{% endfilename %} ```css - h1 a { - color: #FCA205; - } +h1 a { + color: #FCA205; +} ``` -`h1 a` это CSS селектор. Это означает, что мы применяем наши стили к каждому элементу `a` внутри элемента `h1` (например, когда мы имеем в коде что-то вроде: `

link

`). В этом случае мы говорим о том, что нужно изменить цвет элемента на `#FCA205`, то есть на оранжевый. Конечно, ты можешь указать свой собственный цвет! +`h1 a` — это CSS-селектор. Это означает, что мы применяем наши стили к каждому элементу `a` внутри элемента `h1` (например, когда у нас в коде что-то вроде: `

link

`). В этом случае мы говорим о том, что нужно изменить цвет элемента на `#FCA205`, то есть на оранжевый. Конечно, ты можешь указать свой собственный цвет! В CSS файле мы определяем стили для элементов файла HTML. Элементы идентифицируются именами (то есть `a`, `h1`, `body`), атрибутом `class` или атрибутом `id`. Class и id – это имена, которые ты сама присваиваешь элементам. Классы (сlass) определяют группы элементов, а идентификаторы (id) указывают на конкретные элементы. Например, следующий тег может быть идентифицирован CSS с использованием имени тега `a`, класса `external_link` или идентификатора `link_to_wiki_page`: ```html - + ``` -Почитай про CSS селекторы в [CSS Selectors in w3schools][4]. +Почитай про CSS селекторы в [CSS Selectors на w3schools][4]. [4]: 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 staticfiles %} +{% load static %} ``` -Мы просто загружаем здесь статические файлы :). Далее между `` и ``, после ссылок на файлы Bootstrap CSS (браузер читает файлы в порядке их следования, поэтому код нашего файла может переопределить код в файлах Bootstrap) добавь эту строку: +Мы просто загружаем здесь статические файлы :) +Далее между `` и ``, после ссылок на файлы Bootstrap CSS, добавь такую строку: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - + ``` - +Браузер читает файлы в порядке их следования, поэтому нам необходимо удостовериться, что файл расположен в необходимом месте. Иначе код нашего файла может переопределить код в файлах Bootstrap. Мы только что сказали нашему шаблону, где находится наш CSS файл. Твой файл должен теперь выглядеть следующим образом: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - {% load staticfiles %} - - - Django Girls blog - - - - - +{% load static %} + + + Django Girls blog + + + + + + + + {% for post in posts %}
-

Django Girls Blog

+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

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

published: {{ post.published_date }}

-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

-
- {% endfor %} - - + {% endfor %} + + ``` -ОК, сохрани файл и обнови страницу! +Ок, сохрани файл и обнови страницу! ![Рисунок 14.2][5] @@ -142,10 +148,11 @@ Django будет автоматически находить папки "static Отличная работа! Может быть, мы также хотели бы добавить нашему веб-сайту немного пространства и увеличить отступ слева? Давай попробуем! +{% filename %}blog/static/css/blog.css{% endfilename %} ```css - body { - padding-left: 15px; - } +body { + padding-left: 15px; +} ``` Добавь это к твоему CSS, сохрани файл и посмотри, как это работает! @@ -156,19 +163,21 @@ Django будет автоматически находить папки "static Возможно, мы можем настроить шрифт нашего заголовка? Вставь это внутрь тега `` в файле `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). Теперь добавь строку `font-family: 'Lobster';` в CSS файле `blog/static/css/blog.css` внутри блока определения стиля `h1 a` (код помещается между скобками `{` и `}`) и обнови страницу: +{% filename %}blog/static/css/blog.css{% endfilename %} ```css - h1 a { - color: #FCA205; - font-family: 'Lobster'; - } +h1 a { + color: #FCA205; + font-family: 'Lobster'; +} ``` ![Рисунок 14.3][7] @@ -177,120 +186,124 @@ Django будет автоматически находить папки "static Отлично! -Как было указано выше, CSS имеет концепцию классов, которая позволяет назвать часть HTML кода и применять стили только для этой части без всякого эффекта для других. Это очень полезно если у вас есть скажем два блока div, но они выполняют совершенно разные функции (как ваш заголовок и пост), следовательно, вы не хотите, чтобы они выглядели одинаково. +Как было указано выше, в CSS используется концепция классов, которая позволяет назвать часть HTML кода и применять стили только для этой части без всякого эффекта для других. Это очень полезно, если у тебя есть, скажем, два блока div, но они выполняют совершенно разные функции (как ваш заголовок и пост), следовательно, ты не хочешь, чтобы они выглядели одинаково. -Дайте имена определенным частям HTML кода. Добавьте класс под названием `page-header` в блок `div`, содержащий ваш заголовок, как это сделано здесь: +Дадим имена определённым частям HTML кода. Добавь класс под названием `page-header` в блок `div`, содержащий наш заголовок, как это сделано здесь: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - + ``` -А теперь добавьте класс `post` в ваш `div`, содержащий сообщение в блоге. +А теперь добавь класс `post` в твой `div`, содержащий сообщение в блоге: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -
-

published: {{ post.published_date }}

-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

-
+
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
``` -А теперь добавим определения блоков для различных селекторов. Селекторы, которые начинают с символа `.` относятся к классам. Существует много хороших справочников о CSS в Интернете, которые могут помочь вам понять следующий код. А теперь, просто скопируй и вставь код в файл `djangogirls/static/css/blog.css`: +Теперь добавим определения блоков для различных селекторов. Селекторы, которые начинают с символа `.`, относятся к классам. В Интернете много хороших справочников по CSS, которые могут помочь тебе понять следующий код. А сейчас просто скопируй и вставь код в файл `djangogirls/static/css/blog.css`: +{% filename %}blog/static/css/blog.css{% endfilename %} ```css - .page-header { - background-color: #ff9400; - margin-top: 0; - padding: 20px 20px 20px 40px; - } - - .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 { - font-family: 'Lobster', cursive; - } - - .date { - float: right; - color: #828282; - } - - .save { - float: right; - } - - .post-form textarea, .post-form input { - width: 100%; - } - - .top-menu, .top-menu:hover, .top-menu:visited { - color: #ffffff; - float: right; - font-size: 26pt; - margin-right: 20px; - } - - .post { - margin-bottom: 70px; - } - - .post h1 a, .post h1 a:visited { - color: #000000; - } +.page-header { + background-color: #ff9400; + margin-top: 0; + padding: 20px 20px 20px 40px; +} + +.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 { + font-family: 'Lobster', cursive; +} + +.date { + color: #828282; +} + +.save { + float: right; +} + +.post-form textarea, .post-form input { + width: 100%; +} + +.top-menu, .top-menu:hover, .top-menu:visited { + color: #ffffff; + float: right; + font-size: 26pt; + margin-right: 20px; +} + +.post { + margin-bottom: 70px; +} + +.post h1 a, .post h1 a:visited { + color: #000000; +} ``` -Далее переделайте HTML код, отображающий посты. замените: +Далее переделаем код HTML, отображающий посты, используя классы. Замени: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - {% for post in posts %} -
-

published: {{ post.published_date }}

-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

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

published: {{ post.published_date }}

+

{{ 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 %} -
-
- {{ post.published_date }} -
-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

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

Опубликовано: {{ post.published_date }}

- {% endfor %} -
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %}
+
``` -Сохраните эти файлы и обновить свой веб-сайт. +Сохрани эти файлы и обнови свой веб-сайт. ![Рисунок 14.4][8] [8]: images/final.png -Юхууу! Выглядит прекрасно, не так ли? Код, который мы только что вставили в действительности не является сложным для понимания и вы должны быть в состоянии понять большую его часть просто прочитав. +Юхууу! Выглядит прекрасно, не так ли? Код, который мы только что вставили, на самом деле не сложный для понимания, и ты, просто прочитав его, сможешь понять большую часть. -Не бойтесь немного повозиться с этим CSS файлом и попробуйте поменять некоторые вещи. Если что-то сломается, не волнуйтесь, вы всегда можете отменить предыдущее действие! +Не бойся немного повозиться с этим CSS-файлом и попробуй поменять некоторые вещи. Если что-то сломается, не волнуйся, ты всегда можешь отменить предыдущее действие! -В любом случае, мы настоятельно рекомендуем пройти этот бесплатный онлайн курс [Codeacademy HTML & CSS course ][2] как своеобразную домашнюю работу после воркшопа чтобы изучить все, что нужно знать об оформлении ваших веб-сайтов с CSS. +В любом случае, мы настоятельно рекомендуем пройти бесплатный онлайн курс [Codeacademy HTML & CSS course](https://www.codecademy.com/tracks/web) в виде домашней работы после воркшопа, чтобы изучить всё, что нужно знать об оформлении веб-сайтов с помощью CSS. -Готовы к следующей главе?! :) +Готова к следующей главе?! :) diff --git a/ru/css/images/bootstrap1.png b/ru/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/ru/css/images/bootstrap1.png and b/ru/css/images/bootstrap1.png differ diff --git a/ru/css/images/color2.png b/ru/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/ru/css/images/color2.png and b/ru/css/images/color2.png differ diff --git a/ru/css/images/final.png b/ru/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/ru/css/images/final.png and b/ru/css/images/final.png differ diff --git a/ru/css/images/font.png b/ru/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/ru/css/images/font.png and b/ru/css/images/font.png differ diff --git a/ru/css/images/margin2.png b/ru/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/ru/css/images/margin2.png and b/ru/css/images/margin2.png differ diff --git a/ru/deploy/README.md b/ru/deploy/README.md index 27d374a1ccd..0b5ddb8ce89 100755 --- a/ru/deploy/README.md +++ b/ru/deploy/README.md @@ -1,98 +1,107 @@ -# Разверните! +# Публикация в Интернете! > **Примечание**: Эта глава может показаться сложной. Будь упорна, развертывание сайта на сервере является важной частью веб-разработки. Данная глава намеренно расположена в середине учебника для того, чтобы твой наставник смог помочь с таким мудреным процессом, как публикация сайта. Так ты сможешь самостоятельно закончить все главы, даже если время будет поджимать. -До настоящего момента твой сайт был доступен только для локального просмотра, теперь же ты узнаешь как развернуть его на удаленном сервере! Развертывание (deploy) — это процесс публикации приложения в интернете, чтобы люди могли наконец увидеть твое творение :). +До настоящего момента твой сайт был доступен только для локального просмотра, теперь же ты узнаешь, как развернуть его на удалённом сервере! Развертывание (deploy) — это процесс публикации приложения в интернете, чтобы люди могли наконец увидеть твое творение :) -Как ты уже знаешь, веб-сайт должен располагаться на сервере. Есть много компаний, предоставляющих сервера в интернете. Мы воспользуемся услугами одной из них, с довольно простым процессом публикации: [PythonAnywhere][1]. PythonAnywhere бесплатен для маленьких приложений с небольшим числом посетителей, и этого будет более чем достаточно для нас. +Как ты уже знаешь, веб-сайт должен располагаться на сервере. Есть много компаний, предоставляющих сервера в интернете. Мы воспользуемся услугами одной из них, с довольно простым процессом публикации: [PythonAnywhere][1]. PythonAnywhere бесплатен для маленьких приложений с небольшим числом посетителей, и этого будет для нас более чем достаточно. - [1]: https://pythonanywhere.com/ + [1]: https://www.pythonanywhere.com/ -Другим внешним сервисом, которым мы будем пользоваться, является [GitHub][2] — сервис хостинга кода. Существуют и другие похожие сервисы, но практически у каждого программиста есть GitHub аккаунт, теперь будет и у тебя! +Другим внешним сервисом, которым мы воспользуемся, будет [GitHub][2] — сервис хостинга кода. Существуют и другие похожие сервисы, но практически у каждого программиста есть GitHub аккаунт, теперь будет и у тебя! [2]: https://www.github.com -Мы будем использовать GitHub для передачи нашего кода PythonAnywhere и обратно. +В итоге твой код будет в трёх местах. На локальном компьютере ты будешь заниматься разработкой и тестированием. Когда результат тебя устроит, ты загрузишь свою программу на GitHub. А твой сайт будет на PythonAnywhere, и ты сможешь обновлять его, просто загружая новую версию кода с GitHub. # Git -Git — это "система управления версиями", используемая множеством программистов. Эта программа отслеживает изменения, происходящие с файлами, чтобы впоследствии можно было восстановить состояние кода на нужный момент времени. Это немного похоже на функцию отслеживания изменений в Microsoft Word, но куда мощнее. - -## Установка Git - -> **Примечание** Если вы уже выполнили установку, незачем повторять её вновь — вы можете сразу переходить к следующему разделу и начать создание собственного Git репозитория. +> **Примечание:** если ты уже выполнила установку, незачем повторять её вновь — можешь сразу переходить к следующему разделу и начать создание собственного Git-репозитория. {% include "/deploy/install_git.md" %} ## Создаём Git-репозиторий -Git отслеживает изменения определенного набора файлов, который называется репозиторием (сокращенно "репо"). Давайте создадим один для нашего проекта. Откройте консоль и запустите эти команды в папке `djangogirls`: - -> **Заметка**: Проверь текущий рабочий каталог с помощью команд `pwd` (OSX/Linux) или `cd` (Windows) прежде чем инициализировать новый репозиторий. Ты должна находиться в директории `djangogirls`. +Git отслеживает изменения определенного набора файлов, который называется репозиторием (сокращенно "репо"). Давайте создадим такой для нашего проекта. Открой консоль и запусти эти команды в папке `djangogirls`: - $ git init - Initialized empty Git repository in ~/djangogirls/.git/ - $ git config --global user.name "Your Name" - $ git config --global user.email you@example.com +> **Примечание:** проверь текущий рабочий каталог с помощью команд `pwd` (OSX/Linux) или `cd` (Windows) перед инициализацией нового репозитория. Ты должна находиться в директории `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-репозиторий придется только один раз за проект (и тебе больше не придется вводить имя пользователя и адрес электронной почты). Git будет отслеживать изменения всех файлов и каталогов в заданной директории, однако некоторые из них мы предпочли бы игнорировать. Для этого нам нужно создать файл `.gitignore` в корневом каталоге репозитория. Открой редактор и создай новый файл со следующим содержанием: - *.pyc - __pycache__ - myvenv - db.sqlite3 - .DS_Store - +{% filename %}.gitignore{% endfilename %} +``` +*.pyc +*~ +__pycache__ +myvenv +db.sqlite3 +/static +.DS_Store +``` И сохрани его как `.gitignore` в корневом каталоге "djangogirls". -> **Примечание**: Точка в начале имени файла имеет важное значение! Если у тебя есть проблемы с созданием таких файлов (Mac не позволит создать файл с названием, начинающимся с точки, через Finder, например), тогда используй кнопку "Сохранить как" в меню своего редактора кода, это точно поможет. +> **Примечание:** точка в начале имени файла имеет важное значение! Если у тебя есть проблемы с созданием таких файлов (Mac не позволит создать файл с названием, начинающимся с точки, через Finder, например), тогда используй кнопку «Сохранить как» в меню своего редактора кода, это точно поможет. -Используй команду `git status` перед `git add` или в любой другой момент, когда ты не уверена, что изменения — хорошая идея. Это убережёт тебя от таких неприятных сюрпризов как добавление неправильных файлов. Команда `git status` возвращает информацию обо всех ранее неотслеживаемых/изменённых/добавленных в git файлах, а также статус ветки и многое другое. Результат должен быть похож на: +> **Примечание:** среди файлов, которые мы перечислили в `.gitignore`, есть `db.sqlite3`. Этот файл содержит твою локальную базу данных, где будут храниться твои посты. Мы не добавляем его в репозиторий, поскольку твой сайт на PythonAnywhere будет использовать другую базу данных. Эта база данных тоже может быть SQLite, как на твоём рабочем компьютере, но обычно используется MySQL, которая может справиться с большим количеством посетителей, чем SQLite. В любом случае, поскольку мы не копируем базу данных SQLite на GitHub, все посты, которые ты уже создала, будут доступны только на твоём локальном компьютере, и тебе придётся заново создать их на опубликованном сайте. Рассматривай свою локальную базу данных как удобную игровую площадку, где ты можешь тестировать различные идеи и не бояться удалить настоящий пост из своего блога. - $ git status - On branch master +Используй команду `git status` перед `git add` или в любой другой момент, когда ты не уверена, что изменения — хорошая идея. Это убережёт тебя от таких неприятных сюрпризов, как добавление неправильных файлов. Команда `git status` возвращает информацию обо всех ранее неотслеживаемых/изменённых/добавленных в git файлах, а также статус ветки и многое другое. Результат должен быть похож на: - Initial commit +{% filename %}command-line{% endfilename %} +``` +$ git status +On branch master - Untracked files: - (use "git add ..." to include in what will be committed) +No commits yet - .gitignore - blog/ - manage.py - mysite/ +Untracked files: + (use "git add ..." to include in what will be committed) - nothing added to commit but untracked files present (use "git add" to track) + .gitignore + blog/ + manage.py + mysite/ +nothing added to commit but untracked files present (use "git add" to track) +``` И, наконец, мы сохраним наши изменения. Переключись на консоль и набери: - $ git add --all . - $ git commit -m "My Django Girls app, first commit" - [...] - 13 files changed, 200 insertions(+) - create mode 100644 .gitignore - [...] - create mode 100644 mysite/wsgi.py +{% filename %}command-line{% endfilename %} +``` +$ git add --all . +$ git commit -m "My Django Girls app, first commit" + [...] + 13 files changed, 200 insertions(+) + create mode 100644 .gitignore + [...] + create mode 100644 mysite/wsgi.py + ``` ## Загружаем код в репозиторий GitHub -Зайди на [GitHub.com][2] и создай новую бесплатную учётную запись. (если это уже сделано во время подготовки к воркшопу — здорово!) +Зайди на [GitHub.com][2] и создай новую бесплатную учётную запись (если это уже сделано во время подготовки к воркшопу — здорово!). Убедись, что запомнила свой пароль (добавь его в свой менеджер паролей, если им пользуешься). -Затем создай новый репозиторий и назови его "my-first-blog". Не выбирай опцию "initialise with a README", не создавай файл .gitignore (мы сделаем это локально сами) и оставь Лицензию None. +Затем создай новый репозиторий и назови его "my-first-blog". Не выбирай опцию "initialise with a README", не создавай файл .gitignore (мы уже сделали это сами) и оставь лицензию None. ![][3] [3]: images/new_github_repo.png -> **Примечание**: Имя репозитория `my-first-blog` имеет для нас большую важность -- ты можешь, конечно, придумать другое название, но оно будет встречаться множество раз в руководстве и тебе придется заменять его каждый раз на свое. Будет проще для начала остановиться на нашем варианте `my-first-blog`. +> **Примечание:** имя репозитория `my-first-blog` для нас очень важно — ты можешь, конечно, придумать другое название, но оно будет встречаться множество раз в руководстве, и тебе придется заменять его каждый раз на своё. Будет проще для начала остановиться на нашем варианте: `my-first-blog`. -На следующем экране ты можешь найти URL для клонирования репозитория. Выбери вариант "HTTPS", копируй команду и вставь в окно терминала: +На следующем экране ты найдёшь URL для клонирования репозитория. Выбери вариант "HTTPS" и скопируй ссылку: ![][4] @@ -100,25 +109,29 @@ Git будет отслеживать изменения всех файлов Теперь нужно связать локальный репозиторий с репозиторием на GitHub. -Напечатай у себя в консоли следующую команду (Замени `` именем, указанным при создании аккаунта на GitHub, но без угловых скобок): - - $ git remote add origin https://github.com//my-first-blog.git - $ git push -u origin master +Напечатай у себя в консоли следующую команду (замени `` на имя, указанное при создании аккаунта на GitHub, но без угловых скобок): +{% filename %}command-line{% endfilename %} +``` +$ git remote add origin https://github.com//my-first-blog.git +$ git push -u origin master +``` -Введи свое имя пользователя и пароль от аккаунта GitHub, и ты должна увидеть что-то подобное: - - 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; ты должна увидеть что-то такое: +{% 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][5], [этот учебник][6], а также многие другие великолепные проекты с исходным кодом размещены на GitHub :) @@ -126,189 +139,96 @@ Git будет отслеживать изменения всех файлов [5]: https://github.com/django/django [6]: https://github.com/DjangoGirls/tutorial -# Настройка нашего блога на PythonAnywhere - -> **Примечание** Возможно, ты уже завела учётную запись на PythonAnywhere ранее — если так, нет нужды повторять это вновь. - -{% include "/deploy/signup_pythonanywhere.md" %} - -## Загружаем код на PythonAnywhere - -После регистрации на PythonAnywhere ты будешь перемещена на страницу "Consoles". Выбери опцию старта "Bash" консоли -- это версия консоли PythonAnywhere, аналогичная твоему локальному терминалу. - -> **Примечание**: PythonAnywhere использует Linux, так что если ты используешь Windows, то терминал и команды могут немного отличаться от того, к чему ты привыкла на своем компьютере. - -Давай загрузим наш код из GitHub на PythonAnywhere, создав "клон" репозитория. Введи следующую команду в консоли на PythonAnywhere (не забудь заменить `` на свою учётку GitHub): - - $ git clone https://github.com//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 - - -### Создаём виртуальное окружение на PythonAnywhere - -Также как ты делала на своем компьютере, ты можешь создать виртуальное окружение на 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 - - (myvenv) $ pip install django whitenoise - Collecting django - [...] - Successfully installed django-1.8.2 whitenoise-2.0 - +# Настройка блога на PythonAnywhere -> **Примечание** Выполнение команды `pip install` может занять несколько минут. Терпение, терпение! Однако, если это занимает больше 5 минут, что-то не так. Спроси своего инструктора. +## Регистрация на PythonAnywhere - +> **Примечание:** возможно, ты уже завела учётную запись на PythonAnywhere ранее — если так, нет нужды повторять это вновь. -### Сбор статических файлов. - -Задаешься вопросом "что это за whitenoise такой"? Это утилита для работы с так называемыми "статическими файлами". Статические файлы — это файлы, не содержащие программного кода, такие как файлы HTML или CSS. Статические файлы работают на серверах не так как на твоем локальном компьютере, и нам потребуется инструмент, такой как "whitenoise", чтобы управляться с ними. - -Мы ближе познакомимся со статическими файлами в дальнейшем, когда начнем писать CSS для нашего сайта. - -А пока нам просто нужно запускать дополнительную команду под названием `collectstatic`, на сервере. Это даст Django знать, что он должен собрать все статические файлы, которые потребуются серверу. На данный момент эти файлы главным образом позволят админке хорошо выглядеть. - - (myvenv) $ 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/.virtualenvs/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/actions.min.js' - Copying '/home/edith/.virtualenvs/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/inlines.min.js' - [...] - Copying '/home/edith/.virtualenvs/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/css/changelists.css' - Copying '/home/edith/.virtualenvs/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`: - - (myvenv)20:20 ~ $ python manage.py migrate - Operations to perform: - [...] - Applying sessions.0001_initial... OK - - - (mvenv)20:20 ~ $ python manage.py createsuperuser - - -## Публикация нашего блога как веб-приложения - -Теперь наш код загружен на PythonAnywhere, виртуальное окружение готово, статические файлы собраны и база данных инициализирована -- мы готовы опубликовать блог как веб-приложение! +{% include "/deploy/signup_pythonanywhere.md" %} -Вернись в панель управления PythonAnywhere нажав на лого в верхнем левом углу, затем переключись на вкладку **Web** и нажми кнопку **Add a new web app**. +## Настройка сайта на PythonAnywhere -После подтверждения доменного имени, выбери **manual configuration** (NB *не* «Django»!) в диалоговом окне. Затем выбери **Python 3.4** и заверши работу мастера. +Вернись на [главную страницу PythonAnywhere](https://www.pythonanywhere.com/), кликнув логотип. Затем запусти Bash-консоль. Нажав на кнопку bash ты запускаешь командную строку, которая находится на серверах PythonAnywhere. Эта командная строка аналогична той, что есть на твоём собственном компьютере. -> **Примечание**: убедись, что ты выбрала опцию "Manual configuration", а не "Django". Мы слишком круты для стандартного настройщика PythonAnywhere для Django ;-) +Раздел «New Console» (новая консоль) в веб-интерфейсе PythonAnywhere с кнопкой «bash» -### Настройка виртуального окружения +> **Примечание:** PythonAnywhere использует Linux, так что если ты используешь Windows, то терминал и команды могут немного отличаться от того, к чему ты привыкла на своём компьютере. -Ты будешь перенесена на страницу настройки веб-приложения PythonAnywhere, куда тебе будет нужно заходить каждый раз, когда потребуется внести изменения в приложении на сервере. +Чтобы опубликовать сайт на PythonAnywhere, нужно загрузить на PythonAnywhere твой код с Github и затем настроить PythonAnywhere так, чтобы он распознал твой код и запустил твоё веб-приложение. Существуют способы сделать это «вручную», но для PythonAnywhere есть программа-помощник, которая сделает это для тебя. Давай её установим. -![][7] +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ pip3.6 install --user pythonanywhere +``` - [7]: images/pythonanywhere_web_tab_virtualenv.png +Когда ты это запустишь, в консоли будет печататься лог установки. Он начнётся с чего-то вроде `Collecting pythonanywhere`, а последней будет строчка `Successfully installed (...) pythonanywhere- (...)`. -В секции "Virtualenv" кликни по красному тексту "Enter the path to a virtualenv" и набери `/home//my-first-blog/myvenv/`. Нажми на синий прямоугольник с галочкой, чтобы сохранить изменения, прежде чем двигаться дальше. +Теперь запустим эту вспомогательную утилиту, которую ты только что установила. Она настроит твоё приложение, скачав его код с GitHub. Напечатай следующее в консоли PythonAnywhere (не забудь использовать свой ник на GitHub вместо ``, URL в консольной команде должен совпадать с URL, используемым в команде clone): -> **Примечание**: замени имя пользователя на свое. Если ты допустишь ошибку, PythonAnywhere выдаст предупреждение. +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ pa_autoconfigure_django.py https://github.com//my-first-blog.git +``` -### Настройка файла WSGI +Утилита будет печатать в консоль, что она делает: -Django использует протокол WSGI, стандартный протокол для обслуживания веб-сайтов, используя Python, который поддерживается PythonAnywhere. Используя файл настроек WSGI мы позволим PythonAnywhere распознать наш Django блог. +- Скачивает твой код с GitHub +- Создаёт виртуальное окружение на PythonAnywhere, такое же, как на твоём компьютере +- Обновляет твой файл настроек с настройками деплоя +- Создаёт базу данных на PythonAnywhere, используя команду `manage.py migrate` +- Разбирается с твоими статическими файлами (о них будет дальше) +- Настраивает PythonAnywhere так, чтобы твоё приложение было доступно в интернете -Кликни по ссылке "WSGI configuration file" (в секции "Code" наверху страницы -- она будет выглядеть следующим образом: `/var/www/_pythonanywhere_com_wsgi.py`) и ты будешь переключена на редактор. +Все эти шаги автоматизированы на PythonAnywhere, но они совершенно такие же, какие надо было бы совершить с любым другим хостинговым сервисом. -Удали все содержимое и замени его чем-то вроде этого: +Главное, на что нужно обратить внимание сейчас, — это то, что твоя база данных на PythonAnywhere никак не связана с базой данных на твоём компьютере. Поэтому там будут разные посты и разные аккаунты администраторов. Как следствие, для базы на PythonAnywhere необходимо создать аккаунт администратора так же, как ты это делала у себя локально с помощью команды `createsuperuser`. На PythonAnywhere заранее активировано виртуальное окружение, так что всё, что тебе нужно сделать — это запустить в консоли PythonAnywhere команду: -```python -import os -import sys +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +(ola.pythonanywhere.com) $ python manage.py createsuperuser +``` -path = '/home//my-first-blog' # use your own username here -if path not in sys.path: - sys.path.append(path) +Введи параметры для своего пользователя-админа. Лучше всего использовать те же самые данные, что и у тебя на локальном компьютере, чтобы избежать путаницы, если ты конечно не хочешь сделать пароль на сервере PythonAnywhere более надёжным. -os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' +Сейчас, если хочешь, посмотри на файлы на PythonAnywhere с помощью команды `ls`: -from django.core.wsgi import get_wsgi_application -from whitenoise.django import DjangoWhiteNoise -application = DjangoWhiteNoise(get_wsgi_application()) +{% 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 ``` +Ты также можешь заглянуть на страницу «Files» и посмотреть, что лежит на сервере, используя встроенный в PythonAnywhere файловый менеджер. (Со страницы «Console» ты можешь попасть на другие страницы PythonAnywhere, используя кнопку меню в правом верхнем углу. Находясь на какой-либо странице, ты можешь найти ссылки на другие вверху.) -> **Примечание**: не забудь заменить имя пользователя на свое там, где указано `` - -Задача данного файла сказать PythonAnywhere где находится наше веб-приложение и как называется файл настроек Django. Он также загружает "whitenoise" для работы со статическими файлами. +## Ты в сети! -Нажми **Save** и переключись на вкладку **Web**. +Ура, твой сайт теперь доступен всем в интернете! Ты можешь найти ссылку на него на странице «Web» на PythonAnywhere. Этой ссылкой можно делиться с кем хочешь :) -Мы все сделали! Нажми на большую зеленую кнопку **Reload** и можешь проверять свое приложение. Ссылку можно найти в верхней части страницы. +> **Примечание** Это туториал для начинающих, поэтому публикуя сайт, мы использовали несколько хаков, которые не очень хороши с точки зрения безопасности. Если ты захочешь сделать что-то на основе этого проекта или начать новый, прочитай [Django deployment checklist](https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/) для советов по безопасности на твоём сайте. ## Советы по отладке -Если видишь ошибку при попытке посетить свой сайт, для отладочной информации первым делом смотри **журнал ошибок**. Ссылку на него ты найдёшь на [вкладке Web][8] на PythonAnywhere. Посмотри, нет ли там сообщений о каких-нибудь ошибках; самые последние из них приведены ниже. Они включают: - - [8]: https://www.pythonanywhere.com/web_app_setup/ +Если ты столкнулась с ошибкой, запуская скрипт `pa_autoconfigure_django.py`, вот несколько частых причин: -* пропуск одного из шагов в консоли: создание virtualenv, её активация, установка Django в виртуальное окружение, запуск collectstatic, инициализация базы данных. +- Ты забыла создать PythonAnywhere API токен +- Ошибка в GitHub URL +- Если ты видишь сообщение *"Could not find your settings.py"* (невозможно найти settings.py), это может быть вызвано тем, что ты не добавила все файлы в Git или не загрузила их на GitHub. Перечитай Git-секцию выше +- Если ты до этого уже регистрировала аккаунт на PythonAnywhere и наткнулась на ошибку collectstatic, вполне вероятно, что у тебя устаревшая версия SQLite (например, 3.8.2). В этом случае зарегистрируй новый аккаунт и попробуй ещё раз ввести команды, упомянутые в разделе __Настройка блога на PythonAnywhere__. -* ошибка в пути к virtualenv -- рядом должно появляться небольшое предупреждение, если PythonAnywhere не может найти виртуальное окружение по указанному адресу. +Если ты столкнулась с ошибкой при попытке открыть свой сайт, первое место, где нужно искать отладочную информацию — твой **error log**. Ты найдёшь ссылку на него на странице ["Web"](https://www.pythonanywhere.com/web_app_setup/) на PythonAnywhere. Глянь, есть ли там какие-либо сообщения об ошибках; самые новые находятся внизу. -* ошибка в файле настроек WSGI -- ты правильно указала путь к директории my-first-blog? +Ещё есть [общие советы по отладке на PythonAnywhere](http://help.pythonanywhere.com/pages/DebuggingImportError). -* Ты выбрала одну и ту же версию Python для virtualenv и для веб-приложения? Обе должны быть 3.4. - -* Также можешь посмотреть [общие советы по отладке на вики PythonAnywhere][9]. - - [9]: https://www.pythonanywhere.com/wiki/DebuggingImportError - -И помни: твой инструктор здесь, чтобы помогать! +И помни, твой тренер здесь, чтобы помочь! # Ты в сети! -Стандартная страница твоего сайта должна включать приветствие "Welcome to Django", точно также как было на локальном компьютере. Попробуй добавить `/admin/` к концу адреса сайта и перейдешь к панели администратора сайта. Войди под своим именем и паролем и увидишь форму для добавления новых записей в блог. +Стандартная страница твоего сайта должна включать приветствие "It worked!", точно так же как было на локальном компьютере. Попробуй добавить `/admin/` к концу адреса сайта, и перейдёшь к панели администратора сайта. Войди под своим именем и паролем и увидишь форму для добавления новых записей в блог. + +После того, как создашь несколько записей, ты можешь вернуться к своей локальной версии приложения (а не на PythonAnywhere). С этого момента для внесения изменений тебе нужно работать в своей локальной версии. Это обычный подход в веб-программировании: изменять код локально, загружать изменения на GitHub, а затем подтягивать изменения на сервер с сайтом. Такой подход позволяет тебе работать и экспериментировать, не рискуя сломать свой сайт. Круто, правда? -Ты заслужила *огромную* похвалу! Развертывание сервера — одна из самых каверзных частей веб-разработки, и не редко уходит несколько дней, прежде чем заставишь всё работать. А у нас уже есть работающий в сети веб-сайт, вот так вот! +Ты заслужила *огромную* похвалу! Развёртывание сервера — одна из самых каверзных частей веб-разработки, и нередко уходит несколько дней, прежде чем заставишь всё работать. А у нас уже есть работающий в сети веб-сайт, вот так вот! diff --git a/ru/deploy/images/github_get_repo_url_screenshot.png b/ru/deploy/images/github_get_repo_url_screenshot.png index 62a29f5f8d7..ee1560b1e85 100644 Binary files a/ru/deploy/images/github_get_repo_url_screenshot.png and b/ru/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/ru/deploy/images/new_github_repo.png b/ru/deploy/images/new_github_repo.png index 64011e59a52..d1f82e5d863 100644 Binary files a/ru/deploy/images/new_github_repo.png and b/ru/deploy/images/new_github_repo.png differ diff --git a/ru/deploy/images/pythonanywhere_account.png b/ru/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/ru/deploy/images/pythonanywhere_account.png differ diff --git a/ru/deploy/images/pythonanywhere_bash_console.png b/ru/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..68eb2a030e1 Binary files /dev/null and b/ru/deploy/images/pythonanywhere_bash_console.png differ diff --git a/ru/deploy/images/pythonanywhere_beginner_account_button.png b/ru/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/ru/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/ru/deploy/images/pythonanywhere_create_api_token.png b/ru/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..abae45ae37a Binary files /dev/null and b/ru/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/ru/deploy/images/pythonanywhere_web_tab_virtualenv.png b/ru/deploy/images/pythonanywhere_web_tab_virtualenv.png deleted file mode 100644 index 97e87e7b07b..00000000000 Binary files a/ru/deploy/images/pythonanywhere_web_tab_virtualenv.png and /dev/null differ diff --git a/ru/deploy/install_git.md b/ru/deploy/install_git.md index 1ddef84127a..535df8ea1fc 100755 --- a/ru/deploy/install_git.md +++ b/ru/deploy/install_git.md @@ -1,17 +1,50 @@ -### Windows +Git — это «система управления версиями», используемая множеством программистов. Эта программа отслеживает изменения, происходящие с файлами, чтобы впоследствии можно было восстановить состояние кода на нужный момент времени. Это немного похоже на функцию отслеживания изменений в Microsoft Word, но куда мощнее. -Ты можешь загрузить Git с официального сайта [git-scm.com](https://git-scm.com/). Ты можешь нажимать "дальше дальше дальше" на всех этапах установки за исключением одного: на пятом шаге, который называется "Adjusting your PATH environment" (Настройка системной переменной Path), выберите "Run Git and associated Unix tools from the Windows command-line" (Запуск Git и соответствующих Unix утилит через командную строку Windows, нижняя опция). Все остальные настройки можно оставить по умолчанию. Опция "Checkout Windows-style, commit Unix-style line endings" будет неплохим выбором. +## Установка Git -### MacOS + -Загрузи Git с официального сайта [git-scm.com](https://git-scm.com/) и просто следуйте инструкциям по установке. +Ты можешь загрузить Git с официального сайта [git-scm.com](https://git-scm.com/). Ты можешь нажимать "дальше, дальше, дальше" на всех этапах установки за исключением одного: на пятом шаге, который называется "Adjusting your PATH environment" (Настройка системной переменной Path), выбери "Use Git and optional Unix tools from the Windows Command Prompt" (Запуск Git и соответствующих Unix утилит через командную строку Windows, нижняя опция). Все остальные настройки можно оставить по умолчанию. Также неплохо будет выбрать опцию "Checkout Windows-style, commit Unix-style line endings". -### Linux +После окончания установки не забудь перезапустить командную строку или PowerShell. + -Если git ещё не установлен, то он будет доступен через менеджер пакетов, попробуй следующую команду: + - sudo apt-get install git - # or - sudo yum install git - # or - sudo zypper install git +Загрузи Git с официального сайта [git-scm.com](https://git-scm.com/) и просто следуй инструкциям по установке. + +> **Примечание:** если ты используешь OS X 10.6, 10.7 или 10.8, тебе придётся установить git отсюда: [Установка Git для OS X Snow Leopard](https://sourceforge.net/projects/git-osx-installer/files/git-2.3.5-intel-universal-snow-leopard.dmg/download) + + + + + +{% filename %}command-line{% endfilename %} +```bash +$ sudo apt install git +``` + + + + + +{% filename %}command-line{% endfilename %} +```bash +$ sudo dnf install git +``` + + + + + +{% filename %}command-line{% endfilename %} +```bash +$ sudo zypper install git +``` + + diff --git a/ru/deploy/signup_pythonanywhere.md b/ru/deploy/signup_pythonanywhere.md index e98cd6e1b7b..60ef0201968 100755 --- a/ru/deploy/signup_pythonanywhere.md +++ b/ru/deploy/signup_pythonanywhere.md @@ -1,5 +1,19 @@ -Теперь нам потребуется создать бесплатный аккаунт уровня "Beginner" на PythonAnywhere. +PythonAnywhere — это сервис по запуску кода на Python в облаке. Мы будем использовать его, чтобы разместить наш сайт «вживую» в интернете. + +Создай аккаунт уровня "Beginner" на PythonAnywhere. Он бесплатный, так что кредитка не понадобится. * [www.pythonanywhere.com](https://www.pythonanywhere.com/) -> **Примечание**: При выборе имени пользователя, помни что URL блога примет вид `yourusername.pythonanywhere.com`, так что остановись либо на своём нике, либо на имени, связанном с тематикой блога. \ No newline at end of file + ![Страница регистрации на PythonAnywhere с кнопкой создания бесплатного 'Beginner' аккаунта](../deploy/images/pythonanywhere_beginner_account_button.png) + +> **Примечание:** при выборе имени пользователя помни, что URL блога примет вид `yourusername.pythonanywhere.com`, так что остановись либо на своём нике, либо на имени, связанном с тематикой блога. Кроме того, убедись в том, что запомнила пароль (сохрани его в своём менеджере паролей, если им пользуешься). + +## Создание API токена для PythonAnywhere + +Это нужно будет сделать только один раз. Когда ты зарегистрируешься на PythonAnywhere, откроется панель управления (dashboard). На ней в правом верхнем углу будет ссылка на страницу «Account»: + +![Account link on the top right on the page](../deploy/images/pythonanywhere_account.png) + +Там выбери вкладку «API token» и нажми кнопку, на которой написано «Create new API token» (создать новый API token). + +![The API token tab on the Account page](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/ru/django/README.md b/ru/django/README.md index ce3fb13b6f8..23b9357582c 100755 --- a/ru/django/README.md +++ b/ru/django/README.md @@ -1,6 +1,6 @@ # Что такое Django? -Django (*/ˈdʒæŋɡoʊ/ джанго*) -- бесплатный и свободный фреймворк для веб-приложений, написанный на Python. Фреймворк - это набор компонентов, которые помогают разрабатывать веб-сайты быстро и просто. +Django (*/ˈdʒæŋɡoʊ/ джанго*) — бесплатный и свободный фреймворк для веб-приложений, написанный на Python. Фреймворк — это набор компонентов, которые помогают разрабатывать веб-сайты быстро и просто. Каждый раз при разработке веб-сайтов требуются похожие компоненты: способ аутентифицировать пользователей (вход, выход, регистрация), панель управления сайтом, формы, инструменты для загрузки файлов и т. д. @@ -10,18 +10,18 @@ Django (*/ˈdʒæŋɡoʊ/ джанго*) -- бесплатный и свобод ## Зачем нам нужен фреймворк? -Чтобы понять, для чего же нам нужен Django, нам нужно ближе познакомиться с серверами. Во-первых, сервер должен узнать о том, что мы ждем от него веб-страницу. +Чтобы понять, для чего же нам нужен Django, нам нужно ближе познакомиться с серверами. Во-первых, сервер должен узнать о том, что мы ждём от него веб-страницу. -Представь себе почтовый ящик (порт), который проверяется на наличие новых писем (запросов). Это делает веб-сервер. Когда письмо приходит, сервер читает его и отправляет ответ с веб-страничкой. Однако, чтобы что-то отправить нам надо это что-то иметь. И Django как раз и отвечает за создание контента, который будет отправлен в ответе. +Представь себе почтовый ящик (порт), который проверяется на наличие новых писем (запросов). Это делает веб-сервер. Когда письмо приходит, сервер читает его и отправляет ответ с веб-страничкой. Однако чтобы что-то отправить, нам надо это что-то иметь. И Django как раз и отвечает за создание контента, который будет отправлен в ответе. ## Что происходит, когда кто-то запрашивает веб-сайт у твоего сервера? -Когда на сервер приходит запрос, он переадресуется Django, который пытается сообразить что же конкретно от него просят. Для начала он берет адрес веб-страницы и пробует понять -- что же нужно сделать. Эту часть процесса в Django выполняет **urlresolver** (адрес веб-сайта называется URL - Uniform Resource Locator - Единый указатель ресурсов, так что название *urlresolver*, resolver == определитель, имеет определенный смысл). Он не слишком умен, поэтому просто берет список шаблонов и пытается сопоставить их с URL. Django сверяет шаблоны сверху вниз и, если что-то совпадает, он переправляет запрос соответствующей функции (которая называется *view*). +Когда на сервер приходит запрос, он переадресуется Django, который пытается сообразить, что же конкретно от него просят. Для начала он берет адрес веб-страницы и пробует понять — что же нужно сделать. Эту часть процесса в Django выполняет **urlresolver** (адрес веб-сайта называется URL — Uniform Resource Locator — Единый указатель ресурсов, так что название *urlresolver*, resolver == распознаватель, имеет определенный смысл). Он не слишком умён, поэтому просто берет список шаблонов и пытается сопоставить их с URL. Django сверяет шаблоны сверху вниз и, если что-то совпадает, он перенаправляет запрос соответствующей функции (которая называется *view*). Представь себе почтальона с письмом. Она идет вниз по улице и сверяет номера домов с адресом на письме. Если они совпадают, то она оставляет письмо. Так же работает и urlresolver! -Но самые интересные вещи происходят в функции *view*: мы, например, можем обращаться к базе данных за определенной информацией. Может быть пользователь попросил изменить какую-нибудь информацию? Как будто в письме написано: "Пожалуйста, поменяйте описание моей работы." Функция *view* может проверить имеете ли вы разрешение делать это, а затем обновит описание работы и отправит обратно ответ: "Готово!". Затем функция *view* сгенерирует ответ и Django сможет отправить его веб-браузеру пользователя. +Но самые интересные вещи происходят в функции *view*: мы, например, можем обращаться к базе данных за определенной информацией. Может быть, пользователь попросил изменить какую-нибудь информацию? Как будто в письме написано: "Пожалуйста, поменяйте описание моей работы." Функция *view* может проверить, имеете ли вы разрешение делать это, а затем обновит описание работы и отправит обратно ответ: "Готово!". Затем функция *view* сгенерирует ответ, и Django сможет отправить его веб-браузеру пользователя. В реальности все немного сложнее, однако тебе не обязательно знать все технические навороты прямо сейчас. Достаточно основной концепции. -Так что вместо погружения в пучины нюансов, мы просто начнем работать с Django и познакомимся со всеми важными особенностями по мере продвижения! +Так что вместо погружения в пучины нюансов мы просто начнем работать с Django и познакомимся со всеми важными особенностями по мере продвижения! diff --git a/ru/django_admin/README.md b/ru/django_admin/README.md index 0a13a0ca8b7..2b0578ed152 100755 --- a/ru/django_admin/README.md +++ b/ru/django_admin/README.md @@ -1,34 +1,40 @@ # Администрирование Django -Чтобы добавлять, редактировать и удалять записи, для которых мы только сделали модель, нам потребуется использовать права администратора в Django. +Чтобы добавлять, редактировать и удалять записи, для которых мы только что создали модель, мы используем панель управления администратора Django. Давай откроем файл `blog/admin.py` и заменим его содержимое на: +{% filename %}blog/admin.py{% endfilename %} ```python from django.contrib import admin from .models import Post admin.site.register(Post) ``` - -Как ты можешь заметить, мы импортировали (включили) модель Post, которая была определена в предыдущей главе. Чтобы наша модель стала доступна на странице администрирования, нам нужно зарегистрировать её при помощи `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/. Ты увидишь страницу авторизации: ![Страница авторизации][1] [1]: images/login_page2.png -Чтобы залогиниться, тебе сначала нужно создать *суперпользователя (англ. superuser)* - пользователя, который имеет полный доступ к управлению сайтом. Вернись к командной строке, набери `python manage.py createsuperuser`, и нажми Enter. При появлении запроса введи имя пользователя (строчными буквами, без пробелов), адрес электронной почты и пароль. Не беспокойся, если пароль не появляется на экране по мере ввода, так и задумано. Просто напечатай его и нажмите `Enter`, чтобы продолжить. Результат должен выглядеть следующим образом (имя пользователя и почта соответственно будут твоими): +Чтобы залогиниться, тебе сначала нужно создать *суперпользователя (англ. superuser)* — пользователя, который имеет полный доступ к управлению сайтом. Вернись к командной строке, набери `python manage.py createsuperuser`, и нажми Enter. - (myvenv) ~/djangogirls$ python manage.py createsuperuser - Username: admin - Email address: admin@admin.com - Password: - Password (again): - Superuser created successfully. - +> Не забудь: чтобы выполнять команды во время работы сервера, открой новое окно терминала и активируй в нём виртуальное окружение. Мы описывали ввод новых команд в разделе Запуск веб-сервера главы Твой первый проект на Django!. + +При появлении запроса введи имя пользователя (строчными буквами, без пробелов), адрес электронной почты и пароль. Не беспокойся, если пароль не появляется на экране по мере ввода, так и задумано. Просто напечатай его и нажми `Enter`, чтобы продолжить. Результат должен выглядеть следующим образом (имя пользователя и почта, соответственно, будут твоими): + +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py createsuperuser +Username: admin +Email address: admin@admin.com +Password: +Password (again): +Superuser created successfully. +``` Вернись в браузер и войди в систему при помощи имени пользователя и пароля, которые ты только что выбрала. Ты должна попасть в панель управления Django. @@ -36,14 +42,14 @@ admin.site.register(Post) [2]: images/django_admin3.png -Перейди к разделу Posts и немного поэкспериментируй с ним. Добавь пять или шесть постов. Не беспокойся о содержании - можешь просто скопировать и вставить текст из этого учебника, чтобы сэкономить время :). +Перейди к разделу Posts и немного поэкспериментируй с ним. Добавь пять или шесть постов. Не беспокойся о содержании — можешь просто скопировать и вставить текст из этого учебника, чтобы сэкономить время :) -Убедись, что выбрала для двух или трех записей (но не больше) дату публикации. Это пригодится позднее. +Убедись, что выбрала для двух или трёх записей (но не больше) дату публикации. Это пригодится позднее. ![Администрирование Django][3] [3]: images/edit_post3.png -Если ты хочешь узнать больше об администрировании Django, то ознакомься с этим разделом официальной документации: https://docs.djangoproject.com/en/1.8/ref/contrib/admin/ +Если ты хочешь узнать больше об администрировании Django, то ознакомься с этим разделом официальной документации: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/. -Сейчас, вероятно, подходящий момент, чтобы порадовать себя кружечкой кофе (или чая), а также съесть чего-нибудь для пополнения энергии. Ты только что создала свою первую Django модель и заслужила перерыв! +Сейчас, вероятно, подходящий момент, чтобы порадовать себя кружечкой кофе (или чая), а также съесть чего-нибудь для восполнения энергии. Ты только что создала свою первую модель Django и заслужила перерыв! diff --git a/ru/django_admin/images/django_admin3.png b/ru/django_admin/images/django_admin3.png index a450b4f9630..ea01ab951bf 100644 Binary files a/ru/django_admin/images/django_admin3.png and b/ru/django_admin/images/django_admin3.png differ diff --git a/ru/django_admin/images/edit_post3.png b/ru/django_admin/images/edit_post3.png index c8572a73e7d..d577b111424 100644 Binary files a/ru/django_admin/images/edit_post3.png and b/ru/django_admin/images/edit_post3.png differ diff --git a/ru/django_admin/images/images/django_admin3.png b/ru/django_admin/images/images/django_admin3.png index a450b4f9630..ea01ab951bf 100644 Binary files a/ru/django_admin/images/images/django_admin3.png and b/ru/django_admin/images/images/django_admin3.png differ diff --git a/ru/django_admin/images/images/edit_post3.png b/ru/django_admin/images/images/edit_post3.png index c8572a73e7d..d577b111424 100644 Binary files a/ru/django_admin/images/images/edit_post3.png and b/ru/django_admin/images/images/edit_post3.png differ diff --git a/ru/django_admin/images/images/login_page2.png b/ru/django_admin/images/images/login_page2.png index 47153ef6960..6ae26e9959a 100644 Binary files a/ru/django_admin/images/images/login_page2.png and b/ru/django_admin/images/images/login_page2.png differ diff --git a/ru/django_admin/images/login_page2.png b/ru/django_admin/images/login_page2.png index 47153ef6960..6ae26e9959a 100644 Binary files a/ru/django_admin/images/login_page2.png and b/ru/django_admin/images/login_page2.png differ diff --git a/ru/django_forms/README.md b/ru/django_forms/README.md index 2989e67cbe5..43c18372319 100755 --- a/ru/django_forms/README.md +++ b/ru/django_forms/README.md @@ -1,152 +1,161 @@ # Формы в Django -Последним, что нам стоит сделать для нашего веб-сайта является удобный способ добавления и редактирования записей. Django `admin`-панель удобна, но её дизайн сложно изменять. С `forms` (формами) у нас будем иметь абсолютную власть над интерфейсом блога - мы сможем сделать практически все что только можно придумать! +Последним, что нам стоит сделать для нашего веб-сайта, является удобный способ добавления и редактирования записей. `admin`-панель Django удобна, но её дизайн сложно изменять. С `forms` (формами) у нас будет абсолютная власть над интерфейсом блога — мы сможем сделать практически всё, что только можно придумать! -В формах Django удобно то, что мы можем создать новую форму с нуля или воспользоваться `ModelForm` для сохранения содержимого форм в модель. +Формы Django удобны тем, что мы можем создать новую форму с нуля или воспользоваться `ModelForm` для сохранения содержимого формы в модель. Это как раз то, что нам нужно сделать: мы создадим форму для модели `Post`. -Как и любая важная часть Django, формы имеют свой собственный: `forms.py`. +Как и любая важная часть Django, формы имеют свой собственный файл: `forms.py`. Нам нужно создать файл с таким именем в директории `blog`. ``` - blog -    └── forms.py +blog +   └── forms.py ``` Теперь открой его и набери следующее: +{% filename %}blog/forms.py{% endfilename %} ```python - from django import forms - from .models import Post +from django import forms - class PostForm(forms.ModelForm): +from .models import Post - class Meta: - model = Post - fields = ('title', 'text',) +class PostForm(forms.ModelForm): + + class Meta: + model = Post + fields = ('title', 'text',) ``` Для начала нам нужно импортировать формы Django (`from django import forms`) и, разумеется, нашу модель `Post` (`from .models import Post`). -`PostForm`, как ты, вероятно, подозреваешь, это имя для нашей формы. Нам нужно также сообщить Django, что эта форма относится к `ModelForm` (чтобы он смог поколдовать для нас) - `forms.ModelForm` поможет с этим. +`PostForm`, как ты, вероятно, подозреваешь, — это имя для нашей формы. Нам нужно также сообщить Django, что эта форма относится к `ModelForm` (чтобы он смог поколдовать для нас) — `forms.ModelForm` поможет с этим. -Дальше к нас `class Meta`, где мы определяем какая модель будет использоваться для создания формы (`model = Post`). +Дальше у нас `class Meta`, где мы определяем, какая модель будет использоваться для создания формы (`model = Post`). -В завершении мы можем указать, какие поля должны присутствовать в нашей форме. Сейчас нам требуются только поля `title` и `text` - `author` будет автоматически выбран в зависимости от авторизованного пользователя (тебя) и `created_date` должна автоматически проставляться в момент создания записи (т.е. через код), верно? +В завершение мы можем указать, какие поля должны присутствовать в нашей форме. Сейчас нам требуются только поля `title` и `text` — `author` будет автоматически выбран в зависимости от авторизованного пользователя (тебя), а `created_date` должна автоматически проставляться в момент создания записи (т.е. через код), верно? -Вот и все! Теперь мы можем использовать форму в *представлении* и отобразить её в шаблоне. +Вот и всё! Теперь мы можем использовать форму в *представлении* и отобразить её в шаблоне. -Таким образом, мы создали: ссылку на страницу, URL-адрес, представление и шаблон. +Поэтому снова нам необходимо создать ссылку на страницу, URL-адрес, представление и шаблон. ## Ссылка на страницу с формой Пришло время открыть файл `blog/templates/blog/base.html`. Мы добавим ссылку в элемент `div` с именем `page-header`: +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + ``` -Обрати внимание, что мы назвали новое представление `post_new`. +Обрати внимание, что мы назвали новое представление `post_new`. Класс `glyphicon glyphicon-plus` определён в используемой нами теме bootstrap — таким образом мы выведем значок плюса. -После добавления строки, твой html-файл должен выглядеть следующим образом: +После добавления строки твой html-файл должен выглядеть следующим образом: +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - {% load staticfiles %} - - - Django Girls blog - - - - - - - -
-
-
- {% block content %} - {% endblock %} -
+{% 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` и добавить строку: +{% filename %}blog/urls.py{% endfilename %} ```python - url(r'^post/new/$', views.post_new, name='post_new'), +path('post/new/', views.post_new, name='post_new'), ``` Окончательная версия файла будет выглядеть следующим образом: +{% filename %}blog/urls.py{% endfilename %} ```python - from django.conf.urls import url - 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'), - ] +from django.urls import path +from . import views + +urlpatterns = [ + 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` не реализовано. Давай добавим его прямо сейчас. +После перезагрузки веб-сайта мы увидим ошибку `AttributeError`, поскольку представление `post_new` не реализовано. Давай добавим его прямо сейчас. ## Представление post_new Самое время открыть файл `blog/views.py` и добавить следующую строку к остальным, начинающимся с `from`: +{% filename %}blog/views.py{% endfilename %} ```python - from .forms import PostForm +from .forms import PostForm ``` -и наше *представление*: +А затем наше *представление*: +{% filename %}blog/views.py{% endfilename %} ```python - def post_new(request): - form = PostForm() - return render(request, 'blog/post_edit.html', {'form': form}) +def post_new(request): + form = PostForm() + 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-кнопки: `` -* и наконец сразу после открытия тега `< form... >` мы должны добавить `{% raw %}{% csrf_token %}{% endraw %}`. Это очень важно, поскольку так мы делаем форму защищенной! Django будет ругаться, если ты забудешь добавить этот код: +- Нам нужно отобразить форму. Мы можем сделать это, к примеру, простым `{% raw %}{{ form.as_p }}{% endraw %}`. +- Строка выше должна быть обёрнута в HTML-теги `
...
` +- Нам потребуется кнопка `Save`. Мы добавим её при помощи HTML-кнопки: `` +- И, наконец, сразу после открытия тега `< form... >` мы должны добавить `{% raw %}{% csrf_token %}{% endraw %}`. Это очень важно, поскольку так мы делаем форму защищённой! Django будет ругаться, если ты забудешь добавить этот код: ![Страница CSFR Forbidden][1] [1]: 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

-
{% csrf_token %} - {{ form.as_p }} - -
- {% endblock %} +{% extends 'blog/base.html' %} + +{% block content %} +

New post

+
{% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} ``` Время обновить страницу! Ура! Форма отображается! @@ -155,95 +164,108 @@ [2]: images/new_form2.png -Но подожди минутку! Если ты наберешь что-нибудь в полях `title` и `text` и попробуешь сохранить - что произойдет? +Но подожди минутку! Если ты наберёшь что-нибудь в полях `title` и `text` и попробуешь сохранить — что произойдёт? Ничего! Мы снова на той же странице и наш текст пропал... и новая запись не была добавлена. Так что же пошло не так? -Ответ прост: ничего. Нам нужно сделать кое-что еще, чтобы новое *представление* заработало. +Ответ прост: ничего. Нам нужно сделать кое-что ещё, чтобы новое *представление* заработало. ## Сохраняем данные из формы -Снова открой файл `blog/views.py`. Все что у нас есть в представлении `post_new` выглядит пока следующим образом: +Снова открой файл `blog/views.py`. Всё, что у нас есть в представлении `post_new`, выглядит пока следующим образом: +{% filename %}blog/views.py{% endfilename %} ```python - def post_new(request): - form = PostForm() - return render(request, 'blog/post_edit.html', {'form': form}) +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) ``` -После отправки формы мы возвращаемся к тому же представлению, но в этот раз с новыми данными в `request`, а точнее в `request.POST` (имя POST не имеет ничего общего с "постом" в блоге, оно связано с тем, что мы "публикуем" данные). Помнишь, что в HTML-файле, определение `
` имеет параметр `method="POST"`? Все поля формы теперь находятся в `request.POST`. Ты не должна переименовывать `POST` во что-то другое (другое доступное значение параметра `method` - `GET`, но у нас нет времени объяснять разницу сейчас). +После отправки формы мы возвращаемся к тому же представлению, но в этот раз с новыми данными в `request`, а точнее, в `request.POST` (имя POST не имеет ничего общего с "постом" в блоге, оно связано с тем, что мы "публикуем" данные). Помнишь, что в HTML-файле определение `` имеет параметр `method="POST"`? Все поля формы теперь находятся в `request.POST`. Ты не должна переименовывать `POST` во что-то другое (другое доступное значение параметра `method` — `GET`, но у нас сейчас нет времени объяснять разницу). -Получается, что в представлении *view* нам нужно обработать две разные ситуации. Первая: когда мы только зашли на страницу и хотим получить пустую форму. Вторая: когда мы возвращаемся к *представлению* со всей информацией, которую мы ввели в форму. Таким образом, нам потребуется ввести условие (мы будем использовать условный оператор `if` для этой цели). +Получается, что в представлении *view* нам нужно обработать две разные ситуации. Первая: когда мы только зашли на страницу и хотим получить пустую форму. Вторая: когда мы возвращаемся к *представлению* со всей информацией, которую мы ввели в форму. Таким образом, нам потребуется ввести условие (для этого мы будем использовать условный оператор `if`): +{% filename %}blog/views.py{% endfilename %} ```python - if request.method == "POST": - [...] - else: - form = PostForm() +if request.method == "POST": + [...] +else: + form = PostForm() ``` -Теперь заполним строку, занятую `[...]`. Если `method` - `POST`, тогда мы хотим построить `PostForm` с данными из формы, верно? Мы добьемся этого следующим образом: +Теперь заполним строку, занятую `[...]`. Если `method` — `POST`, тогда мы хотим построить `PostForm` с данными из формы, верно? Мы добьёмся этого следующим образом: +{% filename %}blog/views.py{% endfilename %} ```python - form = PostForm(request.POST) +form = PostForm(request.POST) ``` -Легко! Дальше мы проверим корректна ли форма (все необходимые поля заполнены и неверные значения не будут сохранены). Мы сделаем это при помощи `form.is_valid()`. +Легко! Дальше мы проверим, корректна ли форма (все ли необходимые поля заполнены и не отправлено ли некорректных значений). Мы сделаем это при помощи `form.is_valid()`. -Мы проверяем допустимо ли содержание формы и, если все в порядке, сохраняем её! +Мы проверяем, допустимо ли содержимое формы, и, если всё в порядке, сохраняем её! +{% filename %}blog/views.py{% endfilename %} ```python - if form.is_valid(): - post = form.save(commit=False) - post.author = request.user - post.published_date = timezone.now() - post.save() +if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + 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` после добавления новой записи, согласна? Для этого нам понадобится еще один импорт: +{% filename %}blog/views.py{% endfilename %} ```python - from django.shortcuts import redirect +from django.shortcuts import redirect ``` -Добавь эту строку в начало файла. Теперь мы можем сделать переадресацию на страницу `post_detail` для созданной записи. +Добавь эту строку в начало файла. Теперь мы можем сделать переадресацию на страницу `post_detail` для созданной записи: +{% filename %}blog/views.py{% endfilename %} ```python - return redirect('blog.views.post_detail', pk=post.pk) +return redirect('post_detail', pk=post.pk) ``` -`blog.views.post_detail`это имя представления, которое нам необходимо. Помнишь, что это *представление* требует переменную `pk`? Чтобы передать её представлению мы используем аргумент `pk=post.pk`, где `post` - это новая запись в блоге! +`post_detail` — это имя представления, которое нам необходимо. Помнишь, что это *представление* требует переменную `pk`? Чтобы передать её представлению, мы используем аргумент `pk=post.pk`, где `post` — это новая запись в блоге! Хорошо, мы многое обсудили, пора взглянуть на *представление* полностью, верно? +{% filename %}blog/views.py{% endfilename %} ```python - def post_new(request): - if request.method == "POST": - form = PostForm(request.POST) - if form.is_valid(): - post = form.save(commit=False) - post.author = request.user - post.published_date = timezone.now() - post.save() - return redirect('blog.views.post_detail', pk=post.pk) - else: - form = PostForm() - return render(request, 'blog/post_edit.html', {'form': form}) +def post_new(request): + if request.method == "POST": + form = PostForm(request.POST) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm() + 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: Extensions**. +Возможно, ты заметила, что мы устанавливаем дату публикации перед сохранением поста. В последствии мы сделаем _кнопку публикации_ в __Django Girls Tutorial: Extensions__. Это круто! +> Поскольку мы недавно использовали панель администратора Django, система до сих пор думает, что мы авторизованы. Существует несколько случаев, когда мы можем случайно выйти из аккаунта (закрытие браузера, перезапуск базы данных и т.д.). Если ты получаешь ошибку при попытке сохранения записи, то потребуется перейти на страницу http://127.0.0.1:8000/admin и авторизоваться в системе снова. Это решит проблему. В главе **Домашнее задание: добавляем безопасность нашему веб-сайту!** после основного учебника описано окончательное решение этой проблемы. + +![Ошибка при выходе из аккаунта][4] + + [4]: images/post_create_error.png + ## Валидация формы -Теперь мы покажем тебе насколько круты формы в Django. Запись в блоге должна иметь поля `title` и `text`. В нашей модели `Post` мы не указываем, что эти поля необязательны (в отличии от `published_date`), так Django по умолчанию будет ожидать их заполнение пользователем. +Теперь мы покажем тебе, насколько круты формы в Django. Запись в блоге должна иметь поля `title` и `text`. В нашей модели `Post` мы не указываем, что эти поля необязательны (в отличие от `published_date`), так что Django по умолчанию будет ожидать, что пользователь их заполнит. -Попробуй сохранить форму без с незаполненными полями `title` и `text`. Угадай, что произойдет! +Попробуй сохранить форму с незаполненными полями `title` и `text`. Угадай, что произойдёт! ![Валидация формы][3] @@ -251,86 +273,86 @@ Django заботится о проверке всех полей в нашей форме на корректность. Разве не шикарно? -> Поскольку мы недавно использовали панель администратора Django, системы до сих пор думает, что мы авторизованы. Существует несколько случаев, когда мы можем случайно выйти из аккаунта (закрытие браузера, перезапуск базы данных и т.д.). Если ты получаешь ошибку при попытке сохранения записи, то потребуется перейти на страницу http://127.0.0.1:8000/admin и авторизоваться в системе снова. Это решит проблему. В главе **Домашнее задание: добавляем безопасность нашему веб-сайту!** после основного учебника приводится перманентное исправление. - -![Ошибка при выходе из аккаунта][4] - - [4]: images/post_create_error.png +## Форма редактирования -## Редактирование формы - -Теперь мы знаем как добавить новую форму. Но что, если мы хотим внести исправления в уже существующую запись? По сути это схожая с предыдущей задача. Давай быстро создадим пару важных вещей (если ты чего-то не понимаешь, спроси своего тренера или загляни в предыдущие главы, поскольку мы уже объясняли все необходимые шаги). +Теперь мы знаем, как добавить новую форму. Но что, если мы хотим внести исправления в уже существующую запись? По сути это схожая с предыдущей задача. Давай быстро создадим пару важных вещей (если ты чего-то не понимаешь, спроси своего тренера или загляни в предыдущие главы, поскольку мы уже объясняли все необходимые шаги). Открой `blog/templates/blog/post_detail.html` и добавь следующую строку: -```python - +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} +```html + ``` так, чтобы шаблон выглядел следующим образом: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html - {% extends 'blog/base.html' %} +{% extends 'blog/base.html' %} - {% block content %} -
- {% if post.published_date %} -
- {{ post.published_date }} -
- {% endif %} - -

{{ post.title }}

-

{{ post.text|linebreaksbr }}

-
- {% endblock %} +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} + +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endblock %} ``` В файле `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`, так что осталось лишь отсутствующее *представление*. -Let's open a `blog/views.py` and add at the very end of the file: +Давай откроем файл `blog/views.py` и добавим в самый конец следующее: +{% filename %}blog/views.py{% endfilename %} ```python - def post_edit(request, pk): - post = get_object_or_404(Post, pk=pk) - if request.method == "POST": - form = PostForm(request.POST, instance=post) - if form.is_valid(): - post = form.save(commit=False) - post.author = request.user - post.published_date = timezone.now() - post.save() - return redirect('blog.views.post_detail', pk=post.pk) - else: - form = PostForm(instance=post) - return render(request, 'blog/post_edit.html', {'form': form}) +def post_edit(request, pk): + post = get_object_or_404(Post, pk=pk) + if request.method == "POST": + form = PostForm(request.POST, instance=post) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + return redirect('post_detail', pk=post.pk) + else: + form = PostForm(instance=post) + return render(request, 'blog/post_edit.html', {'form': form}) ``` -Выглядит практически идентично представлению `post_new`, верно? Но не совсем. Первое: мы передаем параметр `pk` из URL-адреса. Следующее: мы получаем модель `Post` для редактирования при помощи `get_object_or_404(Post, pk=pk)` и передаем экземпляр post в качестве `instance` форме для сохранения: +Выглядит практически идентично представлению `post_new`, верно? Но не совсем. Во-первых, мы передаём параметр `pk` из URL-адреса. Кроме того, мы получаем модель `Post` для редактирования при помощи `get_object_or_404(Post, pk=pk)` и передаём экземпляр post в качестве `instance` форме и при сохранении… +{% filename %}blog/views.py{% endfilename %} ```python - form = PostForm(request.POST, instance=post) +form = PostForm(request.POST, instance=post) ``` -и когда мы открываем форму для редактирования: +… и когда мы открываем форму для редактирования: +{% filename %}blog/views.py{% endfilename %} ```python - form = PostForm(instance=post) +form = PostForm(instance=post) ``` -Хорошо, давай проверим что все работает! Перейди на страницу `post_detail`. Ты должна увидеть кнопку редактирования в правом верхнем углу: +Хорошо, давай удостоверимся, что всё работает! Перейди на страницу `post_detail`. Ты должна увидеть кнопку редактирования в правом верхнем углу: ![Кнопка Редактировать (Edit)][5] [5]: images/edit_button2.png -Когда ты её нажмешь, то увидишь форму с выбранной записью: +Когда ты её нажмёшь, то увидишь форму с выбранной записью: ![Форма редактирования][6] @@ -338,61 +360,83 @@ Let's open a `blog/views.py` and add at the very end of the file: Поменяй заголовок и текст, а затем сохрани запись! -Поздравляем! Твое приложение становится все более сложным! +Поздравляем! Твое приложение становится всё более сложным! -Если тебе нужно больше информации о формах в Django, то обратись к официальной документации: https://docs.djangoproject.com/en/1.8/topics/forms/ +Если тебе нужно больше информации о формах в Django, обратись к официальной документации: https://docs.djangoproject.com/en/2.0/topics/forms/ ## Безопасность -Круто иметь возможность создавать новые посты просто нажав на ссылку! Однако, сейчас кто угодно из посетителей вашего сайта может создать новую запись в блоге, а это, скорее всего, совсем не то, чего бы вам хотелось. Давай сделаем так, чтобы кнопка показывалась для нас, а не кого-либо еще. +Круто иметь возможность создавать новые посты, просто перейдя по ссылке! Однако сейчас кто угодно из посетителей твоего сайта может создать новую запись в блоге, а это, скорее всего, совсем не то, чего бы тебе хотелось. Давай сделаем так, чтобы кнопка показывалась для нас, а не кого-либо ещё. -В файле `blog/templates/blog/base.html`, найди `page-header` `div` и тег <a> который мы добавили ранее. Должно выглядеть примерно так: +В файле `blog/templates/blog/base.html` найди `page-header` `div` и тег ``, который мы добавили ранее. Должно выглядеть примерно так: +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + ``` -Мы добавим сюда ещё один тэг `{% if %}` чтобы ссылка показывалась только пользователям, вошедшим в админку. То есть, пока что только тебе! Измени тег `< >`, чтобы получилось так: +Мы добавим сюда ещё один тег `{% if %}`, чтобы ссылка показывалась только пользователям, вошедшим в админку. То есть пока что — только тебе! Измени тег ``, чтобы получилось так: +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - {% if user.is_authenticated %} - - {% endif %} +{% if user.is_authenticated %} + +{% endif %} ``` -Из-за этого `{% if %}` ссылка будет отправлена в браузер только если запрашивающий страницу пользователь вошёл в систему. Это не обезопасит создание новых постов полностью, но для начала и это неплохо. Мы подробнее рассмотрим вопросы безопасности в дополнении к учебнику. +Из-за этого `{% if %}` ссылка будет отправлена в браузер, только если запрашивающий страницу пользователь вошёл в систему. Это не обезопасит создание новых постов полностью, но для начала и это неплохо. Мы подробнее рассмотрим вопросы безопасности в дополнении к учебнику. -Поскольку ты авторизована, никаких изменений после обновления страницы ты не увидишь. Но попробуй загрузить страницу в другом браузере или в режиме инкогнито, и увидишь что ссылка не отобразится! +Помнишь иконку редактирования, которую мы добавили на страницу поста? Чтобы посторонние не смогли менять уже созданные посты, нам нужно изменить страничку похожим образом. -## Еще одна вещь: развертывание! +Открой файл `blog/templates/blog/post_detail.html` и найди такую строку: -Теперь давай посмотрим как это будет работать на PythonAnywhere. Пришло время для очередного развертывания! +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} +```html + +``` -* Сначала нам нужно сделать commit и push нового кода в репозиторий Github +Замени её на следующее: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} +```html +{% if user.is_authenticated %} + +{% endif %} ``` - $ git status - $ git add --all . - $ git status - $ git commit -m "Added views to create/edit blog post inside the site." - $ git push + +Поскольку ты авторизована, никаких изменений после обновления страницы ты не увидишь. Но попробуй загрузить страницу в другом браузере или в режиме инкогнито, и увидишь, что ссылка не отобразится! + +## И последнее: публикация! + +Теперь давай посмотрим, как это будет работать на PythonAnywhere. Пришло время для очередного развёртывания! + +* Сначала нам нужно сделать commit и push нового кода в репозиторий GitHub: + +{% filename %}command-line{% endfilename %} +``` +$ git status +$ git add --all . +$ git status +$ git commit -m "Added views to create/edit blog post inside the site." +$ git push ``` -* Затем набери в [Bash консоли PythonAnywhere][7]: +* Затем набери в [Bash-консоли PythonAnywhere][7]: [7]: https://www.pythonanywhere.com/consoles/ +{% filename %}PythonAnywhere command-line{% endfilename %} ``` - $ cd my-first-blog - $ source myvenv/bin/activate - (myvenv)$ git pull - [...] - (myvenv)$ python manage.py collectstatic - [...] +$ cd ~/.pythonanywhere.com +$ git pull +[...] ``` -* И нажми **Reload** на вкладке [Web tab][8]. +(Не забудь подставить вместо свой поддомен на PythonAnywhere без угловых скобок.) + +* Наконец, зайди на страницу ["Web" page][8] (используй кнопку меню в правом верхнем углу консоли) и нажми **Reload**. Обнови страницу блога http://subdomain.pythonanywhere.com/, чтобы увидеть изменения. + [8]: https://www.pythonanywhere.com/web_app_setup/ -Вот и все! Поздравляем :) +Вот и всё! Поздравляем :) diff --git a/ru/django_forms/images/csrf2.png b/ru/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/ru/django_forms/images/csrf2.png and b/ru/django_forms/images/csrf2.png differ diff --git a/ru/django_forms/images/drafts.png b/ru/django_forms/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/ru/django_forms/images/drafts.png and b/ru/django_forms/images/drafts.png differ diff --git a/ru/django_forms/images/edit_button2.png b/ru/django_forms/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/ru/django_forms/images/edit_button2.png and b/ru/django_forms/images/edit_button2.png differ diff --git a/ru/django_forms/images/edit_form2.png b/ru/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/ru/django_forms/images/edit_form2.png and b/ru/django_forms/images/edit_form2.png differ diff --git a/ru/django_forms/images/form_validation2.png b/ru/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/ru/django_forms/images/form_validation2.png and b/ru/django_forms/images/form_validation2.png differ diff --git a/ru/django_forms/images/images/csrf2.png b/ru/django_forms/images/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/ru/django_forms/images/images/csrf2.png and b/ru/django_forms/images/images/csrf2.png differ diff --git a/ru/django_forms/images/images/drafts.png b/ru/django_forms/images/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/ru/django_forms/images/images/drafts.png and b/ru/django_forms/images/images/drafts.png differ diff --git a/ru/django_forms/images/images/edit_button2.png b/ru/django_forms/images/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/ru/django_forms/images/images/edit_button2.png and b/ru/django_forms/images/images/edit_button2.png differ diff --git a/ru/django_forms/images/images/edit_form2.png b/ru/django_forms/images/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/ru/django_forms/images/images/edit_form2.png and b/ru/django_forms/images/images/edit_form2.png differ diff --git a/ru/django_forms/images/images/form_validation2.png b/ru/django_forms/images/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/ru/django_forms/images/images/form_validation2.png and b/ru/django_forms/images/images/form_validation2.png differ diff --git a/ru/django_forms/images/images/new_form2.png b/ru/django_forms/images/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/ru/django_forms/images/images/new_form2.png and b/ru/django_forms/images/images/new_form2.png differ diff --git a/ru/django_forms/images/images/post_create_error.png b/ru/django_forms/images/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/ru/django_forms/images/images/post_create_error.png and b/ru/django_forms/images/images/post_create_error.png differ diff --git a/ru/django_forms/images/new_form2.png b/ru/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/ru/django_forms/images/new_form2.png and b/ru/django_forms/images/new_form2.png differ diff --git a/ru/django_forms/images/post_create_error.png b/ru/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/ru/django_forms/images/post_create_error.png and b/ru/django_forms/images/post_create_error.png differ diff --git a/ru/django_installation/README.md b/ru/django_installation/README.md index 39ef9a7241d..728c98272e3 100755 --- a/ru/django_installation/README.md +++ b/ru/django_installation/README.md @@ -1,5 +1,7 @@ # Установка Django -> **Примечание** Если ты уже выполнила установку — можешь пропустить эту часть и сразу перейти к следующей главе! +> **Примечание:** если ты используешь Chromebook, пропусти эту главу, но выполни инструкции по [настройке для Chromebook](../chromebook_setup/README.md) -{% include "/django_installation/instructions.md" %} \ No newline at end of file +> **Примечание:** если ты уже выполнила установку — можешь пропустить эту часть и сразу перейти к следующей главе! + +{% include "/django_installation/instructions.md" %} diff --git a/ru/django_installation/instructions.md b/ru/django_installation/instructions.md index 0adda7ffec7..e9524d59929 100755 --- a/ru/django_installation/instructions.md +++ b/ru/django_installation/instructions.md @@ -1,113 +1,221 @@ > Отдельные части этой главы основаны на учебных пособиях Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). -> + > Отдельные части этой главы основаны на [учебном пособии django-marcador](http://django-marcador.keimlink.de/), лицензированном под Creative Commons Attribution-ShareAlike 4.0 International License. Руководство django-marcador защищено авторским правом Markus Zapke-Gründemann et al. ## Виртуальное окружение Перед установкой Django мы попросим тебя установить крайне полезный инструмент, который поможет тебе содержать среду разработки в чистоте. Можно пропустить этот шаг, но мы очень советуем этого не делать. Использование лучших рекомендаций с самого начала убережёт от многих проблем в будущем! -Итак, давай создадим **виртуальное окружение** (оно также называется *virtualenv*). Virtualenv будет изолировать зависимости Python/Django для каждого отдельного проекта. Это значит, что изменения одного сайта никогда не затронут другие сайты, которые вы разрабатываете. Удобно, правда? +Итак, давай создадим **виртуальное окружение** (оно также называется *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`. В общем случаем команда будет выглядеть так: +Мы создадим виртуальное окружение под именем `myvenv`. В общем случае команда будет выглядеть так: - python3 -m venv myvenv - +{% filename %}command-line{% endfilename %} +``` +$ python3 -m venv myvenv +``` -### Windows + -Чтобы создать новое `virtualenv`, тебе нужно открыть командную строку (мы рассказывали про неё в одной из прошлых глав - помнишь?) и набрать `C:\Python34\python -m venv myvenv`. Он должен содержать следующее: +Чтобы создать новое `virtualenv`, тебе нужно открыть командную строку и набрать `python -m venv myvenv`. Это будет выглядеть так: - C:\Users\Name\djangogirls> C:\Python34\python -m venv myvenv - +{% filename %}command-line{% endfilename %} +``` +C:\Users\Name\djangogirls> python -m venv myvenv +``` -где `C:\Python34\python` это директория, где ты установила Python и `myvenv` имя твоего `virtualenv`. Ты можешь выбрать любое имя, использовать можно только прописные буквы, без пробелов и специальных символов. Имя виртуального окружения выбирай покороче! +Здесь `myvenv` — имя твоего `virtualenv`. Ты можешь выбрать другое имя, но используй только строчные буквы, без пробелов и специальных символов. Имя виртуального окружения выбирай покороче — тебе придётся часто его набирать! -### Linux and OS X + -Для Linux и OS X достаточно набрать `python3 -m venv myvenv`, чтобы создать `virtualenv`: + - ~/djangogirls$ python3 -m venv myvenv - +В Linux и macOS достаточно набрать `python3 -m venv myvenv`, чтобы создать `virtualenv`: -`myvenv` -- имя виртуального окружения `virtualenv`. Опять же, только строчные буквы и никаких пробелов. Имя виртуального окружения лучше выбирать покороче — его набирать его предстоит не раз! +{% filename %}command-line{% endfilename %} +``` +$ python3 -m venv myvenv +``` -> **ПРИМЕЧАНИЕ:** создание виртуального окружения данной командой на Ubuntu 14.04 приведет к следующей ошибке: -> -> Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 -> -> -> Чтобы обойти эту проблему используй команду `virtualenv`. -> -> ~/djangogirls$ sudo apt-get install python-virtualenv -> ~/djangogirls$ virtualenv --python=python3.4 myvenv -> +`myvenv` — имя виртуального окружения `virtualenv`. Можешь выбрать другое имя, но используй только строчные буквы и никаких пробелов. Имя виртуального окружения лучше выбирать покороче — набирать его предстоит не раз! -## Работаем с virtualenv +> __Примечание:__ В некоторых версиях Debian/Ubuntu может произойти следующая ошибка: -Вышеуказанная команда создаст директорию `myvenv` (или другую, в зависимости от выбранного имени), которая будет содержать виртуальное окружение (по сути -- набор файлов и папок). +>{% 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 +>``` -#### Windows +> __Примечание:__ В некоторых версиях 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 +>``` - C:\Users\Name\djangogirls> myvenv\Scripts\activate - +> то запусти команду: +> +>{% filename %}command-line{% endfilename %} +>``` +>sudo apt install python{{ book.py_version }}-venv +>``` -#### Linux and OS X + + +## Работаем с virtualenv + +Указанная выше команда создаст директорию `myvenv` (или другую, в зависимости от выбранного тобой имени), которая будет содержать виртуальное окружение (по сути — набор файлов и папок). + + Запусти виртуальное окружение, выполнив: - ~/djangogirls$ source myvenv/bin/activate - +{% filename %}command-line{% endfilename %} +``` +C:\Users\Name\djangogirls> myvenv\Scripts\activate +``` -Не забудь поменять `myvenv` на выбранное для `virtualenv` имя! +> __ПРИМЕЧАНИЕ:__ в Windows 10 при работе в Windows PowerShell ты можешь получить ошибку вида `execution of scripts is disabled on this system`. В этом случае открой ещё одно окно 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 +>``` -> **ПРИМЕЧАНИЕ:** иногда команда `source` может быть недоступна. В таком случае, используй следующий метод: -> -> ~/djangogirls$ . myvenv/bin/activate -> + + + + +Запусти виртуальное окружение, выполнив: -Ты поймешь, что `virtualenv` запущено, когда увидишь приписку в командной строке: +{% filename %}command-line{% endfilename %} +``` +$ source myvenv/bin/activate +``` - (myvenv) C:\Users\Name\djangogirls> - +Не забудь поменять `myvenv` на выбранное тобой имя для `virtualenv`! -или: +> __ПРИМЕЧАНИЕ:__ иногда команда `source` может быть недоступна. В таком случае используй следующий метод: +> +>{% filename %}command-line{% endfilename %} +>``` +>$ . myvenv/bin/activate +>``` - (myvenv) ~/djangogirls$ - + -Обрати внимание на появление префикса `(myvenv)`! +Ты поймёшь, что `virtualenv` запущено, когда увидишь префикс `(myvenv)` в начале приглашения командной строки. -При работе с виртуальным окружением, команда `python` будет автоматически обращаться к правильной версии языка, так что тебе не обязательно использовать `python3`. +При работе с виртуальным окружением команда `python` будет автоматически обращаться к правильной версии языка, так что ты можешь использовать просто `python` вместо `python3`. Отлично, теперь мы будем хранить все важные зависимости в одном месте. Наконец можно установить Django! ## Установка Django -После запуска `virtualenv` ты можешь установить Django используя `pip`. Набери в командной строке строке `pip install django==1.8` (обрати внимание на двойной знак равенства: `==`). +После запуска `virtualenv` ты можешь установить Django. - (myvenv) ~$ pip install django==1.8 - Downloading/unpacking django==1.8 - Installing collected packages: django - Successfully installed django - Cleaning up... - +Перед этим мы должны удостовериться, что у тебя установлена последняя версия `pip` — программы, которую мы используем для установки Django. -для Windows +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~$ python3 -m pip install --upgrade pip +``` -> Если ты получаешь сообщение об ошибке при запуске pip, проверь что путь к директории с проектом не содержит пробелы или специальные символы (`C:\Users\User Name\djangogirls`). Если проблема в этом, то, пожалуйста, перенеси свой проект в другое место, адрес которого не будет содержать пробелы и специальные символы (предложение: `C:\djangogirls`). После этого еще раз попробуй запустить pip. +### Установка библиотек через указание требований -для Linux +Файл с требованиями (requirements) хранит список зависимостей, которые нужно установить с помощью +`pip install`: + +Для начала создай файл `requirements.txt` внутри директории `djangogirls/`, используя текстовый редактор, который ты установила ранее. Просто создай в редакторе новый файл, а затем сохрани его под именем `requirements.txt` в директории `djangogirls/`. После этого твоя директория будет выглядеть так: + +``` +djangogirls +└───requirements.txt +``` + +В файл `djangogirls/requirements.txt` нужно добавить такой текст: + +{% filename %}djangogirls/requirements.txt{% endfilename %} +``` +Django~={{ book.django_version }} +``` + +Теперь выполни команду `pip install -r requirements.txt`, чтобы установить Django. + +{% filename %}command-line{% endfilename %} +``` +(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.1MB) +Installing collected packages: Django +Successfully installed Django-{{ book.django_version }} +``` + + + + +> Если при запуске pip в Windows ты получаешь сообщение об ошибке, проверь, что путь к директории с проектом не содержит пробелов или специальных символов (`C:\Users\User Name\djangogirls`). Если проблема в этом, то, пожалуйста, перенеси свой проект в другое место, адрес которого не будет содержать пробелов и специальных символов (предлагаем `C:\djangogirls`). Создай новое виртуальное окружение в новой директории, после этого удали старое и попробуй запустить команды выше заново (перемещение виртуального окружения не сработает, поскольку в нём используются абсолютные пути). + + + + + +> При попытке установки Django твоя командная строка может зависнуть. Если это произошло, вместо приведённой выше команды используй: +> +>{% filename %}command-line{% endfilename %} +>``` +>C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +>``` + + + + + +Вот и всё! Теперь ты (наконец-то) готова создать своё Django-приложение! diff --git a/ru/django_models/README.md b/ru/django_models/README.md index 0a2daf7ed1f..0d5909d7048 100755 --- a/ru/django_models/README.md +++ b/ru/django_models/README.md @@ -1,32 +1,34 @@ # Модели Django -Нам нужно что-то, что будет хранить все записи нашего блога. Но прежде, давай поговорим о вещах, называемых `объектами`. +Нам нужно что-то, что будет хранить все записи нашего блога. Но прежде давай поговорим о вещах, называемых `объектами`. ## Объекты -В программировании существует особая концепция, она называется -- `объектно-ориентированным программированием`. Идея заключается в том, что вместо скучной последовательности инструкций мы моделируем вещи и описываем как они взаимодействуют друг с другом. +В программировании существует особая концепция, она называется `объектно-ориентированным программированием`. Идея заключается в том, что вместо скучной последовательности инструкций мы моделируем вещи и описываем, как они взаимодействуют друг с другом. Так что же такое объект? Это совокупность поведения и свойств. Звучит странно, но мы приведем пример. -Если мы хотим смоделировать кошку, то создадим объект `Cat`, который обладает определенными свойствами, например `color` (цвет), `age` (возраст), `mood` (настроение: плохое, хорошее, сонное ;)), `owner` (хозяин, например другой объект -- `Person` или, если кошка дикая, это свойство будет пустым). - -Объект `Cat` будет иметь набор определенных действий: `purr` (мурчать), `scratch` (царапаться) или `feed` (кормить, где мы дадим кошке немного `CatFood` (кошачьей еды), которая так же может быть отдельным объектом со своими свойствами, например `taste` (вкусом)). - - Cat - -------- - color - age - mood - owner - purr() - scratch() - feed(cat_food) - - - CatFood - -------- - taste - +Если мы хотим смоделировать кошку, то создадим объект `Cat`, который обладает определенными свойствами, например, `color` (цвет), `age` (возраст), `mood` (настроение: плохое, хорошее, сонное ;)), `owner` (хозяин, например, другой объект — `Person` — или, если кошка дикая, это свойство будет пустым). + +Объект `Cat` будет иметь набор определённых действий: `purr` (мурчать), `scratch` (царапаться) или `feed` (кормить, где мы дадим кошке немного `CatFood` — кошачьей еды, которая так же может быть отдельным объектом со своими свойствами, например, `taste` — вкусом). + +``` +Cat +-------- +color +age +mood +owner +purr() +scratch() +feed(cat_food) +``` + +``` +CatFood +-------- +taste +``` Основная идея, таким образом, заключается в описании объекта в коде, используя его параметры (`свойства объекта`) и доступные ему действия (`методы`). @@ -34,16 +36,17 @@ Для начала стоит ответить на вопрос: что такое запись в блоге? Какие свойства она имеет? -Ну, запись содержит какой-то текст и заголовок, это наверняка, верно? Было бы неплохо также знать кто её написал -- так что нам нужен автор. Ну и в заключении, нам нужно знать когда запись создана и когда опубликована. +Ну, запись наверняка содержит какой-то текст и заголовок, верно? Было бы неплохо также знать, кто её написал — так что нам нужен автор. Ну и в заключение, нам нужно знать, когда запись создана и когда опубликована. - Post - -------- - title - text - author - created_date - published_date - +``` +Post +-------- +title +text +author +created_date +published_date +``` Какие вещи можно сделать с записью в блоге? Было бы неплохо иметь `метод` для её публикации, согласна? @@ -53,42 +56,54 @@ ## Модель в Django -Зная, что представляет из себя объект, мы можем создать Django модель для записи в блоге. +Зная, что представляет из себя объект, мы можем создать модель Django для записи в блоге. -Модель в Django это объект определенного свойства - он хранится в `базе данных`. База данных представляет собой совокупность различных данных. Это то место, где ты будешь хранить информацию о своих пользователях, записях в блоге и т.д. Мы будем использовать базу данных SQLite для хранения информации. Это стандартная база данных в Django -- её вполне хватит для наших нужд сейчас. +Модель в Django — это объект определённого свойства: он хранится в `базе данных`. База данных представляет собой совокупность различных данных. Это то место, где ты будешь хранить информацию о своих пользователях, записях в блоге и т.д. Мы будем использовать базу данных SQLite для хранения информации. Это стандартная база данных в Django — её сейчас вполне хватит для наших нужд. Ты можешь представить модель в базе данных как электронную таблицу с колонками (полями) и строками (данными). ### Создание приложения -Для аккуратности мы создадим отдельное приложение в нашем проекте. Очень удобно иметь хорошо организованное рабочее место с самого начала. Для создания приложения нам понадобиться набрать следующую инструкцию в командной строке (из директории `djangogirls`, где находится файл `manage.py`): +Для аккуратности мы создадим отдельное приложение в нашем проекте. Очень удобно иметь хорошо организованное рабочее место с самого начала. Для создания приложения нам понадобится набрать следующую инструкцию в командной строке (из директории `djangogirls`, где находится файл `manage.py`): - (myvenv) ~/djangogirls$ python manage.py startapp blog - +{% filename %}macOS и Linux:{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py startapp blog +``` +{% filename %}Windows:{% endfilename %} +``` +(myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog +``` + + +Обрати внимание, что в нашем проекте появилась новая папка `blog`, которая содержит некоторые файлы. Таким образом, структура нашего проекта будет выглядеть так: -Обрати внимание, что в нашем проекте появилась новая папка `blog`, которая содержит некоторые файлы. Структура нашего проекта, таким образом, будет выглядеть так: - djangogirls - ├── mysite - | __init__.py - | settings.py - | urls.py - | wsgi.py - ├── manage.py - └── blog - ├── migrations - | __init__.py - ├── __init__.py - ├── admin.py - ├── models.py - ├── tests.py - └── views.py - +``` +djangogirls +├── blog +│   ├── __init__.py +│   ├── admin.py +│   ├── apps.py +│   ├── migrations +│   │   └── __init__.py +│   ├── models.py +│   ├── tests.py +│   └── views.py +├── db.sqlite3 +├── manage.py +└── mysite + ├── __init__.py + ├── settings.py + ├── urls.py + └── wsgi.py +``` -После того как приложение создано, нам нужно сообщить Django, что теперь он должен его использовать. Мы сделаем это через файл `mysite/settings.py`. Нам нужно найти `INSTALLED_APPS` и добавить к списку `'blog',` прямо перед `)`. Конечный результат должен выглядеть следующим образом: +После того, как приложение создано, нам нужно сообщить Django, что теперь он должен его использовать. Мы сделаем это с помощью файла `mysite/settings.py`. Нам нужно найти `INSTALLED_APPS` и добавить к списку `'blog',` прямо перед `]`. Конечный результат должен выглядеть следующим образом: +{% filename %}mysite/settings.py{% endfilename %} ```python -INSTALLED_APPS = ( +INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -96,29 +111,28 @@ INSTALLED_APPS = ( 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', -) +] ``` - ### Создание модели записи в блоге -В файле `blog/models.py` мы определяем все `Модели` - модель записи для блога также пойдет сюда. +В файле `blog/models.py` мы определяем все `Модели` — модель записи для блога также пойдёт сюда. Открой файл `blog/models.py`, удали весь текст и вставь на его место следующий код: +{% filename %}blog/models.py{% endfilename %} ```python +from django.conf import settings from django.db import models from django.utils import timezone class Post(models.Model): - author = models.ForeignKey('auth.User') + 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() @@ -127,53 +141,60 @@ class Post(models.Model): def __str__(self): 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):` — эта строка определяет нашу модель (`объект`). -`class Post(models.Model):` -- эта строка определяет нашу модель (`объект`). +- `class` — это специальное ключевое слово для определения объектов. +- `Post` — это имя нашей модели, мы можем поменять его при желании (специальные знаки и пробелы использовать нельзя). Всегда начинай имена классов с прописной буквы. +- `models.Model` означает, что объект Post является моделью Django, так Django поймет, что он должен сохранить его в базу данных. -* `class` это специальное ключевое слово для определения объектов. -* `Post` это имя нашей модели, мы можем поменять его при желании (специальные знаки и пробелы использовать нельзя). Всегда начинай имена классов с прописной буквы. -* `models.Model` означает, что объект Post является моделью Django, так Django поймет, что он должен сохранить его в базу данных. +Дальше мы задаем свойства, о которых уже говорили: `title`, `text`, `created_date`, `published_date` и `author`. Чтобы это сделать, нам нужно определиться с типом полей (это текст? число? дата? ссылка на другой объект? например, на пользователя?). -Дальше мы задаем свойства, о которых уже говорили: `title`, `text`, `created_date`, `published_date` и `author`. Чтобы это сделать нам нужно определиться с типом полей (это текст? число? дата? ссылка на другой объект? например, на пользователя?). +- `models.CharField` — так мы определяем текстовое поле с ограничением на количество символов. +- `models.TextField` — так определяется поле для неограниченно длинного текста. Выглядит подходящим для содержимого поста, верно? +- `models.DateTimeField` — дата и время. +- `models.ForeignKey` — ссылка на другую модель. -* `models.CharField` -- так мы определяем текстовое поле с ограничением на количество символов. -* `models.TextField` -- так определяется поле для неограниченно длинного текста. Выглядит подходящим для содержимого поста, верно? -* `models.DateTimeField` -- дата и время. -* `models.ForeignKey` -- ссылка на другую модель. +Мы не будем объяснять каждую запятую, поскольку на это уйдет слишком много времени. Ознакомься с официальной документаций Django: если хочешь узнать больше о полях моделей и о том, как определять разные объекты, то эта ссылка может помочь: https://docs.djangoproject.com/en/1.11/ref/models/fields/#field-types. -Мы не будем объяснять каждую запятую, поскольку на это уйдет слишком много времени. Ознакомься с официальной документаций Django — если хочешь узнать больше о полях моделей и о том как определять разные объекты, то эта ссылка может помочь: (https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-types). +Что насчёт `def publish(self):`? Это как раз метод `публикации` для записи, о котором мы говорили. `def` означает, что создаётся функция/метод, а `publish` — это название этого метода. Можно изменить имя метода, если хочешь. Существует правило для имён функций: нужно использовать строчные буквы, а пробелы заменять на подчёркивания. Например, метод, вычисляющий среднюю цену, может называться `calculate_average_price`. -Что насчет `def publish(self):`? Это как раз метод `публикации` для записи, о котором мы говорили. `def` означает, что создаётся функция/метод, а `publish` — это название этого метода. Можно изменить имя метода, если хочешь. Существует правило для имён функций: нужно использовать строчные буквы, а пробелы заменять на подчёркивания. Например метод, вычисляющий среднюю цену может называться `calculate_average_price`. +Методы часто `возвращают` что-то. Например, метод `__str__`. В нашем случае после вызова метода `__str__()` мы получим текст (**строку**) с заголовком записи. -Методы часто `возвращают` что-то. Например, метод `__str__`. В наше случае, после вызова метода `__str__()` мы получим текст (**строку**) с заголовком записи. +Также обрати внимание, что оба метода `def publish(self):` и `def __str__(self):` внутри класса имеют дополнительный отступ. Поскольку в Python важны отступы, нам необходимо использовать их для методов внутри класса — иначе методы не будут принадлежать к классу, и при запуске программы может получиться что-то неожиданное. -Если тема моделей тебе до сих пор непонятна -- не стесняйся обратиться к тренеру! Мы знаем, что она действительно сложна, особенно когда ты изучаешь параллельно объекты и функции. Но мы надеемся, что все это кажется тебе теперь не магией! +Если тема моделей тебе до сих пор непонятна — не стесняйся обратиться к тренеру! Мы знаем, что она действительно сложна, особенно когда ты изучаешь параллельно объекты и функции. Но мы надеемся, что всё это больше не кажется тебе магией! -### Создаем таблицы моделей в базе данных +### Создаём таблицы моделей в базе данных Последним шагом будет добавление нашей модели в базу данных. Сначала мы должны дать Django знать, что сделали изменения в нашей модели (мы её только что создали!). Набери `python manage.py makemigrations blog`. Должно получиться примерно так: - (myvenv) ~/djangogirls$ python manage.py makemigrations blog - Migrations for 'blog': - 0001_initial.py: - - Create model Post - +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py makemigrations blog +Migrations for 'blog': + blog/migrations/0001_initial.py: + - Create model Post +``` + +**Примечание:** не забудь сохранить отредактированные файлы. Иначе твой компьютер выполнит команду с их предыдущей версией, и могут появиться неожиданные ошибки. Django создал для нас файл с миграцией для базы данных. Набери `python manage.py migrate blog`, результат должен быть следующим: - (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 - +{% 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 +``` -Ура! Модель записи для блога теперь в базе данных, было бы неплохо посмотреть на неё, верно? Тогда переходи к следующей главе! +Ура! Модель записи для блога теперь в базе данных, и было бы неплохо посмотреть на неё, верно? Тогда переходи к следующей главе! diff --git a/ru/django_orm/README.md b/ru/django_orm/README.md index cd367d8af36..c57f57d4c27 100755 --- a/ru/django_orm/README.md +++ b/ru/django_orm/README.md @@ -1,157 +1,204 @@ # Django ORM и QuerySet -В этой главе ты узнаешь как Django подключается к базе данных и сохраняет в неё информацию. Давай начнем! +В этой главе ты узнаешь, как Django подключается к базе данных и сохраняет в неё информацию. Давай начнём! ## Что такое QuerySet? -QuerySet, по сути, список объектов заданной Модели. QuerySet позволяет читать данные из базы данных, фильтровать и изменять их порядок. +QuerySet, по сути, — список объектов заданной модели. QuerySet позволяет читать данные из базы данных, фильтровать и изменять их порядок. Проще научиться на примере. Давай попробуем, согласна? ## Интерактивная консоль Django -Открой свой локальный терминал (не на PythonAnywhere), и набери следующую команду: +Открой свой локальный терминал (не на PythonAnywhere) и набери следующую команду: - (myvenv) ~/djangogirls$ python manage.py shell - +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py shell +``` Результат должен быть таким: - (InteractiveConsole) - >>> - +{% filename %}command-line{% endfilename %} +```python +(InteractiveConsole) +>>> +``` -Ты находишься в интерактивной консоли Django. По сути, это та же интерактивная консоль Python, но с магией Django :). Ты можешь использовать весь синтаксис Python, разумеется. +Ты находишься в интерактивной консоли Django. По сути, это та же интерактивная консоль Python, но с магией Django :) Ты можешь использовать весь синтаксис Python, разумеется. ### Все объекты Давай попробуем вывести на экран все записи в нашем блоге. Ты можешь сделать это следующей командой: - >>> 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 +``` -Упс! Ошибка. Она говорит, что не существует объекта с именем Post. И это верно -- мы забыли импортировать его! +Упс! Ошибка. Она говорит, что не существует объекта с именем Post. И это верно — мы забыли импортировать его! - >>> from blog.models import Post - +{% filename %}command-line{% endfilename %} +```python +>>> from blog.models import Post +``` -Все просто: мы импортируем модель `Post` из `blog.models`. Давай попробуем получить все записи блога еще раз: +Всё просто: мы импортируем модель `Post` из `blog.models`. Давай попробуем получить все записи блога ещё раз: - >>> Post.objects.all() - [, ] - +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.all() +, ]> +``` -Это список записей, с которыми мы работали до этого! Мы создали их через панель администратора Django. Теперь же, мы хотим создавать записи через Python, так как же мы этого добьемся? +Это список записей, с которыми мы работали до этого! Мы создали их через панель администратора Django. Теперь же мы хотим создавать записи с помощью Python, так как же мы этого добьёмся? -### Создаем объект +### Создаём объект Создать объект 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`, который будет отвечать за автора записи. Как это сделать? +Но у нас есть один недочёт: `me`. Мы должны передать этой переменной экземпляр модели `User`, который будет отвечать за автора записи. Как это сделать? -Давай импортируем модель user для начала: +Давай для начала импортируем модель 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() +]> +``` Это суперпользователь, которого мы создали ранее! Нам нужен его экземпляр: - me = User.objects.get(username='ola') - +{% filename %}command-line{% endfilename %} +```python +>>> me = User.objects.get(username='ola') +``` -Как ты можешь заметить, мы получили (`get`) пользователя (`User`) с именем `username` 'ola'. Шикарно! В твоем случае, имя, конечно, может отличаться. +Как ты можешь заметить, мы получили (`get`) пользователя (`User`) с именем `username` 'ola'. Шикарно! В твоём случае имя, конечно, может отличаться. -Теперь мы наконец можем создать наш пост: +Теперь мы, наконец, можем создать наш пост: - >>> 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 будет достаточно. +Можешь повеселиться и добавить ещё записей. 2-3 будет достаточно. ### Фильтрация объектов -Важной особенностью QuerySets является возможность фильтровать объекты. Предположим, нам нужно найти все записи пользователя ola. Мы используем метод `filter` вместо метода `all` в `Post.objects.all()`. В кавычках мы укажем условия, по которым будет построена выборка записей. В нашей ситуации условием будет являться равенство поля `author` переменной `me`. В Django мы можем написать это следующим образом: `author=me`. Теперь наш код выглядит следующим образом: +Важной особенностью QuerySets является возможность фильтровать объекты. Предположим, нам нужно найти все записи пользователя ola. Мы используем метод `filter` вместо метода `all` в `Post.objects.all()`. В скобках мы укажем условия, по которым будет построена выборка записей. В нашей ситуации условием будет являться равенство поля `author` переменной `me`. В Django мы можем написать это следующим образом: `author=me`. Теперь наш код выглядит следующим образом: - >>> Post.objects.filter(author=me) - [, , , ] - +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.filter(author=me) +, , , ]> +``` А может быть мы хотим получить все записи со словом 'title' в поле `title`? - >>> Post.objects.filter(title__contains='title') - [, ] - +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.filter(title__contains='title') +, ]> +``` -> **Примечание**: Обрати внимание на два символа нижнего подчеркивания (`_`) между `title` и `contains`. Django's ORM использует этот синтаксис для разделения имен полей ("title") и операций или фильтров ("contains"). Если ты используешь только один символ нижнего подчеркивания, то получишь ошибку "FieldError: Cannot resolve keyword title_contains". +> **Примечание**: обрати внимание на два символа нижнего подчёркивания (`_`) между `title` и `contains`. Django ORM использует этот синтаксис для разделения имён полей ("title") и операций или фильтров ("contains"). Если ты используешь только один символ нижнего подчёркивания, то получишь ошибку "FieldError: Cannot resolve keyword title_contains". Ты также можешь получить список всех опубликованных записей. Мы просто отфильтруем записи по полю `published_date`: - >>> from django.utils import timezone - >>> Post.objects.filter(published_date__lte=timezone.now()) - [] +{% filename %}command-line{% endfilename %} +```python +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) + +``` -К сожалению, пост, который мы добавили в консоли Python еще не опубликован. Мы можем изменить это! Сначала выберем запись, которую мы хотим опубликовать: +К сожалению, пост, который мы добавили в консоли Python, ещё не опубликован. Мы можем изменить это! Сначала выберем запись, которую мы хотим опубликовать: - >>> post = Post.objects.get(title="Sample title") - +{% filename %}command-line{% endfilename %} +```python +>>> post = Post.objects.get(title="Sample title") +``` Дальше мы опубликуем её с помощью метода `publish`! - >>> post.publish() - +{% filename %}command-line{% endfilename %} +```python +>>> post.publish() +``` -Теперь попробуй получить список опубликованных сообщений снова (нажмите стрелку вверх 3 раза и затем `enter`): +Теперь попробуй получить список опубликованных сообщений снова (нажми стрелку вверх 3 раза и затем `enter`): + +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +]> +``` - >>> 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 %} +```python +>>> Post.objects.order_by('-created_date') +, , , ]> +``` + ### Соединение QuerySets QuerySets можно **сцеплять**, создавая цепочки: - >>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') - +``` +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> +``` -Это — мощный и удобный инструмент, позволяющий писать сложные запросы. +Это мощный и удобный инструмент, позволяющий писать сложные запросы. Отлично! Теперь ты готова к следующей части! Чтобы закрыть интерактивную консоль, набери: - >>> exit() - $ +{% filename %}command-line{% endfilename %} +```python +>>> exit() +$ +``` diff --git a/ru/django_start_project/README.md b/ru/django_start_project/README.md index 22f008d8c7c..667381fb96c 100755 --- a/ru/django_start_project/README.md +++ b/ru/django_start_project/README.md @@ -1,140 +1,198 @@ # Твой первый проект на Django! > Часть этой главы основана на учебных пособиях Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). -> + > Отдельные части этой главы основаны на учебном пособии [django-marcador ][1], лицензированном под Creative Commons Attribution-ShareAlike 4.0 International License. Руководство django-marcador защищено авторским правом Markus Zapke-Gründemann et al. [1]: http://django-marcador.keimlink.de/ Мы собираемся создать простой блог! -Первый шаг — создать новый проект Django. Попросту, это значит что мы запустим несколько стандартных скриптов из поставки Django, которые создадут для нас скелет проекта. Это просто куча каталогов и файлов, которые мы будем использовать позже. +Первый шаг — создать новый проект Django. В сущности, это значит, что мы запустим несколько стандартных скриптов из поставки Django, которые создадут для нас скелет проекта. Это просто куча каталогов и файлов, которые мы используем позже. + +Названия этих каталогов и файлов очень важны для Django. Ты не должна переименовывать их. Перемещать их в другое место тоже не самая удачная идея. Django необходима определенная структура, чтобы иметь возможность найти важные вещи. + +> Не забудь: ты должна запускать все команды в virtualenv. Если ты не видишь в командной строке префикса `(myvenv)`, то необходимо активировать virtualenv. Мы объясняли, как это сделать, в разделе __Работаем с virtualenv__ главы __Установка Django__. Для этого нужно набрать `myvenv\Scripts\activate` в Windows или `source myvenv/bin/activate` в Mac OS / Linux. + + + +В консоли Mac OS или Linux нужно запустить следующую команду (**не забудь добавить точку `.` в конце**): -Имена этих каталог и файлов очень важны для Django. Ты не должна переименовывать их. Перемещать их в другое место тоже не самая удачная идея. Django необходима определенная структура, чтобы иметь возможность найти важные вещи. +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ django-admin startproject mysite . +``` + +> Точка `.` крайне важна, потому что говорит скрипту установить Django в вашем текущем каталоге (который и обозначается сокращённо точкой `.`) +> +> **Примечание:** при вводе приведённой команды помни, что тебе нужно набирать только часть, начинающуюся с `django-admin`. `(myvenv) ~/djangogirls$` — это просто пример строки-приглашения терминала. -> Не забудь: ты должна запускать все команды в virtualenv. Если ты не видишь в командной строке префикса `(myvenv)`, то необходимо активировать virtualenv. Мы объясняли как это сделать в разделе **Работаем с virtualenv** главы **Установка Django**. Для этого нужно набрать `myvenv\Scripts\activate` в Windows или `source myvenv/bin/activate` в Mac OS / Linux. + -В консоли Mac OS или Linux нужно запустить следующую команду; **не забудьте добавить точку `.` в конце**: + - (myvenv) ~/djangogirls$ django-admin startproject mysite . - +В Windows запусти следующую команду (**не забудь добавить точку `.` в конце**): -В Windows; **не забудьте добавить точку `.` в конце**: +{% filename %}command-line{% endfilename %} +``` +(myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . +``` +> Точка `.` крайне важна, потому что говорит скрипту установить Django в вашем текущем каталоге (который и обозначается сокращённо точкой `.`) - (myvenv) C:\Users\Name\djangogirls> django-admin startproject mysite . - +> **Примечание:** при вводе приведённой команды помни, что тебе нужно набирать только часть, начинающуюся с `django-admin.exe`. `(myvenv) C:\Users\Name\djangogirls>` — это просто пример приглашения командной строки. -> `.` Точка крайне важна, потому что говорит скрипту устанавливать Django в вашем текущем каталоге (который и обозначается сокращённо точкой `.`) -> -> **Примечание** При вводе команд выше, помните что вам нужно набирать только часть, начинающуюся с `django-admin` или `django-admin.py`. `(myvenv) ~/djangogirls$` и `(myvenv) C:\Users\Name\djangogirls>` — это просто примеры строк-приглашений терминала. + -`django-admin.py` это скрипт, который создаст необходимую структуру директорий и файлы для нас. Ты должна теперь иметь следующую структуру проекта: +`django-admin.py` — это скрипт, который создаст необходимую структуру директорий и файлы для нас. Теперь у твоего проекта должна быть следующая структура: - djangogirls - ├───manage.py - └───mysite - settings.py - urls.py - wsgi.py - __init__.py - +``` +djangogirls +├───manage.py +├───mysite +│ settings.py +│ urls.py +│ wsgi.py +│ __init__.py +└───requirements.txt +``` +> **Примечание:** в своей структуре директорий ты также увидишь ранее созданную нами директорию с виртуальным окружением. -`manage.py` это другой скрипт, который помогает с управлением сайтом. С помощью него мы сможем запустить веб-сервер на твоем компьютере без установки дополнительных программ. +`manage.py` — это другой скрипт, который помогает с управлением сайтом. С помощью него мы, помимо прочего, сможем запустить веб-сервер на твоем компьютере без установки дополнительных программ. Файл `settings.py` содержит настройки для твоего веб-сайта. Помнишь нашу аналогию с почтальоном? Файл `urls.py` содержит список шаблонов, по которым ориентируется `urlresolver`. -Давай пока забудем про остальные файлы - мы не будем их изменять. Только не удали их случайно! +Давай пока забудем про остальные файлы — мы не будем их изменять. Только не удали их случайно! + ## Изменяем настройки -Давай внесем изменения в `mysite/settings.py`. Открой файл в текстовом редакторе, который ты выбрала ранее. +Давай внесём изменения в `mysite/settings.py`. Открой файл в текстовом редакторе, который ты выбрала ранее. -Было бы неплохо установить корректный часовой пояс на нашем сайте. Перейди к [списку часовых поясов википедии][2] и скопируй название своего часового пояса (TZ). (например, `Europe/Moscow`) +**Примечание:** помни, что `settings.py` — самый обычный файл. Ты можешь открыть его из своего редактора кода, используя меню «Файл -> Открыть». При этом ты увидишь обычное окно, в котором ты можешь перейти к своему файлу `settings.py` и выбрать его. Либо ты можешь открыть этот файл, перейдя в директорию проекта djangogirls на твоём рабочем столе и щёлкнув по нему правой кнопкой мыши; затем выбери свой редактор кода из предложенного списка. Важно выбрать именно редактор, поскольку у тебя могут быть установлены программы, которые откроют наш файл, но не позволят его изменить. + +Было бы неплохо установить корректный часовой пояс на нашем сайте. Перейди к [списку часовых поясов википедии][2] и скопируй название своего часового пояса (TZ) (например, `Europe/Moscow`). [2]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones -В файле settings.py найди строку, содержащую `TIME_ZONE`, и модифицируй её в соответствии со своим часовым поясом: +В файле settings.py найди строку, содержащую `TIME_ZONE`, и измени её в соответствии со своим часовым поясом: +{% filename %}mysite/settings.py{% endfilename %} ```python TIME_ZONE = 'Europe/Moscow' ``` - -Замени "Europe/Moscow" на соответствующий часовой пояс +Код языка состоит из сокращённого названия языка, например `en` для английского или `ru` для русского, и кода страны, например, `ru` для России или `ch` для Швейцарии. Тебе понадобится эта настройка, если ты хочешь, чтобы все встроенные кнопки и уведомления от Django были на твоём языке. Таким образом, надпись на кнопке «Cancel» будет переведена на заданный тобой язык. [Django поставляется с большим набором готовых переводов](https://docs.djangoproject.com/en/1.11/ref/settings/#language-code). + +Измени язык, отредактировав следующую строку: + +{% filename %}mysite/settings.py{% endfilename %} +```python +LANGUAGE_CODE = 'ru-ru' +``` + -Нам также необходимо добавить в настройки информацию о расположении статических файлов (мы познакомимся со статичными файлами и CSS в следующих главах). Спустись в *конец* файла и после переменной `STATIC_URL` добавь новую - `STATIC_ROOT`: +Нам также необходимо добавить в настройки информацию о расположении статических файлов (мы познакомимся со статическими файлами и CSS в следующих главах). Спустись в *конец* файла и после переменной `STATIC_URL` добавь новую — `STATIC_ROOT`: +{% filename %}mysite/settings.py{% endfilename %} ```python STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') +STATIC_ROOT = BASE_DIR / 'static' ``` - + +Когда наcтройка `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'` ## Настройка базы данных -Существует множество различных баз данных, которые могут хранить данные для твоего сайта. Мы будем использовать стандартную -- `sqlite3`. +Существует множество различных баз данных, которые могут хранить данные для твоего сайта. Мы будем использовать стандартную — `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`). Если все прошло успешно, то ты увидишь следующий результат: - (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... - Running migrations: - Rendering model states... DONE - Applying contenttypes.0001_initial... OK - Applying auth.0001_initial... OK - Applying admin.0001_initial... 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 sessions.0001_initial... OK - +Чтобы создать базу данных для нашего блога, набери в командной строке следующее: `python manage.py migrate` (мы должны быть в директории `djangogirls`, где расположен файл `manage.py`). Если всё прошло успешно, то ты увидишь следующий результат: -И мы закончили! Пришло время запустить веб-сервер и посмотреть работает ли наш веб-сайт! +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py migrate +Operations to perform: + Apply all migrations: auth, admin, 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 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 sessions.0001_initial... OK +``` -Ты должна быть в директории, где расположен файл `manage.py` (в нашем случае -- `djangogirls`). Запустим веб-сервер из командной строки: `python manage.py runserver`: +Вот и всё! Пришло время запустить веб-сервер и посмотреть, работает ли наш веб-сайт! - (myvenv) ~/djangogirls$ python manage.py runserver - +## Запуск веб-сервера -Если вы используете Windows, и команда падает с ошибкой `UnicodeDecodeError`, используйте вместо неё другую: +Ты должна быть в директории, где расположен файл `manage.py` (в нашем случае — `djangogirls`). Запустим веб-сервер из командной строки: `python manage.py runserver`: - (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 - +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py runserver +``` -Теперь тебе нужно проверить работает ли веб-сайт - открой браузер (Firefox, Chrome, Safari, Internet Explorer или любой другой) и набери следующий адрес: +Если ты работаешь в Windows, и команда падает с ошибкой `UnicodeDecodeError`, используй вместо неё другую: - http://127.0.0.1:8000/ - +{% filename %}command-line{% endfilename %} +``` +(myvenv) ~/djangogirls$ python manage.py runserver 0:8000 +``` -Веб-сервер займёт командную строку, пока вы его не остановите. Чтобы и дальше иметь возможность набирать команды, откройте ещё одно окно терминала и активируйте в нём виртуальное окружение. Чтобы остановить веб-сервер, перейдите обратно в окно, в котором он работает и нажмите CTRL + C - кнопки Control и C вместе (в Windows, может потребоваться нажать клавиши Ctrl + Break). +Теперь тебе нужно проверить, работает ли веб-сайт — открой браузер (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 +``` Поздравляем! Ты только что создала свой первый веб-сайт и запустила его на веб-сервере! Ну не круто ли? ![Сработало!][3] [3]: images/it_worked2.png -Готова к следующему шагу? Пришло время создать наполнение для нашего блога! +Пока работает веб-сервер, в терминале не будет приглашения для ввода команд. Ты всё ещё сможешь ввести текст, но не сможешь выполнить никакую другую команду. Это происходит потому, что сервер продолжает работу, "слушая" входящие запросы. + +> Мы рассматривали, как работают веб-сервера, в главе Как работает интернет. + +Веб-сервер займёт командную строку, пока ты его не остановишь. Чтобы и дальше иметь возможность набирать команды, открой ещё одно окно терминала и активируй в нём виртуальное окружение. Чтобы остановить веб-сервер, перейди обратно в окно, в котором он работает, и нажми CTRL + C — кнопки Control и C вместе (в Windows может потребоваться нажать клавиши Ctrl + Break). + +Готова к следующему шагу? Пришло время создать содержимое для нашего блога! diff --git a/ru/django_start_project/images/images/it_worked2.png b/ru/django_start_project/images/images/it_worked2.png index 4412ecfc49e..4efa554e567 100644 Binary files a/ru/django_start_project/images/images/it_worked2.png and b/ru/django_start_project/images/images/it_worked2.png differ diff --git a/ru/django_start_project/images/it_worked2.png b/ru/django_start_project/images/it_worked2.png index 4412ecfc49e..08b4b50238b 100644 Binary files a/ru/django_start_project/images/it_worked2.png and b/ru/django_start_project/images/it_worked2.png differ diff --git a/ru/django_templates/README.md b/ru/django_templates/README.md index 22e7b6e85ac..1d964c1f879 100755 --- a/ru/django_templates/README.md +++ b/ru/django_templates/README.md @@ -6,16 +6,17 @@ Как видишь, в HTML нельзя помещать код Python, поскольку браузеры не понимают его. Они знают только HTML. Мы помним, что HTML статичен, в то время как Python позволяет динамические изменения. -**Теги шаблонов Django** позволяют нам вставлять Python в HTML, так что ты можешь создавать динамические веб-сайты быстрее и проще. То что надо! +__Теги шаблонов Django__ позволяют нам вставлять Python в HTML, так что ты можешь создавать динамические веб-сайты быстрее и проще. То, что надо! ## Отображаем шаблон списка записей В предыдущей главе мы передали нашему шаблону список записей в переменной `posts`. Теперь мы отобразим его в HTML. -Чтобы вставить переменную в шаблон Django, нам нужно использовать двойные фигурные скобочки с именем переменной внутри: +Чтобы вставить переменную в шаблон Django, нам нужно использовать двойные фигурные скобки с именем переменной внутри: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - {{ posts }} +{{ posts }} ``` Попробуй это в шаблоне `blog/templates/blog/post_list.html`. Замени всё, начиная со второго `
` и вплоть до третьего `
` кодом `{{ posts }}`. Сохрани файл и обнови страницу, чтобы увидеть результат: @@ -26,16 +27,18 @@ Как ты можешь заметить, мы получили следующую строку: -``` - [, ] +{% 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 %} - {{ post }} - {% endfor %} +{% for post in posts %} + {{ post }} +{% endfor %} ``` Попробуй вставить это в свой шаблон. @@ -44,64 +47,67 @@ [2]: images/step2.png -Сработало! Но мы хотим, чтобы они отображались как статические записи, которые мы создавали в главе **Введение в HTML**. Ты можешь смешивать HTML и теги шаблонов. Наш элемент `body` будет выглядеть следующим образом: +Сработало! Но мы хотим, чтобы они отображались как статические записи, которые мы создавали в главе __Введение в HTML__. Ты можешь смешивать HTML и теги шаблонов. Наш элемент `body` будет выглядеть следующим образом: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + + +{% for post in posts %}
-

Django Girls Blog

+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

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

published: {{ post.published_date }}

-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

-
- {% endfor %} +{% endfor %} ``` -{% raw %}Всё что ты поместишь между `{% for %}` и `{% endfor %}` будет повторено для каждого объекта в списке. Обнови страницу:{% endraw %} +{% raw %}Всё, что ты поместишь между `{% for %}` и `{% endfor %}`, будет повторено для каждого объекта в списке. Обнови страницу:{% endraw %} ![Рисунок 13.3][3] [3]: images/step3.png -Ты заметила, что мы использовали немного другую запись в этот раз `{{ post.title }}` или `{{ post.text }}`? Мы обращаемся к различным полям нашей модели `Post`. Также `|linebreaksbr` прогоняет текст через фильтр, для преобразования переносов строк в параграфы. +Ты заметила, что мы использовали немного другую запись в этот раз: `{{ post.title }}` или `{{ post.text }}`? Мы обращаемся к различным полям нашей модели `Post`. Также `|linebreaksbr` прогоняет текст через фильтр для преобразования переносов строк в параграфы. -## Еще один момент +## Ещё один момент -Пришло время еще раз убедиться, что наш сайт будет работать в сети, согласна? Попробуем развернуть новую версию сайта на PythonAnywhere. Краткий обзор необходимых шагов... +Пришло время ещё раз убедиться, что наш сайт будет работать в сети, согласна? Попробуем развернуть новую версию сайта на PythonAnywhere. Краткий обзор необходимых шагов... -* Сначала загружаем код на Github +* Сначала загружаем код на GitHub +{% filename %}command-line{% endfilename %} ``` - $ git status - [...] - $ git add --all . - $ git status - [...] - $ git commit -m "Modified templates to display posts from database." - [...] - $ git push +$ git status +[...] +$ git add --all . +$ git status +[...] +$ git commit -m "Modified templates to display posts from database." +[...] +$ git push ``` -* Затем заходим на [PythonAnywhere][4], открываем **Bash console** и набираем команду: +* Затем заходим на [PythonAnywhere][4], открываем **Bash console** и набираем команду: [4]: https://www.pythonanywhere.com/consoles/ +{% filename %}PythonAnywhere command-line{% endfilename %} ``` - $ cd my-first-blog - $ git pull - [...] +$ cd $USER.pythonanywhere.com +$ git pull +[...] ``` -* Наконец, переключаемся на вкладку [Web][5] и жмем кнопку **Reload**. Обновления запущены в жизнь! +* Наконец, переключаемся на вкладку [Web][5] и жмём кнопку **Reload**. Обновления запущены в жизнь! Даже если записи в твоём блоге на PythonAnywhere отличаются от записей в блоге на локальном сервере, то всё в порядке. Базы данных на твоём локальном компьютере и на PythonAnywhere не синхронизируются, в отличиет от остальных файлов проекта. [5]: https://www.pythonanywhere.com/web_app_setup/ -Поздравляем! Теперь попробуй добавить новые записи через панель администратора Django (не забывай указывать published_date!) и перезагрузи страницу, чтобы проверить появились ли они. +Поздравляем! Теперь попробуй добавить новые записи через панель администратора Django (не забывай указывать published_date!). Удостоверься, что ты в панели администратора своего сайта на PythonAnywhere (https://yourname.pythonanywhere.com/admin). Затем обнови страницу, чтобы проверить, появились ли новые записи. -Работает как по волшебству? Есть чем гордиться! Отойди от компьютера на секунду - ты заслужила перерыв. :) +Работает как по волшебству? Есть чем гордиться! Отойди от компьютера на секунду — ты заслужила перерыв :) ![Рисунок 13.4][6] diff --git a/ru/django_templates/images/donut.png b/ru/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/ru/django_templates/images/donut.png and b/ru/django_templates/images/donut.png differ diff --git a/ru/django_templates/images/images/donut.png b/ru/django_templates/images/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/ru/django_templates/images/images/donut.png and b/ru/django_templates/images/images/donut.png differ diff --git a/ru/django_templates/images/images/step1.png b/ru/django_templates/images/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/ru/django_templates/images/images/step1.png and b/ru/django_templates/images/images/step1.png differ diff --git a/ru/django_templates/images/images/step2.png b/ru/django_templates/images/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/ru/django_templates/images/images/step2.png and b/ru/django_templates/images/images/step2.png differ diff --git a/ru/django_templates/images/images/step3.png b/ru/django_templates/images/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/ru/django_templates/images/images/step3.png and b/ru/django_templates/images/images/step3.png differ diff --git a/ru/django_templates/images/step1.png b/ru/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/ru/django_templates/images/step1.png and b/ru/django_templates/images/step1.png differ diff --git a/ru/django_templates/images/step2.png b/ru/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/ru/django_templates/images/step2.png and b/ru/django_templates/images/step2.png differ diff --git a/ru/django_templates/images/step3.png b/ru/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/ru/django_templates/images/step3.png and b/ru/django_templates/images/step3.png differ diff --git a/ru/django_urls/README.md b/ru/django_urls/README.md index 3cb60caee70..009af50a28a 100755 --- a/ru/django_urls/README.md +++ b/ru/django_urls/README.md @@ -1,130 +1,102 @@ # URL-адреса Django -Мы собираемся сделать нашу первую веб-страничку — домашнюю страницу твоего блога! Но для начала, давай чуть ближе познакомимся с URL-адресами в Django. +Мы собираемся сделать нашу первую веб-страничку — домашнюю страницу твоего блога! Но для начала давай чуть ближе познакомимся с URL-адресами в Django. ## Что такое 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-адрес][1] [1]: images/url.png -Любая страница в Интернете нуждается в собственном URL-адресе. Таким образом ваше приложение точно знает, что показать пользователю, который открывает конкретный URL-адрес. В Django мы используем кое-что под названием `URLconf` (англ. URL configuration, конфигурация URL). URLconf — это набор шаблонов, которые Django попробует сравнить с полученным URL, чтобы выбрать правильный метод для отображения (view). +Любая страница в Интернете нуждается в собственном URL-адресе. Таким образом ваше приложение точно знает, что показать пользователю, который открывает конкретный URL-адрес. В Django мы используем так называемый `URLconf` (англ. URL configuration, конфигурация URL). URLconf — это набор шаблонов, которые Django попробует сравнить с полученным URL, чтобы выбрать правильный метод для отображения (view). ## Как 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 уже кое-что разместил здесь для нас. -Строки, начинающиеся с символа `#` являются комментариями -- это означает, что они будут игнорироваться Python. Удобно, не правда ли? +Строки, расположенные между тройными кавычками (`'''` или `"""`), называются `docstrings` — ты можешь добавить их в начале файла, класса или метода для описания их функциональности. 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 используются так называемые регулярные выражения (англ. "regular expressions" — сокращённо `regex`). Регулярные выражения имеют множество (множество!) правил, которые формируют поисковый шаблон. Поскольку регулярные выражения являются довольно сложной темой, мы остановимся на них чуть подробнее. - -Если ты все еще хочешь разобраться в написании шаблонов - нам потребуется лишь ограниченное число правил для описания шаблона, например: - ^ начало текста - $ конец текста - \d цифра - + предыдущий пункт должен быть повторен как минимум один раз - () часть шаблона - - -Все остальное в шаблоне url будет интерпретироваться буквально. - -Теперь представь, что у нас есть веб-сайт с адресом `http://www.mysite.com/post/12345/`, где `12345` номер записи в блоге. - -Писать представления для всех номеров будет весьма утомительно. С помощью регулярных же выражений мы можем создать шаблон, соответствующий url, который позволит извлекать из адреса номер: `^post/(\d+)/$`. Давай разобьём шаблон на части, чтобы понять его логику: - -* **^post/** говорит Django рассматривать url с `post/` в начале (сразу после `^`) -* **(\d+)** означает, что дальше должен присутствовать номер (одна или несколько цифр) и мы хотим извлечь его из url -* **/** говорит Django об очередном символе `/` после номера -* **$** означает конец url, т.е. шаблону соответствуют только адреса с `/` на конце +Таким образом, любому URL-адресу, начинающемуся с `admin/`, Django будет находить соответствующее *view* (представление). В этом случае мы охватываем большое количество различных URL-адресов, которые явно не прописаны в этом маленьком файле — так он становится более аккуратным и удобочитаемым. ## Твой первый URL-адрес в Django! -Пришло время создать твой первый URL-адрес! Мы хотим, чтобы 'http://127.0.0.1:8000/' возвращал домашнюю страничку нашего блога со списком записей в нем. +Пришло время создать твой первый URL-адрес! Мы хотим, чтобы 'http://127.0.0.1:8000/' возвращал домашнюю страничку нашего блога со списком записей в нём. Мы также хотим сохранить файл `mysite/urls.py` в максимально аккуратном виде, так что мы импортируем URL-адреса для нашего приложения `blog` в `mysite/urls.py`. -Удали комментарии (строки, начинающиеся с `#`) и добавь импорт `blog.urls` в главный URL (`''`). +Вперёд, добавь строку для импорта `blog.urls`. Обрати внимание, что здесь мы используем функцию `include`, поэтому тебе придется импортировать её в строке `from django.urls...`. Файл `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` в начале строки. Это полезный намек для Python, что строка может содержать специальные символы, предназначенные не для самого Python, а для регулярного выражения. - ## blog.urls Создай новый пустой файл `blog/urls.py`. Отлично! Добавь в него следующие две строки: +{% filename %}blog/urls.py{% endfilename %} ```python -from django.conf.urls import url +from django.urls import path from . import views ``` - -Так мы импортировали все методы Django и все `views` (представления) из приложения `blog` (у нас их пока нет, но через минуту они появятся!) +Так мы импортировали функцию `path` Django и все `views` (представления) из приложения `blog` (у нас их пока нет, но через минуту они появятся!) После этого мы можем добавить наш первый URL-шаблон: +{% filename %}blog/urls.py{% endfilename %} ```python urlpatterns = [ - url(r'^$', views.post_list, name='post_list'), + path('', views.post_list, name='post_list'), ] ``` - -Как ты можешь заметить, мы связали `view` под именем `post_list` с URL-адресом `^$`. Это регулярное выражение будет соответствовать `^` (началу) и следующему `$` (концу), т.е. пустой строке. Это правильно, потому что для обработчиков URL в Django '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, которое будет использовано чтобы идентифицировать его. Оно может быть таким же, как имя представления (англ. view), а может и чем-то совершенно другим. Мы будем использовать именованные URL позднее в проекте, поэтому важно указывать их имена уже сейчас. Мы также должны попытаться сохранить имена URL-адресов уникальными и легко запоминающимися. +Последняя часть `name='post_list'` — это имя URL, которое будет использовано, чтобы идентифицировать его. Оно может быть таким же, как имя представления (англ. view), а может и чем-то совершенно другим. Мы будем использовать именованные URL позднее в проекте, поэтому важно указывать их имена уже сейчас. Мы также должны попытаться сохранить имена URL-адресов уникальными и легко запоминающимися. -Все в порядке? Тогда открой http://127.0.0.1:8000/ в браузере, чтобы увидеть результат. +Если сейчас ты попытаешься открыть страницу http://127.0.0.1:8000/ в браузере, то увидишь сообщение о том, что веб-страница недоступна. Это произошло потому, что сервер (помнишь, как мы набирали `runserver`?) перестал обрабатывать запросы. Чтобы понять почему, открой окно своей командной строки. ![Ошибка][2] [2]: images/error1.png -Теперь нет никакого "оно работает", верно? Не беспокойся, это всего лишь страница ошибки, здесь нечего пугаться! Она, на самом деле, довольно полезна: - -Ты можешь прочесть, что не существует атрибута с именем 'post_list' -- **no attribute 'post_list'**. Не напоминает ли *post_list* тебе что-нибудь? Так мы назвали свое представление! Это значит, что всё на месте, просто мы ещё не создали наше *представление*. Не беспокойся, мы этим займемся. +В твоей командной строке появилось сообщение об ошибке, но не беспокойся — оно, на самом деле, довольно полезно. Ты можешь прочесть, что не существует атрибута с именем 'post_list' — __no attribute 'post_list'__. Это название **представления**, которое Django пытается найти и использовать, но мы же его ещё не создали. В данный момент раздел `/admin/` тоже не будет работать. Не беспокойся, мы этим займёмся. -> Если хочешь узнать больше о Django URLconfs, посмотри официальную документацию: https://docs.djangoproject.com/en/1.8/topics/http/urls/ +> Если хочешь узнать больше о Django URLconfs, посмотри официальную документацию: https://docs.djangoproject.com/en/2.0/topics/http/urls/ diff --git a/ru/django_urls/images/error1.png b/ru/django_urls/images/error1.png index cc17593d19d..250028e996b 100644 Binary files a/ru/django_urls/images/error1.png and b/ru/django_urls/images/error1.png differ diff --git a/ru/django_urls/images/images/error1.png b/ru/django_urls/images/images/error1.png index cc17593d19d..250028e996b 100644 Binary files a/ru/django_urls/images/images/error1.png and b/ru/django_urls/images/images/error1.png differ diff --git a/ru/django_urls/images/images/url.png b/ru/django_urls/images/images/url.png index 6cd1bd96291..b59f9dce992 100644 Binary files a/ru/django_urls/images/images/url.png and b/ru/django_urls/images/images/url.png differ diff --git a/ru/django_urls/images/url.png b/ru/django_urls/images/url.png index 6cd1bd96291..b59f9dce992 100644 Binary files a/ru/django_urls/images/url.png and b/ru/django_urls/images/url.png differ diff --git a/ru/django_views/README.md b/ru/django_views/README.md index 6363a32ac90..69c4186af4b 100755 --- a/ru/django_views/README.md +++ b/ru/django_views/README.md @@ -2,7 +2,7 @@ Пришло время избавиться от ошибки, на которую мы наткнулись в прошлой главе :) -*view* это то место, где мы разместим "логику" работы нашего приложения. Оно запросит информацию из `модели`, которую мы создали ранее, и передаст её в `шаблон`. Шаблонами мы займёмся в следующей главе. Представления похожи на методы в Python и лишь немногим сложнее того, с чем мы уже сталкивались в главе **Введение в Python**. +*view*, или *представление*, — это то место, где мы разместим «логику» работы нашего приложения. Оно запросит информацию из `модели`, которую мы создали ранее, и передаст её в `шаблон`. Шаблонами мы займёмся в следующей главе. Представления похожи на методы в Python и лишь немногим сложнее того, с чем мы уже сталкивались в главе __Введение в Python__. Представления размещаются в файле `views.py`. Мы добавим свои *представления* в файл `blog/views.py`. @@ -10,24 +10,28 @@ Хорошо, давай откроем этот файл и посмотрим на его содержимое: +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render # Create your views here. ``` - -Не слишком много кода. Простейшее *представление* может выглядеть следующим образом. +Не слишком много кода. +Помнишь, что строки, начинающиеся с символа `#` — это комментарии? То есть Python не будет пытаться запустить их содержимое. + + Простейшее *представление* может выглядеть следующим образом. + +{% filename %}blog/views.py{% endfilename %} ```python def post_list(request): return render(request, 'blog/post_list.html', {}) ``` - -Как ты можешь заметить, мы создали метод (`def`) с именем `post_list`, который принимает в `request` в качестве аргумента и `return` (возвращает) результат работы метода `render`, который соберет наш шаблон страницы `blog/post_list.html`. +Как ты можешь заметить, мы создали функцию (`def`) с именем `post_list`, которая принимает `request` в качестве аргумента и возвращает (`return`) результат работы функции `render`, которая уже соберёт наш шаблон страницы `blog/post_list.html`. -Сохрани файл, перейди по адресу http://127.0.0.1:8000/ и посмотри что у нас получилось. +Сохрани файл, перейди по адресу http://127.0.0.1:8000/ и посмотри, что у нас получилось. Другая ошибка! Читаем, что произошло: @@ -35,6 +39,6 @@ def post_list(request): [1]: images/error.png -Это просто: *TemplateDoesNotExist* -- такого шаблона не существует. Давай исправим ошибку и создадим шаблон в следующей главе! +Это значит, что, по крайней мере, сервер снова работает, но что-то всё же пошло не так, верно? Не беспокойся, это просто страница с сообщением об ошибке, бояться совершенно нечего! Как и сообщения об ошибках в консоли, такие страницы чрезвычайно полезны. Здесь ты можешь прочесть: *TemplateDoesNotExist* — такого шаблона не существует. Давай исправим ошибку и создадим шаблон в следующей главе! -> Подробнее о представлениях в Django можно узнать из официальной документации: https://docs.djangoproject.com/en/1.8/topics/http/views/ +> Подробнее о представлениях в Django можно узнать из официальной документации: https://docs.djangoproject.com/en/1.11/topics/http/views/ diff --git a/ru/django_views/images/error.png b/ru/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/ru/django_views/images/error.png and b/ru/django_views/images/error.png differ diff --git a/ru/django_views/images/images/error.png b/ru/django_views/images/images/error.png deleted file mode 100644 index 391c9e61e16..00000000000 Binary files a/ru/django_views/images/images/error.png and /dev/null differ diff --git a/ru/dynamic_data_in_templates/README.md b/ru/dynamic_data_in_templates/README.md index b167b696ae7..06109f7c694 100755 --- a/ru/dynamic_data_in_templates/README.md +++ b/ru/dynamic_data_in_templates/README.md @@ -1,28 +1,28 @@ # Динамически изменяющиеся данные в шаблонах -Отдельные части уже размещены в нужных местах: модель `Post`, определена в файле `models.py`, `post_list` - в файле `views.py` и добавлен шаблон. Но как нам отобразить записи в шаблоне HTML-страницы? Ведь именно этого нам и нужно добиться: взять определенный контент (модели, сохраненные в базе данных) и аккуратно отобразить их в шаблоне, верно? +Отдельные части уже размещены в нужных местах: модель `Post` определена в файле `models.py`, `post_list` — в файле `views.py`, и добавлен шаблон. Но как нам отобразить записи в шаблоне HTML-страницы? Ведь именно этого нам и нужно добиться: взять определённый контент (модели, сохранённые в базе данных) и аккуратно отобразить их в шаблоне, верно? -Для этого и предназначены *представления*: соединять между собой модели и шаблоны. В `post_list` *представлениям* нужно будет взять модели, которые мы хотим отобразить и передать их шаблону. Таким образом, в *представлениях* мы определяем что (какая модель) будет отображена в шаблоне. +Для этого и предназначены *представления*: соединять между собой модели и шаблоны. В `post_list` *представлению* нужно будет взять модели, которые мы хотим отобразить, и передать их шаблону. Таким образом, в *представлениях* мы определяем, что (какая модель) будет отображена в шаблоне. -Хорошо, так как мы этого добьемся? +Хорошо, так как мы этого добьёмся? -Нам нужно открыть файл `blog/views.py`. Таким образом *представление* `post_list` будет выглядеть следующим образом: +Нам нужно открыть файл `blog/views.py`. Пока что *представление* `post_list` выглядит следующим образом: +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render def post_list(request): return render(request, 'blog/post_list.html', {}) ``` - -Помнишь мы говорили о включении кода из других файлов? Теперь нам нужно включить модель, которую мы определили в файле `models.py`. Мы добавим строку `from .models import Post` следующим образом: +Помнишь, мы говорили о включении кода из других файлов? Теперь нам нужно включить модель, которую мы определили в файле `models.py`. Мы добавим строку `from .models import Post` следующим образом: +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render from .models import Post ``` - Точка перед `models` означает *текущую директорию* или *текущее приложение*. Поскольку `views.py` и `models.py` находятся в одной директории, мы можем использовать точку `.` и имя файла (без расширения `.py`). Затем мы импортируем модель (`Post`). @@ -30,18 +30,20 @@ from .models import Post ## QuerySet -Ты уже должна быть знакома с принципом работы QuerySets. Мы говорили о нем в главе [Django ORM (QuerySets)][1]. +Ты уже должна быть знакома с принципом работы QuerySet. Мы говорили о нём в главе [Django ORM (QuerySets)][1]. [1]: ../django_orm/README.md -Сейчас нас интересует список записей блога, отсортированных по `published_date`, согласна? Мы уже делали это в главе о QuerySets! +Сейчас нас интересует список записей блога, отсортированных по `published_date`, согласна? Мы уже делали это в главе о QuerySet! +{% filename %}blog/views.py{% endfilename %} ```python - Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') -``` +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)`, но сначала не забудь добавить строку `from django.utils import timezone`: +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render from django.utils import timezone @@ -51,18 +53,16 @@ def post_list(request): posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') return render(request, 'blog/post_list.html', {}) ``` - - -Пожалуйста, обрати внимание, что мы создали *переменную* для QuerySet: `posts`. Можешь думать о ней как об имени для нашего QuerySet. Теперь мы можем обращаться к нему, используя имя. -Кроме того, код использует функцию `timezone.now()`, так что нужно также импортировать `timezone`. +Нам осталось передать QuerySet `posts` в шаблон (мы расскажем о том, как отобразить его на странице, в следующей главе). -Нам осталось передать 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 @@ -72,8 +72,7 @@ def post_list(request): posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') return render(request, 'blog/post_list.html', {'posts': posts}) ``` - -Вот и все! Теперь пришло время перейти к шаблону и отобразить QuerySet на странице! +Вот и всё! Теперь пришло время перейти к шаблону и отобразить QuerySet на странице! -Подробнее о QuerySets в Django можно узнать в официальной документации: https://docs.djangoproject.com/en/1.8/ref/models/querysets/ +Подробнее о QuerySets в Django можно узнать в официальной документации: https://docs.djangoproject.com/en/1.11/ref/models/querysets/ diff --git a/ru/extend_your_application/README.md b/ru/extend_your_application/README.md index 8b47ff6d4c4..658ae9c05ff 100755 --- a/ru/extend_your_application/README.md +++ b/ru/extend_your_application/README.md @@ -1,45 +1,50 @@ +{% set warning_icon = '' %} + # Расширяем свое приложение -Мы уже выполнили часть необходимых шагов для создания веб-сайта: мы знаем как создать модель, URL, представление и шаблон. Мы также знаем как улучшить визуальный дизайн с помощью CSS. +Мы уже выполнили часть необходимых шагов для создания веб-сайта: мы знаем как создать модель, URL, представление и шаблон. Мы также знаем, как улучшить визуальный дизайн с помощью CSS. -Время практики! +Время для практики! -Первое, что нам потребуется в блоге - страница для отображения конкретной записи, верно? +Первое, что нам потребуется в блоге — страница для отображения конкретной записи, верно? У нас уже есть модель `Post`, так что нам не нужно добавлять дополнительный код в файл `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.published_date }} -
-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

+{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }}
- {% endfor %} - {% endblock content %} +

{{ 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 %} -`blog.views.post_detail` это путь к *представлению* `post_detail`, которое нам нужно создать. Пожалуйста, обрати внимание: `blog` - это имя нашего приложения (директория `blog`), `views` - имя файла `views.py` без расширения и последнее - `post_detail` - имя *представления*. +Параметр `post_detail` означает, что Django будет искать URL с именем `post_detail` в файле `blog.urls.py`. -Теперь, когда мы перейдем по адресу http://127.0.0.1:8000/ мы получим ошибку (как и ожидается, поскольку у нас нет прописанного URL и *представления* для `post_detail`). Она будет выглядеть следующим образом: +А что насчёт `pk=post.pk`? `pk` — это сокращение от primary key (первичный ключ). Он уникальным образом определяет каждую запись в базе данных. Поскольку мы не задали первичного ключа в нашей модели `Post`, Django создал такой ключ за нас (по умолчанию это порядковый номер, то есть 1, 2, 3…) и добавил поле `pk` к каждой записи блога. Для получения первичного ключа мы напишем `post.pk` — точно так же, как мы получали значения остальных полей (`title`, `author` и т.д.) нашего объекта `Post`. + +Теперь, когда мы перейдем по адресу http://127.0.0.1:8000/, мы получим ошибку (как и ожидается, поскольку у нас нет прописанного URL и *представления* для `post_detail`). Она будет выглядеть следующим образом: ![Ошибка NoReverseMatch][1] @@ -47,29 +52,30 @@ ## Создадим URL для страницы поста -Давай создадим URL в `urls.py` для *представления* `post_detail`! +Давай создадим в `urls.py` URL для *представления* `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`, которое будет отображать пост целиком. Добавь строчку `url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'),` в файл `blog/urls.py`. Файл должен выглядеть примерно так: +Давай создадим URL в файле `blog/urls.py` и укажем Django на *представление* под названием `post_detail`, которое будет отображать пост целиком. Добавь строчку `path('post//', views.post_detail, name='post_detail')` в файл `blog/urls.py`. Файл должен выглядеть так: +{% filename %}{{ warning_icon }} blog/urls.py{% endfilename %} ```python - from django.conf.urls import url - from . import views +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'), - ] +urlpatterns = [ + 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/` совершенно правильным! - `/` - затем нам нужен еще один символ **/** - `$` - "конец"! - -Если ты введешь адрес `http://127.0.0.1:8000/post/5/` в браузер, Django должен понять, что тебе требуется *представление* под именем `post_detail`, и передать информацию о переменной `pk` (равной `5`) этому *представлению*. +Фрагмент `post//` определяет шаблон URL-адреса. Сейчас мы его поясним: +- `post/` значит, что после начала строки URL должен содержать слово **post** и косую черту **/**. Пока всё в порядке. +- `` — эта часть посложнее. Она означает, что Django ожидает целочисленное значение и преобразует его в представление — переменную `pk`. +- `/` — затем нам нужен еще один символ __/__ перед тем, как адрес закончится. -`pk` сокращение от `primary key` (первичный ключ). Это имя часто используют в Django проектах. Но ты можешь назвать эту переменную как пожелаешь (помни: строчные буквы и `_` вместо пробелов!). Для примера, вместо `(?P[0-9]+)` мы могли бы иметь переменную `post_id`, таким образом эта часть кода выглядела бы как: `(?P[0-9]+)`. -Славненько, мы добавили новый шаблон URL в файл `blog/urls.py`! Давай обновим страницу: http://127.0.0.1:8000/ Бууум! Ещё одна ошибка! Как и ожидалось! +Славненько, мы добавили новый шаблон URL в файл `blog/urls.py`! Давай обновим страницу: http://127.0.0.1:8000/. Бууум! Сервер снова перестал работать. Проверь консоль — как и ожидалось, ещё одна ошибка! ![AttributeError][2] @@ -79,57 +85,62 @@ ## Добавим представление для страницы поста -В этот раз *представление* получит дополнительный параметр `pk`. Но как дать нашему *представлению* знать о нем? Для этого мы определим функцию как `def post_detail(request, pk):`. Обрати внимание, что мы должны использовать тоже имя переменной, что мы выбрали для обработки URL (`pk`). Пропуск переменной будет неправилен и приведет к ошибке! +В этот раз *представление* получит дополнительный параметр `pk`. Но как дать нашему *представлению* знать о нём? Для этого мы определим функцию как `def post_detail(request, pk):`. Обрати внимание, что мы должны использовать то же имя переменной, что мы выбрали для обработки URL (`pk`). Пропуск переменной будет неправилен и приведёт к ошибке! Теперь мы хотим получить одну конкретную запись из блога. Для этого потребуется использовать QuerySet: +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} ```python - Post.objects.get(pk=pk) +Post.objects.get(pk=pk) ``` -Однако в этом коде есть проблема. Если не существует экземпляра объекта `Post` с заданным `primary key` (`pk`) мы получим страшную ошибку! +Однако в этом коде есть проблема. Если не существует экземпляра объекта `Post` с заданным `primary key` (`pk`), мы получим страшную ошибку! ![Ошибка DoesNotExist][3] [3]: images/does_not_exist2.png -Мы этого не хотим! Однако, Django, конечно, имеет средство, которое позволит нам её обойти: `get_object_or_404`. В случае, если не существует экземпляра объекта `Post` с заданным `pk`, мы получим намного более приятную страницу (которая называется `Page Not Found 404`). +Мы этого не хотим! Однако в Django, конечно, есть средство, которое позволит нам её обойти: `get_object_or_404`. В случае, если не существует экземпляра объекта `Post` с заданным `pk`, мы получим намного более приятную страницу (которая называется `Page Not Found 404`). ![Страница не найдена][4] [4]: images/404_2.png -Хорошая новость в том, что ты можешь сделать свою страницу `Page not found`. Но для нас сейчас это не самая важная задача и мы её пропустим. +Хорошая новость состоит в том, что ты можешь сделать свою страницу `Page not found`. Но для нас сейчас это не самая важная задача, и мы её пропустим. Хорошо, пришло время добавить *представление* в файл `views.py`! +В файле `blog/urls.py` мы создали шаблон URL под названием `post_detail`, который ссылался на представление под названием `views.post_detail`. Это значит, что Django ожидает найти функцию-представление с названием `post_detail` в `blog/views.py`. + Нам нужно открыть файл `blog/views.py` и добавить в него следующий код: +{% filename %}blog/views.py{% endfilename %} ```python - from django.shortcuts import render, get_object_or_404 +from django.shortcuts import render, get_object_or_404 ``` -Рядом с другими строками, начинающимися с `from`. В конец же файла мы добавим наше новое *представление*: +— рядом с другими строками, начинающимися с `from`. В конец же файла мы добавим наше новое *представление*: +{% filename %}blog/views.py{% endfilename %} ```python - def post_detail(request, pk): -     post = get_object_or_404(Post, pk=pk) -     return render(request, 'blog/post_detail.html', {'post': post}) +def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) ``` -Именно. Теперь обнови страницу http://127.0.0.1:8000/ +Вот так. Теперь обнови страницу http://127.0.0.1:8000/ ![Представление списка записей][5] [5]: images/post_list2.png -Заработало! Только что произойдет, если ты попробуешь перейти по ссылке из заголовка записи? +Заработало! Только что произойдёт, если ты попробуешь перейти по ссылке из заголовка записи? ![Ошибка TemplateDoesNotExist][6] [6]: images/template_does_not_exist2.png -Ой, нет! Другая ошибка! Но мы уже знаем как иметь с ней дело, верно? Нам нужно добавить шаблон! +Ой, нет! Другая ошибка! Но мы уже знаем, как иметь с ней дело, верно? Нам нужно добавить шаблон! ## Создадим шаблон для страницы поста @@ -137,61 +148,82 @@ Он должен содержать следующее: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html - {% extends 'blog/base.html' %} +{% extends 'blog/base.html' %} - {% block content %} -
- {% if post.published_date %} -
- {{ post.published_date }} -
- {% endif %} -

{{ post.title }}

-

{{ post.text|linebreaksbr }}

-
- {% endblock %} +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endblock %} ``` И снова мы расширяем `base.html`. В блоке `content` мы отображаем дату публикации (published_date, если она существует), заголовок и текст. Нам также нужно обсудить пару важных вещей, хорошо? -{% raw %}`{% if ... %} ... {% endif %}` это тег шаблона, который мы можем использовать, если нам нужно что-то проверить (помнишь конструкцию `if ... else ..` из главы **Введение в Python**?). В данном случае мы хотим проверить, не пуста ли дата публикации `published_date` поста.{% endraw %} +{% raw %}`{% if ... %} ... {% endif %}` — это тег шаблона, который мы можем использовать, если нам нужно что-то проверить (помнишь конструкцию `if ... else ..` из главы **Введение в Python**?). В данном случае мы хотим проверить, не пуста ли дата публикации поста — `published_date`.{% endraw %} -Отлично, можешь перезагрузить страницу и проверить пропала ли ошибка `Page not found`. +Отлично, можешь перезагрузить страницу и проверить, пропала ли ошибка `Page not found`. ![Отдельная страницы записи][7] [7]: images/post_detail2.png -Ура! Все работает! +Ура! Всё работает! -## Еще одна вещь: развертывание! +## Ещё одна вещь: развёртывание! -Было бы неплохо проверить, что веб-сайт все еще будет работать на PythonAnywhere, верно? Давай еще раз проведем развертывание. +Было бы неплохо проверить, что веб-сайт всё ещё будет работать на PythonAnywhere, верно? Давай еще раз проведём развёртывание. +{% filename %}command-line{% endfilename %} ``` - $ 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 +$ 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 ``` -* Затем набери в [Bash консоли PythonAnywhere][8]: +Затем набери в [Bash-консоли PythonAnywhere][8]: [8]: https://www.pythonanywhere.com/consoles/ +{% filename %}PythonAnywhere command-line{% endfilename %} ``` - $ cd my-first-blog - $ source myvenv/bin/activate - (myvenv)$ git pull - [...] - (myvenv)$ python manage.py collectstatic - [...] +$ cd ~/.pythonanywhere.com +$ git pull +[...] ``` -* И нажми **Reload** на вкладке [Web tab][9]. +И нажми **Reload** на вкладке [Web][9]. [9]: https://www.pythonanywhere.com/web_app_setup/ -Вот и все! Поздравляем :) +## Обновим статические файлы на сервере + +Серверы вроде PythonAnywhere часто обрабатывают статические файлы (например, CSS) не так, как Python-файлы. Так происходит потому, что сервера могут оптимизировать их использование так, чтобы они быстрее загружались. В результате после того, как мы поменяли CSS-файлы, надо дать серверу команду обновить их. Эта команда называется `collectstatic`. + +Начни с активации virtualenv, если окружение уже не активно (PythonAnywhere использует для этого команду `workon`. Она работает так же, как `source myenv/bin/activate`, которую ты используешь на своём компьютере. + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ workon .pythonanywhere.com +(ola.pythonanywhere.com)$ python manage.py collectstatic +[...] +``` + +Команда `manage.py collectstatic` немножко похожа на `manage.py migrate`. Мы сперва вносим какие-то изменения в наш код, а затем сообщаем Django *применить* эти изменения — к набору статических файлов на сервере или к базе данных. + +В любом случае, мы теперь готовы перейти по ссылке ["Web" page][10] (нажав на кнопку в меню в правом верхнем углу консоли) и кликнуть на **Reload**, а затем посмотреть на страницу [https://subdomain.pythonanywhere.com][11], где отобразится результат. + + [10]: https://www.pythonanywhere.com/web_app_setup/ + [11]: https://subdomain.pythonanywhere.com + + +Вот и всё! Поздравляем :) diff --git a/ru/extend_your_application/images/404_2.png b/ru/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/ru/extend_your_application/images/404_2.png and b/ru/extend_your_application/images/404_2.png differ diff --git a/ru/extend_your_application/images/attribute_error2.png b/ru/extend_your_application/images/attribute_error2.png index 6edcd9933c3..33a3b36b1d3 100644 Binary files a/ru/extend_your_application/images/attribute_error2.png and b/ru/extend_your_application/images/attribute_error2.png differ diff --git a/ru/extend_your_application/images/does_not_exist2.png b/ru/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/ru/extend_your_application/images/does_not_exist2.png and b/ru/extend_your_application/images/does_not_exist2.png differ diff --git a/ru/extend_your_application/images/no_reverse_match2.png b/ru/extend_your_application/images/no_reverse_match2.png index 306926206f8..aba1c9c8980 100644 Binary files a/ru/extend_your_application/images/no_reverse_match2.png and b/ru/extend_your_application/images/no_reverse_match2.png differ diff --git a/ru/extend_your_application/images/post_detail2.png b/ru/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/ru/extend_your_application/images/post_detail2.png and b/ru/extend_your_application/images/post_detail2.png differ diff --git a/ru/extend_your_application/images/post_list2.png b/ru/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/ru/extend_your_application/images/post_list2.png and b/ru/extend_your_application/images/post_list2.png differ diff --git a/ru/extend_your_application/images/template_does_not_exist2.png b/ru/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/ru/extend_your_application/images/template_does_not_exist2.png and b/ru/extend_your_application/images/template_does_not_exist2.png differ diff --git a/ru/how_the_internet_works/README.md b/ru/how_the_internet_works/README.md index f22cb9de4a2..76f31772038 100755 --- a/ru/how_the_internet_works/README.md +++ b/ru/how_the_internet_works/README.md @@ -1,14 +1,16 @@ # Как работает Интернет +> Для проходящих курс дома: эта глава рассмотрена в видео [How the Internet Works](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 файлы где-то на жестком диске. Для Интернета мы используем специальные, мощные компьютеры, называемые *серверами*. У них нет экрана, мыши или клавиатуры, потому что их основной целью является хранение и обслуживание данных. Вот почему они называются *серверами*--потому что они *обслуживают* (serve) твои данные. +Как и с любым файлом, нам нужно хранить HTML файлы где-то на жёстком диске. Для Интернета мы используем специальные, мощные компьютеры, называемые *серверами*. У них нет экрана, мыши или клавиатуры, потому что их основной целью является хранение и обслуживание данных. Вот почему они называются *серверами* — потому что они *обслуживают* (serve) твои данные. Хорошо, но ты хочешь знать, как выглядит Интернет, так? @@ -18,13 +20,13 @@ [1]: images/internet_1.png -Довольно беспорядочно, правда? На самом деле, это сеть связанных машин (упомянутых выше *серверов*). Сотен тысяч машин! Километры и километры кабелей по всему миру! Ты можешь посетить веб-сайт с картой подводных кабелей (http://submarinecablemap.com/), чтобы увидеть, насколько сложной является сеть. Вот скриншот с сайта: +Довольно беспорядочно, правда? На самом деле, это сеть связанных машин (упомянутых выше *серверов*). Сотен тысяч машин! Километры и километры кабелей по всему миру! На веб-сайте с картой подводных кабелей (http://submarinecablemap.com/) ты сможешь увидеть, насколько сложной является сеть. Вот скриншот с сайта: ![Рисунок 1.2][2] [2]: images/internet_3.png -Поразительно, не так ли? Однако, очевидно, что невозможно соединить кабелем каждую машину, подключенную к Интернету. Таким образом, чтобы достичь нужной машины (например, хранящей https://djangogirls.org), мы должны передать запрос через множество других машин. +Поразительно, не так ли? Однако, очевидно, что невозможно соединить друг с другом кабелем все машины, подключенные к Интернету. Таким образом, чтобы достичь нужной машины (например, хранящей https://djangogirls.org), мы должны передать запрос через множество других машин. Этот процесс выглядит следующим образом: @@ -34,7 +36,7 @@ Представь себе, что когда ты вводишь адрес https://djangogirls.org, то отправляешь письмо, в котором говорится: «Дорогие Django Girls, я хочу увидеть сайт djangogirls.org. Отправьте мне его, пожалуйста!» -Твое письмо отправляется в ближайшее почтовое отделение. Затем оно направляется в другое, которое немного ближе к адресату, а затем в следующее и так далее до его доставки в пункт назначения. Единственное отличие в том, что при отправке множества писем (*пакетов данных*) по одному адресу, каждое из них может пойти через совершенно разные почтовые отделения (*маршрутизаторы*). Это зависит от того, как они были распределены в каждом отделении. +Твое письмо отправляется в ближайшее почтовое отделение. Затем оно направляется в другое, которое немного ближе к адресату, а затем в следующее и так далее до его доставки в пункт назначения. Единственное отличие в том, что при отправке множества писем (*пакетов данных*) по одному адресу каждое из них может пойти через совершенно разные почтовые отделения (*маршрутизаторы*). Это зависит от того, как они были распределены в каждом отделении. ![Рисунок 1.4][4] @@ -48,6 +50,6 @@ Поэтому, в принципе, когда у тебя есть веб-сайт, то необходимо иметь и *сервер* (машину), где он находится. Когда *сервер* получает входящий *запрос* (в письме), он отправляет обратно твой веб-сайт (в другом письме). -Поскольку это руководство по Django, разумно будет спросить -- что же он делает в этой системе. Когда ты отправляешь ответ, то ты не всегда хочешь отправлять одно и то же письмо всем получателям. Намного лучше, если твои письма являются персонифицированными, особенно для человека, который только что тебе написал сам, правильно? Django помогает тебе с созданием этих персонализированных, интересных писем :). +Поскольку это руководство по Django, разумно будет спросить — что же он делает в этой системе. Когда ты отправляешь ответ, то ты не всегда хочешь отправлять одно и то же письмо всем получателям. Намного лучше, если твои письма являются персонифицированными, особенно для человека, который только что тебе написал сам, правильно? Django помогает тебе с созданием этих персонализированных, интересных писем :). -Ну, хватит болтать, время заняться делом! \ No newline at end of file +Ну, хватит болтать, время заняться делом! diff --git a/ru/how_the_internet_works/images/internet_1.png b/ru/how_the_internet_works/images/internet_1.png index 9c5bcf0b003..e289eac2b23 100644 Binary files a/ru/how_the_internet_works/images/internet_1.png and b/ru/how_the_internet_works/images/internet_1.png differ diff --git a/ru/how_the_internet_works/images/internet_2.png b/ru/how_the_internet_works/images/internet_2.png index dd5861f376f..e8cf8b77999 100644 Binary files a/ru/how_the_internet_works/images/internet_2.png and b/ru/how_the_internet_works/images/internet_2.png differ diff --git a/ru/how_the_internet_works/images/internet_3.png b/ru/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/ru/how_the_internet_works/images/internet_3.png and b/ru/how_the_internet_works/images/internet_3.png differ diff --git a/ru/how_the_internet_works/images/internet_4.png b/ru/how_the_internet_works/images/internet_4.png index 2661cec1b61..d4748ac48ef 100644 Binary files a/ru/how_the_internet_works/images/internet_4.png and b/ru/how_the_internet_works/images/internet_4.png differ diff --git a/ru/html/README.md b/ru/html/README.md index 447b7b6a1c5..6ac6ac5b843 100755 --- a/ru/html/README.md +++ b/ru/html/README.md @@ -1,51 +1,52 @@ # Введение в HTML -Так что же это за шаблон, ты можешь спросить. +«Так что же это за шаблон?» — можешь спросить ты. -Шаблон -- это файл, который мы можешь использовать повторно для отображения различной информации в заданном формате, например, ты можешь использовать шаблон, чтобы упростить написание письма, поскольку письма хоть и различаются по содержанию и получателю, но сохраняют общую структуру. +Шаблон — это файл, который ты можешь использовать повторно для отображения различной информации в заданном формате; например, ты можешь использовать шаблон, чтобы упростить написание письма, поскольку письма хоть и различаются по содержанию и получателю, но сохраняют общую структуру. -Шаблоны в Django написаны на языке, называемом HTML (это тот HTML, о котором было упоминание в первой главе **Как работает Интернет**). +Шаблоны в Django написаны на языке, называемом HTML (это тот HTML, о котором было упоминание в первой главе __Как работает Интернет__). ## Что такое HTML? -HTML -- это простой код, который может быть интерпретирован твоим браузером -- таким как Chrome, Firefox или Safari -- чтобы отобразить веб-страницу пользователю. +HTML — это простой код, который может быть интерпретирован твоим браузером — таким как Chrome, Firefox или Safari — чтобы отобразить веб-страницу пользователю. -HTML (от англ. "HyperText Markup Language") - язык гипертекстовой разметки. **Гипертекст** - это тип текста, поддерживающий гиперссылки между страницами. Под **разметкой** понимается введение в текст документа кода, который будет говорить браузеру (в нашем случае) как интерпретировать веб-страницу. HTML код строится при помощи **тегов**, каждый из которых должен начинаться с `<` и заканчиваться `>`. Эти теги представляют **элементы** разметки. +HTML (от англ. "HyperText Markup Language") — язык гипертекстовой разметки. __Гипертекст__ — это тип текста, поддерживающий гиперссылки между страницами. Под __разметкой__ понимается введение в текст документа кода, который будет говорить браузеру (в нашем случае), как интерпретировать веб-страницу. HTML код строится при помощи __тегов__, каждый из которых должен начинаться с `<` и заканчиваться `>`. Эти теги представляют __элементы__ разметки. ## Твой первый шаблон! -Создание шаблона означает создание файла шаблона. Все есть файл, верно? Ты уже заметила это, наверно. +Создание шаблона означает создание файла шаблона. Всё есть файл, верно? Ты уже наверняка заметила это. -Шаблоны сохраняются в директории `blog/templates/blog`. Для начала создай директорию `templates` внутри папки blog. Затем создай другую директорию `blog` внутри папки templates: +Шаблоны сохраняются в директории `blog/templates/blog`. Для начала создай директорию `templates` внутри директории blog. Затем создай другую директорию `blog` внутри директории templates: - blog - └───templates - └───blog - +``` +blog +└───templates + └───blog +``` -(Ты, вероятно, можешь задаться вопросом: зачем нам нужны две директории с одинаковым названием `blog` - как ты узнаешь позже, это просто удобное соглашение об именовании, которое делает жизнь проще, когда вещи серьезно усложняются.) +(Ты, вероятно, можешь задаться вопросом: зачем нам нужны две директории с одинаковым названием `blog` — как ты узнаешь позже, это просто удобное соглашение об именовании, которое делает жизнь проще, когда вещи серьезно усложняются.) Теперь создай файл `post_list.html` (для начала оставь его пустым) внутри директории `blog/templates/blog`. -Посмотри как выглядит твой веб-сайт после этого: http://127.0.0.1:8000/ +Посмотри, как выглядит твой веб-сайт после этого: http://127.0.0.1:8000/ -> Если тебя все еще встречает ошибка `TemplateDoesNotExists`, попробуй перезапустить сервер. Перейди в командную строку, останови веб-сервер нажатием Ctrl+C (Ctrl и С одновременно) и запусти его снова командой `python manage.py runserver`. +> Если тебя всё ещё встречает ошибка `TemplateDoesNotExists`, попробуй перезапустить сервер. Перейди в командную строку, останови веб-сервер нажатием Ctrl+C (Ctrl и С одновременно) и запусти его снова командой `python manage.py runserver`. ![Рисунок 11.1][1] [1]: images/step1.png -Ошибки больше нет! Поздравляем :) Однако, твой веб-сайт все равно ничего не отображает, кроме пустой страницы, поскольку твой шаблон пуст. Нам нужно это исправить. +Ошибки больше нет! Поздравляем :) Однако твой веб-сайт всё равно ничего не отображает, кроме пустой страницы, поскольку твой шаблон пуст. Нам нужно это исправить. Добавь следующий код в файл шаблона: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html

Hi there!

It works!

``` - Как теперь выглядит твой веб-сайт? Нажми сюда, чтобы узнать: http://127.0.0.1:8000/ @@ -55,33 +56,34 @@ HTML (от англ. "HyperText Markup Language") - язык гипертекс Заработало! Хорошая работа :) -* Наиболее базовой тег, ``, всегда присутствует в начале веб-страницы и `` - в конце. Как ты можешь заметить, основной контент веб-сайта находится между тегами `` и `` -* `

` - это тег для параграфов; `

`, соответственно, закрывает каждый параграф +- Наиболее базовый тег, ``, всегда присутствует в начале веб-страницы, а `` — в конце. Как ты можешь заметить, основной контент веб-сайта находится между тегами `` и ``. +- `

` — это тег для параграфов; `

`, соответственно, закрывает каждый параграф. -## Head & body +## Head и body -Каждая HTML-страница также делится на два элемента: **head** и **body**. +Каждая HTML-страница также делится на два элемента: __head__ и __body__. -* **head** -- это элемент, содержащий информацию о документе, которая не отображается на экране. +- __head__ — это элемент, содержащий информацию о документе, которая не отображается на экране. -* **body** -- это элемент, который содержит все, что будет отражено на веб-странице. +- __body__ — это элемент, который содержит всё, что будет отражено на веб-странице. -Мы используем тег `` чтобы сообщить браузеру о настройках страницы и тег `` - о её содержимом. +Мы используем тег ``, чтобы сообщить браузеру о настройках страницы, и тег `` — о её содержимом. Например, ты можешь разместить элемент title между тегов ``: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - - - Ola's blog - - -

Hi there!

-

It works!

- - -``` - + + + Ola's blog + + +

Hi there!

+

It works!

+ + +``` + Сохрани файл и обнови страницу. @@ -89,123 +91,135 @@ HTML (от англ. "HyperText Markup Language") - язык гипертекс [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 - - - - -
-

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` (параграфа) с текстом, один для даты и другой для самого текста записи. - -Это даст нам следующий эффект: + + + 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` (параграфа) с текстом, один для даты, а другой — для самого текста записи. + +Это даёт нам следующий результат: ![Рисунок 11.4][4] [4]: images/step6.png -Ура! Однако, до сих пор наш шаблон отображал лишь **одну и ту же информацию** - тогда как раньше мы говорили, что шаблоны позволяют нам отображать **различную** информацию в **одном и том же формате**. +Ура! Однако до сих пор наш шаблон отображал лишь __одну и ту же информацию__ — тогда как раньше мы говорили, что шаблоны позволяют нам отображать __различную__ информацию в __одном и том же формате__. + +Что мы действительно хотим, так это отображать существующие записи, добавленные через панель администратора Django; этим и займёмся в следующий раз. -Что мы действительно хотим - это отображать существующие записи, добавленные через панель администратора Django, этим и займемся в следующий раз. +## И ещё кое-что: публикация! -## Еще одно: развертывание! +Хотелось бы увидеть всё это вживую в интернете, согласна? Давай проведём еще одно развёртывание веб-сайта на PythonAnywhere. -Хотелось бы увидеть все это в живую в интернете, согласна? Давай проведем еще одно развертывание веб-сайта на PythonAnywhere: +### Commit и push кода в репозиторий GitHub -### Commit и push кода в репозиторий Github +Во-первых, давай посмотрим, какие файлы были изменены с момента последнего развёртывания (выполни эти команды локально, не на PythonAnywhere): -Во-первых, давай посмотрим, какие файлы были изменены с момента последнего развертывания (выполни эти команды локально, не на PythonAnywhere): +{% filename %}command-line{% endfilename %} +``` +$ git status +``` - $ git status - +Убедись, что находишься в директории `djangogirls`, и попроси `git` выбрать все изменения в пределах папки: -Убедись, что находишься в директории `djangogirls` и сообщи `git` выбрать все изменения в пределах папки: +{% filename %}command-line{% endfilename %} +``` +$ git add --all . +``` - $ git add --all . - +> **Примечание**: `--all` («всё») означает, что `git` также обратит внимание на удалённые файлы (по умолчанию он отслеживает новые/изменённые файлы). Также помни (из третьей главы), что `.` означает текущую директорию. -> **Примечание**: `-A` (сокращение от "all" - "все") означает, что `git` также обратит внимание на удаленные файлы (по умолчанию, он отслеживает новые/измененные файлы). Также помни (из третьей главы), что `.` означает текущую директорию. +Прежде чем мы загрузим файлы, давай проверим, что именно `git` будет загружать (все файлы, которые `git` готов отправить на сервер, отмечаются шрифтом зелёного цвета): -Прежде чем мы загрузим файлы, давай проверим, что именно `git` будет загружать (все файлы, который `git` готов отправить на сервер отмечаются шрифтом зеленого цвета): +{% filename %}command-line{% endfilename %} +``` +$ git status +``` - $ git status - +Мы почти у цели, пришло время сохранить изменения в истории. К сохраняемой версии мы добавим небольшое сообщение, в котором кратко опишем изменения. Можешь набрать в качестве сообщения всё, что захочешь, однако полезно использовать информативную запись, так будет проще вспомнить внесённые изменения в будущем. + +{% filename %}command-line{% endfilename %} +``` +$ git commit -m "Changed the HTML for the site." +``` -Мы почти у цели, пришло время сохранить изменения в истории. К сохраняемой версии мы приложим небольшое сообщение, в котором кратко опишем изменения. Можешь набрать в качестве сообщения все что захочешь, однако, полезно использовать информативную запись, так будет проще вспомнить внесенные изменения в будущем. - $ git commit -m "Changed the HTML for the site." - +> __Примечание__: убедись, что используешь двойные кавычки вокруг комментария. -> **Примечание**: Убедись, что используешь двойные кавычки вокруг комментария. +После того, как мы сделали это, мы загрузим (заpush'им) изменения на GitHub: -После того, как мы сделали это, мы загрузим (заpush'им) изменения на Github: +{% filename %}command-line{% endfilename %} +``` +$ git push +``` - git push - ### Загружаем новый код на PythonAnywhere и перезапускаем веб-приложение -* Открой вкладку ["терминалы"][5] на PythonAnywhere и переключись на уже запущенную **консоль Bash** (или новую). Затем набери следующую команду: +* Открой вкладку ["терминалы"][5] на PythonAnywhere и переключись на уже запущенную **консоль Bash** (или новую). Затем набери следующую команду: [5]: https://www.pythonanywhere.com/consoles/ - $ 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 +[...] +``` -Можешь обратить внимание как твой код будет загружаться на сервер. Если хочешь проверить успешность процедуры - открой вкладку **Файлы** и просмотри свой код на PythonAnywhere. +Можешь понаблюдать, как твой код будет загружаться на сервер. Если хочешь проверить успешность процедуры — открой вкладку **Файлы** и просмотри свой код на PythonAnywhere. -* Наконец, переключись на вкладку [Web][6] и нажми кнопку **Reload**. +* Наконец, переключись на вкладку [Web][6] и нажми кнопку **Reload**. [6]: https://www.pythonanywhere.com/web_app_setup/ diff --git a/ru/html/images/step1.png b/ru/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/ru/html/images/step1.png and b/ru/html/images/step1.png differ diff --git a/ru/html/images/step3.png b/ru/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/ru/html/images/step3.png and b/ru/html/images/step3.png differ diff --git a/ru/html/images/step4.png b/ru/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/ru/html/images/step4.png and b/ru/html/images/step4.png differ diff --git a/ru/html/images/step6.png b/ru/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/ru/html/images/step6.png and b/ru/html/images/step6.png differ diff --git a/ru/images/application.png b/ru/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/ru/images/application.png and b/ru/images/application.png differ diff --git a/ru/installation/README.md b/ru/installation/README.md index dcc794f313e..73b77d8a527 100755 --- a/ru/installation/README.md +++ b/ru/installation/README.md @@ -1,39 +1,46 @@ # Если ты занимаешься дома -Если ты занимаешься по этому руководство дома, а не на одной из [встреч 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 Grils включают в себя "вечер настроек", когда мы устанавливаем всё что нужно, чтобы не тратить на это время в течение основного семинара, это очень удобно для нас. - -Если ты также считаешь эту идею удачной, то можешь следовать содержанию главы. Чтобы сразу перейти к изучению нового материала, пропустив установку необходимых программ, просто пропусти эту главу - мы будем объяснять все необходимые вещи по мере продвижения по руководству. +Дело в том, что по ходу руководства мы всё равно будем рассматривать все эти вещи, а текущий раздел является дополнительным, где мы просто собрали инструкции по установке вместе (это используется в некоторых форматах мастер-классов). Ты можешь установить все сразу, воспользовавшись инструкцией ниже. Но можешь пропустить этот раздел, приступив к изучению основного материала, где детали установки мы объясним по мере необходимости. Удачи! -# Установка +# Если ты посещаешь мастер-класс -В процессе мастер-класса мы будем создавать блог и у нас есть несколько подготовительных задач по установке, которые не помешало бы выполнить заранее, чтобы тебе не пришлось отвлекаться от программирования. +Если ты находишься на одном из [мероприятий Django Girls](https://djangogirls.org/events/): +- Эта страница для тебя, если ты находишься на встрече Django Girls "вечер настроек" перед основным семинаром! Следуй инструкции ниже, а если возникнут трудности, попроси наставника помочь. На основном мастер-классе ты можешь пропускать инструкции по установке, с которыми столкнёшься. +- Возможно, организаторы мастер-класса, в котором ты будешь участвовать, попросили установить всё необходимое перед событием. Если это так, то эта страница для тебя! Следуй инструкции ниже. Если что-то самостоятельно выполнить не получилось, ничего страшного, на мероприятии ты можешь воспользоваться помощью наставника. +- Если мастер-класс, участницей которого ты являешься, не организует встречу "вечер настроек" (или ты не смогла присутствовать), и организаторы не попросили тебя попытаться установить все до начала мероприятия, пропусти этот раздел и переходи к главе [Как работает интернет](../how_the_internet_works/README.md). Не переживай, ты установишь все необходимое во время прохождения руководства на самом мастер-классе. -# Установка Python +# Установка +На мастер-классе ты будешь создавать блог. Также по мере необходимости, ты узнаешь, как устанавливать различное программное обеспечение и создашь некоторые учетные записи. Данная страница является местом, где собраны вместе все необходимые инструкции по установке и регистрации. -{% include "/python_installation/instructions.md" %} + +{% include "/chromebook_setup/instructions.md" %} + -# Настрока virtualenv и установка Django +# Краткое введение в командную строку +В инструкции ниже ты часто будешь встречать такие термины, как "консоль", "терминал", "командная строка", на самом деле, они обозначают одно и тоже - окно на компьютере, в которое ты можешь вводить команды. Когда приступишь к основному руководству, ты узнаешь больше о командной строке. На данном этапе необходимо знать только, как открыть окно и как оно выглядит. +{% include "/intro_to_command_line/open_instructions.md" %} -{% include "/django_installation/instructions.md" %} +# Установка Python +{% include "/python_installation/instructions.md" %} # Установка редактора кода - {% include "/code_editor/instructions.md" %} -# Установка Git +# Настрока virtualenv и установка Django +{% include "/django_installation/instructions.md" %} +# Установка Git {% include "/deploy/install_git.md" %} # Создание учётной записи на GitHub - Перейди на [GitHub.com](https://www.github.com) и зарегистрируй новый бесплатный аккаунт. # Создание учётной записи на PythonAnywhere - {% include "/deploy/signup_pythonanywhere.md" %} # Начинай читать diff --git a/ru/intro_to_command_line/README.md b/ru/intro_to_command_line/README.md index 738d5c35480..33233a30f9c 100755 --- a/ru/intro_to_command_line/README.md +++ b/ru/intro_to_command_line/README.md @@ -1,72 +1,96 @@ # Знакомство с командной строкой -Вот это интересно, да?! Ты напишешь свою первую строку кода всего через несколько минут :) +> Для тех, кто проходит руководство дома: о материале этой главы рассказывает видео [Ваш новый друг — командная строка](https://www.youtube.com/watch?v=jvZLWhkzX-8). -**Позволь представить нашего первого нового друга: командную строку!** +Вот это да! Всего через несколько минут ты напишешь свою первую строку кода! :) -Следующие шаги покажут как использовать черное окно, которым пользуются все хакеры. В начале оно может показаться немного пугающим, но, на самом деле это просто окно, которое ждет от тебя команды. +__Позволь представить нашего первого нового друга: командную строку!__ -> **Примечание** Пожалуйста, обратите внимание, что в этой книге мы используем термины «каталог» и «папка» взаимозаменяемо, эти слова обозначают одно и то же. +Следующие шаги покажут, как использовать чёрное окно, которым пользуются все хакеры. В начале оно может показаться немного пугающим, но, на самом деле это просто окно, которое ждет от тебя команды. + +> **Примечание** Пожалуйста, обрати внимание, что в этом руководстве мы используем термины «каталог» и «папка» взаимозаменяемо: эти слова обозначают одно и то же. ## Что такое командная строка? -Окно, которое обычно называют **командной строкой** или **интерфейсом командной строки (англ. CLI, Command Line Interface)**, является текстовым приложением для просмотра, обработки и манипулирования файлами на вашем компьютере. Как Проводник Windows или Finder на Mac, но без графического интерфейса. Другими названиями для командной строки являются: *cmd*, *CLI*, *prompt*, *консоль* или *терминал*. +Окно, которое обычно называют __командной строкой__ или __интерфейсом командной строки (англ. CLI, Command Line Interface)__, является текстовым приложением для просмотра, обработки и манипулирования файлами на вашем компьютере. Она делает то же, что и Проводник в Windows или Finder в macOS, но у неё нет графического интерфейса. Другими названиями для командной строки являются: *cmd*, *CLI*, *prompt*, *консоль* или *терминал*. ## Открываем интерфейс командной строки Для того, чтобы начать экспериментировать, нам нужно сначала открыть интерфейс командной строки. +{% include "/intro_to_command_line/open_instructions.md" %} + +## Командная строка -### Windows +Перед тобой должно появиться белое или чёрное окошко. Оно ожидает, когда ты введёшь команду. -Перейти в меню Пуск → Все программы → Стандартные → Командная строка. + -### Mac OS X -Приложения → Утилиты → Терминал. +Если у тебя Mac или Linux, ты, скорее всего, увидишь знак `$` в конце строки (перед курсором): -### Linux +{% filename %}command-line{% endfilename %} +``` +$ +``` + -Вероятно, командная строка скрывается по адресу: Приложения → Стандартные → Терминал, но это может зависеть от конкретной системы. Если не сможешь найти - Google поможет :) + -## Командная строка -Теперь ты должна увидеть окно белого или черного цвета, которое ожидает команд. +Если у тебя Windows, строка будет оканчиваться символом `>`, вот так: -Если ты используешь Mac или Linux, то, вероятно, увидишь символ `$`: - $ - +{% filename %}command-line{% endfilename %} +``` +> +``` -В Windows ты увидишь знак `>`: +Можешь заглянуть в инструкцию для пользовательниц Linux чуть выше -- нам что-то подобное ещё встретится, когда мы дойдём до PythonAnywhere. - > - + -Каждую команду будет предварять этот знак и один пробел, но тебе не придется их вводить. Компьютер сделает это за нас :) +Перед каждой твоей командой будет стоять знак `$` или `>` и пробел. Но тебе не нужно их печатать! Компьютер уже сделал это за тебя. :) -> Небольшое примечание: в твоем случае до знака командной строки может быть что-то вроде `C:\Users\ola >` или `Olas-MacBook-Air:~ ola$`, и это 100% правильно. В данном руководстве мы просто будем сокращать запись до разумного минимума. +> Небольшое примечание: перед курсором командной строки может быть написано что-то вроде `C:\Users\ola>` или `Olas-MacBook-Air:~ ola$`. Это абсолютно нормально. + +То, что написано до знака `$` или `>`, плюс сам знак, всё вместе называется *приглашением командной строки*. Как правило, оно включает адрес папки, в которой ты сейчас находишься. Оно приглашает тебя ввести в окно команду. + +Далее в руководстве перед каждой командой, которую тебе нужно будет ввести, мы будем писать символ `$` или `>`. Иногда слева от него мы будем добавлять ещё немного текста. Не обращай внимания на левую часть и просто печатай команду — она начинается после специального символа. ## Твоя первая команда (УРА!) -Давай начнем с чего-то простого. Введи следующую команду: +Давай введём следующую команду: + + - $ whoami - +{% filename %}command-line{% endfilename %} +``` +$ whoami +``` -или + - > whoami - -И затем нажми `enter`. Вот наш результат: + - $ whoami - olasitarska - +{% filename %}command-line{% endfilename %} +``` +> whoami +``` -Как видишь, компьютер только что напечатал твоё имя пользователя. Аккуратный, правда? :) + -> Попробуй набирать каждую команду самостоятельно, а не копировать и вставлять. Ты запомнишь больше таким образом! +Теперь нажми `Enter`. Вот что получилось: + +{% filename %}command-line{% endfilename %} +``` +$ whoami +olasitarska +``` + +Как видишь, компьютер только что вывел на экран твоё имя пользователя. Классно, а? :) + +> Постарайся набирать каждую команду вручную, а не копировать и вставлять. Так ты больше запомнишь! ## Основы @@ -74,206 +98,340 @@ ### Текущий каталог -Было бы приятно знать, где мы находимся сейчас, верно? Давай посмотрим. Введи следующую команду и нажми `enter`: +Было бы неплохо знать, где мы находимся сейчас, верно? Давай посмотрим. Набери эту команду и нажми `Enter`: + + + + +{% filename %}command-line{% endfilename %} +``` +$ pwd +/Users/olasitarska +``` - $ pwd - /Users/olasitarska - +> Примечание: 'pwd' означает 'print working directory' (вывести рабочий каталог). -Если ты в Windows: + - > cd - C:\Users\olasitarska - + + + +{% filename %}command-line{% endfilename %} +``` +> cd +C:\Users\olasitarska +``` +> Примечание: 'cd' означает 'change directory'(сменить каталог). Если ты пользуешься PowerShell, можешь ввести pwd — как на Linux или macOS. + + Ты, вероятно, увидишь нечто похожее на своем компьютере. Когда ты открываешь командную строку, то обычно находишься в домашнем каталоге текущего пользователя. -> Примечание: «pwd» означает «вернуть рабочий каталог» 'print working directory'. +--- + +### Как узнать больше о командах + +У многих команд для командной строки есть встроенная справка! Например, вот как узнать подробнее о команде, которая показывает, в какой папке ты сейчас находишься: + + + +В macOS и Linux есть команда `man` — справка о других командах (на английском языке). Набери `man pwd` и посмотри, что пишут о команде `pwd`. Используй `man` с другими командами, чтобы посмотреть для них справку. Как правило, справки `man` выводятся постранично. Нажми пробел, чтобы перейти на следующую страницу. Чтобы выйти, нажми `q`. + + + + + + +Чтобы вывести справку, почти к любой команде можно добавить `/?`. Чтобы прочитать всю справку, возможно, придётся прокрутить текст вниз. Попробуй набрать `cd /?`. + + -* * * ### Список файлов и каталогов -Так что же в нем? Было бы здорово узнать. Давайте посмотрим: +Так что же в нем? Было бы здорово узнать. Давай посмотрим: - $ ls - Applications - Desktop - Downloads - Music - ... - + -Windows: +{% filename %}command-line{% endfilename %} +``` +$ ls +Applications +Desktop +Downloads +Music +... +``` + - > 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 - ... - + -* * * + +{% 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 +... +``` +> Примечание: в PowerShell можешь использовать 'ls' — как в Linux или macOS. + + +--- ### Смена текущего каталога -Теперь вернемся в наш каталог рабочего стола: +Теперь вернёмся в наш каталог рабочего стола: + + + +{% filename %}command-line{% endfilename %} +``` +$ cd Desktop +``` + + + + +{% filename %}command-line{% endfilename %} +``` +$ cd Desktop +``` - $ cd Desktop - +Обрати внимание, что название каталога "Desktop" может быть переведено на язык твоей учётной записи в системе Linux. +В таком случае набери вместо `Desktop` переводное название: например, `Рабочий стол` (в кавычках — они нужны, чтобы командная строка поняла кириллицу). -Windows: + - > cd Desktop - + + + +{% filename %}command-line{% endfilename %} +``` +> cd Desktop +``` + Проверь, что рабочий каталог действительно изменился: - $ pwd - /Users/olasitarska/Desktop - + + +{% filename %}command-line{% endfilename %} +``` +$ pwd +/Users/olasitarska/Desktop +``` + -Windows: + - > cd - C:\Users\olasitarska\Desktop - +{% filename %}command-line{% endfilename %} +``` +> cd +C:\Users\olasitarska\Desktop +``` + Вот и он! -> ПРО совет: Если ты введешь `cd D` и затем нажмешь `Tab` на клавиатуре, в командной строке будет автоматически набрана остальная часть имени, что позволит быстрее перемещаться по каталогам. Если существует более одной папки, название которой начинается с «D», нажми `Tab` дважды, чтобы получить список вариантов. +> Совет от профи: если ты введешь `cd D` и затем нажмешь `tab` на клавиатуре, в командной строке будет автоматически набрана остальная часть имени, что позволит быстрее перемещаться по каталогам. Если c "D", начинается название не одной папки, нажми `Tab` дважды, чтобы получить список вариантов. -* * * +--- ### Создание каталога -Как насчет создания каталога practice на рабочем столе? Вы можете сделать это таким образом: +Как насчет создания каталога practice на рабочем столе? Ты можешь сделать это так: - $ mkdir practice - + -Windows: +{% filename %}command-line{% endfilename %} +``` +$ mkdir practice +``` + - > mkdir practice - + -Эта маленькая команда создаст папку с именем `practice` на рабочем столе. Ты можешь проверить, появилась ли она, просто взглянув на рабочий стол или введя команду `ls` / `dir`! Попробуй :) -> ПРО совет: Если ты не хочешь вводить одни и те же команды снова и снова, попробуйте нажать на `стрелку вверх` и `стрелку вниз` на клавиатуре, чтобы просмотреть недавно использованные команды. +{% filename %}command-line{% endfilename %} +``` +> mkdir practice +``` + -* * * +Эта маленькая команда создаст папку с именем `practice` на рабочем столе. Ты можешь проверить, появилась ли она, просто взглянув на рабочий стол или введя команду `ls` (для Linux и macOS) или `dir` (если у тебя Windows)! Попробуй. :) -### Тренеруемся! +> Совет от профи: если ты не хочешь вводить одни и те же команды снова и снова, попробуй нажать на `стрелку вверх` и `стрелку вниз` на клавиатуре для просмотра недавно использованных команд. + +--- + +### Тренируемся! Небольшая задачка: в недавно созданной папке `practice` создай папку с названием `test`. Используй команды `cd` и `mkdir`. #### Решение: - $ cd practice - $ mkdir test - $ ls - test - + + +{% filename %}command-line{% endfilename %} +``` +$ cd practice +$ mkdir test +$ ls +test +``` + -Windows: + - > cd practice - > mkdir test - > dir - 05/08/2014 07:28 PM test - + +{% filename %}command-line{% endfilename %} +``` +> cd practice +> mkdir test +> dir +05/08/2014 07:28 PM test +``` + Поздравляем! :) -* * * +--- ### Чистка -Мы не хотим оставлять беспорядок, поэтому давай удалим все, что мы создали до этого момента. +Мы не хотим оставлять беспорядок, поэтому давай удалим всё, что мы создали до этого момента. Во-первых, мы должны вернуться на рабочий стол: - $ cd .. - + + +{% filename %}command-line{% endfilename %} +``` +$ cd .. +``` + + + -Windows: - > cd.. - +{% filename %}command-line{% endfilename %} +``` +> cd .. +``` + -Используя `..` с командой `cd` ты можешь сменить текущий каталог на родительский (то есть каталог, содержащий в себе текущий). +Используя `..` с командой `cd`, ты можешь сменить текущий каталог на родительский (то есть каталог, который содержит в себе текущий). Проверь, где ты находишься: - $ pwd - /Users/olasitarska/Desktop - + -Windows: +{% filename %}command-line{% endfilename %} +``` +$ pwd +/Users/olasitarska/Desktop +``` + - > cd - C:\Users\olasitarska\Desktop - + + + +{% filename %}command-line{% endfilename %} +``` +> cd +C:\Users\olasitarska\Desktop +``` + Пришло время удалить каталог `practice`: -> **Внимание**: удаление файлов с помощью `del`, `rmdir` или `rm` безвозвратно, это означает, что *удаленные файлы будут потеряны навсегда*! Поэтому будь очень осторожна с этими командами. +> __Внимание__: удаление файлов с помощью `del`, `rmdir` или `rm` необратимо. Это означает, что _удалённые файлы будут потеряны навсегда_! Поэтому будь очень осторожна с этими командами. + + - $ rm -r practice - +{% filename %}command-line{% endfilename %} +``` +$ rm -r practice +``` + -Windows: + - > rmdir /S practice - practice, Are you sure ? Y - + +{% filename %}command-line{% endfilename %} +``` +> rmdir /S practice +practice, Are you sure ? Y +``` + Готово! Давай проверим, что папка действительно удалена: - $ ls - + + +{% filename %}command-line{% endfilename %} +``` +$ ls +``` + + + -Windows: - > dir - +{% filename %}command-line{% endfilename %} +``` +> dir +``` + ### Выход -Вот и все на данный момент! Теперь можно безопасно закрыть командную строку. Давай сделаем это как хакеры, согласна? :) +Вот и всё на данный момент! Теперь можно безопасно закрыть командную строку. Давай сделаем это как хакеры, согласна? :) - $ exit - + -Windows: +{% filename %}command-line{% endfilename %} +``` +$ exit +``` + - > exit - + + + +{% 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** +rmdir (или 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][1] содержит полный справочник команд для всех операционных систем. - - [1]: http://ss64.com +Если тебе интересно, на [ss64.com](http://ss64.com) можно найти полный справочник команд для всех операционных систем (на английском языке). -## Готова? +## Готова продолжить? Давай погрузимся в мир Python! diff --git a/ru/intro_to_command_line/open_instructions.md b/ru/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..685d27bcb85 --- /dev/null +++ b/ru/intro_to_command_line/open_instructions.md @@ -0,0 +1,28 @@ + + + +В зависимости от твоей версии Windows и того, какая у тебя клавиатура, одно из следующих действий откроет окно командной строки (возможно, придётся немного поэкспериментировать, но все варианты пробовать необязательно): +- Перейди в меню Пуск (или на экран Пуск), в строке поиска набери "Командная строка". +- Перейди в меню Пуск → Windows → Командная строка. +- Перейди в меню Пуск → Все программы → Служебные → Командная строка. +- Перейди на экран Пуск, наведи мышь на нижний левый угол экрана и нажми на стрелочку вниз, которая появится там. (Если у тебя тачскрин, листни пальцем снизу вверх.) Откроется страница "Приложения". Выбери пункт "Командная строка" в разделе "Windows". +- Удерживая клавишу Windows на клавиатуре, нажми X. В появившемся меню выбери пункт "Командная строка". +- Удерживая клавишу Windows, нажми R, чтобы появилось окно "Выполнить". Набери в строке cmd и нажми OK. + +![Type "cmd" in the "Run" window](../python_installation/images/windows-plus-r.png) + +В какой-то момент тебе понадобятся два окна командной строки одновременно. Однако в некоторых версиях Windows, если ты попытаешься запустить вторую командную строку, когда одна уже запущена тем же способом, ты вместо этого попадёшь в уже открытое окно командной строки. Попробуй у себя на компьютере и посмотри, что будет! Если у тебя получается открыть только одно окно командной строки, попробуй какой-нибудь другой из вышеприведённых способов в списке. По крайней мере один из них сможет открыть новое окно командной строки. + + + + + +Перейди в Приложения → Прочие → Терминал. + + + + + +Вероятно, командная строка скрывается по адресу: Приложения → Стандартные → Терминал или Приложения → Система → Терминал, но это может зависеть от конкретной системы. Если не сможешь найти — Google поможет :) + + diff --git a/ru/python_installation/README.md b/ru/python_installation/README.md index a50e21ae58e..18f7631dc23 100755 --- a/ru/python_installation/README.md +++ b/ru/python_installation/README.md @@ -1,13 +1,15 @@ # Давай начнем работать с Python -Мы, наконец-то, здесь! +Мы наконец-то здесь! -Для начала, позволь рассказать что такое Python. Python - это очень популярный язык программирования, который может использоваться для создания веб-сайтов, игр, научного программного обеспечения, графики и многого, многого другого. +Но сначала позволь рассказать, что такое Python. Python — это очень популярный язык программирования, который может использоваться для создания веб-сайтов, игр, научного программного обеспечения, графики и многого, многого другого. -Python возник в конце 80-х годов, и его основной целью является быть удобным для чтения людьми (не только машинами!). Именно поэтому он выглядит намного проще, чем другие языки программирования. Это делает его простым для изучения, но не волнуйся, Python кроме этого еще и очень мощный язык! +Python возник в конце 80-х годов, и его основная цель — быть понятным для людей (а не только машин!). Благодаря этому он выглядит простым, но не беспокойся — Python кроме этого ещё и очень мощный язык! # Установка Python -> **Примечание** Если ты уже прошла через шаги установки, не нужно делать это снова - можешь переходить прямо к следующей главе! +> **Примечание:** если ты используешь Chromebook, пропусти эту главу, но выполни инструкции по [настройке для Chromebook](../chromebook_setup/README.md) -{% include "/python_installation/instructions.md" %} \ No newline at end of file +> **Примечание:** если ты уже прошла шаги установки, не нужно делать это снова — можешь переходить прямо к следующей главе! + +{% include "/python_installation/instructions.md" %} diff --git a/ru/python_installation/images/add_python_to_windows_path.png b/ru/python_installation/images/add_python_to_windows_path.png index 9510d6f2176..3266efb6177 100644 Binary files a/ru/python_installation/images/add_python_to_windows_path.png and b/ru/python_installation/images/add_python_to_windows_path.png differ diff --git a/ru/python_installation/images/python-installation-options.png b/ru/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..a0a6c65d81d Binary files /dev/null and b/ru/python_installation/images/python-installation-options.png differ diff --git a/ru/python_installation/images/windows-plus-r.png b/ru/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/ru/python_installation/images/windows-plus-r.png differ diff --git a/ru/python_installation/instructions.md b/ru/python_installation/instructions.md index 7a385f25015..b27995effa8 100755 --- a/ru/python_installation/instructions.md +++ b/ru/python_installation/instructions.md @@ -1,66 +1,113 @@ +> Для проходящих руководство дома: эта глава рассмотрена в видео [Installing Python & Code Editor](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 }} или более высокая, она должна подойти. + + + + +Для начала проверь, какая версия Windows у тебя на компьютере — 32-битная или 64-битная. Это будет указано в строке «Тип системы» на странице «Сведения о системе». Чтобы попасть туда, попробуй один из этих способов: +* Нажми одновременно клавиши Windows и Pause/Break +* Открой панель управления из меню Windows, оттуда перейди в «Система и безопасность», затем в «Система» +* Нажми клавишу Windows, затем перейди по разделам Настройки > Система > О системе + +Ты можешь загрузить Python для Windows с официального веб-сайта: https://www.python.org/downloads/windows/. Перейди по ссылке «Latest Python 3 Release - Python x.x.x». Если у тебя установлена **64-битная** версия Windows, скачай **Windows installer (64-bit)**. Если нет — скачай **Windows installer (32-bit)**. После загрузки дистрибутива ты должна запустить его (двойным щелчком) и следовать инструкциям. + +Обрати внимание на экран мастера установки, который называется «Setup» (Настройка): тебе нужно пролистать его вниз и выбрать опцию «Add Python {{ book.py_version }} to the PATH» (Добавить Python {{ book.py_version }} к системной переменной PATH), как на рисунке (это может выглядеть по-разному в зависимости от версии, которую ты устанавливаешь): + +![Не забудь добавить Python в системную переменную Path](../python_installation/images/python-installation-options.png) + +Когда установка закончится, ты можешь увидеть предложение узнать больше о Python или об установленной тобой версии. Закрой это окно — ты узнаешь намного больше в этом руководстве! + +Примечание: если ты используешь старую версию Windows (7, Vista или ещё более старую версию), и установка Python {{ book.py_version }} завершается выводом сообщения об ошибке, ты можешь попробовать: +1. либо установить все доступные обновления Windows и попробовать установить Python {{ book.py_version }} заново; +2. либо установить [более раннюю версию Python](https://www.python.org/downloads/windows/), например, [3.4.6](https://www.python.org/downloads/release/python-346/). + +Если тебе пришлось установить раннюю версию Python, экран установки может выглядеть чуть иначе, чем показано выше. Не забудь прокрутить окно до строки «Add python.exe to Path», затем нажми кнопку слева от неё и выбери пункт «Will be installed on local hard drive»: -### Windows +![Добавление Python в переменную Path, ранние версии](../python_installation/images/add_python_to_windows_path.png) -Ты можешь загрузить Python для Windows с официального веб-сайта: https://www.python.org/downloads/release/python-343/. После загрузки ***.msi** файла, ты должна запустить его (двойной щелчок) и следовать инструкциям. Важно помнить путь (каталог), куда ты установила Python. Это понадобится позже! + -Обрати внимание на второй экран мастера установки, который называется "Customize" (Настройка): тебе нужно пролистать его вниз и выбрать опцию "Add python.exe to the Path" (Добавить python.exe к системной переменной Path), как на рисунке: + -![Не забудьте добавить Python в системную переменную Path](../python_installation/images/add_python_to_windows_path.png) +> **Примечание:** перед установкой Python в macOS тебе нужно проверить, что в настройках твоего Mac разрешено устанавливать пакеты, загруженные не из App Store. Перейди в Системные настройки (в папке «Программы»), нажми «Защита и безопасность» и выбери вкладку «Общие». Если в разделе «Разрешать загрузки из:» выбран вариант «App Store для Mac», смени его на «App Store для Mac и от установленных разработчиков». -### Linux +Тебе нужно перейти по ссылке https://www.python.org/downloads/ и скачать дистрибутив Python: + + * Скачай файл *macOS installer*, + * Сделай двойной щелчок на *python-{{ book.py_release }}-macosx11.pkg* для запуска установщика. + + + + Вполне вероятно, что у тебя уже установлен Python. Чтобы проверить это (а также версию языка), открой консоль и введи следующую команду: - $ python3 --version - Python 3.4.3 - +{% filename %}command-line{% endfilename %} +``` +$ python3 --version +Python {{ book.py_release }} +``` +Если у тебя установлена другая версия Python, не меньше чем {{ book.py_min_version }} (например, {{ book.py_min_release }}), то нет необходимости обновляться. Если Python не установлен, или ты хочешь использовать другую версию языка, то можешь установить его следующим образом: -#### Debian или Ubuntu -Введи эту команду в консоль: + - $ sudo apt-get install python3.4 - + -#### Fedora (версии вплоть до 21) +Введи эту команду в консоль: -Используй следующую команду в консоли: +{% filename %}command-line{% endfilename %} +``` +$ sudo apt install python3 +``` - $ sudo yum install python3.4 - + -#### Fedora (версии 22 и выше) + Используй следующую команду в консоли: - $ sudo dnf install python3.4 - - -#### openSUSE +{% filename %}command-line{% endfilename %} +``` +$ sudo dnf install python3 +``` -Используй следующую команду в консоли: +Если у тебя старая версия Fedora, то ты можешь получить ошибку «command `dnf` is not found». В этом случае используй `yum`. - $ sudo zypper install python3 + + -### OS X +Используй следующую команду в консоли: -Тебе нужно перейти по ссылке https://www.python.org/downloads/release/python-343/ и скачать дистрибутив Python: +{% filename %}command-line{% endfilename %} +``` +$ sudo zypper install python3 +``` - * Скачай файл *Mac OS X 64-bit/32-bit installer*, - * Сделай двойной щелчок на *python-3.4.3-macosx10.6.pkg* для запуска установщика. + Убедись, что установка прошла успешно, открыв приложение *Терминал* и запустив команду `python3`: - $ python3 --version - Python 3.4.3 - +{% filename %}command-line{% endfilename %} +``` +$ python3 --version +Python {{ book.py_release }} +``` +Версия, которую ты увидишь, может быть и не {{ book.py_release }} — там будет такая версия, которую ты установила. + +**ПРИМЕЧАНИЕ:** если ты используешь Windows и получила ошибку с сообщением, что `python3` не найден, попробуй ввести `python` (без `3`) и проверь, будет ли это версия Python {{ book.py_min_version }} или выше. -* * * +---- -Если у тебя остались какие-либо сомнения, или что-то пошло не так и ты понятия не имеешь что делать дальше - спроси своего тренера! Иногда дела идут не совсем гладко, поэтому лучше попросить помощи у кого-то с большим опытом. +Если у тебя остались какие-либо сомнения, или что-то пошло не так, и ты понятия не имеешь, что делать дальше, — спроси своего тренера! Иногда дела идут не совсем гладко, поэтому лучше попросить помощи у кого-то с большим опытом. diff --git a/ru/python_introduction/README.md b/ru/python_introduction/README.md index 9bb54f840d9..000e55a2db5 100755 --- a/ru/python_introduction/README.md +++ b/ru/python_introduction/README.md @@ -1,3 +1,5 @@ +{% set warning_icon = '' %} + # Введение в Python > Часть этой главы основана на учебных пособиях Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). @@ -6,98 +8,129 @@ ## Консоль Python -Чтобы начать играть с Python, нам нужно открыть *командную строку* на твоем компьютере. Ты уже должна знать, как это сделать -- мы изучали это в главе [Введение в интерфейс командой строки][1]. +> Для проходящих руководство дома: этот раздел рассмотрен в видео [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U). + +Чтобы начать играть с Python, нам нужно открыть *командную строку* на твоём компьютере. Ты уже должна знать, как это сделать — мы изучали это в главе [Введение в интерфейс командной строки][1]. [1]: ../intro_to_command_line/README.md -После того, как будешь готова, следуйте приведенным ниже инструкциям. +Когда будешь готова, следуй приведенным ниже инструкциям. -Мы хотим открыть консоль Python, так что набери `python` если работаешь в Windows, или `python3` для Mac OS/Linux, и нажми `enter`. +Мы хотим открыть консоль Python, так что набери `python`, если работаешь в Windows, или `python3` для Mac OS/Linux, и нажми `enter`. - $ python3 - Python 3.4.3 (...) - Type "help", "copyright", "credits" or "license" for more information. - >>> - +{% filename %}command-line{% endfilename %} +``` +$ python3 +Python {{ book.py_release }} (...) +Type "help", "copyright", "credits" or "license" for more information. +>>> +``` ## Твоя первая команда Python! -После запуска Python, консоль изменилась на `>>>`. Для нас это означает, что сейчас мы можем использовать только команды на языке Python. Тебе не нужно вводить `>>>` - Python будет делать это за нас. +После запуска Python командная строка изменилась на `>>>`. Для нас это означает, что сейчас мы можем использовать только команды на языке Python. Тебе не нужно вводить `>>>` — Python будет делать это за нас. -Если ты хочешь выйти из консоли Python, в любой момент -- просто введи `exit()` или используй сочетание клавиш `Ctrl + Z` для Windows и `Ctrl + D` для Mac/Linux. Тогда ты больше не будешь видеть `>>>`. +Если ты хочешь выйти из консоли Python, в любой момент — просто введи `exit()` или используй сочетание клавиш `Ctrl + Z` для Windows и `Ctrl + D` для Mac/Linux. Тогда ты больше не будешь видеть `>>>`. -Пока что мы не хотим выходить из консоли Python. Мы хотим узнать больше о ней. Давай начнём с чего-нибудь совсем простого. Например, попробуй набрать простое математическое выражение, вроде `2 + 3` и нажми `enter`. +Пока что мы не хотим выходить из консоли Python. Мы хотим узнать больше о ней. Давай начнём с чего-нибудь совсем простого. Например, попробуй набрать простое математическое выражение, вроде `2 + 3`, и нажми `enter`. - >>> 2 + 3 - 5 - +{% filename %}command-line{% endfilename %} +```python +>>> 2 + 3 +5 +``` + +Прекрасно! Видишь, как выскочил ответ? Python знает математику! Ты можешь попробовать другие команды, например: + +- `4 * 5` +- `5 - 1` +- `40 / 2` -Прекрасно! Видишь, как выскочил ответ? Python знает математику! Ты можешь попробовать другие команды, такие как: - `4 * 5` - `5 - 1` - `40 / 2` +Чтобы вычислить степень числа, например, 2 в кубе, мы вводим: +{% filename %}command-line{% endfilename %} +```python +>>> 2 ** 3 +8 +``` Поиграй с этим немного и затем вернись сюда :). -Как видишь, Python является прекрасным калькулятором. Если тебе интересно, что еще можно сделать... +Как видишь, Python является прекрасным калькулятором. Если тебе интересно, что ещё можно сделать... ## Строки -Как насчет твоего имени? Введи свое имя в кавычках, вот так: +Как насчет твоего имени? Введи своё имя в кавычках, вот так: - >>> "Ola" - 'Ola' - +{% filename %}command-line{% endfilename %} +```python +>>> "Ola" +'Ola' +``` -Сейчас ты создала свою первую строку! Это последовательность символов, которые могут быть обработаны компьютером. Строка должна всегда начинаться и заканчиваться одинаковым символом. Им может быть одинарная (`'`) или двойная (`"`) кавычка (разницы нет!) Кавычки говорят Python'у, что внутри них находится строка. +Ты только что создала свою первую строку! Это последовательность символов, которые могут быть обработаны компьютером. Строка должна всегда начинаться и заканчиваться одинаковым символом. Им может быть одинарная (`'`) или двойная (`"`) кавычка (разницы нет!) Кавычки говорят Python'у, что внутри них находится строка. Строки могут быть слиты воедино. Попробуй так: - >>> "Hi there " + "Ola" - 'Hi there Ola' - +{% filename %}command-line{% endfilename %} +```python +>>> "Hi there " + "Ola" +'Hi there Ola' +``` Ты также можешь умножать строки на число: - >>> "Ola" * 3 - 'OlaOlaOla' - +{% filename %}command-line{% endfilename %} +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` Если тебе нужно поставить апостроф внутри строки, то есть два способа сделать это. -Использование двойных кавычек: +Используй двойные кавычки: - >>> "Runnin' down the hill" - "Runnin' down the hill" - +{% filename %}command-line{% endfilename %} +```python +>>> "Runnin' down the hill" +"Runnin' down the hill" +``` -или предварение апострофа обратной косой чертой (``): +или поставь перед апострофом обратную косую черту (`\`): - >>> 'Runnin\' down the hill' - "Runnin' down the hill" - +{% filename %}command-line{% endfilename %} +```python +>>> 'Runnin\' down the hill' +"Runnin' down the hill" +``` Прикольно, да? Чтобы увидеть своё имя прописными буквами, просто набери: - >>> "Ola".upper() - 'OLA' - +{% filename %}command-line{% endfilename %} +```python +>>> "Ola".upper() +'OLA' +``` -Ты только что использовала **функцию** `upper` для своей строки! Функция (такая как `upper()`) представляет собой набор инструкций, который должен выполнить Python на заданном объекте (в нашем случае: `"Ola"`) при её вызове. +Ты только что использовала __метод__ `upper` своей строки! Метод (такой как `upper()`) представляет собой набор инструкций, который должен выполнить Python над заданным объектом (в нашем случае: `"Ola"`) при его вызове. Если ты хочешь узнать количество букв в своём имени, то и для этого тоже существует функция! - >>> len("Ola") - 3 - +{% filename %}command-line{% endfilename %} +```python +>>> len("Ola") +3 +``` -Интересно, почему иногда мы вызываем функцию добавлением `.` к концу строки (как `"Ola".upper()`), а иногда сначала пишем имя функции и затем помещаем строку в скобки? Ну, в некоторых случаях функции принадлежат объектам, например функция `upper()`, которая может быть применена только к строкам. В этом случае мы называем функцию **методом**. В другом случае функции не относятся к чему-то конкретному и могут использоваться для различных типов объектов, например функция `len()`. Вот почему мы передаем `"Ola"` в качестве параметра функции `len`. +Интересно, почему иногда мы вызываем функцию добавлением `.` к концу строки (как `"Ola".upper()`), а иногда сначала пишем имя функции и затем помещаем строку в скобки? Ну, в некоторых случаях функции принадлежат объектам, например, функция `upper()`, которая может быть применена только к строкам. В этом случае мы называем функцию __методом__. В другом случае функции не относятся к чему-то конкретному и могут использоваться для различных типов объектов, например, функция `len()`. Вот почему мы передаем `"Ola"` в качестве параметра функции `len`. -### Краткий обзор +### Подведём итог -OK, достаточно о строках. Пока ты узнала о: +Хорошо, достаточно о строках. Пока ты узнала следующее: -* **консоль** - ввод команд (кода) в интерактивную командную строку Python приводит к ответам на Python -* **числа и строки** - в Python числа используются для вычислений, а строки - для текстовых объектов -* **операторы** - такие как + и *, объединяют значения для получения нового -* **функции** - такие как upper() и len(), выполняют действия над объектами. +* __командная строка__ — ввод команд (кода) в интерактивную командную строку Python приводит к ответам на Python; +* __числа и строки__ — в Python числа используются для вычислений, а строки - для текстовых объектов; +* __операторы__, такие как + и *, объединяют значения для получения нового; +* __функции__, такие как upper() и len(), выполняют действия над объектами. Таковы основы каждого языка программирования, который ты можешь выучить. Готова к чему-то посложнее? Мы уверены, что готова! @@ -105,70 +138,89 @@ OK, достаточно о строках. Пока ты узнала о: Давай попробуем кое-что новенькое. Можем ли мы получить длину числа так же, как длину твоего имени? Введи `len(304023)` и нажми `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 %} +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` + +Мы получили нашу первую ошибку! Иконкой {{ warning_icon }} мы будем обозначать код, который при запуске сработает не так, как ожидается. Совершение ошибок (даже преднамеренных) -- важная часть обучения! -Мы получили нашу первую ошибку! Она говорит о том, что у объектов типа «int» (целые числа) нет длины. Так что же мы можем сейчас сделать? Может быть мы можем написать наше число в виде строки? У строк ведь есть длина, верно? +Она говорит о том, что у объектов типа «int» (целые числа) нет длины. Так что же мы можем сейчас сделать? Может быть, мы можем написать наше число в виде строки? У строк ведь есть длина, верно? - >>> len(str(304023)) - 6 - +{% filename %}command-line{% endfilename %} +```python +>>> len(str(304023)) +6 +``` -Сработало! Мы использовали функцию `str` внутри функции `len`. `str()` преобразует все в строки. +Сработало! Мы использовали функцию `str` внутри функции `len`. `str()` преобразует всё в строки. -* Функция `str` преобразует объекты в **строки** -* Функция `int` преобразует объекты в **целые числа** +- Функция `str` преобразует объекты в __строки__ +- Функция `int` преобразует объекты в __целые числа__ -> Важно: мы можем преобразовать число в текст, но не всегда удается преобразовать текст в числа - например, каков будет результат `int('hello')`? +> Важно: мы можем преобразовать число в текст, но не всегда удается преобразовать текст в числа — например, каков будет результат `int('hello')`? ## Переменные -Переменные -- важное понятие в программировании. Переменная -- это не более чем имя для чего-то, чтобы использовать его позднее. Программисты используют переменные для хранения данных, чтобы их код был более читабельным, и для того, чтобы им не пришлось запоминать что есть что. +Переменные — важное понятие в программировании. Переменная — это всего лишь имя для чего-то, чтобы использовать его позднее. Программисты используют переменные для хранения данных, чтобы их код был более читабельным, и для того, чтобы им не пришлось запоминать, что есть что. Допустим, мы хотим создать новую переменную с именем `name`: - >>> name = "Ola" - +{% filename %}command-line{% endfilename %} +```python +>>> name = "Ola" +``` Видишь? Это очень легко! Просто введи: name равно Ola. Как ты уже заметила, твоя программа не возвращает ничего, как было ранее. Так откуда мы знаем, что переменная действительно существует? Просто введи `name` и нажми `Enter`: - >>> name - 'Ola' - +{% filename %}command-line{% endfilename %} +```python +>>> name +'Ola' +``` Ура! Твоя первая переменная:)! Ты всегда можешь изменить то, к чему она относится: - >>> name = "Sonja" - >>> name - +{% filename %}command-line{% endfilename %} +```python +>>> name = "Sonja" +>>> name +'Sonja' +``` -Ты можешь использовать их также и в функциях: +Ты также можешь использовать переменные и в функциях: - >>> len(name) - 5 - +{% filename %}command-line{% endfilename %} +```python +>>> len(name) +5 +``` Круто, правда? Переменными, конечно, может быть что угодно, и цифры тоже! Попробуй следующее: - >>> a = 4 - >>> b = 6 - >>> a * b - 24 - +{% filename %}command-line{% endfilename %} +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` Но что делать, если мы использовали неправильное имя? Можешь догадаться, что произойдет? Давай попробуем! - >>> city = "Tokyo" - >>> ctiy - Traceback (most recent call last): - File "", line 1, in - NameError: name 'ctiy' is not defined - +{% 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 +``` Ошибка! Как ты можешь видеть, в Python есть различные типы ошибок, эта называется **NameError**. Python выдаст эту ошибку при попытке использовать переменную, которая пока не определена. При возникновении этой ошибки проверь свой код, чтобы узнать, не написала ли ты неправильно имя переменной. @@ -178,327 +230,427 @@ OK, достаточно о строках. Пока ты узнала о: Попробуй ввести: - >>> name = 'Maria' - >>> name - 'Maria' - >>> print(name) - Maria - +{% filename %}command-line{% endfilename %} +```python +>>> name = 'Maria' +>>> name +'Maria' +>>> print(name) +Maria +``` Если просто ввести `name`, интерпретатор Python вернет строковое *представление* переменной 'name', которым, в нашем случае, являются буквы M-a-r-i-a, окруженные одинарными кавычками, ''. Когда ты вводишь `print(name)`, Python "печатает" содержание переменной на экран, без кавычек, что удобнее. -Как мы увидим позднее, `print()` пригодится когда нам будет нужно печатать что-то изнутри функций или когда мы захотим напечатать что-то на нескольких строчках. +Как мы увидим позднее, `print()` пригодится, когда нам будет нужно печатать что-то изнутри функций или когда мы захотим напечатать что-то на нескольких строчках. ## Списки -Помимо строк и целых чисел Python имеет богатую коллекцию других типов объектов. Сейчас мы собираемся представить тебе один из них - **list** (список). Списки - это именно то, о чем ты подумала: объекты, которые являются списками других объектов :) +Помимо строк и целых чисел Python имеет богатую коллекцию других типов объектов. Сейчас мы собираемся представить тебе один из них — **list** (список). Списки — это именно то, о чём ты подумала: объекты, которые являются списками других объектов :) Давай начнем с создания списка: - >>> [] - [] - +{% filename %}command-line{% endfilename %} +```python +>>> [] +[] +``` Отлично, это пустой список. Не особенно полезен, да? Давай создадим список лотерейных номеров. Мы не хотим повторять их каждый раз, так что присвоим список переменной: - >>> lottery = [3, 42, 12, 19, 30, 59] - +{% filename %}command-line{% endfilename %} +```python +>>> lottery = [3, 42, 12, 19, 30, 59] +``` -Замечательно, у нас есть список! Что мы можем с ним сделать? Для начала посмотрим как много лотерейных номеров в нашем списке. Есть идеи какую функцию можно использовать для этого? Ты её уже знаешь! +Замечательно, у нас есть список! Что мы можем с ним сделать? Для начала посмотрим, как много лотерейных номеров в нашем списке. Есть идеи, какую функцию можно использовать для этого? Ты её уже знаешь! - >>> len(lottery) - 6 - +{% filename %}command-line{% endfilename %} +```python +>>> len(lottery) +6 +``` -Точно! `len()` вернет тебе количество объектов в списке. Удобно, правда? Может быть мы теперь отсортируем его: +Точно! `len()` вернет тебе количество объектов в списке. Удобно, правда? Пожалуй, мы теперь отсортируем его: - >>> lottery.sort() - +{% filename %}command-line{% endfilename %} +```python +>>> lottery.sort() +``` -Эта команда не возвращает ничего, она просто меняет порядок номеров в списке. Давайте выведем его на экран и посмотрим что получилось: +Эта команда не возвращает ничего, она просто меняет порядок номеров в списке. Давайте выведем его на экран и посмотрим, что получилось: - >>> print(lottery) - [3, 12, 19, 30, 42, 59] - +{% filename %}command-line{% endfilename %} +```python +>>> print(lottery) +[3, 12, 19, 30, 42, 59] +``` Как видишь, номера в списке теперь отсортированы от меньшего к большему. Поздравляем! -Может быть нам нужно изменить порядок? Давай сделаем это! +Может, нам нужно обратить порядок? Давай сделаем это! - >>> lottery.reverse() - >>> print(lottery) - [59, 42, 30, 19, 12, 3] - +{% filename %}command-line{% endfilename %} +```python +>>> lottery.reverse() +>>> print(lottery) +[59, 42, 30, 19, 12, 3] +``` Просто, правда? Если хочешь добавить что-то к своему списку, то можешь воспользоваться этой командой: - >>> lottery.append(199) - >>> print(lottery) - [59, 42, 30, 19, 12, 3, 199] - +{% filename %}command-line{% endfilename %} +```python +>>> lottery.append(199) +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +``` -Если ты хочешь получить первый номер в списке, то можешь воспользоваться **индексами**. Индекс это номер позиции в списке, на котором находится нужное нам значение. Программисты предпочитают начать считать с 0, так что первому объекту в списке соответствует индекс 0, следующему —1, и так далее. Попробуй ввести: +Если ты хочешь получить только первый номер в списке, то можешь воспользоваться **индексами**. Индекс — это номер позиции в списке, на котором находится нужное нам значение. Программисты предпочитают начать считать с 0, так что первому объекту в списке соответствует индекс 0, следующему —1, и так далее. Попробуй ввести: - >>> print(lottery[0]) - 59 - >>> print(lottery[1]) - 42 - +{% filename %}command-line{% endfilename %} +```python +>>> print(lottery[0]) +59 +>>> print(lottery[1]) +42 +``` -Как видишь, ты можешь обратиться к различным объектам в своем списке используя имя списка и индекс объекта в квадратных скобках. +Как видишь, ты можешь обратиться к различным объектам в своем списке, используя имя списка и индекс объекта в квадратных скобках. -Чтобы удалить что-либо из списка, тебе понадобятся **индексы**, с которыми мы уже разобрались выше, и команда `pop()`. Давай попробуем закрепить пройденное примером; мы будем удалять первый элемент из нашего списка. +Чтобы удалить что-либо из списка, тебе понадобятся **индексы**, с которыми мы уже разобрались выше, и команда `pop()`. Давай попробуем закрепить пройденное на примере: мы будем удалять первый элемент из нашего списка. - >>> print(lottery) - [59, 42, 30, 19, 12, 3, 199] - >>> print(lottery[0]) - 59 - >>> lottery.pop(0) - >>> print(lottery) - [42, 30, 19, 12, 3, 199] - +{% filename %}command-line{% 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] +``` -Сработало как заклинание! +Сработало как по маслу! -В качестве дополнительной тренировки попробуй следующие индексы: 6, 7, 1000, -1, -6 и -1000. Сможешь предсказать результат? Видишь логику работы? +В качестве дополнительной тренировки попробуй следующие индексы: 6, 7, 1000, -1, -6 и -1000. Можешь предсказать результат? Видишь логику работы? Ты можешь найти перечень всех методов, относящихся к списку, в этой главе официальной документации Python: https://docs.python.org/3/tutorial/datastructures.html ## Словари +> Для проходящих руководство дома: этот раздел рассмотрен в видео [Python Basics: Dictionaries](https://www.youtube.com/watch?v=ZX1CVvZLE6c). + Словари схожи со списками, но ты обращаешься к значениям словаря по ключу, а не по индексу. Ключом может быть любая строка или число. Давай создадим пустой словарь: - >>> {} - {} - +{% filename %}command-line{% endfilename %} +```python +>>> {} +{} +``` Это показывает, что мы создали пустой словарь. Ура! Теперь попробуй следующую команду (можешь заменить значения на своё имя, страну и т.д.): - >>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} - +{% filename %}command-line{% endfilename %} +```python +>>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} +``` -Этой командой ты создала переменную `participant` с тремя парами ключ-значение: +Этой командой ты создала переменную `participant` с тремя парами ключ/значение: -* Ключ `name`, указывающий на значение `'Ola'` (`строковый` объект), -* ключ `country`, указывающий на значение `'Poland'` (еще одна `строка`), -* и ключ `favorite_numbers`, указывающий на значение `[7, 42, 92]` (объект типа `список` с тремя числами внутри). +- ключ `name`, указывающий на значение `'Ola'` (объект типа `строка`), +- ключ `country`, указывающий на значение `'Poland'` (еще одна `строка`), +- и ключ `favorite_numbers`, указывающий на значение `[7, 42, 92]` (объект типа `список` с тремя числами внутри). Значение конкретного ключа можно узнать следующим образом: - >>> print(participant['name']) - Ola - +{% filename %}command-line{% endfilename %} +```python +>>> print(participant['name']) +Ola +``` -Видишь, синтаксис похож на работу со списком. Но вместо того чтобы запоминать индекс, тебе нужно помнить ключ. +Видишь, синтаксис похож на работу со списком. Но вместо того, чтобы запоминать индекс, тебе нужно помнить ключ. Что случится, если мы спросим у Python значение несуществующего в словаре ключа? Можешь предположить? Давай попробуем и узнаем наверняка! - >>> participant['age'] - Traceback (most recent call last): - File "", line 1, in - KeyError: 'age' - +{% filename %}{{ warning_icon }} command-line{% endfilename %} +```python +>>> participant['age'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'age' +``` -Смотри, другая ошибка! Эта называется **KeyError**. Python услужливо напоминает, что ключа `'age'` не существует в словаре. +Смотри, другая ошибка! Эта называется **KeyError**. Python услужливо напоминает, что ключа `'age'` нет в словаре. Когда стоит использовать словарь, а когда список? Это хороший вопрос для самостоятельного размышления. Сделай предположение перед тем, как читать дальше. -* Тебе нужна упорядоченная последовательность элементов? Список - наш выбор. -* Тебе нужны сочетания ключ - значение, чтобы быстро искать значения (по ключу) в дальнейшем? Словарь отлично подойдет. +- Тебе нужна упорядоченная последовательность элементов? Список — наш выбор. +- Тебе нужны сочетания ключ/значение, чтобы быстро искать значения (по ключу) в дальнейшем? Словарь отлично подойдет. -Словари, как и списки, *изменяемы*, т. е. они могут быть изменены после того как были созданы. Ты можешь добавить новые пары ключ/значение в словарь следующим образом: +Словари, как и списки, *изменяемы*, т. е. они могут быть изменены после того, как были созданы. Ты можешь добавить новые пары ключ/значение в словарь следующим образом: - >>> participant['favorite_language'] = 'Python' - +{% filename %}command-line{% endfilename %} +```python +>>> participant['favorite_language'] = 'Python' +``` -Также как в примере со списками, использование функции `len()` вернет число пар ключ/значение в словаре. Попробуй сама: +Так же как в примере со списками, использование функции `len()` вернёт число пар ключ/значение в словаре. Попробуй сама: + +{% filename %}command-line{% endfilename %} +```python +>>> len(participant) +4 +``` - >>> len(participant) - 4 - +Надеюсь, всё вышеизложенное понятно. :) Готова к новым приключениям со словарями? На следующей строке тебя ждут изумительные вещи. -Надеюсь все вышеизложенное понятно. :) Готова к новым приключениям со словарями? На следующей строке тебя ждут изумительные вещи. +Ты можешь использовать команду `pop()` для удаления элементов из словаря. Скажем, ты хочешь удалить элемент с ключом `'favorite_numbers'`. Просто набери следующую команду: -Ты можешь использовать команду `pop()` для удаления элементов из словаря. Скажем, ты хочешь удалить элемент с ключом `'favorite_numbers'`, просто набери следующую команду: +{% filename %}command-line{% endfilename %} +```python +>>> participant.pop('favorite_numbers') +[7, 42, 92] +>>> participant +{'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +``` - >>> participant.pop('favorite_numbers') - >>> participant - {'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} - +Как видишь, пара ключ/значение с ключом 'favorite_numbers' была удалена. -Как видно, пара ключ-значение с ключом 'favorite_numbers' была удалена. +Помимо этого, ты можешь заменить значение, связанное с уже существующим ключом. Набери: -Помимо этого, ты можешь заменить значение, ассоциированное с уже существующим ключом. Набери: +{% filename %}command-line{% endfilename %} +```python +>>> participant['country'] = 'Germany' +>>> participant +{'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} +``` - >>> participant['country'] = 'Germany' - >>> participant - {'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} - -Значение, на которое ссылается ключ `'country'` было изменено с `'Poland'` на `'Germany'`. :) Захватывает? Еще бы! Ты выучила еще одну потрясающую штуку. +Значение, на которое ссылается ключ `'country'`, изменилось с `'Poland'` на `'Germany'`. :) Захватывает? Ещё бы! Ты выучила еще одну потрясающую штуку! -### Содержание +### Подведём итог Шикарно! Теперь ты знаешь немало о программировании. Мы познакомились с: -* **ошибками** - теперь ты знаешь как читать и анализировать ошибки, которые возникают, если Python не понимает твоей команды -* **переменными** - именами для объектов, которые упрощают твой код и делают его более читабельным -* **списками** - последовательностями объектов в заданном порядке -* **словарями** - объектами, хранящими пары ключ-значение +* __ошибками__ — теперь ты знаешь как читать и анализировать ошибки, которые возникают, если Python не понимает твоей команды; +* __переменными__ — именами для объектов, которые упрощают твой код и делают его более читабельным; +* __списками__ — последовательностями объектов в заданном порядке; +* __словарями__ — объектами, хранящими пары ключ/значение. Готова к продолжению? :) -## Сравниваем вещи +## Сравнения + +> Для проходящих руководство дома: этот раздел рассмотрен в видео [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4). -Немалая часть программирования требует сравнения вещей. Что проще всего сравнить друг с другом? Числа, конечно. Давай посмотрим как это работает: +В программировании часто надо что-то сравнивать. Что проще всего сравнить друг с другом? Числа, конечно. Давай посмотрим, как это работает: - >>> 5 > 2 - True - >>> 3 < 1 - False - >>> 5 > 2 * 2 - True - >>> 1 == 1 - True - >>> 5 != 2 - True - +{% filename %}command-line{% endfilename %} +```python +>>> 5 > 2 +True +>>> 3 < 1 +False +>>> 5 > 2 * 2 +True +>>> 1 == 1 +True +>>> 5 != 2 +True +``` Мы передали Python несколько чисел для сравнения. Как ты можешь заметить, Python сравнивает не только числа, но и результаты методов (например, умножения). Неплохо, правда? -Хочешь спросить почему мы написал двойной символ равенства `==`, чтобы проверить одинаковы ли числа? Потому что одинарные символ равенства `=` уже задействован под присваивание значения переменным. Ты всегда, **всегда** должна писать два символа равенства `==`, если хочешь проверить одинаковы ли объекты. Мы также можем проверить различаются ли объекты. Для этого, мы используем `!=`, как показано в примере выше. +Хочешь спросить, почему мы написали двойной символ равенства `==`, чтобы проверить, одинаковы ли числа? Потому что одинарные символ равенства `=` уже задействован под присваивание значения переменным. Ты всегда, __всегда__ должна писать два символа равенства `==`, если хочешь проверить, одинаковы ли объекты. Мы также можем проверить, различаются ли объекты. Для этого мы используем `!=`, как показано в примере выше. Дадим Python еще два задания: - >>> 6 >= 12 / 2 - True - >>> 3 <= 2 - False - +{% filename %}command-line{% endfilename %} +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` С `>` и `<` все понятно, но что значат `>=` и `<=`? Читай их следующим образом: -* 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 Супер! Хочешь еще? Тогда попробуй вот это: - >>> 6 > 2 and 2 < 3 - True - >>> 3 > 2 and 2 < 1 - False - >>> 3 > 2 or 2 < 1 - True - +{% filename %}command-line{% endfilename %} +```python +>>> 6 > 2 and 2 < 3 +True +>>> 3 > 2 and 2 < 1 +False +>>> 3 > 2 or 2 < 1 +True +``` -Ты можешь передать Python так много чисел, как захочешь, и он будет возвращать ответ! Хитро, правда? +Ты можешь передать Python столько чисел, сколько захочешь, и он будет возвращать ответ! Хитро, правда? -* **and** - если ты используешь `and` оператор, оба сравнения по бокам от него должны быть True (верны), чтобы результат всей команды был равен True -* **or** - если ты используешь `or` оператор, достаточно одному из сравнений по бокам от него быть равным True, чтобы результат всей команды также равнялся True +- __and__ — если ты используешь оператор `and`, оба сравнения по обе стороны от него должны быть True (верны), чтобы результат всей команды был равен True. +- __or__ — если ты используешь оператор `or`, достаточно одному из сравнений по обе стороны от него быть равным True, чтобы результат всей команды также равнялся True. -Ты когда-нибудь слышала выражение "сравнивать яблоки и апельсины"? Попробуем что-то подобное в Python: +Ты когда-нибудь слышала выражение "сравнивать тёплое с мягким"? Попробуем сделать что-то подобное в Python: - >>> 1 > 'django' - Traceback (most recent call last): - File "", line 1, in - TypeError: unorderable types: int() > str() - +{% 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' +``` -Как мы видим, Python не знает как сравнить число (`int`) и строку (`str`) между собой. Поэтому он просто возвращает нам ошибку **TypeError** и предупреждает, что объекты заданных типов не могут быть сравнены. +Как мы видим, Python не знает, как сравнить число (`int`) и строку (`str`) между собой. Поэтому он просто возвращает нам ошибку **TypeError** и предупреждает, что объекты заданных типов не могут быть сравнены. ## Логические значения -Между прочим, ты только что познакомилась с новым типом объектов в Python. Он называется **Boolean** (логический) -- и это наверно самый простой тип из всех. +Между прочим, ты только что познакомилась с новым типом объектов в Python. Он называется __Boolean__ (логический) — и это, наверное, самый простой тип из всех. -Существует только два логических объекта в Python: - True (Истина) - False (Ложь) +Существует только два логических объекта в Python: +- True (Истина), +- False (Ложь). -Чтобы Python понимал тебя, ты всегда должна писать True с заглавной буквы (остальные прописные). **true, TRUE, tRUE не будет восприниматься -- только True.** (Та же логика применима к False, само собой.) +Чтобы Python понимал тебя, ты всегда должна писать True с заглавной буквы (остальные прописные). **true, TRUE, tRUE не будут восприниматься — только True.** (Та же логика применима к False, само собой.) Ты можешь присваивать переменным логические значения! Смотри сюда: - >>> a = True - >>> a - True - +{% filename %}command-line{% endfilename %} +```python +>>> a = True +>>> a +True +``` Или так: - >>> a = 2 > 5 - >>> a - False - +{% filename %}command-line{% endfilename %} +```python +>>> a = 2 > 5 +>>> a +False +``` Попрактикуйся с логическими значениями на примере этих выражений: -* `True and True` -* `False and True` -* `True or 1 == 1` -* `1 != 2` - -Поздравляем! Логические значения одна из самых классных фишек программирования и ты только что научилась ими пользоваться! +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` +Поздравляем! Логические значения — одна из самых классных фишек программирования, и ты только что научилась ими пользоваться! # Сохраняй! -До сих пор мы писали весь код в интерактивной консоли, где Python сразу анализировал, обрабатывал и выполнял наши команды. Мы были ограничены одной строкой. Обычно, программы сохраняются в файлах и выполняются **интерпретатором** или **компилятором** нашего языка программирования. Пока мы только просили **интерпретатор** Python выполнять наши однострочные команды из консоли. Однако, нам понадобиться больше места для следующих задач, поэтому задача минимум: +> Для проходящих руководство дома: этот раздел рассмотрен в видео [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk). + +До сих пор мы писали весь код в интерактивной консоли, где Python сразу анализировал, обрабатывал и выполнял наши команды. Мы были ограничены одной строкой. Обычно, программы сохраняются в файлах и выполняются **интерпретатором** или **компилятором** нашего языка программирования. Пока мы только просили **интерпретатор** Python выполнять наши однострочные команды из консоли. Однако нам понадобится больше места для следующих задач, поэтому задача минимум: -* Закрыть интерактивную консоль Python -* Открыть наш текстовый редактор -* Сохранить код в новом файле -* Запустить его! +- закрыть интерактивную консоль Python; +- открыть наш текстовый редактор; +- сохранить код в новом файле; +- запустить его! -Чтобы закрыть интерактивную консоль Python просто набери функцию `exit()` : +Чтобы закрыть интерактивную консоль Python, просто набери функцию `exit()`: - >>> exit() - $ - +{% filename %}command-line{% endfilename %} +```python +>>> exit() +$ +``` -Это вернет тебя в командную строку. +Это вернёт тебя в командную строку. -В главе [Текстовый редактор][2] мы выбрали себе редактор. Нам нужно открыть его сейчас и записать следующий код в новый файл: +В главе [Текстовый редактор][2] мы выбрали себе редактор. Нам нужно открыть его сейчас и записать следующий код в новый файл (или, если ты используешь Chromebook, создай новый файл в облачной IDE и открой файл, который будет во встроенном редакторе кода): [2]: ../code_editor/README.md +{% filename %}editor{% endfilename %} ```python print('Hello, Django girls!') ``` - - -> **Примечание** Ты должна уже была заметить одну из крутейших вещей в редакторах кода: цвета! В интерактивной консоли Python весь текст был одного цвета, сейчас же функция `print` должна отличаться по цвету от текста, который передается в неё в качестве атрибута. Это называется «синтаксическая подсветка», и это действительно удобная штука для программирования. Цвет подсветки может подсказать тебе о незакрытой кавычке или опечатке в ключевом слове (таком как `def` в определении функции, с которым мы скоро познакомимся). Это одна из причин, по которой мы используем редакторы кода :) Очевидно, ты уже искушенный Python разработчик, так что не стесняйся добавить что-нибудь по своему вкусу из ранее изученного. -Теперь нам нужно сохранить файл с кодом и дать ему подходящее имя. Давай назовем его **python_intro.py** и сохраним на рабочий стол. Мы можем назвать файл как хотим, но важно чтобы название заканчивалось на **.py**. Расширение **.py** говорит операционной системе, что это **исполняемый файл python**, и Python может его запустить. +Теперь нам нужно сохранить файл с кодом и дать ему подходящее имя. Давай назовем его **python_intro.py** и сохраним на рабочий стол. Мы можем назвать файл как хотим, но важно, чтобы название заканчивалось на **.py**. Расширение **.py** говорит операционной системе, что это **исполняемый файл python**, и Python может его запустить. + +> **Примечание** Ты должна уже была заметить одну из крутейших вещей в редакторах кода: цвета! В интерактивной консоли Python весь текст был одного цвета, сейчас же функция `print` должна отличаться по цвету от текста, который передается в неё в качестве аргумента. Это называется «синтаксическая подсветка», и это действительно удобная штука для программирования. Цвет подсветки может подсказать тебе о незакрытой кавычке или опечатке в ключевом слове (таком как `def` в определении функции, с которым мы скоро познакомимся). Это одна из причин, по которой мы используем редакторы кода :) + После сохранения файла пришло время запустить его! Используя навыки из раздела о командной строке, открой терминал и **поменяй текущую директорию** на рабочий стол. + + Для Mac команда будет выглядеть так: - $ cd ~/Desktop - +{% filename %}command-line{% endfilename %} +``` +$ cd ~/Desktop +``` + + + Для Linux (слово "Desktop" может быть переведено на твой язык, например "Рабочий стол"): - $ cd ~/Desktop - +{% filename %}command-line{% endfilename %} +``` +$ cd ~/Desktop +``` + + + + + +В командной строке Windows команда будет такой: + +{% filename %}command-line{% endfilename %} +``` +> cd %HomePath%\Desktop +``` + + + + + +В Windows Powershell команда будет такой: + +{% filename %}command-line{% endfilename %} +``` +> cd $Home\Desktop +``` + -И для windows: - > cd %HomePath%\Desktop - +Если возникли проблемы — просто обратись за помощью. -Если возникли проблемы - просто обратись за помощью. +Теперь используй Python, чтобы запустить код в файле: + +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hello, Django girls! +``` -Теперь используй Python чтобы запустить код в файле: +Примечание: Windows не распознаёт команду 'python3'. Вместо этого для запуска файла используй команду 'python': - $ python3 python_intro.py - Hello, Django girls! - +{% filename %}command-line{% endfilename %} +```python +> python python_intro.py +``` -Отлично! Ты только что запустила свою первую программу, чей код был сохранен в файле. Чувствуешь воодушевление? +Отлично! Ты только что запустила свою первую программу, код которой был сохранен в файле. Чувствуешь воодушевление? Можно передвигаться дальше к такому незаменимому в программировании инструменту как: @@ -508,55 +660,64 @@ print('Hello, Django girls!') Замени код в своем файле **python_intro.py** на: +{% filename %}python_intro.py{% endfilename %} ```python if 3 > 2: ``` - Если мы сохраним его и запустим, то получим ошибку: - $ python3 python_intro.py - File "python_intro.py", line 2 - ^ - SyntaxError: unexpected EOF while parsing - +{% filename %}{{ warning_icon }} command-line{% endfilename %} +``` +$ python3 python_intro.py +File "python_intro.py", line 2 + ^ +SyntaxError: unexpected EOF while parsing +``` Python предполагает, что мы должны дать ему инструкции, которые будут им выполнены при соблюдении условия `3 > 2` (т. е. при равенстве условия логическому значению `True`). Давай попробуем заставить Python напечатать на экране “It works!”. Внеси следующие изменения в **python_intro.py**: +{% filename %}python_intro.py{% endfilename %} ```python if 3 > 2: print('It works!') ``` - -Обратила внимание как мы сделали отступ во второй строке из 4 символов пробела? Мы поступаем так, чтобы Python понимал какой код после условного оператора if должен быть выполнен, если условие равно True. Можно ограничиться и одним пробелом, однако, практически все программисты Python используют 4, чтобы код выглядел аккуратно и читабельно. Каждая `табуляция` также считается за 4 пробела. +Обратила внимание, что мы сделали отступ во второй строке из 4 символов пробела? Мы поступаем так, чтобы Python понимал, какой код после условного оператора if должен быть выполнен, если условие равно True. Можно ограничиться и одним пробелом, однако практически все программисты Python используют 4, чтобы код выглядел аккуратно и читабельно. Каждая `табуляция` также считается за 4 пробела. -Сохраняем и запускаем еще раз: +Сохраняем и запускаем ещё раз: - $ python3 python_intro.py - It works! - +{% filename %}command-line{% endfilename %} +```python +$ python3 python_intro.py +It works! +``` + +Примечание: запомни, что Windows не распознаёт команду 'python3'. Всегда используй 'python' вместо 'python3' для запуска файлов. ### Что, если условие не True? -В предыдущем примере код выполнялся только когда условие равнялось True. Однако, Python имеет операторы `elif` и `else`: +В предыдущем примере код выполнялся, только когда условие равнялось True. Однако Python имеет операторы `elif` и `else`: +{% filename %}python_intro.py{% endfilename %} ```python if 5 > 2: print('5 is indeed greater than 2') else: print('5 is not greater than 2') ``` - Если запустить этот код, он напечатает: - $ python3 python_intro.py - 5 is indeed greater than 2 - +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +5 is indeed greater than 2 +``` -Если 2 больше 5, то будет выполнена следующая команда. Просто, правда? Давай посмотрим как работает оператор `elif`: +Если 2 больше 5, то будет выполнена следующая команда. Просто, правда? Давай посмотрим, как работает оператор `elif`: +{% filename %}python_intro.py{% endfilename %} ```python name = 'Sonja' if name == 'Ola': @@ -566,18 +727,20 @@ elif name == 'Sonja': else: print('Hey anonymous!') ``` - и запускаем: - $ python3 python_intro.py - Hey Sonja! - +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hey Sonja! +``` -Видишь, что произошло? `elif` позволяет добавить дополнительные условия, которые запускаются если предыдущие не срабатывают. +Видишь, что произошло? `elif` позволяет добавить дополнительные условия, которые запускаются, если предыдущие не срабатывают. Можно использовать сколько угодно `elif` после первого `if`. Например: +{% filename %}python_intro.py{% endfilename %} ```python volume = 57 if volume < 20: @@ -593,31 +756,53 @@ elif 80 <= volume < 100: else: print("My ears are hurting! :(") ``` - Python проходит через каждую проверку условия и выводит: - $ python3 python_intro.py - Perfect, I can hear all the details - +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Perfect, I can hear all the details +``` + +## Комментарии + +Комментарии — это строки, начинающиеся с символа `#`. Ты можешь написать всё, что тебе заблагорассудится, после символа `#`, и Python не обратит на это внимания. Комментарии могут помочь другим людям быстрее понять твой код. + +Давай посмотрим, как они выглядят: + +{% 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!") +``` + +Тебе не стоит писать комментарий для каждой строки кода, но он может быть полезен, чтобы пояснить причину определённых действий или добавить описание, когда код делает что-то особенно сложное. -### Содержание -В последних трех упражнениях ты познакомилась с: +### Подведём итог -* **сравнением вещей** - в Python ты можешь сравнивать вещи друг с другом при помощи `>`, `>=`, `==`, `<=`, `<` и `and`, `or` операторов -* **Boolean** - тип объекта, который может иметь только два значения: `True` или `False` -* **сохранением файлов** - хранение кода в файлах позволяет выполнять длинные программы. -* **if...elif...else** - условные операторы, которые позволяют выполнять код только при определенных условиях. +В последних трёх упражнениях ты познакомилась с: + +- __сравнением__ — в Python ты можешь сравнивать объекты друг с другом при помощи `>`, `>=`, `==`, `<=`, `<` и операторов `and`, `or`; +- __Boolean__ — типом объекта, который может иметь только два значения: `True` или `False`; +- __сохранением файлов__ — хранение кода в файлах позволяет выполнять длинные программы; +- __if...elif...else__ — условными операторами, которые позволяют выполнять код только при определенных условиях; +- __комментариями__ — строками, которые Python не запускает и которые позволяют документировать твой код. Пришло время для последней части этой главы! ## Твоя собственная функция! -Помнишь функции, такие как `len()`, которые можно использовать в Python? Тогда у нас есть хорошие новости — сейчас ты научишься писать свои собственные функции! +> Для проходящих руководство дома: этот раздел рассмотрен в видео [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0). + +Помнишь функции, такие как `len()`, которые можно использовать в Python? Тогда у нас есть хорошая новость — сейчас ты научишься писать свои собственные функции! -Функция - это последовательность инструкций, которые должен выполнить Python. Каждая функция в Python начинается с ключевого слова `def`, имеет свое имя и параметры. Давай начнем с простого примера. Замени код в **python_intro.py** на следующий: +Функция — это последовательность инструкций, которые должен выполнить Python. Каждая функция в Python начинается с ключевого слова `def`, имеет свое имя и параметры. Давай начнем с простого примера. Замени код в **python_intro.py** на следующий: +{% filename %}python_intro.py{% endfilename %} ```python def hi(): print('Hi there!') @@ -625,28 +810,36 @@ def hi(): hi() ``` - + Отлично, наша первая функция готова! -Ты можешь задаться вопросом, почему мы написали имя функции в конце файла. Причина в том, что Python читает и исполняет код из файла сверху вниз. Поэтому, для использования нашей функции мы должны вызвать её в конце файла. +Ты можешь задаться вопросом, почему мы написали имя функции в конце файла. Причина в том, что Python читает и исполняет код из файла сверху вниз. Поэтому для использования нашей функции мы должны вызвать её в конце файла. -Давай запустим и посмотрим что произойдет: +Давай запустим и посмотрим, что произойдет: + +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hi there! +How are you? +``` - $ python3 python_intro.py - Hi there! - How are you? - +Примечание: если это не сработало, не поддавайся панике! Вывод командной строки поможет тебе понять, почему так произошло: +- Если ты получила ошибку `NameError`, то, возможно, ты что-то неправильно ввела, поэтому проверь, что ты использовала одно и то же имя при создании функции в строке `def hi():` и при её вызове в строке `hi()`. +- Если ты получила ошибку `IndentationError`, проверь, что обе строки с вызовом `print` начинаются с одинакового количества пробелов: Python хочет, чтобы весь код внутри функции был аккуратно выровнен. +- Если при запуске команда не вывела вообще ничего, проверь, чтобы в начале последней строки `hi()` *не было* отступа — если он есть, эта строка тоже становится частью функции, и функция никогда не запустится. -Это было просто! Давай напишем нашу первую функцию с параметрами. Мы будем использовать предыдущий пример - функцию, которая пишут 'hi' и имя пользователя: +Давай напишем нашу первую функцию с параметрами. Мы будем использовать предыдущий пример — функцию, которая пишет 'hi' и имя пользователя: +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): ``` - Как ты можешь заметить, мы передали нашей функции параметр `name`: +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): if name == 'Ola': @@ -658,92 +851,105 @@ def hi(name): hi() ``` - Помни: функция `print` расположена внутри блока оператора `if` с отступом в четыре пробела. Это потому, что она запускается тогда, когда выполняется условие. Давай посмотрим, как это работает: - $ 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' - +{% 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' +``` -Упс, ошибка. К счастью, Python выдает довольно подробное сообщение об ошибке. Оно говорит нам, что функция `hi()` (которую мы определили) имеет один обязательный аргумент (`name`) и мы забыли передать его при вызове функции. Давай исправим это в конце файла: +Упс, ошибка. К счастью, Python выдает довольно подробное сообщение об ошибке. Оно говорит нам, что функция `hi()` (которую мы определили) имеет один обязательный аргумент (`name`), и мы забыли передать его при вызове функции. Давай исправим это в конце файла: +{% filename %}python_intro.py{% endfilename %} ```python hi("Ola") ``` - -И запустим еще раз: +И запустим ещё раз: - $ python3 python_intro.py - Hi Ola! - +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hi Ola! +``` -И если мы поменяем имя? +А если мы поменяем имя? +{% filename %}python_intro.py{% endfilename %} ```python hi("Sonja") ``` - И повторим: - $ python3 python_intro.py - Hi Sonja! - +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hi Sonja! +``` -Теперь, как ты думаешь, что произойдет, если ты наберешь другое имя? (Не Ola или Sonja) Попробуй сама и проверь была ли ты права. Результат должен быть таким: +Теперь, как ты думаешь, что произойдет, если ты наберешь другое имя? (Не Ola или Sonja) Попробуй сама и проверь, была ли ты права. Результат должен быть таким: - Hi anonymous! - +{% filename %}command-line{% endfilename %} +``` +Hi anonymous! +``` -Шикарно, верно? Так тебе не придется повторяться каждый раз, когда ты захочешь изменить имя. И это именно та причина, для которой нам и нужны функции - ты никогда не захочешь повторять свой код! +Шикарно, верно? Так тебе не придется повторяться каждый раз, когда ты захочешь изменить имя. И это именно та причина, для которой нам и нужны функции — ты никогда не захочешь повторять свой код! -Давай попробуем что-то похитрее -- существует немало имен и писать условие для каждого будет тяжело, правда? +Давай попробуем что-то похитрее — существует немало имён, и писать условие для каждого будет тяжело, правда? +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): print('Hi ' + name + '!') hi("Rachel") ``` - Давай выполним этот код: - $ python3 python_intro.py - Hi Rachel! - +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hi Rachel! +``` + Поздравляем! Ты только что научилась писать свои собственные функции :) ## Циклы +> Для проходящих руководство дома: этот раздел рассмотрен в видео [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0). + Ну вот и последняя часть. Быстро время пролетело, верно? :) Программисты не любят повторяться. Программирование — это автоматизация вещей, поэтому мы не хотим приветствовать каждого человека по имени вручную, верно? Здесь пригодятся циклы. Еще помнишь о списках? Давай создадим список девушек: +{% filename %}python_intro.py{% endfilename %} ```python girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] ``` - Мы хотим поздороваться с каждой по имени. У нас есть функция `hi`, которая этим и занимается, так что давай поместим её в цикл: +{% filename %}python_intro.py{% endfilename %} ```python for name in girls: ``` - -Оператор `for` работает по схожему принципу что и `if`; код после обоих операторов должен иметь отступ в четыре пробела. +Оператор `for` работает по схожему принципу что и `if`; в коде после обоих операторов должен быть отступ в четыре пробела. Ниже полный код, который должен быть у нас в файле: +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): print('Hi ' + name + '!') @@ -753,35 +959,37 @@ for name in girls: hi(name) print('Next girl') ``` - И после запуска: - $ python3 python_intro.py - Hi Rachel! - Next girl - Hi Monica! - Next girl - Hi Phoebe! - Next girl - Hi Ola! - Next girl - Hi You! - Next girl - +{% filename %}command-line{% endfilename %} +``` +$ python3 python_intro.py +Hi Rachel! +Next girl +Hi Monica! +Next girl +Hi Phoebe! +Next girl +Hi Ola! +Next girl +Hi You! +Next girl +``` Как ты можешь заметить, все команды внутри цикла `for` (с отступом от левого края) будут выполняться для каждого элемента списка `girls`. -Ты также можешь использовать цикл `for` на числах, используя функцию `range`: +Ты также можешь использовать цикл `for` с числами с помощью функции `range`: +{% filename %}python_intro.py{% endfilename %} ```python for i in range(1, 6): print(i) ``` - Что выведет на экран: +{% filename %}command-line{% endfilename %} ``` 1 2 @@ -789,17 +997,16 @@ for i in range(1, 6): 4 5 ``` - -Функция `range` создает список чисел, следующих от первого до второго с заданным шагом (начало, конец и шаг мы передаем функции как параметры, если шаг не указать, как в примере выше, он будет по умолчанию равен 1). +Функция `range` создает список чисел, следующих от первого до второго с заданным шагом (начало, конец и шаг мы передаем функции как параметры; если шаг не указать, как в примере выше, он будет по умолчанию равен 1). -Обрати внимание что второе число (конец списка) не включается в результат работы функции (`range(1, 6)` создает список от 1 до 5, не включающий 6). Это потому, что «range» — полуоткрытый диапазон, то есть включает в себя первое значение, но не включает последнего. +Обрати внимание, что второе число (конец списка) не включается в результат работы функции (`range(1, 6)` создает список от 1 до 5, не включающий 6). Это потому, что «range» — полуоткрытый диапазон, то есть включает в себя первое значение, но не включает последнее. -## Содержание +## Подведём итог -Вот и всё. **Ты чертовски крута!** Эта глава была непростой, так что ты можешь гордиться собой. Мы-то точно тобой гордимся — вон как далеко продвинулась уже! +Вот и всё. __Ты чертовски крута!__ Эта глава была непростой, так что ты можешь гордиться собой. Мы-то точно тобой гордимся — вон как далеко продвинулась уже! -Тебе может потребоваться перерыв - прогуляйся и дай отдых глазам перед тем, как мы перейдем к следующей главе. :) +Тебе может потребоваться перерыв — прогуляйся и дай отдых глазам перед тем, как мы перейдем к следующей главе. :) ![Пирожок][3] diff --git a/ru/python_introduction/images/cupcake.png b/ru/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/ru/python_introduction/images/cupcake.png and b/ru/python_introduction/images/cupcake.png differ diff --git a/ru/template_extending/README.md b/ru/template_extending/README.md index e44f1180444..9a3197ed855 100755 --- a/ru/template_extending/README.md +++ b/ru/template_extending/README.md @@ -1,89 +1,112 @@ # Расширение шаблона -Еще одной удобной вещью в Django является **расширение шаблонов**. Что это значит? Ты можешь использовать различные блоки HTML-кода для разных частей своего веб-сайта. +Ещё одной удобной вещью в Django является __расширение шаблонов__. Что это значит? Ты можешь использовать одни и те же блоки HTML-кода для разных частей своего веб-сайта. -Так тебе не придется повторяться каждый раз, когда потребуется использовать туже информацию/структуру. И если появится необходимость что-то изменить - не придется вносить правки в каждую страницу - достаточно скорректировать шаблон! +Так тебе не придётся повторяться каждый раз, когда потребуется использовать ту же информацию/структуру. И если появится необходимость что-то изменить, не придётся вносить правки в каждую страницу: достаточно скорректировать шаблон! -## Создаем базовый шаблон +## Создаём базовый шаблон -Базовый шаблон - это наиболее общая типовая форма страницы, которую ты расширяешь для отдельных случев. +Базовый шаблон — это наиболее общая типовая форма страницы, которую ты расширяешь для отдельных случев. Давай создадим файл `base.html` в директории `blog/templates/blog/`: ``` - blog - └───templates -     └───blog -             base.html -             post_list.html +blog +└───templates + └───blog + base.html + post_list.html ``` -Теперь открой его и скопируй все из `post_list.html` в `base.html`: - -```html - {% load staticfiles %} - - - Django Girls blog - - - - - - - - -
-
-
- {% for post in posts %} -
-
- {{ post.published_date }} -
-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

-
- {% endfor %} -
-
-
- - -``` - -Затем в файле `base.html` замени все между тегами `` и `` следующим кодом: +Теперь открой его и скопируй всё из `post_list.html` в `base.html`: +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html +{% load static %} + + + Django Girls blog + + + + + +
- {% block content %} - {% endblock %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %}
+ +``` + +Затем в файле `base.html` замени всё между тегами `` и `` следующим кодом: + +{% filename %}blog/templates/blog/base.html{% endfilename %} +```html + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ ``` -Мы просто заменили все между `{% for post in posts %}{% endfor %}` следующим: +Мы просто заменили всё между `{% for post in posts %}{% endfor %}` следующим: +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - {% block content %} - {% endblock %} +{% block content %} +{% endblock %} ``` -Что это означает? Ты только что создала `block` - тег шаблона, позволяющий вставлять HTML-код этого блока в другие шаблоны, расширяющие `base.html`. Мы покажем как это сделать через секунду. +Что это означает? Ты только что создала `block` — тег шаблона, позволяющий вставлять HTML-код этого блока в другие шаблоны, расширяющие `base.html`. Мы покажем, как это сделать, через секунду. -Теперь сохрани все и открой `blog/templates/blog/post_list.html` снова. Тебе нужно удалить весь код вне тегов body, а также ``, в итоге файл будет выглядеть следующим образом: +Теперь сохрани всё и открой `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.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+{% endfor %} +``` + +Мы хотим использовать это фрагмент в твоём шаблоне для отображения содержимого. Пора добавить теги блоков в этот файл! + +{% raw %}Нам нужно, чтобы новый тег блока соответствовал тегу в файле `base.html`. Также нам необходимо включить весь код, который соответствует твоему блоку с содержимым. Для этого расположи всё между `{% block content %}` и `{% endblock %}`. Вот так:{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} +```html +{% block content %} {% for post in posts %}
@@ -93,32 +116,28 @@

{{ post.text|linebreaksbr }}

{% endfor %} +{% endblock %} ``` -А теперь добавь следующую строку в начало файла: - -``` - {% extends 'blog/base.html' %} -``` - -{% raw %}Таким образом мы расширили шаблон `base.html` шаблоном `post_list.html`. Осталось последнее: обернуть все (кроме добавленной выше первой строки) в `{% block content %}` и `{% endblock content %}`. Таким образом:{% endraw %} +Осталось последнее: нам нужно связать эти два шаблона друг с другом. Ведь именно для этого и нужно расширение шаблонов! Мы сделаем это, добавив тег `extends` в начало файла. Вот так: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - {% extends 'blog/base.html' %} +{% extends 'blog/base.html' %} - {% block content %} - {% for post in posts %} -
-
- {{ post.published_date }} -
-

{{ post.title }}

-

{{ post.text|linebreaksbr }}

+{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }}
- {% endfor %} - {% endblock content %} +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} ``` Готово! Проверь, что твой веб-сайт работает нормально :) -> Если появилась ошибка `TemplateDoesNotExists`, которая говорит что не существует файла `blog/base.html`, после того как ты запустила веб-сервер через команду `runserver` в рабочей строке, попробуй остановить его (одновременно нажми Ctrl + C находясь в командной строке) и перезапусти веб-сервер командой `python manage.py runserver`. +> Если появилась ошибка `TemplateDoesNotExists`, это значит, что нет файла `blog/base.html` и `runserver` запущен в командной строке. Попробуй остановить его (одновременно нажми Ctrl + C) и перезапусти веб-сервер командой `python manage.py runserver`. diff --git a/ru/whats_next/README.md b/ru/whats_next/README.md index d0c03193faa..160d98d1a5f 100755 --- a/ru/whats_next/README.md +++ b/ru/whats_next/README.md @@ -1,40 +1,38 @@ # Что дальше? -Поздравь себя! **Ты нереально крута**. Мы очень гордимся! <3 +Поздравь себя! __Ты нереально крута__. Мы очень гордимся! <3 ### Что делать дальше? Сделай перерыв и расслабься. Ты только что закончила огромную работу. -И не забудь подписаться на: +И не забудь подписаться на страничку Django Girls в [Facebook](http://facebook.com/djangogirls) и [Twitter](https://twitter.com/djangogirls), чтобы оставаться в курсе новостей. -* Страничку Django Girls в [Facebook][1] и [Twitter][2], чтобы оставаться в курсе новостей +### Можем ли мы посоветовать дополнительные ресурсы для обучения? - [1]: http://facebook.com/djangogirls - [2]: https://twitter.com/djangogirls +Конечно! Сейчас доступно _огромное_ количество ресурсов для изучения всевозможных навыков программирования. Мы поможем подобрать тебе то, что будет полезно изучить на следующем этапе. Вот несколько бесплатных ресурсов (или ресурсов с большим количеством бесплатного контента): -### Можем ли мы посоветовать дополнительные ресурсы для обучения? +#### Django +- Другое наше руководство, [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org/) +- [Django's official tutorial](https://docs.djangoproject.com/en/2.0/intro/tutorial01/) +- [Getting Started With Django video lessons](http://www.gettingstartedwithdjango.com/) + +#### HTML, CSS и JavaScript +- [Codecademy's web development course](https://www.codecademy.com/learn/paths/web-development) +- [freeCodeCamp](https://www.freecodecamp.org/) + +#### Python +- [Codecademy's Python course](https://www.codecademy.com/learn/learn-python) +- [Google's Python course](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's Python specialization](https://www.coursera.org/specializations/python) – некоторые видеокурсы можно изучать бесплатно, также можешь получить сертификат Coursera после успешного прохождения +- [Python for Everybody](https://www.py4e.com/) + +#### Работа с данными +- [Codecademy's data science course](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 "миссий" бесплатно -Кончено! Прежде всего попробуй [Учебнике Django Girls: Дополнительные темы][3]. - - [3]: http://djangogirls.gitbooks.io/django-girls-tutorial-extensions/ - -Позднее ты можешь попробовать ресурсы из списка ниже. Мы очень рекомендуем все из них! - -- [Django's official tutorial][4] -- [New Coder tutorials][5] -- [Code Academy Python course][6] -- [Code Academy HTML & CSS course][7] -- [Django Carrots tutorial][8] -- [Learn Python The Hard Way book][9] -- [Getting Started With Django video lessons][10] -- [Two Scoops of Django: Best Practices for Django 1.8 book][11] - - [4]: https://docs.djangoproject.com/en/1.8/intro/tutorial01/ - [5]: http://newcoder.io/tutorials/ - [6]: https://www.codecademy.com/en/tracks/python - [7]: https://www.codecademy.com/tracks/web - [8]: https://github.com/ggcarrots/django-carrots/ - [9]: http://learnpythonthehardway.org/book/ - [10]: http://gettingstartedwithdjango.com/ - [11]: https://twoscoopspress.com/products/two-scoops-of-django-1-8 +Нам уже не терпится узнать, что ты создашь следующим! diff --git a/sk/GLOSSARY.md b/sk/GLOSSARY.md old mode 100755 new mode 100644 index 38a876ffe64..a45f5aea436 --- a/sk/GLOSSARY.md +++ b/sk/GLOSSARY.md @@ -1,3 +1,3 @@ # editor kódu -Editor kódu je aplikácia, pomocou ktorej môžeš svoj kód uložiť, takže sa k nemu môžeš neskôr vrátiť. Kde ho môžeš zohnať, zistíš v [kapitole o editore kódu](./code_editor/README.md) \ No newline at end of file +Editor kódu je aplikácia, pomocou ktorej môžeš svoj kód uložiť, aby si sa k nemu mohla neskôr vrátiť. Kde ho môžeš zohnať, zistíš v [kapitole o editore kódu](./code_editor/README.md) \ No newline at end of file diff --git a/sk/README.md b/sk/README.md old mode 100755 new mode 100644 index e2f0d550b3f..18d32e6d7b0 --- a/sk/README.md +++ b/sk/README.md @@ -1,48 +1,51 @@ -# Príručka k Django Girls +# Django Girls tutoriál -[![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) -> Toto dielo je zverejnené pod medzinárodnou licenciou Creative Commons Attribution-ShareAlike ("uvedenie autora – rovnaké šírenie") 4.0. Ak chcete zobraziť kópiu tejto licencie, navštívte https://creativecommons.org/licenses/by-sa/4.0/ +> Toto dielo je zverejnené pod licenciou Creative Commons Attribution-ShareAlike 4.0 International License. Ak chceš vidieť kópiu tejto licencie, navštív https://creativecommons.org/licenses/by-sa/4.0/ + +## Vitaj + +Vitaj v Django Girls tutoriáli! Tešíme sa, že tu si. :) V tomto tutoriáli sa vydáme na cestu pod kapotu webových technológií a ponúkneme ti letmý pohľad na všetky čiastočky a kúsky, ktoré musia do seba zapadnúť, aby vytvorili web tak, ako ho poznáme. + +Ako to býva so všetkým, čo je neznáme, aj toto bude dobrodružstvo - ale žiadny strach, keď si už nabrala odvahu byť tu, zvládneš to v pohode. :) ## Úvod -Mala si niekedy pocit, že svet je stále viac a viac o technológiách a ty v nich zaostávaš? Uvažovala si niekedy, že by si si vytvorila webovú stránku, ale nikdy si nemala dosť motivácie začať? Zdalo sa ti niekedy, že svet softvéru je pre teba príliš komplikovaný a že sama nezvládneš nič vytvoriť? +Mala si niekedy pocit, že svet je stále viac a viac o technológiách, ku ktorým (zatiaľ) nemáš vzťah? Uvažovala si niekedy, že by si si vytvorila webovú stránku, ale nikdy si nemala dostatok motivácie začať? Zdalo sa ti niekedy, že svet softvéru je pre teba príliš komplikovaný na to, aby si sa vôbec pokúsila niečo sama vytvoriť? -Máme pre teba dobrú správu! Programovanie nie je také zložité, ako sa zdá a chceme ti ukázať, aké môže byť zábavné. +Máme pre teba dobrú správu! Programovanie nie je také zložité, ako sa zdá, a my ti chceme ukázať, aké môže byť zábavné. -Tento návod z teba neurobí mávnutím čarovného prútika programátorku. Ak chceš byť dobrá, čakajú ťa mesiace či dokonca roky štúdia a praxe. Chceme ti ale ukázať, že vytvorenie webovej stránky nie je také ťažké, ako sa zdá. Pokúsime sa ti vysvetliť rôzne technológie tak, aby si sa ich nemusela báť. +Tento návod z teba neurobí programátorku mávnutím čarovného prútika. Ak v tom chceš byť dobrá, čakajú ťa mesiace či dokonca roky štúdia a praxe. Chceme ti ale ukázať, že programovanie a vytváranie webových stránok nie je také ťažké, ako sa zdá. Pokúsime sa ti vysvetliť rôzne technológie tak, aby si sa ich nemusela báť. -Dúfame, že sa ti tieto veci zapáčia tak veľmi ako nám! +Dúfame, že sa ti technológia zapáči tak veľmi ako nám! -## Čo ťa tento návod naučí? +## Čo ťa tento tutoriál naučí? -Po skončení budeš mať funkčnú webovú aplikáciu: tvoj vlastný blog. Ukážeme ti, ako ho zverejniť na webe, kde ho môže každý navštíviť! +Po skončení budeš mať funkčnú webovú aplikáciu - tvoj vlastný blog. Ukážeme ti, ako ho zverejniť na webe, kde ho môže každý navštíviť! Výsledok bude vyzerať asi takto: -![Obrázok 0.1][2] +![Obrázok 0.1](images/application.png) - [2]: images/application.png +> Ak budeš na tomto projekte pracovať sama a nemáš mentorku či mentora, ktorý ti pomáha, môžeš v prípade problémov navštíviť tento chat: [![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial). Požiadali sme naše mentorky a mentorov, ale aj absolventky, aby sa na tomto chate občas ukázali a pomohli ostatným! Neboj sa opýtať, čomu nerozumieš! -> Ak budeš na tomto projekte pracovať sama a nemáš mentora, ktorý ti pomáha, môžeš v prípade problémov navštíviť tento chat: [![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). Požiadali sme našich mentorov, ale aj absolventky, aby sa na tomto chate občas ukázali a pomohli ostatným, ktorí môžu zápasiť s problémami! Neboj sa pripojiť a opýtať sa, na čo potrebuješ! +OK, [začnime pekne po poriadku...](./how_the_internet_works/README.md) -OK, [začnime pekne po poriadku...][3] +## Nasledovanie tutoriálu doma - [3]: ./how_the_internet_works/README.md +Zúčastniť sa Django Girls workshopu je skvelé, ale uvedomujeme si, že nie vždy je možné niektorý navštíviť. Preto ťa chceme povzbudiť v tom, aby si skúsila postupovať podľa tohto tutoriálu doma. Pre čitateľky doma v súčasnosti pripravujeme videá, vďaka ktorým bude jednoduchšie tutoriál nasledovať sama. Stále sa na tom pracuje, ale viac a viac vecí bude čoskoro na kanáli na YouTube pod názvom [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed). -## Informácie a možnosti ako sa zapojiť +V každej kapitole, ktorá už bola spracovaná, sa nachádza odkaz na príslušné video. -Tento návod vytvorili a udržiavajú [DjangoGirls][4]. Ak nájdete chyby alebo by ste chceli aktualizovať tento návod, prosím [postupujte podľa pokynov][5]. +## Informácie a možnosti, ako sa zapojiť - [4]: https://djangogirls.org/ - [5]: https://github.com/DjangoGirls/tutorial/blob/master/README.md +Tento návod vytvorili a udržiavajú [DjangoGirls](https://djangogirls.org/). Ak nájdeš chyby alebo by si chcela tento tutoriál aktualizovať, prosím, [postupuj podľa pokynov](https://github.com/DjangoGirls/tutorial/blob/master/README.md). -## Chceš pomôcť s prekladom do iných jayzkov? +## Chceš pomôcť s prekladom do iných jazykov? V súčasnosti koordinujeme preklady cez platformu crowdin.com: https://crowdin.com/project/django-girls-tutorial -Ak tvoj jazyk nie je v zozname na crowdin.com, [daj nám prosím vedieť][6] a povedz, aký jazyk máme pridať. - - [6]: https://github.com/DjangoGirls/tutorial/issues/new +Ak sa tvoj jazyk nenachádza v zozname na [crowdin](https://crowdin.com/), [daj nám, prosím, vedieť](https://github.com/DjangoGirls/tutorial/issues/new), aký jazyk máme pridať. \ No newline at end of file diff --git a/sk/SUMMARY.md b/sk/SUMMARY.md old mode 100755 new mode 100644 index 4db235abfb7..29aedb95212 --- a/sk/SUMMARY.md +++ b/sk/SUMMARY.md @@ -1,26 +1,35 @@ # Zhrnutie -* [Úvod](README.md) -* [Inštalácia](installation/README.md) -* [Ako funguje Internet](how_the_internet_works/README.md) -* [Úvod do príkazového riadku](intro_to_command_line/README.md) -* [Inštalácia Pythonu](python_installation/README.md) -* [Editor kódu](code_editor/README.md) -* [Úvod do jazyka Python](python_introduction/README.md) -* [Čo je Django?](django/README.md) -* [Inštalácia Django](django_installation/README.md) -* [Tvoj prvý Django projekt!](django_start_project/README.md) -* [Django modely](django_models/README.md) -* [Django admin](django_admin/README.md) -* [Nasadenie!](deploy/README.md) -* [Django url](django_urls/README.md) -* [Django views - čas tvoriť!](django_views/README.md) -* [Úvod do HTML](html/README.md) -* [Django ORM (tvorba dotazov)](django_orm/README.md) -* [Dynamické dáta v šablónach](dynamic_data_in_templates/README.md) -* [Šablóny Django](django_templates/README.md) -* [CSS - aby to pekne vyzeralo](css/README.md) -* [Rozširovanie šablón](template_extending/README.md) -* [Ako rozšíriť aplikáciu](extend_your_application/README.md) -* [Formuláre Django](django_forms/README.md) -* [Čo ďalej?](whats_next/README.md) +* [Úvod](README.md) +* [Inštalácia](installation/README.md) + * [Príkazový riadok](installation/README.md#command-line) + * [Python](installation/README.md#python) + * [Editor kódu](installation/README.md#code-editor) + * [Virtuálne prostredie](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) +* [Inštalácia (chromebook)](chromebook_setup/README.md) +* [Ako funguje internet](how_the_internet_works/README.md) +* [Úvod do príkazového riadku](intro_to_command_line/README.md) +* [Inštalácia Pythonu](python_installation/README.md) +* [Editor kódu](code_editor/README.md) +* [Úvod do jazyka Python](python_introduction/README.md) +* [Čo je Django?](django/README.md) +* [Inštalácia Djanga](django_installation/README.md) +* [Tvoj prvý Django projekt!](django_start_project/README.md) +* [Django modely](django_models/README.md) +* [Django admin](django_admin/README.md) +* [Nasadenie!](deploy/README.md) +* [Django URL](django_urls/README.md) +* [Django viewy - čas tvoriť!](django_views/README.md) +* [Úvod do HTML](html/README.md) +* [Django ORM (QuerySety)](django_orm/README.md) +* [Dynamické dáta v šablónach](dynamic_data_in_templates/README.md) +* [Django šablóny](django_templates/README.md) +* [CSS - skrášlime to](css/README.md) +* [Rozširovanie šablón](template_extending/README.md) +* [Ako rozšíriť aplikáciu](extend_your_application/README.md) +* [Django formuláre](django_forms/README.md) +* [Čo ďalej?](whats_next/README.md) \ No newline at end of file diff --git a/sk/chromebook_setup/README.md b/sk/chromebook_setup/README.md new file mode 100644 index 00000000000..a218b11f42b --- /dev/null +++ b/sk/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# Nastavenie Chromebooku + +> **Poznámka** Ak už máš po [inštalácii](../installation/README.md), nemusíš toto robiť znova. Môžeš ísť rovno na [Úvod do Pythonu](../python_introduction/README.md). + +{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/sk/chromebook_setup/instructions.md b/sk/chromebook_setup/instructions.md new file mode 100644 index 00000000000..981d9157711 --- /dev/null +++ b/sk/chromebook_setup/instructions.md @@ -0,0 +1,158 @@ +Túto časť [môžeš preskočiť](http://tutorial.djangogirls.org/en/installation/#install-python), ak nepoužívaš Chromebook. Ak ho používaš, tak tvoja inštalácia bude trochu iná. Zvyšok inštalačných pokynov môžeš ignorovať. + +### Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com) + +Cloud IDE je nástroj, ktorý ti poskytne editor kódu a prístup na počítač, ktorý beží v cloude na internete, kde môžeš inštalovať, písať a spúšťať softvér. Počas tohto tutoriálu sa Cloud IDE bude tváriť ako tvoj *lokálny stroj*. Príkazy budeš zadávať do terminálového rozhrania tak, ako tvoje spoluúčastníčky, čo používajú macOS, Ubuntu, alebo Windows, ale tvoj terminál bude pripojený na počítač, ktorý beží niekde inde a ktorý Cloud IDE pripraví pre teba. Tu sú inštrukcie pre cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com). Môžeš si vybrať jedno z Cloud IDE riešení a postupovať podľa inštrukcií pre zvolený typ IDE. + +#### PaizaCloud Cloud IDE + +1. Choď na [PaizaCloud Cloud IDE](https://paiza.cloud/) +2. Vytvor si účet +3. Klikni na *New Server* a vyber si Django appku +4. Klikni na tlačítko Terminal (na ľavej strane okna) + +Teraz by si mala vidieť rozhranie s bočnou lištou a tlačidlami naľavo. Klikni na tlačítko Terminal, aby sa ti otvorilo terminálové okno s takýmto promptom: + +{% filename %}Terminal{% endfilename %} + + $ + + +Terminál na PaizaCloud Cloud IDE je pripravený na tvoje inštrukcie. Oknu môžeš zmeniť veľkosť alebo ho maximalizovať, aby bolo trochu väčšie. + +#### AWS Cloud9 + +Cloud 9 momentálne vyžaduje, aby si si vytvorila AWS účet a vložila informácie o kreditnej karte. + +1. Nainštaluj si Cloud 9 z [Chrome webového obchodu](https://chrome.google.com/webstore/detail/cloud9/nbdmccoknlfggadpfkmcpnamfnbkmkcp) +2. Choď na [c9.io](https://c9.io) a klikni na *Get started with AWS Cloud9* +3. Vytvor si AWS účet (je potrebné zadať údaje o svojej kreditnej karte, ale účet môžeš používať zdarma). +4. Na AWS Dashboarde napíš do vyhľadávania *Cloud9* a klikni naň +5. Na Cloud 9 dashboarde klikni na *Create environment* +6. Nazvi ho *django-girls* +7. Pri konfigurácii nastavení vyber *Create a new instance for environment (EC2)* ako "Environment Type" a *t2.micro* ako "Instance type" (malo by tam byť napísané "Free-tier eligible."). Prednastavené cost-saving nastavenie je okej, aj ostatné prednastavené hodnoty môžeš nechať tak. +8. Klikni na *Next step* +9. Klikni na *Create environment* + +Teraz by si mala vidieť rozhranie s bočnou lištou, veľkým hlavným oknom s trochou textu a malým oknom v dolnej časti, ktoré vyzerá takto nejak: + +{% filename %}bash{% endfilename %} + + tvojaprezyvka:~/workspace $ + + +Táto dolná časť je tvoj terminál. Môžeš ho použiť na poslanie inštrukcií vzdialenému Cloud 9 počítaču. Okno môžeš zväčšiť. + +#### Glitch.com Cloud IDE + +1. Choď na [Glitch.com](https://glitch.com/) +2. Vytvor si účet (https://glitch.com/signup) alebo použi svoj účet na GitHube, ak máš. (Pozri inštrukcie ku GitHubu nižšie.) +3. Klikni na *New Project* a vyber *hello-webpage* +4. Klikni na rozbaľovacie menu Tools (vľavo dole v okne) a potom na tlačítko Terminal, aby sa ti otvorila terminálová záložka s takýmto promptom: + +{% filename %}Terminal{% endfilename %} + + app@nazov-tvojho-glitch-projektu:~ + + +Ak používaš Glitch.com ako tvoje cloud IDE, nemusíš si vytvárať virtuálne prostredie. Namiesto toho vytvor nasledujúce súbory ručne: + +{% 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 +``` + +Keď budeš mať tieto súbory vytvorené, choď do Terminálu a vykonaj nasledujúce príkazy, aby si si vytvorila svoj prvý Django projekt: + +{% filename %}Terminal{% endfilename %} + + django-admin.py startproject mysite . + refresh + + +Aby si mala prístup k detailným chybovým hláškam, môžeš si aktivovať debug logy vo svojej Glitch aplikácii. Pridaj nasledovné na koniec súboru `mysite/settings.py`. + +{% 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, + }, + }, +} +``` + +Toto vytvorí súbor `debug.log`, v ktorom nájdeš detaily o tom, čo Django robí, ako aj chybové hlášky, ktoré sa môžu vyskytnúť. Toto ti značne uľahčí opravovanie tvojej stránky, ak niečo nebude fungovať. + +Prvotný reštart tvojho Glitch projektu by mal zlyhať. (Keď klikneš na tlačítko `Show` hore a potom na `In a New Window`, mala by si sa dostať po chybovú hlášku `DisallowedHost`.) V tejto chvíli sa tým nemusíš zaoberať, tutoriál to vyrieši v momente, keď budeš meniť nastavenia svojho Django projektu v súbore `mysite/settings.py`. + +### Virtuálne prostredie + +Virtuálne prostredie (tiež nazývané virtualenv) je ako súkromná krabica, do ktorej môžeme uložiť užitočný počítačový kód pre projekt, na ktorom pracujeme. Používame ho na oddelenie rôznych častí kódu pre rôzne projekty, aby sa nám medzi nimi nepomiešali veci. + +Spusti: + +{% filename %}Cloud 9{% endfilename %} + + mkdir djangogirls + cd djangogirls + python3 -m venv myvenv + source myvenv/bin/activate + pip install django~={{ book.django_version }} + + +(všimni si, že v poslednom riadku sme použili vlnovku a za ňou znamienko rovnosti: `~=`). + +### GitHub + +Vytvor si [GitHub](https://github.com) účet. + +### PythonAnywhere + +DjangoGirls tutoriál obsahuje kapitolu o niečom, čomu sa hovorí nasadenie (deployment). Je to proces prenesenia kódu, ktorý poháňa tvoju novú webovú aplikáciu, na verejne dostupný počítač (ešte nazývaný aj server), aby aj ostatní ľudia videli tvoju prácu. + +Táto časť je trochu zvláštna, keď pracuješ s týmto tutoriálom na Chromebooku, lebo už používaš počítač, ktorý je na internete (na rozdiel od notebooku). Napriek tomu je stále užitočná, lebo si môžeme predstaviť pracovné prostredie Cloud 9 ako miesto, kde sa nachádza nedokončená práca, a PythonAnywhere ako miesto, kde ukážeme našu prácu, keď bude hotová. + +Tak si vytvor nový PythonAnywhere účet na [www.pythonanywhere.com](https://www.pythonanywhere.com). \ No newline at end of file diff --git a/sk/code_editor/README.md b/sk/code_editor/README.md old mode 100755 new mode 100644 index 97a5ffc6e23..e9e19606304 --- a/sk/code_editor/README.md +++ b/sk/code_editor/README.md @@ -1,7 +1,11 @@ # Editor kódu +> Pre čitateľky a čitateľov doma: Táto kapitola je spracovaná vo videu [Installing Python & Code Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s). + O chvíľu napíšeš svoj prvý riadok kódu, takže je načase si stiahnuť editor kódu! -> **Poznámka** Toto si už možno spravila v kapitole Inštalácia - ak áno, môžeš pokračovať rovno na ďalšiu kapitolu! +> **Poznámka** Ak používaš Chromebook, preskoč túto kapitolu a postupuj podľa pokynov na [nastavenie Chromebooku](../chromebook_setup/README.md). Cloud IDE, ktoré si si vybrala (PaizaCloud Cloud IDE alebo AWS Cloud9) už obsahuje editor kódu. Keď si otvoríš nejaký súbor vo svojom IDE pomocou menu File, automaticky budeš tento editor používať. +> +> **Poznámka** Toto si už možno urobila v [kapitole Inštalácia](../installation/README.md) - ak áno, môžeš preskočiť rovno na ďalšiu kapitolu! {% include "/code_editor/instructions.md" %} \ No newline at end of file diff --git a/sk/code_editor/instructions.md b/sk/code_editor/instructions.md old mode 100755 new mode 100644 index b2d8c066e7f..6f2f2f950d5 --- a/sk/code_editor/instructions.md +++ b/sk/code_editor/instructions.md @@ -1,31 +1,37 @@ -Existuje veľa rôznych editorov a zväčša sa vyberajú podľa osobných preferencií. Väčšina Python programátorov používa zložité, ale veľmi výkonné IDE (integrované vývojové prostredie), ako napríklad PyCharm. Pre začiatočníka je to pravdepodobne menej vhodné; naše odporúčania sú rovnako výkonné, ale oveľa jednoduchšie. +Existuje veľa rôznych editorov a zväčša sa vyberajú podľa osobných preferencií. Väčšina programátorov a programátoriek v Pythone používa zložité, ale veľmi výkonné IDE (integrované vývojové prostredie) ako napríklad PyCharm. Pre začiatočníčku je to pravdepodobne menej vhodné; naše odporúčania sú rovnako výkonné, ale oveľa jednoduchšie. -Naše návrhy sú uvedené nižšie, ale neváhaj sa opýtať svojho trénera, aké sú jeho preferencie - potom bude jednoduchšie od neho získať pomoc. +Naše návrhy sú uvedené nižšie, ale neváhaj sa opýtať svojej mentorky alebo mentora, aké sú ich preferencie - bude ti jednoduchšie vedieť pomocť. + +## Visual Studio Code + +Visual Studio Code je editor zdrojového kódu, ktorý vyvíja Microsoft pre Windows, Linux a macOS. Podporuje debugovanie, priamu prácu s Gitom, zvýrazňovanie syntaxe, inteligentné dopĺňanie kódu, snippety a refaktorovanie kódu. + +[Stiahni si ho odtiaľto](https://code.visualstudio.com/) ## Gedit -Gedit je open-source, editor zdarma dostupný pre všetky operačné systémy. +Gedit je open source editor zdarma dostupný pre všetky operačné systémy. -[Stiahni si tu](https://wiki.gnome.org/Apps/Gedit#Download) +[Stiahni si ho odtiaľto](https://wiki.gnome.org/Apps/Gedit#Download) -## Sublime Text 3 +## Sublime Text -Sublime Text je veľmi populárny editor so skúšobnou verziou zdarma. Je jednoduchý na inštaláciu a používanie, je dostupný pre všetky operačné systémy. +Sublime Text je veľmi populárny editor so skúšobnou verziou zdarma a je dostupný pre všetky operačné systémy. -[Stiahni si tu](https://www.sublimetext.com/3) +[Stiahni si ho odtiaľto](https://www.sublimetext.com/) ## Atom -Atom je veľmi nový editor vytvorený [GitHubom](https://github.com/). Je zdarma, open-source, jednoduchý na inštaláciu a používanie. Je dostupný pre Windows, OS X a Linux. +Atom je ďalší populárny editor. Je zdarma, open source a dostupný pre Windows, macOS a Linux. Atom je vyvíjaný [GitHubom](https://github.com/). -[Stiahni si tu](https://atom.io/) +[Stiahni si ho odtiaľto](https://atom.io/) -## Prečo inštalujeme editor? +## Prečo inštalujeme editor kódu? -Môžete Vás zaujímať, prečo inštalujeme takýto špeciálny editor kódu, radšej než používať niečo ako Word alebo Notepad. +Možno ti napadlo, prečo inštalujeme takýto špeciálny editor kódu namiesto toho, aby sme použili niečo ako Word alebo Notepad. -Prvý dôvod je, že kód musí byť **čistý text** a problém s programami ako Word a Textedit je ten, že v skutočnosti nevytvárajú čistý text, produkujú obohatený text (s fontom a formátovaním), používajú vlastné formáty ako [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format). +Prvý dôvod je, že kód musí byť **čistý text** a problém s editormi ako Word a Textedit je ten, že v skutočnosti nevytvárajú čistý text, ale produkujú obohatený text (s fontami a formátovaním) a používajú vlastné formáty ako [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format). -Druhý dôvod je, že editor kódu je špecializovaný na editáciu kódu, takže môže poskytovať pomocné funkcie ako zvýraznenie kódu farbou podľa jeho významu alebo automaticky za Vás uzatvárať úvodzovky. +Druhý dôvod je, že editor kódu je špecializovaný na editáciu kódu, takže môže poskytovať pomocné funkcie ako zvýraznenie kódu farbou podľa jeho významu, alebo automaticky za teba uzatvárať úvodzovky. -Všetko uvidíme neskôr. Čoskoro budeš premýšľať o svojom starom vernom editore ako o svojom obľúbenom nástroji :) \ No newline at end of file +Všetko uvidíme neskôr. Čoskoro budeš považovať svoj verný editor za svoj obľúbený nástroj. :) \ No newline at end of file diff --git a/sk/css/README.md b/sk/css/README.md old mode 100755 new mode 100644 index 5c6611baa15..6f8d0c76a9a --- a/sk/css/README.md +++ b/sk/css/README.md @@ -1,146 +1,147 @@ -# CSS - skrášli to! +# CSS - skrášlime to! Náš blog vyzerá zatiaľ dosť škaredo, však? Je čas to napraviť! Použijeme na to CSS. ## Čo je CSS? -Kaskádové štýly (CSS, angl. Cascading Style Sheets) je jazyk, ktorý sa používa na popis vzhľadu a formátovania webstránky napísanej v značkovacom jazyku (napríklad HTML). Predstav si to ako make-up pre našu webstránku :). +Kaskádové štýly (CSS, angl. Cascading Style Sheets) sú jazyk, ktorý sa používa na popis vzhľadu a formátovania webstránky napísanej v markupovom jazyku (napríklad HTML). Predstav si to ako make-up pre našu webstránku. ;) -Ale asi nechceme začať úplne od nuly, však? Znova použijeme niečo, čo už bolo vytvorené programátormi a sprístupnené na internete zadarmo. Veď vieš, znovuobjavovanie kolesa nie je žiadna zábava. +Ale nechceme začať zase od nuly, že? Znovu použijeme niečo, čo iné programátorky a programátori zverejnili na internete zadarmo. Ako vieš, vymýšlať koleso nie je žiadna zábava. -## Používajme Bootstrap! +## Použime Bootstrap! Bootstrap je jedným z najpopulárnejších HTML a CSS frameworkov pre vývoj krásnych webových stránok: https://getbootstrap.com/ -Bol napísaný programátormi, ktorí pracovali pre Twitter a ďalej ho vyvíjajú dobrovoľníci z celého sveta. +Bol napísaný programátormi a programátorkami, ktorí pracovali pre Twitter. Teraz je vyvíjaný dobrovoľníkmi a dobrovoľníčkami z celého sveta! ## Inštalácia Bootstrapu -Na inštaláciu Bootstrapu musíš pridať do hlavičky `` vo svojom `.html` súbore (`blog/templates/blog/post_list.html`) toto: +Aby si nainštalovala Bootstrap, otvor svoj súbor `.html` vo svojom editore a pridaj toto do sekcie ``: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - - + ``` -Nepridá to do tvojho projektu žiadne súbory. Iba to ukazuje na súbory, ktoré už existujú na internete. Skúsme to, otvor svoju webstránku a obnov stránku. Tu to máme! - -![Obrázok 14.1][1] +Nepridá to do tvojho projektu žiadne súbory. Iba to ukazuje na súbory, ktoré už existujú na internete. Skúsme to, otvor svoju webstránku a obnov stránku. Už to máme! - [1]: images/bootstrap1.png +![Obrázok 14.1](images/bootstrap1.png) -Už teraz vyzerá lepšie! +Už to vyzerá lepšie! ## Statické súbory v Djangu -Konečne sa pozrieme zblízka na veci, ktoré nazývame **statické súbory**. Sú to všetky tvoje CSS a obrázky -- súbory, ktoré nie sú dynamické, takže ich obsah nezávisí od kontextu požiadavky a budú rovnaké pre všetkých užívateľov. +Konečne sa pozrieme zblízka na veci, ktoré nazývame **statické súbory**. Statické súbory sú všetky tvoje CSS a obrázky. Ich obsah nie je závislý na kontexte žiadosti a budú rovnaké pre každého používateľa či používateľku. ### Kam umiestniť statické súbory pre Django -Ako si už videla, keď sme spustili `collectstatic` na serveri, Django už vie, kde má nájsť statické súbory pre vstavané "adminské" aplikácie. Teraz už musíme len pridať nejaké statické súbory pre našu vlastnú aplikáciu, `blog`. +Django už vie, kde nájsť statické súbory pre zabudovanú aplikáciu "admin". Teraz už len musíme pridať niektoré statické súbory pre našu vlastnú aplikáciu `blog`. To urobíme tak, že vo vnútri našej aplikácie blog vytvoríme adresár s názvom `static`: -``` -djangogirls -├── blog -│ ├── migrations -│ └── static -└── mysite -``` + djangogirls + ├── blog + │ ├── migrations + │ ├── static + │   └── templates + └── mysite + -Django automaticky nájde všetky priečinky s názvom "static" vo všetkých priečinkoch tvojich aplikácií a bude môcť používať ich obsah ako statické súbory. +Django automaticky nájde všetky zložky s názvom "static" vo všetkých priečinkoch tvojej aplikácie. Následne bude možné použiť ich obsah ako statické súbory. ## Tvoj prvý CSS súbor! -Vytvorme teraz CSS súbor, ktorý tvojej web stránke pridá vlastný štýl. Vytvor nový adresár s názvom `css` vnútri adresára `static`. Potom vytvor nový súbor s názvom `blog.css` vo vnútri tohto adresára `css`. Pripravená? +Vytvorme teraz CSS súbor, ktorý tvojej web stránke pridá tvoj vlastný štýl. Vytvor nový adresár s názvom `css` vnútri adresára `static`. Potom vytvor nový súbor s názvom `blog.css` vo vnútri tohto adresára `css`. Pripravená? -``` -djangogirls -└─── blog - └─── static - └─── css - └─── blog.css -``` - -Je čas napísať nejaké CSS! Otvor v editore kódu súbor `blog/static/css/blog.css`. + djangogirls + └─── blog + └─── static + └─── css + └─── blog.css + -Nepôjdeme príliš do hĺbky ohľadne prispôsobovania web stránky a učenia sa CSS, pretože je to celkom jednoduché a môžeš sa to naučiť sama po tomto workshope. Odporúčame ti urobiť si [kurz Codeacademy HTML & CSS][2], tam sa dozvieš všetko, čo potrebuješ vedieť, aby bola tvoja webstránka vďaka CSS krajšia. +Je čas napísať trochu CSS! Otvor v editore kódu súbor `blog/static/css/blog.css`. - [2]: https://www.codecademy.com/tracks/web +Tu sa nebudeme do hĺbky zaoberať úpravou a štúdiom CSS. Na konci tejto stránky sa nachádza odkaz na bezplatný CSS kurz, ak sa o tom chceš dozvedieť viac. -Ale urobme aspoň niečo. Čo keby sme zmenili farbu hlavičky? Počítače používajú špeciálne kódy, aby rozumeli farbám. Začínajú `#`, potom nasleduje 6 písmen (A-F) a číslic (0-9). Kódy farieb nájdeš napríklad tu: http://www.colorpicker.com/. Môžeš tiež použiť [preddefinované farby][3] ako napríklad `red` (červená) alebo `green` (zelená). +Ale urobme aspoň niečo. Čo keby sme zmenili farbu hlavičiek? Počítače používajú špeciálne kódy, aby rozumeli farbám. Tieto kódy sa začínajú `#` potom nasleduje 6 písmen (A-F) a číslic (0-9). Napríklad kód pre modrú je `#0000FF`. Kódy farieb nájdeš napríklad tu: http://www.colorpicker.com/. Môžeš tiež použiť [preddefinované farby](http://www.w3schools.com/colors/colors_names.asp) ako napríklad `red` (červená) alebo `green` (zelená). - [3]: http://www.w3schools.com/cssref/css_colornames.asp +Do súboru `blog/static/css/blog.css` pridaj nasledujúci kód: -V súbore `blog/static/css/blog.css` pridaj nasledujúci kód: +{% filename %}blog/static/css/blog.css{% endfilename %} ```css -h1 a { - color: #FCA205; +h1 a, h2 a { + color: #C25100; } + ``` -`h1 a` je CSS Selector. To znamená, že náš štýl aplikujeme na akýkoľvek element `a` vo vnútri elementu `h1` (napríklad ak máme v kóde niečo takéto: `

link

`). V tomto prípade elementu hovoríme, aby zmenil svoju farbu na `#FCA205`, čo je oranžová. Samozrejme, sem môžeš zadať vlastnú farbu! +`h1 a` je CSS selektor. Znamená to, že aplikujeme naše štýly na všetky `a` elementy, ktoré sa nachádzajú vnútri `h1` elementu. Selektor `h2 a` robí presne to isté, akurát pre elementy `h2`. Takže keď máme niečo ako: `

link

`, použije sa na to štýl `h1 a`. V tomto prípade elementu hovoríme, aby zmenil svoju farbu na `#FCA205`, čo je tmavooranžová. Alebo si môžeš vybrať vlastnú farbu, akurát daj pozor, aby dobre kontrastovala s bielym pozadím! -V CSS súbore definujeme štýly pre elementy v HTML súbore. Elementy sa identifikujú podľa svojho názvu (t. j. `a` `h1`, `body`), atribútom `class` (trieda) alebo atribútom `id`. Triedy a id sú názvy, ktorými nazveš elementy. Triedy definujú skupiny elementov a idy poukazujú na konkrétne elementy. Napríklad, nasledujúci tag môže byť identifikovaný v CSS pomocou tagu `a`, triedy `external_link` a idu `link_to_wiki_page`: +V CSS súbore definujeme štýly pre elementy v HTML súbore. Prvý spôsob, akým môžme identifikovať elementy, je názov elementu. Môžno si pamätáš tieto tagy z HTML sekcie. Veci ako `a`,`h1`, a `body` sú príklady názvov elementov. Elementy taktiež identifikujeme pomocou atribútu `class` alebo atribútu `id`. Triedy (class) a id sú názvy, ktorými nazveš elementy. Triedy definujú skupiny elementov a id-čká poukazujú na konkrétne elementy. Napríklad nasledujúci element môže byť identifikovaný v CSS pomocou názvu `a`, triedy `external_link`, alebo id `link_to_wiki_page`: ```html ``` -Prečítaj si o [CSS selektoroch na w3schools][4]. +O [CSS selektoroch](http://www.w3schools.com/cssref/css_selectors.asp) si môžeš prečítať viac na stránkach w3schools. - [4]: http://www.w3schools.com/cssref/css_selectors.asp +Ešte musíme povedať našej HTML šablóne, že sme pridali nejaké CSS. Otvor súbor `blog/templates/blog/post_list.html` v editore a pridaj tento riadok na úplný začiatok: -Potom musíme povedať našej HTML šablóne, že sme pridali nejaké CSS. Otvor súbor `blog/templates/blog/post_list.html` a pridaj tento riadok na úplný začiatok: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} ``` -Práve načítavame statické súbory :). Potom medzi `` a ``, po odkazoch na CSS súbory Bootstrapu pridaj nasledujúci riadok (prehliadač číta súbory v poradí, v akom sú zadané, takže kód v našom súbore môže prepísať už načítaný kód z Bootstrapu): +Tu sme len nahrali statické súbory. :) Medzi tagmi `` a ``, po odkazoch na bootstrapové CSS súbory, pridaj tento riadok: - html - +{% filename %}blog/templates/blog/post_list.html{% endfilename %} +```html + +``` -Práve sme našej šablóne povedali, kde sa nachádza náš CSS súbor. +Prehliadač číta súbory, ktoré dostane, zaradom, takže sa musíme uistiť, že sú na správnom mieste. Inak kód v našich súboroch môže byť prepísaný kódom z boostrapových súborov. Práve sme našej šablóne povedali, kde sa nachádza náš CSS súbor. Súbor by mal teraz vyzerať asi takto: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html -{% load staticfiles %} +{% load static %} + Django Girls blog - - + - + {% for post in posts %} -
-

published: {{ post.published_date }}

-

{{ post.title }}

+
+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} ``` -OK, ulož súbor a obnov stránku! +OK, súbor ulož a obnov stránku! -![Obrázok 14.2][5] +![Obrázok 14.2](images/color2.png) - [5]: images/color2.png +Pekne! Možno by sme chceli dať našej webovej stránke trochu priestoru na dýchanie. Zväčšíme okraj na ľavej strane? Skúsme to! -Pekne! Možno by sme chceli dať našej webovej stránke trochu vzduchu. Zväčšíme okraj na ľavej strane? Skúsme si to! +{% filename %}blog/static/css/blog.css{% endfilename %} ```css body { @@ -148,80 +149,90 @@ body { } ``` -Pridaj to do svojho CSS, ulož súbor a pozri, ako to funguje! - -![Obrázok 14.3][6] +Pridaj to do svojho CSS, súbor ulož a pozri, ako to funguje! - [6]: images/margin2.png +![Obrázok 14.3](images/margin2.png) Mohli by sme trochu upraviť font v našej hlavičke, nie? Skopíruj toto do svojej hlavičky `` v súbore `blog/templates/blog/post_list.html`: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html - + ``` -Tento riadok naimportuje z Google fontov (https://www.google.com/fonts) font, ktorý sa volá *Lobster*. +Rovnako ako predtým, skontroluj poradie a umiestni pred odkaz na `blog/static/css/blog.css`. Tento riadok bude importovať font pod názvom *Lobster* z Google Fonts (https://www.google.com/fonts). + +Nájdi deklaračný blok `h1 a` (kód medzi zátvorkami `{` a `}`) v CSS súbore `blog/static/css/blog.css`. Teraz pridaj riadok `font-family: 'Lobster';` medzi zátvorky a obnov stránku: -Teraz pridaj riadok `font-rodina: 'Lobster';` do CSS súboru `blog/static/css/blog.css` vnútri deklarácie `h1 a` (to je ten kód medzi zátvorkami `{` a `}`) a obnov stránku: +{% filename %}blog/static/css/blog.css{% endfilename %} ```css -h1 a { - color: #FCA205; +h1 a, h2 a { + color: #C25100; font-family: 'Lobster'; } ``` -![Obrázok 14.3][7] - - [7]: images/font.png +![Obrázok 14.3](images/font.png) Super! -Ako sme už spomenuli vyššie, CSS má koncept tried, ktorými v podstate pomenuješ časť HTML kódu a aplikuješ štýly len na túto konkrétnu časť, bez vplyvu na ostatné časti. Je to super užitočné, ak máš dva div-y, z ktorých každý robí niečo úplne iné (napríklad hlavička a príspevok), takže nechceš, aby vyzerali rovnako. +Ako bolo uvedené vyššie, CSS má koncept tried. Triedy ti umožňujú pomenovať časti HTML kódu a použiť štýly iba na tejto časti bez zasahovania do iných častí. To môže byť veľmi užitočné! Možno máš dva divy, ktoré robia niečo iné (ako tvoja hlavička a tvoj príspevok). Triedy ti pomôžu docieliť, aby vyzerali každý inak. + +Poďme skúsiť pomenovať niektoré časti HTML kódu. Zmeň `header`, ktorý obsahuje tvoju hlavičku, takto: -Skús pomenovať niektoré časti HTML kódu. Pridaj triedu s názvom `page-header` do `div`u, ktorý obsahuje hlavičku, takto nejako: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - + ``` -A teraz pridaj triedu, `post` do `div`u, v ktorom je blog post. +A teraz pridaj triedu `post` do tvojho `article`, v ktorom je blog post. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -
-

published: {{ post.published_date }}

-

{{ post.title }}

+
+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ ``` -Teraz pridáme deklarácie rôznym selektorom. Selektory, ktoré začínajú `.` sa týkajú tried. Na webe je ohľadne CSS veľa skvelých tutorialov a vysvetlení, ktoré ti pomôžu pochopiť nasledujúci kód. Ale teraz len skopíruj a vlož nasledujúci kód do súboru `blog/static/css/blog.css`: +Teraz pridáme deklarácie pre rôzne selektory. Selektory, ktoré začínajú znamienkom `.`, sa týkajú tried. Na webe je ohľadne CSS veľa skvelých tutorialov a vysvetlení, ktoré ti pomôžu pochopiť nasledujúci kód. Ale teraz len skopíruj a vlož nasledujúci kód do tvojho súboru `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; } @@ -229,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; @@ -244,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; +} ``` -Teraz s deklaráciami tried obklop HTML kód, ktorý zobrazuje posty. Nahraď toto: +Teraz deklaráciami tried obklop HTML kód, ktorý zobrazuje posty. Nahraď toto: + +{% 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 %} ``` v súbore `blog/templates/blog/post_list.html` týmto: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html -
+
-
+
{% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %}
-
+
``` Ulož tieto súbory a obnov svoju web stránku. -![Obrázok 14.4][8] - - [8]: images/final.png +![Obrázok 14.4](images/final.png) -No paráda! Vyzerá to super, nie? Kód, ktorý sme práve vložili, fakt nie je veľmi ťažké pochopiť a väčšinu asi pochopíš už len tým, že ho prečítaš. +Super! Vyzerá to úžasne, nie? Pozri sa na kód, ktorý sme práve vložili, a nájdi miesta, kde sme pridali triedy v HTML a použili sme ich v CSS. Kde by si spravila zmenu, ak by si chcela dátum spraviť tyrkysový? -Neboj sa trochu pohrať s týmto CSS, skús niektoré veci zmeniť. Ak niečo pokazíš, nevadí, vždy sa môžeš vrátiť späť! +Neboj sa trochu pohrať s týmto CSS a poskúšať pomeniť niektoré veci. Hranie sa s CSS ti pomôže porozumieť tomu, čo robia rôzne veci. Ak niečo pokazíš, neboj sa, môžeš vždy vrátiť zmeny späť! -Mimochodom, naozaj odporúčame tento bezplatný on-line [kurz HTML & CSS Codeacademy ][2] ako domácu úlohu po skončení tohto workshopu, kde sa naučíš všetko, čo potrebuješ vedieť, aby boli tvoje webové stránky s CSS krajšie. +Vrelo odporúčame online kurzy zdarma "Basic HTML & HTML5" a "Basic CSS" na [freeCodeCamp](https://learn.freecodecamp.org/). Naučia ťa všetko o tom, ako môžeš svoje stránky skrášliť pomocou HTML a CSS. -Pripravená na ďalšiu kapitolu?! :) +Pripravená na ďalšiu kapitolu?! :) \ No newline at end of file diff --git a/sk/css/images/bootstrap1.png b/sk/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/sk/css/images/bootstrap1.png and b/sk/css/images/bootstrap1.png differ diff --git a/sk/css/images/color2.png b/sk/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/sk/css/images/color2.png and b/sk/css/images/color2.png differ diff --git a/sk/css/images/final.png b/sk/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/sk/css/images/final.png and b/sk/css/images/final.png differ diff --git a/sk/css/images/font.png b/sk/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/sk/css/images/font.png and b/sk/css/images/font.png differ diff --git a/sk/css/images/margin2.png b/sk/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/sk/css/images/margin2.png and b/sk/css/images/margin2.png differ diff --git a/sk/deploy/README.md b/sk/deploy/README.md old mode 100755 new mode 100644 index b44fdb35981..45fb39c6b0b --- a/sk/deploy/README.md +++ b/sk/deploy/README.md @@ -1,324 +1,181 @@ # Nasadenie! -> **Poznámka** Občas bude možno trochu ťažké prehrýzť sa touto kapitolou. Vydrž a dokonči ju, nasadenie je dôležitou časťou vývoja webových stránok. Táto kapitola je umiestnená uprostred tutorialu, takže mentor ti môže pomôcť s trochu náročnejšími časťami procesu spúšťania tvojej web stránky online. To znamená, že môžeš dokončiť tutorial aj sama, ak ti nevyjde čas. +> **Poznámka** Môže byť trochu ťažké prehrýzť sa touto kapitolou. Vydrž a dokonči ju, nasadenie je dôležitou časťou vývoja webových stránok. Táto kapitola je umiestnená uprostred tutoriálu, aby ti mentor či mentorka mohli pomôcť s trochu náročnejšími časťami procesu spúšťania tvojej webovej stránky online. To znamená, že môžeš dokončiť tutoriál aj sama, ak ti nevyjde čas. -Až doteraz bola tvoja web stránka dostupná len v tvojom počítači, teraz sa však naučíš, ako ju nasadiť! Nasadenie je proces publikovania aplikácie na internete, takže ju ľudia konečne môžu vidieť :). +Až do tohto momentu bola tvoja webová stránka dostupná len v tvojom počítači. Teraz sa naučíš, ako ju nasadiť! Nasadenie (deployment) je proces publikovania aplikácie na internete, aby ju všetci konečne mohli vidieť. :) -Ako už vieš, web stránka musí byť umiestnená na serveri. Na internete je množstvo poskytovateľov serverov. My použijeme jedného, ktorý má pomerne jednoduchý proces nasadenia: [PythonAnywhere][1]. PythonAnywhere je bezplatný pre malé aplikácie, ktoré nemajú príliš veľa návštevníkov, takže zatiaľ ti to určite bude stačiť. +Ako už vieš, webová stránka musí byť umiestnená na serveri. Na internete existuje množstvo poskytovateľov serverov, my použijeme [PythonAnywhere](https://www.pythonanywhere.com/). PythonAnywhere je bezplatný pre malé aplikácie, ktoré nemajú príliš veľa návštevníkov a návštevníčok, takže zatiaľ ti to určite bude stačiť. - [1]: https://pythonanywhere.com/ +Ďalšou externou službou, ktorú budeme využívať, je [GitHub](https://www.github.com), kde sa uchovávajú zdrojové kódy. Existujú aj ďalšie podobné služby, no v dnešnej dobe už majú takmer všetci programátori a programátorky githubové konto a teraz ho už budeš mať aj ty! -Ďalšou externou službou, ktorú budeme využívať je [GitHub][2], kde sa uchovávajú zdrojové kódy. Existujú aj ďalšie takéto služby, no dnes už majú takmer všetci programátori na GitHube konto a teraz ho budeš mať už aj ty! - - [2]: https://www.github.com - -GitHub použijeme ako odrazový mostík na prenos nášho kódu z a do PythonAnywhere. +Tieto tri miesta budú pre teba dôležité. Lokálny počítač bude miestom, kde budeš vyvíjať a testovať. Keď si spokojná so zmenami, uložíš kópiu programu na GitHub. Tvoja webová stránka bude na PythonAnywhere a budeš ju aktualizovať stiahnutím novej kópie svojho kódu z GitHubu. # Git -Git je "systém na správu verzií", ktorý využíva množstvo programátorov. Tento softvér sleduje v priebehu času zmeny v tvojich súboroch, takže sa kedykoľvek môžeš vrátiť ku konkrétnej verzii. Niečo ako funkcia "sledovať zmeny" vo Worde, ale oveľa výkonnejšie. - -## Inštalácia Gitu - -> **Poznámka** Ak si už kroky inštalácie robila, nemusíš to robiť znova a môžeš preskočiť na ďalšiu časť a začať vytvárať Git repozitár. +> **Poznámka** Ak už máš za sebou [inštaláciu](../installation/README.md), nemusíš toto robiť znova - môžeš preskočiť na ďalšiu časť a začať s vytváraním vlastného Git repozitára. {% include "/deploy/install_git.md" %} -## Spustenie Git repozitára +## Založenie Git repozitára + +Git sleduje zmeny na konkrétnej skupine súborov, v niečom, čo sa nazýva úložisko kódu alebo repozitár (skrátene "repo"). Založme si repo pre náš projekt. Otvor konzolu a spusti nasledujúce príkazy v adresári `djangogirls`: -Git sleduje zmeny na konkrétnej množine súborov, v niečom, čo sa nazýva úložisko kódu alebo repozitár (skrátene "repo"). Založme si repo pre náš projekt. Otvor konzolu a spusti nasledujúce príkazy v adresári `djangogirls`: +> **Poznámka** Skontroluj si aktuálny pracovný priečinok príkazom `pwd` (macOS/Linux) alebo `cd` (Windows) pred inicializáciou repozitára. Mala by si byť v priečinku `djangogirls`. -> **Poznámka** Skontroluj si aktuálny pracovný adresár s príkazom`pwd` v OSX/Linux alebo `cd` vo Windowse pred inicializáciou úložiska. Mala by si byť v priečinku `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 config --global user.name "Tvoje Meno" + $ git config --global user.email ty@example.com + + +Inicializácia Git repozitára je niečo, čo musíme urobiť len raz za projekt (a už nikdy nebudeš musieť znovu zadávať užívateľské meno a e-mail). + +### Upravenie názvu vetvy + +Vo verziách Gitu starších ako **2.28** budeš musieť zmeniť meno svojej vetvy na "main". Ak chceš zistiť, akú verziu Gitu máš, prosím, spusti nasledovný príkaz: + +{% filename %}command-line{% endfilename %} + + $ git --version + git version 2.xx... + + +V prípade, že druhé číslo verzie ("xx" vyššie) je menšie ako 28, budeš musieť spustiť nasledujúci príkaz, aby si premenovala svoju vetvu. Ak je to 28 alebo viac, pokračuj, prosím, sekciou "Ignorovanie súborov". Rovnako ako v časti "Inicializácia" je toto niečo, čo musíme spraviť len jeden jediný raz vrámci projektu, a aj to iba v prípade, ak je tvoja verzia Gitu menšia ako 2.28: + +{% filename %}command-line{% endfilename %} -Inicializácia git repozitára je niečo, čo musíme urobiť len raz za projekt (a už nikdy nebudeš musieť znovu zadať užívateľské meno a e-mail). + $ git branch -M main + + +### Ignorovanie súborov Git bude sledovať zmeny všetkých súborov a priečinkov v tomto adresári, ale sú aj niektoré súbory, ktoré chceme ignorovať. To urobíme tak, že vytvoríme súbor s názvom `.gitignore` v základnom adresári. Otvor si editor a vytvor nový súbor s týmto obsahom: -``` +{% filename %}.gitignore{% endfilename %} + + # Python *.pyc + *~ __pycache__ - myvenv + + # Env + .env + myvenv/ + venv/ + + # Database db.sqlite3 + + # Static folder at project root + /static/ + + # macOS + ._* .DS_Store -``` - -A ulož ho ako `.gitignore` do hlavného adresára "djangogirls". + .fseventsd + .Spotlight-V100 + + # Windows + Thumbs.db* + ehthumbs*.db + [Dd]esktop.ini + $RECYCLE.BIN/ + + # Visual Studio + .vscode/ + .history/ + *.code-workspace + + +A ulož ho ako `.gitignore` v priečinku "djangogirls". + +> **Poznámka** Bodka na začiatku názvu súboru je dôležitá! Ak máš problém vytvoriť takýto súbor (napríklad Macom sa nepáči, ak chceš cez Vyhľadávanie (Finder) vytvoriť súbory, ktoré sa začínajú bodkou), potom použi funkciu "Uložiť ako" vo svojom editore, to funguje vždy. A daj pozor na to, aby si k názvu súboru nepridala `.txt`, `.py` alebo akúkoľvek inú koncovku - Git ho rozpozná, iba ak sa volá presne `.gitignore`. V Linuxe a MacOS sú súbory, ktoré začínajú `.` (ako `.gitignore`), považované za skryté a príkaz `ls` ich neukáže. Namiesto neho môžeš použiť `ls -a`, aby si súbor `.gitignore` videla. +> +> **Poznámka** Jeden zo súborov, ktoré si spomenula vo svojom súbore `.gitignore`, je `db.sqlite3`. Tento súbor je tvoja lokálna databáza, kde sú uložení všetci tvoji používatelia/používateľky a príspevky. Budeme sa riadiť štandardnými programátorskými postupmi, čo znamená, že budeme používať dve rôzne databázy, jednu pre svoju vlastnú lokálnu testovaciu stránku a druhú pre svoju online stránku na PythonAnywhere. Na PythonAnywhere to možno bude SQLite, tak ako na stroji, na ktorom vyvíjaš, ale zvyčajne by si tam skôr použila databázu, ktorá sa volá MySQL, ktorá zvládne oveľa viac navštevníčiek a návštevníkov ako SQLite. Tak či onak, to, že ignoruješ svoju SQLite databázu v kópii pre GitHub, znamená, že všetky príspevky a superuser, ktorých si doteraz vytvorila, budú dostupní len lokálne, a na produkčnej verzii budeš musieť vytvoriť nových. Svoju lokálnu databázu si môžeš predstaviť ako pieskovisko, na ktorom si môžeš vyskúšať rôzne veci a nebáť sa, že zmažeš reálne príspevky zo svojho blogu. + +Vždy je dobré použiť príkaz `git status` pred `git add` alebo kedykoľvek, keď si nebudeš istá, čo sa zmenilo. Pomôže ti to vyhnúť sa prekvapeniam ako napríklad pridanie nesprávnych súborov. Príkaz `git status` vracia informácie o nesledovaných (untracked) či zmenených (modified) súboroch, alebo súboroch pripravených na zmenu (staged), o stave vetvy a veľa ďalších vecí. Výstup by mal byť podobný nasledovnému: + +{% filename %}command-line{% endfilename %} -> **Poznámka** Bodka na začiatku názvu súboru je dôležitá! Ak máš problém vytvoriť takýto súbor (napríklad Macom sa nepáči, ak chceš cez Vyhľadávanie (Finder) vytvoriť súbory, ktoré sa začínajú bodkou), potom použi funkciu "Uložiť ako" vo svojom editore, to je nepriestrelné. - -Vždy je dobré použiť príkaz `git status` pred `git add` alebo kedykoľvek, keď si nebudeš istá, čo sa zmenilo. To ti pomôže vyhnúť sa prekvapeniam ako napríklad pridanie nesprávnych súborov. Príkaz `git status` dáva informácie o nesledovaných (untracked) či zmenených (modified) súboroch, alebo súboroch pripravených na zmenu (staged), o stave vetvy a veľa ďalšieho. Výstup by mal vyzerať takto nejako: - -``` $ git status - On branch master - - Initial commit - + 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) -``` + -A nakoniec uložíme naše zmeny. Teraz prejdi na konzolu a zadaj nasledujúce príkazy: +A nakoniec uložíme naše zmeny. Prejdi na konzolu a zadaj nasledujúce príkazy: -``` - $ git add -A . +{% 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 -``` + ## Prenos nášho kódu na GitHub -Choď na [GitHub.com][2] a zaregistruj sa na nové bezplatné konto. (Ak si to už urobila v prípravke na workshop, tak to je skvelé!) - -Potom vytvor nové úložisko a pomenuj ho "my-first-blog". Nechaj políčko "initialise with README" nezaškrtnuté, možnosť .gitignore nechaj prázdnu (to sme už urobili ručne) a nechaj licenciu nastavenú ako None. - -![][3] - - [3]: images/new_github_repo.png - -> **Poznámka** Názov `my-first-blog` je dôležitý -- mohla by si si vybrať aj niečo iné, ale bude sa to ďalej vyskytovať veľakrát a musela by si to zakaždým nahradiť. Asi bude ľahšie, ak ostaneš pri názve `my-first-blog`. - -Na ďalšej obrazovke sa zobrazí klon URL tvojho repozitára. Vyber si verziu "HTTPS", skopírujte ju, a o chvíľu ju použijeme v termináli: - -![][4] - - [4]: images/github_get_repo_url_screenshot.png - -Teraz musíme pripojiť Git repozitár v počítači k tomu na GitHube. - -Napíš do konzoly nasledujúci príkaz (nahraď `` svojím užívateľským menom na GitHube, ale bez lomených zátvoriek): - -``` -$ git remote add origin https://github.com//my-first-blog.git -$ git push -u origin master -``` - -Zadaj svoje užívateľské meno a heslo na GitHube a malo by sa ti zobraziť niečo takého: - -``` -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. -``` - - - -Tvoj kód je na GitHube. Kľudne si to over! Zistíš, že sa nachádza vo vyberanej spoločnosti - [Django][5], [Django Girls Tutorial][6] a mnoho iných skvelých open sourcových softvérových projektov uchováva svoj kód na GitHube :) - - [5]: https://github.com/django/django - [6]: https://github.com/DjangoGirls/tutorial - -# Vytvorenie nášho blogu na PythonAnywhere - -> **Poznámka** Možno si už účet na PythonAnywhere vytvorila počas inštalácie - ak áno, nemusíš to robiť znova. - -{% include "/deploy/signup_pythonanywhere.md" %} - -## Natiahnutie nášho kódu na PythonAnywhere - -Po registrácii na PythonAnywhere, budeš presmerovaná na svoju nástenku alebo stránku "Konzoly". Vyber si možnosť spustiť "Bash" konzolu - to je PythonAnywhere verzia konzoly, rovnaká ako na tvojom počítači. - -> **Poznámka** PythonAnywhere je založený na Linuxe, takže ak si vo Windowse, konzola bude vyzerať trochu inak ako v tvojom počítači. - -Poďme teraz natiahnuť náš kód z GitHubu na PythonAnywhere vytvorením "klonu" nášho repo. Zadaj nasledujúci príkaz do konzoly na PythonAnywhere (nezabudni použiť užívateľské meno z GitHubu namiesto ``): - -``` -$ git clone https://github.com//my-first-blog.git -``` - -Toto natiahne kópiu tvojho kódu na PythonAnywhere. Môžeš si to overiť zadaním `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 -``` - -### Vytvorenie virtualenv na PythonAnywhere - -Tak ako si to urobila vo svojom počítači, virtualenv môžeš vytvoriť aj na PythonAnywhere. V Bash konzole zadaj: - -``` -$ 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 -``` - -> **Poznámka:** Krok `pip install` môže trvať aj niekoľko minút. Trpezlivosť, trpezlivosť! Ale ak to trvá dlhšie ako 5 minút, niečo nie je v poriadku. Spýtaj sa svojho tútora. - - - -### Zber statických súborov. - -Zaujímalo ťa, čo je to vlastne ten "whitenoise"? Je to nástroj na obsluhu takzvaných "statických súborov". Statické súbory su také súbory, ktoré sa pravidelne nemenia, ani nespúšťajú kód programu, ako napríklad HTML či CSS súbory. Na serveroch fungujú inak ako na tvojom počítači a na ich obsluhu potrebujeme nástroj ako je "whitenoise". - -O statických súboroch sa naučíme trochu viac neskôr, keď budeme upravovať CSS pre našu stránku. - -Teraz len musíme na serveri spustiť jeden príkaz navyše - `collectstatic`. Ten povie Djangu, aby na serveri zhromaždil všetky statické súbory, ktoré potrebuje. Práve teraz sú to väčšinou súbory, ktoré zabezpečujú, aby adminská stránka vyzerala dobre. - -``` -(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 -``` - -Napíš "yes" a ono to zmizne! Aj ty zbožňuješ vyrábať stránky plné výstupov z počítačov alebo nepochopiteľného textu? Ja osobne si k tomu vymýšľam čudné zvuky. Brp, brp, brp... - -``` -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'. -``` - -### Vytvorenie databázy na PythonAnywhere - -Ďalšia vec, v ktorej sa líši tvoj počítač od servera: používa inú databázu. Takže užívateľské kontá a posty sa môžu na serveri líšiť od tých v počítači. - -Môžeme inicializovať databázu na serveri, rovnako ako sme to urobili v tvojom počítači, pomocou `migrate` a `createsuperuser`: - -``` -(mvenv) $ python manage.py migrate -Operations to perform: -[...] - Applying sessions.0001_initial... OK - - -(mvenv) $ python manage.py createsuperuser -``` - -## Publikovanie nášho blogu ako webovú aplikáciu - -Teraz je náš kód na PythonAnywhere, náš virtualenv pripravený, statické súbory sú zhromaždené a databáza inicializovaná. Môžeme to teda zverejniť ako webovú aplikáciu! - -Kliknutím na logo PythonAnywhere sa vráť na nástenku a tam klikni na kartu **Web**. Nakoniec, stlač **Add a new web app** (Pridaj novú aplikáciu). - -Po potvrdení názvu tvojej domény, vyber v dialógu **manual configuration** (pozor, *nie* "Django" možnosť). Ďalej vyber **Python 3.4** a kliknutím na tlačidlo Ďalej dokonči sprievodcu. - -> **Poznámka** Uisti sa, že si si vybrala možnosť "Manual configuration" (Manuálne nastavenie), nie "Django". Sme príliš cool, aby sme používali predvolené nastavenia PythonAnywhere Django ;-) - -### Nastavenie virtualenv - -Budeš presmerovaná na PythonAnywhere konfiguračnú obrazovku pre tvoju aplikáciu. Sem budeš musieť chodiť vždy, keď budeš chcieť urobiť nejaké zmeny v tvojej aplikácii na serveri. - -![][7] - - [7]: images/pythonanywhere_web_tab_virtualenv.png - -V časti "Virtualenv" klikni na červený text "Enter the path to a virtualenv" a zadaj: `/home//my-first-blog/myvenv/`. Klikni na modré políčko s fajočkou a ulož tak cestu predtým, ako budeš pokračovať ďalej. - -> **Poznámka** Nahraď svoje užívateľské meno podľa potreby. Ak urobíš chybu, PythonAnywhere ti zobrazí malé upozornenie. - -### Konfigurácia súboru WSGI - -Django funguje pomocou "protokolu WSGI", ktorý je štandardom pre obsluhu webových stránok pomocou Pythonu, a ktorý PythonAnywhere podporuje. Aby PythonAnywhere rozpoznal náš Django blog, musíme upraviť WSGI konfiguračný súbor. - -Klikni na link "WSGI configuration file" (v časti "Code" v hornej časti stránky -- bude sa volať nejako takto `/var/www/_pythonanywhere_com_wsgi.py`) a dostaneš sa do editora. - -Vymaž celý obsah a nahraď ho niečím takýmto: - -```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) +Choď na [GitHub.com](https://www.github.com) a založ (Sign Up) si nový účet zdarma. (Ak si to už spravila počas prípravy na workshop, super!) Zapamätaj si svoje heslo (a pridaj si ho do svojho správcu hesiel, ak nejaký používaš). -os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' +Potom vytvor nový repozitár a pomenuj ho "my-first-blog". Políčko "initialize with a README" nechaj nezaškrtnuté, voľbu .gitignore nechaj prázdnu (urobili sme to manuálne) a License nechaj ako None. -from django.core.wsgi import get_wsgi_application -from whitenoise.django import DjangoWhiteNoise -application = DjangoWhiteNoise(get_wsgi_application()) -``` +![](images/new_github_repo.png) -> **Poznámka** Nezabudni nahradiť svoje vlastné užívateľské meno namiesto `` +> **Poznámka** Názov `my-first-blog` je dôležitý -- mohla by si si vybrať aj niečo iné, ale bude sa to ďalej vyskytovať veľakrát a musela by si to zakaždým nahradiť. Pravdepodobne bude pohodlnejšie, ak ostaneš pri názve `my-first-blog`. -Úlohou tohto súboru je povedať PythonAnywhere, kde nájde našu aplikáciu a ako sa volá súbor s nastaveniami Djanga. Taktiež nastavuje nástroj "whitenoise" pre statické súbory. +Na nasledujúcej stránke sa ti ukáže klonovacia URL tvojho repa, ktorú budeme potrebovať v niektorých z nasledujúcich príkazov: -Klikni na **Save** a vráť sa na kartu **Web**. +![](images/github_get_repo_url_screenshot.png) -Hotovo! Klikni na veľké zelené tlačidlo **Reload** a potom sa už môžeš pozrieť na svoju aplikáciu. Odkaz na ňu nájdeš navrchu stránky. +Teraz musíme pripojiť Git repozitár v tvojom počítači k tomu na GitHube. -## Tipy pre ladenie +Napíš do konzoly nasledujúci príkaz (nahraď `` svojím užívateľským menom na GitHube, ale bez špicatých zátvoriek - URL by mala byť rovnaká ako klonovacia URL, ktorú si práve videla). -Ak pri pokuse navštíviť svoju stránku uvidíš chybu, prvým miestom, kde hľadať problém je **error log**. Odkaz naňho nájdeš na PythonAnywhere v [karte Web][8]. Pozri, či tam nie sú nejaké chybové hlášky - tie najnovšie sú naspodku. Najčastejšie problémy bývajú: +{% filename %}command-line{% endfilename %} - [8]: https://www.pythonanywhere.com/web_app_setup/ + $ git remote add origin https://github.com//my-first-blog.git + $ git push -u origin main + -* Vynechaný krok, ktorý sme robili v konzole: vytvorenie virtualenv, jeho aktivácia, inštalácia Djanga do virtualenvu, spustenie collectstatic, presun databázy. +Keď pošleš niečo na GitHub, spýta sa ťa to na tvoje githubové meno a heslo (buď rovno v príkazovom riadku alebo vo vyskakovacom okne) a keď ich zadáš, mala by si vidieť niečo takéto: -* Chyba v ceste virtualenv v karte Web -- ak je nejaký problém, zvyčajne tam bude malá červená chybová hláška. +{% filename %}command-line{% endfilename %} -* Chyba vo WSGI konfiguračnom súbore -- zadala si cestu do adresára my-first-blog správne? + 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/ola/my-first-blog.git + + * [new branch] main -> main + Branch main set up to track remote branch main from origin. + -* Vybrala si si rovnakú verziu Pythonu pre virtualenv ako pre webovú aplikáciu? Obidve by mali byť 3.4. + -* Môžeš skúsiť aj [Všeobecné tipy na ladenie na PythonAnywhere wiki][9]. +Tvoj kód je na GitHube. Choď sa naň pozrieť! Zistíš, že sa nachádza vo vyberanej spoločnosti - [Django](https://github.com/django/django), [Django Girls Tutorial](https://github.com/DjangoGirls/tutorial) a mnoho iných skvelých open sourcových softvérových projektov uchováva svoj kód na GitHube. :) - [9]: https://www.pythonanywhere.com/wiki/DebuggingImportError +{% include "/deploy/pythonanywhere.md" %} -A nezabudni, tvoj tréner je tu na to, aby ti pomohol! +# Choď sa pozrieť na svoju stránku! -# Si online! +Hlavná stránka tvojej aplikácie by ťa mala vítať nápisom "It worked!", tak ako na tvojom počítači. Skús pridať `/admin/` na koniec adresy URL, a budeš presmerovaná na stránky administrácie. Prihlás sa svojím menom a heslom a uvidíš, že môžeš na server pridať nové príspevky. Nezabudni, že príspevky z tvojej lokálnej testovacej databázy sme neposlali na tvoj online blog. -Hlavná stránka tvojej aplikácie by ťa mala vítať nápisom "Welcome to Django", tak ako na tvojom počítači. Skús pridať `/admin/` na koniec adresy URL, a budeš presmerovaná na stránky administrácie. Prihlás sa s užívateľským menom a heslom a uvidíš, že môžeš pridávať nové príspevky (posty) na server. +Keď vytvoríš niekoľko príspevkov, môžeš sa vrátiť do tvojho lokálneho prostredia (nie PythonAnywhere). Odteraz by si na zmenách mala pracovať vo svojom lokálnom prostredí. To je štandardný pracovný postup pri vývoji webových aplikácií - urobíš zmeny lokálne, dáš tieto zmeny na GitHub a stiahneš zmeny na svoj webový server. Vďaka tomu môžeš pracovať a experimentovať bez toho, aby si niečo pokazila na svojej online stránke. Celkom cool, že? -*OHROMNE* sa potľapkaj po chrbte! Nasadenie serveru je jedna z najzradnejších častí vývoja web stránok a často zaberie ľuďom aj niekoľko dní, kým to spojazdnia. Ale ty už máš teraz svoju stránku online, na skutočnom internete! +*PORIADNE* sa potľapkaj po chrbte! Nasadenie serveru je jedna z najzradnejších častí vývoja web stránok a často zaberie ľuďom aj niekoľko dní, kým to celé spojazdnia. Ale ty už máš svoju stránku online teraz, na skutočnom internete! \ No newline at end of file diff --git a/sk/deploy/images/github_get_repo_url_screenshot.png b/sk/deploy/images/github_get_repo_url_screenshot.png index 62a29f5f8d7..ee1560b1e85 100644 Binary files a/sk/deploy/images/github_get_repo_url_screenshot.png and b/sk/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/sk/deploy/images/new_github_repo.png b/sk/deploy/images/new_github_repo.png index 64011e59a52..d1f82e5d863 100644 Binary files a/sk/deploy/images/new_github_repo.png and b/sk/deploy/images/new_github_repo.png differ diff --git a/sk/deploy/images/pythonanywhere_account.png b/sk/deploy/images/pythonanywhere_account.png new file mode 100644 index 00000000000..612d4528e11 Binary files /dev/null and b/sk/deploy/images/pythonanywhere_account.png differ diff --git a/sk/deploy/images/pythonanywhere_bash_console.png b/sk/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..458b43f5d0d Binary files /dev/null and b/sk/deploy/images/pythonanywhere_bash_console.png differ diff --git a/sk/deploy/images/pythonanywhere_beginner_account_button.png b/sk/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/sk/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/sk/deploy/images/pythonanywhere_create_api_token.png b/sk/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..6e617d0a53e Binary files /dev/null and b/sk/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/sk/deploy/images/pythonanywhere_web_tab_virtualenv.png b/sk/deploy/images/pythonanywhere_web_tab_virtualenv.png deleted file mode 100644 index 97e87e7b07b..00000000000 Binary files a/sk/deploy/images/pythonanywhere_web_tab_virtualenv.png and /dev/null differ diff --git a/sk/deploy/install_git.md b/sk/deploy/install_git.md old mode 100755 new mode 100644 index 584d4bcd159..ddd087ecb83 --- a/sk/deploy/install_git.md +++ b/sk/deploy/install_git.md @@ -1,19 +1,83 @@ -### Windows +Git je "systém na správu verzií", ktorý využíva množstvo programátoriek a programátorov. Tento softvér sleduje v priebehu času zmeny v tvojich súboroch, takže sa kedykoľvek môžeš vrátiť ku konkrétnej verzii. Je to v podstate niečo ako nástroj na nasledovanie zmien v programoch na spracovanie textu (napr. Microsoft Word alebo LibreOffice Writer), ale omnoho mocnejšie. -Git si môžeš stiahnuť z [git-scm.com](https://git-scm.com/). Môžeš bez obáv klikať na "ďalej ďalej ďalej" pri všetkých krokoch okrem jedného. V kroku 5, označenom ako "Nastavenie prostredia PATH", zvoľ "Spustiť Git a príslušné Unixové nástroje z príkazového riadku systému Windows" (spodná možnosť). V ostatných prípadoch sú predvolené nastavenia v poriadku. Možnosť "Checkout Windows-style, commit Unix-style line endings" je OK. +## Inštalácia Gitu -### MacOS + + +Git si môžeš stiahnuť z [git-scm.com](https://git-scm.com/). Môžeš bez obáv klikať na "ďalej" pri všetkých krokoch okrem jedného. V kroku, kde to od teba bude chcieť, aby si si vybrala svoj editor, by si si mala vybrať Nano, a v kroku "Adjusting your PATH environment" zvoľ "Use Git and optional Unix tools from the Windows Command Prompt" (spodná možnosť). V ostatných prípadoch sú predvolené nastavenia v poriadku. Možnosť "Checkout Windows-style, commit Unix-style line endings" je OK. + +Ak ti bude počas inštalácie ponúknutá možnosť "Adjusting the name of the initial branch in new repositories", prosím, zvoľ "Override the default" a použi "main". Týmto bude tvoja inštalácia Gitu v súlade so všeobecným smerovaním globálnej programátorskej komunity. Vetvu "main" budeme používať v celom tomto tutoriáli. Pozri, prosím, na https://sfconservancy.org/news/2020/jun/23/gitbranchname/ a https://github.com/github/renaming pre viac detailov o tejto téme. + +Nezabudni reštartovať príkazový riadok alebo PowerShell po úspešnom dokončení inštalácie. + + Stiahni si Git z [git-scm.com](https://git-scm.com/) a riaď sa inštrukciami. -### Linux +Ak ti bude počas inštalácie ponúknutá možnosť "Adjusting the name of the initial branch in new repositories", prosím, zvoľ "Override the default" a použi "main". Týmto bude tvoja inštalácia Gitu v súlade so všeobecným smerovaním globálnej programátorskej komunity. Vetvu "main" budeme používať v celom tomto tutoriáli. Pozri, prosím, na https://sfconservancy.org/news/2020/jun/23/gitbranchname/ a https://github.com/github/renaming pre viac detailov o tejto téme. -Ak ho ešte nemáš nainštalovaný, git by mal byť dostupný pomocou správcu balíčkov, takže vyskúšaj: +> **Poznámka** Ak používaš OS X 10.6, 10.7 alebo 10.8, budeš musieť nainštalovať verziu Gitu odtiaľto: [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) + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo apt install git ``` -sudo apt-get install git -# or -sudo yum install git -# or -sudo zypper install git + +### Upravenie prednastaveného názvu vetvy + +Týmto bude tvoja inštalácia Gitu v súlade so všeobecným smerovaním globálnej programátorskej komunity. Vetvu "main" budeme používať v celom tomto tutoriáli. Pozri, prosím, na https://sfconservancy.org/news/2020/jun/23/gitbranchname/ a https://github.com/github/renaming pre viac detailov o tejto téme. + +{% filename %}command-line{% endfilename %} + + $ git config --global --add init.defaultBranch main + + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo dnf install git ``` + +### Upravenie prednastaveného názvu vetvy + +Týmto bude tvoja inštalácia Gitu v súlade so všeobecným smerovaním globálnej programátorskej komunity. Vetvu "main" budeme používať v celom tomto tutoriáli. Pozri, prosím, na https://sfconservancy.org/news/2020/jun/23/gitbranchname/ a https://github.com/github/renaming pre viac detailov o tejto téme. + +{% filename %}command-line{% endfilename %} + + $ git config --global --add init.defaultBranch main + + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo zypper install git +``` + +### Upravenie prednastaveného názvu vetvy + +Týmto bude tvoja inštalácia Gitu v súlade so všeobecným smerovaním globálnej programátorskej komunity. Vetvu "main" budeme používať v celom tomto tutoriáli. Pozri, prosím, na https://sfconservancy.org/news/2020/jun/23/gitbranchname/ a https://github.com/github/renaming pre viac detailov o tejto téme. + +{% filename %}command-line{% endfilename %} + + $ git config --global --add init.defaultBranch main + + + \ No newline at end of file diff --git a/sk/deploy/pythonanywhere.md b/sk/deploy/pythonanywhere.md new file mode 100644 index 00000000000..ffb93607159 --- /dev/null +++ b/sk/deploy/pythonanywhere.md @@ -0,0 +1,88 @@ +# Vytvorenie nášho blogu na PythonAnywhere + +## Vytvorenie PythonAnywhere účtu + +> **Poznámka** Možno si si už účet na PythonAnywhere vytvorila počas inštalácie - ak áno, nemusíš to robiť znova. +> +> {% include "/deploy/signup_pythonanywhere.md" %} + + +## Konfigurácia našej stránky na PythonAnywhere + +Choď naspäť do hlavného [PythonAnywhere dashboardu](https://www.pythonanywhere.com/) kliknutím na logo a vyber možnosť začať "Bash" konzolu -- to je PythonAnywhere verzia príkazového riadku, presne ako na tvojom počítači. + +![Sekcia "New Console" na webovom rozhraní PythonAnywhere s tlačítkom pre "bash"](images/pythonanywhere_bash_console.png) + +> **Poznámka** PythonAnywhere je založený na Linuxe, takže ak si vo Windowse, konzola bude vyzerať trochu inak ako v tvojom počítači. Nasadenie webovej aplikácie na PythonAnywhere zahŕňa stiahnutie kódu z GitHubu a nakonfigurovanie PythonAnywhere, aby ho rozpoznal a začal ho poskytovať ako webovú aplikáciu. Sú manuálne spôsoby, ako to urobiť, ale PythonAnywhere poskytuje pomocný nástroj, ktorý všetko urobí za teba. Najprv ho nainštalujme: + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ pip{{ book.pa_py_version }} install --user pythonanywhere +``` + +Malo by to zobraziť niečo ako `Collecting pythonanywhere` a nakoniec skončiť riadkom, ktorý hovorí `Successfully installed (...) pythonanywhere- (...)`. + +Teraz spustíme pomocníka, ktorý automaticky nakonfiguruje našu aplikáciu z GitHubu. Zadaj nasledujúci príkaz do konzoly na PythonAnywhere (nezabudni použiť užívateľské meno z GitHubu namiesto ``, aby sa URL zhodovala s klonovacou URL z GitHubu): + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ pa_autoconfigure_django.py --python={{ book.pa_py_version }} https://github.com//my-first-blog.git +``` + +Keď budeš sledovať, ako to beží, uvidíš, čo to robí: + +- Sťahuje tvoj kód z GitHubu +- Vytvára virtualenv na PythonAnywhere, presne ako na tvojom počítači +- Aktualizuje tvoj súbor settings so zopár nastaveniami špecifickými pre nasadenie +- Pripravuje databázu na PythonAnywhere pomocou príkazu `manage.py migrate` +- Nastavuje tvoje statické súbory (o tých sa dozvieme viac neskôr) +- A nastavuje PythonAnywhere, aby sprístupnil tvoju stránku cez svoju API + +Na PythonAnywhere sú všetky tieto kroky zautomatizované, ale sú to presne tie isté kroky, aké by si musela spraviť u hocijakého iného poskytovateľa serverov. + +Dôležitá vec, ktorú si treba teraz všimnúť, je, že tvoja databáza na PythonAnywhere je vlastne úplne iná a oddelená od databázy na tvojom PC - to znamená, že budeš mať iné príspevky a administrátorský účet. Preto musíme najprv inicializovať admin účet pomocou `createsuperuser`, presne ako sme to spravili na svojom vlastnom počítači. PythonAnywhere pre teba automaticky vytvoril virtualenv, takže ti stačí spustiť: + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +(ola.pythonanywhere.com) $ python manage.py createsuperuser +``` + +Zadaj detaily pre admin užívateľa. Najlepšie je použiť tie isté, ako používaš na vlastnom počítači, a predísť tak prípadnému zmäteniu neskôr, ibaže by si chcela spraviť heslo na PythonAnywhere o niečo bezpečnejšie. + +A teraz, ak chceš, sa môžeš pozrieť na svoj kód na PythonAnywhere pomocou `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 +``` + +Môžeš tiež ísť do záložky "Files" a pohybovať sa pomocou zabudovaného PythonAnywhere prehliadača súborov. (Na stránke Console sa vieš dostať ku zvyšku stránok na PythonAnywhere pomocou tlačítka v menu v pravom hornom okraji. Keď už si na jednej z týchto stránok, linky na ostatné nájdeš hore.) + + +## Si online! + +Tvoja stránka by teraz mala byť online na internete! Preklikaj sa cez stránku "Web" na PythonAnywhere, kým sa dostaneš k odkazu na ňu. Môžeš ho poslať, komu len chceš. :) + + +> **Poznámka** Toto je začiatočnícky tutoriál a pre nasadenie stránky sme si niektoré veci zjednodušili, čo nie je ideálne z pohľadu bezpečnosti. Ak sa rozhodneš na tomto projekte ďalej stavať, mala by si si prejsť [Django deployment checklist](https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/) pre zopár tipov, ako svoju stránku zabezpečiť. + +## Debugovacie tipy + + +Ak uvídíš chybu počas behu skriptu `pa_autoconfigure_django.py`, toto sú niektoré z častých dôvodov: + +- Zabudla si si vytvoriť PythonAnywhere API token. +- Urobila si chybu vo svojej githubovej URL. +- Ak sa ti zobrazí chybové hlásenie *"Could not find your settings.py"*, pravdepodobne je to spôsobené tým, že sa ti nepodarilo pridať všetky súbory do Gitu a/alebo sa ich nepodarilo úspešne pridať na GitHub. Znovu sa pozri na odstavec o Gite vyššie +- Ak si už mala účet na PythonAnywhere a mala si problém s collectstatic, pravdepodobne máš účet so staršou verziou SQLite (napr. 3.8.2). V takom prípade si vytvor nový účet a skús príkazy v sekcii PythonAnywhere vyššie. + + +Ak pri pokuse navštíviť svoju stránku uvidíš chybu, prvým miestom, kde hľadať problém, je **error log**. Odkaz naň nájdeš na PythonAnywhere v [záložke Web](https://www.pythonanywhere.com/web_app_setup/). Pozri, či tam nie sú nejaké chybové hlášky - tie najnovšie sú naspodku. + +Môžeš skúsiť aj [všeobecné debugovacie tipy na help stránke PythonAnywhere](http://help.pythonanywhere.com/pages/DebuggingImportError). + +A nezabudni, tvoja mentorka alebo mentor sú tu na to, aby ti pomohli! diff --git a/sk/deploy/signup_pythonanywhere.md b/sk/deploy/signup_pythonanywhere.md old mode 100755 new mode 100644 index d0bd7bbc141..45420d0c81d --- a/sk/deploy/signup_pythonanywhere.md +++ b/sk/deploy/signup_pythonanywhere.md @@ -1,5 +1,19 @@ -Je čas prihlásiť sa zdarma k účtu "Beginner" na PythonAnywhere. +PythonAnywhere je služba, ktorá ti umožní nechať bežať svoj kód v Pythone na serveroch v "cloude". Použijeme ju na uverejnenie našej stránky na internete. - * [www.pythonanywhere.com](https://www.pythonanywhere.com/) +Náš blog uverejníme na PythonAnywhere. Vytvor si "Beginner" účet na PythonAnywhere (verzia zdarma stačí, nepotrebuješ kreditnú kartu). -> **Poznámka** Pri výbere používateľského mena, mysli na to, že URL tvojho blogu bude v tvare `tvojeuzivatelskemeno.pythonanywhere.com`, takže si vyber prezývku alebo názov o čom tvoj blog je. \ No newline at end of file +* [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +![Stránka PythonAnywhere, kde sa vytvára účet, s tlačidlom pre vytvorenie "Beginner" účtu zdarma](../deploy/images/pythonanywhere_beginner_account_button.png) + +> **Poznámka** Pri výbere používateľského mena mysli na to, že URL tvojho blogu bude v tvare `tvojeuzivatelskemeno.pythonanywhere.com`, takže si vyber prezývku alebo názov, o čom tvoj blog je. Taktiež si určite zapamätaj svoje heslo (pridaj si ho do svojho správcu hesiel, ak nejaký používaš). + +## Vytvorenie PythonAnywhere API tokenu + +Toto je niečo, čo musíš spraviť len raz. Keď si vytvoríš PythonAnywhere účet, hodí ťa to na tvoju nástenku. Nájdi odkaz na svoj účet (Account) vpravo hore: + +![Odkaz na účet (Account) vpravo hore na stránke](../deploy/images/pythonanywhere_account.png) + +následne vyber záložku "API token" a stlač tlačítko "Create new API token". + +![Záložka API token na Account stránke](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/sk/django/README.md b/sk/django/README.md old mode 100755 new mode 100644 index b63ab11c197..28f25e210cf --- a/sk/django/README.md +++ b/sk/django/README.md @@ -1,27 +1,27 @@ # Čo je Django? -Django (*džängou*) je bezplatný a open source webový framework na vytváranie webových aplikácií, napísaný v Pythone. Webový framework je súbor komponentov, ktoré ti pomôžu vytvárať stránky rýchlejšie a ľahšie. +Django (*džängou*) je bezplatný open sourcový webový framework na vytváranie webových aplikácií napísaný v Pythone. Webový framework je súbor komponentov, ktoré ti pomôžu vytvárať stránky rýchlejšie a ľahšie. -Pri tvorení webových stránok, potrebuješ vždy sadu podobných komponentov: spôsob, ako riešiť autentifikáciu užívateľov (registráciu, prihlásenie, odhlásenie), kontrolný panel web stránky, formuláre, spôsob, ako nahrávať súbory, atď. +Pri tvorení webových stránok potrebuješ vždy sadu podobných komponentov: spôsob, ako riešiť autentifikáciu užívateľov a užívateliek (registráciu, prihlásenie, odhlásenie), kontrolný panel web stránky, formuláre, spôsob, ako nahrávať súbory, atď. -Našťastie si iní ľudia už dávno všimli, že weboví vývojári čelia pri tvorbe nového webu podobným problémom, takže sa spojili a vytvorili frameworky (Django je jedným z nich) a tie ti poskytujú hotové komponenty, ktoré môžeš používať. +Našťastie si iní ľudia už dávno všimli, že webové vývojárky a vývojári čelia pri tvorbe nového webu podobným problémom, takže sa spojili a vytvorili frameworky (Django je jedným z nich), ktoré ti poskytujú hotové komponenty, ktoré môžeš použiť. -Frameworky sú tu na to, aby si nemusela znovu vynájsť koleso. Pomôžu ti uľahčiť tvorbu nových web stránok. +Frameworky sú tu na to, aby si nemusela znovu vynachádzať koleso. Uľahčia ti tvorbu nových web stránok. ## Prečo potrebuješ framework? Aby sme pochopili, čo vlastne Django je, potrebujeme sa zblízka pozrieť na servery. Prvá vec, čo o nich musíš vedieť, je, že budú obsluhovať tvoju stránku. -Predstav si poštovú schránku (port), na ktorej sa sledujú prichádzajúce listy (žiadosti). To vlastne robí web server. Web server prečíta list a pošle odpoveď v podobe web stránky. Ale ak chceš niečo poslať, potrebuješ mať nejaký obsah. A Django je to, čo ti obsah pomôže vytvoriť. +Predstav si poštovú schránku (port), na ktorej sa sledujú prichádzajúce listy (žiadosti). To vlastne robí web server. Web server si prečíta list a pošle odpoveď v podobe web stránky. Ale ak chceš niečo poslať, potrebuješ mať nejaký obsah. A Django je to, čo ti ten obsah pomôže vytvoriť. -## Čo sa stane, ak niekto požaduje z tvojho servera web stránku? +## Čo sa stane, ak si niekto vyžiada web stránku z tvojho servera? -Keď na webový server príde žiadosť, tá je preposlaná do Djanga, ktoré sa pokúsi zistiť, čoho sa vlastne žiadosť týka. Najprv si zoberie adresu webstránky a zisťuje, čo má urobiť. Túto časť vykonáva Django **urlresolver** (všimni si, že adresa webstránku sa nazýva - Uniform Resource Locator - URL, takže názov *urlresolver* dáva zmysel). Nie je to nič extra inteligentné - zoberie zoznam vzorov a porovnáva ich s URL. Django overuje vzory od vrchu po spodok a ak nájde zhodu, Django pošle žiadosť príslušnej funkcii (ktorá sa nazýva *view* - pohľad). +Keď na webový server príde žiadosť, tá je preposlaná do Djanga, ktoré sa pokúsi zistiť, čoho sa vlastne žiadosť týka. Najprv si zoberie adresu webstránky a zisťuje, čo má urobiť. Túto časť vykonáva Django **urlresolver** (všimni si, že adresa webstránku sa nazýva URL (Uniform Resource Locator), takže názov *urlresolver* dáva zmysel). Nie je to žiadna veda - zoberie zoznam vzorov (patterns) a porovnáva ich s URL. Django overuje vzory od vrchu smerom dolu a ak nájde zhodu, pošle žiadosť príslušnej funkcii (ktorá sa nazýva *view*). Predstav si poštárku s listom. Kráča ulicou a porovnáva čísla domov s číslom na liste. Ak sa zhoduje, nechá tam list. Takto funguje urlresolver! -Vo funkcii *view* sa dejú všetky zaujímavé veci: môžeme sa pozrieť do databázy a vyhľadať nejaké informácie. Čo ak užívateľ požiada o zmenu v údajoch? Napríklad listom, v ktorom je žiadosť "Prosím, zmeňte popis mojej práce." *view* overí, či máš oprávnenie na túto zmenu, potom aktualizuje popis tvojej práce a naspäť pošle správu: "Hotovo!". Potom *view* vygeneruje odpoveď a Django ju môže odoslat tvojmu webovému prehliadaču. +Vo funkcii *view* sa dejú všetky zaujímavé veci: môžeme sa pozrieť do databázy a vyhľadať nejaké informácie. Čo ak užívateľka požiada o zmenu v údajoch? Je to, akoby poslala list s obsahom: "Prosím, zmeňte popis mojej práce." *view* overí, či je oprávnená takú zmenu spraviť, potom popis práce zaktualizuje a naspäť pošle správu: "Hotovo!". Následne *view* vygeneruje odpoveď a Django ho pošle do prehliadača patriacemu užívateľke. -Samozrejme, vyššie uvedený popis je trochu zjednodušený, ale zatiaľ ešte nepotrebuješ vedieť všetky technické detaily. Pre všeobecnú predstavu to však stačí. +Samozrejme, vyššie uvedený popis je trochu zjednodušený, ale zatiaľ ešte nepotrebuješ vedieť všetky technické detaily. Pre všeobecnú predstavu to stačí. -Takže namiesto zložitého študovania detailov, jednoducho začneme v Djangu niečo vytvárať a všetky dôležité veci sa naučíme popri tom! \ No newline at end of file +Takže namiesto zložitého študovania detailov jednoducho začneme v Djangu niečo budovať a všetky dôležité veci sa naučíme popri tom! \ No newline at end of file diff --git a/sk/django_admin/README.md b/sk/django_admin/README.md old mode 100755 new mode 100644 index 660bd303332..f90e02f3536 --- a/sk/django_admin/README.md +++ b/sk/django_admin/README.md @@ -1,8 +1,10 @@ # Django admin -Na pridávanie, editovanie a mazanie postov, ktoré sme práve namodelovali, budeme používať Django admina. +Na pridávanie, editovanie a mazanie príspevkov, ktoré sme práve namodelovali, budeme používať Django admina. -Otvorme súbor `blog/admin.py` a nahraďme jeho obsah týmto: +Otvorme súbor `blog/admin.py` v editore a nahraďme jeho obsah týmto: + +{% filename %}blog/admin.py{% endfilename %} ```python from django.contrib import admin @@ -13,37 +15,43 @@ admin.site.register(Post) Ako vidíš, importujeme model Post definovaný v predchádzajúcej kapitole. Aby bol náš model viditeľný na adminskej stránke, musíme ho zaregistrovať pomocou `admin.site.register(Post)`. -OK, je čas pozrieť sa na náš Post model. Nezabudni v konzole spustiť web server pomocou príkazu `python manage.py runserver`. Spusti prehliadač a zadaj adresu http://127.0.0.1:8000/admin/. Uvidíš takúto prihlasovaciu stránku: +OK, je čas pozrieť sa na náš Post model. Nezabudni v konzole spustiť web server pomocou príkazu `python manage.py runserver`. V prehliadači zadaj adresu http://127.0.0.1:8000/admin/. Zobrazí sa ti takáto prihlasovacia stránka: -![Prihlasovacia stránka][1] +![Prihlasovacia stránka](images/login_page2.png) - [1]: images/login_page2.png +Pre prihlásenie musíš vytvoriť *superusera* - užívateľa, ktorý má kontrolu nad všetkým na stránke. Vráť sa do príkazového riadku, napíš `python manage.py createsuperuser` a stlač enter. -Pre prihlásenie musíš vytvoriť *superusera* - užívateľa, ktorý má kontrolu nad všetkým na stránke. Vráť sa do príkazového riadku, napíš `python manage.py createsuperuser` a stlač enter. Po výzve zadaj svoje meno (malé písmená, bez medzier), emailovú adresu a heslo. Ak nevidíš heslo, ktoré zadávaš, tým sa netráp - tak to má byť. Len ho zadaj a pokračuj stlačením `enter`. Výstup by mal vyzerať asi takto (kde užívateľské meno a email by mali byť tvoje vlastné): +> Ak chceš zadať viac príkazov, kým web server beží, otvor nové okno terminálu a aktivuj svoj virtualenv. Ako písať príkazy sme si povedali v kapitole **Tvoj prvý Django projekt!** v odstavci **Spustenie webového serveru**. -``` -(myvenv) ~/djangogirls$ python manage.py createsuperuser -Username: admin -Email address: admin@admin.com -Password: -Password (again): -Superuser created successfully. -``` +{% filename %}macOS alebo Linux:{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py createsuperuser + + +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py createsuperuser + -Vráť sa do prehliadača. Prihlás sa zvolenými údajmi ako superuser, mala by sa ti zobraziť nástenka (dashboard) Django admina. +Po výzve zadaj svoje meno (malé písmená, bez medzier), emailovú adresu a heslo. **Netráp sa, že nevidíš heslo, ktoré zadávaš, tak to má byť.** Len ho zadaj a stlač `enter`. Výstup by mal vyzerať asi takto (kde užívateľské meno a email by mali byť tvoje vlastné): -![Django admin][2] + Username: ola + Email address: ola@example.com + Password: + Password (again): + Superuser created successfully. + - [2]: images/django_admin3.png +Vráť sa do prehliadača. Prihlás sa zvolenými údajmi ako superuser, mala by sa ti zobraziť nástenka Django admina. -Prejdi do Postov a trochu experimentuj. Pridaj päť či šesť blog postov. Netráp sa veľmi s obsahom - trebárs skopíruj a vlož text z tohto tutorialu, nech ušetríš čas :). +![Django admin](images/django_admin3.png) -Uisti sa, že aspoň dva alebo tri posty (ale nie všetky) majú nastavený dátum publikovania. Bude to neskôr užitočné. +Choď do kategórie Posts a trochu sa s ňou pohraj. Pridaj 5 alebo 6 príspevkov. Netráp sa s obsahom - je viditeľný len pre teba na tvojom lokálnom počítači - môžeš skopírovať nejaký text z tohto tutoriálu, aby si ušetrila čas. :) -![Django admin][3] +Uisti sa, že aspoň dva alebo tri príspevky (ale nie všetky) majú nastavený dátum publikovania. Príde nám to vhod neskôr. - [3]: images/edit_post3.png +![Django admin](images/edit_post3.png) -Ak chceš vedieť viac o Django admine, pozri si dokumentáciu Djanga: https://docs.djangoproject.com/en/1.8/ref/contrib/admin/ +Ak chceš vedieť viac o Django admine, pozri si dokumentáciu Djanga: https://docs.djangoproject.com/en/5.1/ref/contrib/admin/ -Teraz je asi vhodný čas dať si kávu (alebo čaj), alebo niečo pod zub a nabrať trochu energie. Práve si vytvorila svoj prvý Django model - zaslúžiš si trochu oddychu! +Teraz je asi vhodný čas dať si kávu (alebo čaj) alebo niečo pod zub a nabrať trochu energie. Práve si vytvorila svoj prvý Django model - zaslúžiš si trochu oddychu! \ No newline at end of file diff --git a/sk/django_admin/images/django_admin3.png b/sk/django_admin/images/django_admin3.png index 25bcc4edda8..fb221bd18e1 100644 Binary files a/sk/django_admin/images/django_admin3.png and b/sk/django_admin/images/django_admin3.png differ diff --git a/sk/django_admin/images/edit_post3.png b/sk/django_admin/images/edit_post3.png index 34f2a195ec5..57299b6f5af 100644 Binary files a/sk/django_admin/images/edit_post3.png and b/sk/django_admin/images/edit_post3.png differ diff --git a/sk/django_admin/images/login_page2.png b/sk/django_admin/images/login_page2.png index 85137f4d162..c16d1aa4289 100644 Binary files a/sk/django_admin/images/login_page2.png and b/sk/django_admin/images/login_page2.png differ diff --git a/sk/django_forms/README.md b/sk/django_forms/README.md old mode 100755 new mode 100644 index 38652b5eeeb..4a956b8adf6 --- a/sk/django_forms/README.md +++ b/sk/django_forms/README.md @@ -1,24 +1,24 @@ -# Formuláre Django +# Django formuláre -Posledná vec, ktorú chceme urobiť na našej web stránke je vytvoriť príjemný spôsob pridávania a úpravy blog postov. Django `admin` je v pohode, ale ťažko sa prispôsobuje a upravuje do krajšej podoby. Pomocou `formulárov` budeme mať absolútnu moc nad naším rozhraním - môžeme urobiť takmer čokoľvek, čo si vieme predstaviť! +Posledná vec, ktorú chceme urobiť na našej web stránke, je vytvoriť pohodlný spôsob pridávania a úpravy blogových príspevkov. Django `admin` je v pohode, ale ťažko sa prispôsobuje a upravuje do krajšej podoby. Pomocou `formulárov` budeme mať absolútnu moc nad naším rozhraním - môžeme urobiť takmer čokoľvek, čo si vieme predstaviť! Na Django formulároch je fajn, že ich môžeme vytvoriť úplne od nuly alebo vytvoriť `ModelForm`, ktorý uloží výsledok formulára do modelu. -To je presne, čo chceme robiť: vytvoríme formulár pre náš `Post` model. +A toto je presne to, čo chceme urobiť: vytvoríme formulár pre náš model `Post`. -Tak ako všetky ostatné dôležité časti Djanga, formuláre majú svoj vlastný súbor: `forms.py`. +Tak, ako všetky ostatné dôležité časti Djanga, aj formuláre majú svoj vlastný súbor: `forms.py`. Musíme vytvoriť súbor s týmto názvom v adresári `blog`. -``` -blog - └── forms.py -``` + blog + └── forms.py + -OK, otvorme to a napíšme tento kód: +OK, otvorme ho v editore a napíšme nasledovný kód: -``` -python +{% filename %}blog/forms.py{% endfilename %} + +```python from django import forms from .models import Post @@ -30,91 +30,115 @@ class PostForm(forms.ModelForm): fields = ('title', 'text',) ``` -Najskôr musíme importovať Django formuláre (`from django import forms`) a, samozrejme, náš `Post` model (`from .models import Post`). +Najskôr musíme naimportovať Django formuláre (`from django import forms`) a náš model `Post` (`from .models import Post`). -`PostForm`, ako asi správne predpokladáš, je meno nášho formulára. Musíme Djangu povedať, že tento formulár je `ModelForm` (aby Django pre nás mohlo trochu čarovať) - za to je zodpovedný `forms.ModelForm`. +`PostForm`, ako asi správne predpokladáš, je názov nášho formulára. Musíme Djangu povedať, že tento formulár je `ModelForm` (aby Django pre nás mohlo trochu čarovať) - za to je zodpovedný `forms.ModelForm`. Ďalej máme `triedu Meta`, kde Djangu povieme, ktorý model by mal byť použitý na vytvorenie tohto formulára (`model = Post`). -Nakoniec môžeme Djangu povedať, ktoré formuláre budú v našom formulári. Pri tomto scenári, chceme boli zobrazené iba `title` (nadpis) a `text` - `author` by mala byť aktuálne prihlásená osoba (teda ty!) a dátum vytvorenia `created_date` by mal automaticky nastavený pri vytvorení postu (t.j. v kóde). +Nakoniec môžeme Djangu povedať, ktoré polia budú v našom formulári. V tomto prípade chceme, aby boli zobrazené iba `title` (nadpisy) a `text` - `author` by mala byť aktuálne prihlásená osoba (teda ty!) a dátum vytvorenia `created_date` by mal byť automaticky nastavený pri vytvorení postu (t.j. v kóde), však? -To je všetko! Jediné, čo treba teraz urobiť, je použiť formulár v *zobrazení* (angl. view) a zobraziť ho v šablóne. +To je všetko! Jediné, čo treba teraz urobiť, je použiť formulár vo *viewe* a zobraziť ho v šablóne. -Takže ešte raz vytvoríme: link na stránku, URL, zobrazenie a šablónu. +Takže ešte raz vytvoríme link na stránku, URL, zobrazenie a šablónu. ## Link na stránku s formulárom -Je čas otvoriť `blog/templates/blog/base.html`. Pridáme link do `divu` s názvom `page-header`: +Predtým, než pridáme link, budeme potrebovať zopár ikoniek, ktoré použijeme ako tlačidlá pre link. V rámci tohto tutoriálu si stiahni [file-earmark-plus.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/file-earmark-plus.svg) a ulož ho do priečinku `blog/templates/blog/icons/` + +> Poznámka: Pre stiahnutie SVG obrázku otvor kontextové menu k linku (väčšinou stlačením pravého tlačidla na myši) a zvoľ "Uložiť odkaz ako". V dialógu, kde si vyberáš, kde sa má súbor uložiť, sa nasmeruj do priečinku `djangogirls` svojho Django projektu a ďalej do podadresára `blog/templates/blog/icons/` a ulož súbor tam. + +Prišiel čas otvoriť `blog/templates/blog/base.html` v editore. Teraz môžeme použiť tento súbor s ikonkou do našej základnej šablóny takto. V elemente `div` vnútri `header` sekcie pridáme link pred element `h1`: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + + {% include './icons/file-earmark-plus.svg' %} + ``` -Všimni si, že chceme zavolať náš nový view (zobrazenie) `post_new`. +Všimni si, že chceme zavolať náš nový view `post_new`. [SVG ikonku](https://icons.getbootstrap.com/icons/file-earmark-plus/) máme z [Bootstrap Icons](https://icons.getbootstrap.com/) a zobrazí sa ako ikonka stránky s pluskom. Použijeme šablónový príkaz `include`. Týmto dosiahneme, že sa obsah súboru vloží do Django šablóny. Webový prehliadač vie, ako sa s týmto typom obsahu vysporiadať, bez toho, aby bolo treba čokoľvek ďalej spracovávať. + +> Všetky Bootstrapové ikonky si môžeš stiahnuť [tu](https://github.com/twbs/icons/releases/download/v1.11.3/bootstrap-icons-1.11.3.zip). Súbor rozbaľ a skopíruj všetky obrázkové súbory SVG do nového adresára vo vnútri `blog/templates/blog/` s názvom `icons`. Vďaka tomuto môžeš pristupovať k ikonke ako `pencil-fill.svg` pomocou cesty `blog/templates/blog/icons/pencil-fill.svg` -Po pridaní riadku by tvoj html súbor mal vyzerať asi takto: +Po zmene riadku by tvoj HTML súbor mal vyzerať takto: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} + Django Girls blog - - + - -
+ +
-
+
{% block content %} {% endblock %}
-
+
``` -Keď uložíš a obnovíš stránku http://127.0.0.1:8000 uvidíš samozrejme známu chybu `NoReverseMatch`, však? +Po uložení a obnove stránky http://127.0.0.1:8000 uvidíš našu starú známu chybu `NoReverseMatch`. Je to tak? Dobre! ## URL -Otvor `blog/urls.py` a pridaj riadok: +Otvoríme `blog/urls.py` v editore a pridáme riadok: + +{% filename %}blog/urls.py{% endfilename %} ```python -url(r'^post/new/$', views.post_new, name='post_new'), +path('post/new/', views.post_new, name='post_new'), ``` A výsledný kód bude vyzerať takto: +{% 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'), ] ``` -Po obnovení stránky uvidíme chybu `AttributeError`, pretože nemáme implementovaný view (zobrazenie) `post_new`. Pridajme ho teraz. +Po obnovení stránky uvidíme chybu `AttributeError`, pretože nemáme naimplementovaný view `post_new`. Pridajme ho teraz. + +## View post_new -## view (zobrazenie) post_new +Teraz otvoríme súbor `blog/views.py` v editore a pridáme nasledujúce riadky so zvyškom importovacích riadkov `from`: -Teraz otvoríme súbor `blog/views.py` a pridáme tam nasledujúce riadky so zvyškom importovacích riadkov `from`: +{% filename %}blog/views.py{% endfilename %} ```python from .forms import PostForm ``` -a náš *view*: +A potom náš *view*: + +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): @@ -122,50 +146,50 @@ def post_new(request): return render(request, 'blog/post_edit.html', {'form': form}) ``` -Nový formulár `Post` vytvoríme tak, že sputíme `PostForm()` a prepošleme ho šablóne. K tomuto *view* sa ešte vrátime, ale teraz poďme rýchlo vytvoriť šablónu formulára. +Nový formulár pre `Post` vytvoríme tak, že zavoláme `PostForm()` a prepošleme ho šablóne. K tomuto *viewu* sa ešte vrátime, ale teraz poďme rýchlo vytvoriť šablónu formulára. ## Šablóna -Musíme vytvoriť súbor `post_edit.html` v adresári `blog/ templates/blog`. Aby formulár fungoval, potrebujeme niekoľko vecí: +Musíme vytvoriť súbor `post_edit.html` v priečinku `blog/templates/blog` a otvoriť ho v editore. Aby formulár fungoval, potrebujeme niekoľko vecí: -* musíme zobraziť formulár. To môžeme urobiť jednoducho takto `{% raw %}{{ form.as_p }}{% endraw %}`. -* riadok vyššie musí byť obalený HTML tagom: `...` -* potrebujeme tlačidlo `Uložiť`. Vytvoríme ho ako HTML tlačidlo: `` -* a nakoniec, hneď za otváracím tagom `
` musíme pridať `{% raw %}{% csrf_token %}{% endraw %}`. Toto je veľmi dôležité, vďaka tomu je formulár bezpečný! Ak na túto časť zabudneš, Django sa bude pri ukladaní formuláru sťažovať: +* Musíme zobraziť formulár. Môžeme to urobiť (napríklad) pomocou {% raw %}`{{ form.as_p }}`{% endraw %}. +* Riadok vyššie musí byť obalený HTML elementom form: `...
`. +* Potrebujeme tlačidlo `Uložiť`. Vytvoríme ho ako HTML tlačidlo: ``. +* A nakoniec hneď za otváracím tagom `
` musíme pridať `{% raw %}{% csrf_token %}{% endraw %}`. Toto je veľmi dôležité, vďaka tomu je formulár zabezpečený! Ak na to zabudneš, Django sa bude sťažovať, keď sa pokúsiš formulár uložiť: -![CSFR Zakázaná stránka][1] +![CSFR Zakázaná stránka](images/csrf2.png) - [1]: images/csrf2.png +OK, poďme sa pozrieť, ako by malo vyzerať HTML v `post_edit.html`: -OK, pozrime sa, ako by malo vyzerať HTML v `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 %} ``` -Obnovíme stránku! Aha! Tvoj formulár je na svete! - -![Nový formulár][2] +Čas obnoviť stránku! Aha! Tvoj formulár je na svete! - [2]: images/new_form2.png +![Nový formulár](images/new_form2.png) -Ale počkaj chvíľku! Keď niečo zadáš niečo do polí `title` a `text` a skúsiš to uložiť - čo sa stane? +Ale moment! Keď zadáš niečo do polí `title` a `text` a skúsiš to uložiť, čo sa stane? -Nič! Sme stále na rovnakej stránke a náš text je preč... a žiaden nový príspevok sa nepridal. Takže čo sa pokazilo? +Nič! Sme stále na rovnakej stránke a náš text zmizol... a žiaden nový príspevok sa nepridal. Takže čo sa pokazilo? -Odpoveď znie: nič. Akurát budeme mať ešte trochu práce v našom *view* (zobrazení). +Odpoveď znie: nič. Akurát musíme ešte trochu popracovať na našom *viewe*. ## Uloženie formuláru -Znova otvor `blog/views.py`. Momentálne máme v `post_new` len toto: +Znova otvor `blog/views.py` v editore. Momentálne máme v `post_new` len toto: + +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): @@ -173,26 +197,32 @@ def post_new(request): return render(request, 'blog/post_edit.html', {'form': form}) ``` -Keď odošleme formulár, vrátime sa do rovnakého view, ale teraz už máme v `request` aj nejaké údaje, presnejšie v `request.POST` (názov nemá nič spoločné s "postom" na blogu, ide len o to, že posielame - "postujeme" údaje). Pamätáš si, že naša definícia formuláru `
` v HTML súbore mala premennú `method="POST"`? Všetky polia z formulára sú teraz v `request.POST`. `POST` by si nemala premenovať na nič iné (jediná ďalšia platná hodnota pre premennú `method` je `GET`, teraz ale nemáme čas vysvetliť si rozdiel). +Keď odošleme formulár, vrátime sa do rovnakého viewu, ale teraz už máme v `request` aj nejaké údaje, presnejšie v `request.POST` (názov nemá nič spoločné s "postom" na blogu, ide len o to, že posielame - "postujeme" údaje). Pamätáš si, ako naša definícia formuláru `` v HTML súbore mala premennú `method="POST"`? Všetky polia z formulára sú teraz v `request.POST`. `POST` by si nemala premenovať na nič iné (jediná ďalšia platná hodnota pre premennú `method` je `GET`, teraz ale nemáme čas vysvetliť si rozdiel). + +Takže v našom *viewe* musíme ošetriť dva rôzne prípady: prvý, ak pristupujeme na stránku prvýkrát a chceme prázdny formulár, a druhý, keď sa vrátime na *view* s už predvyplnenými údajmi formulára. Takže potrebujeme pridať podmienku (na to použijeme `if`): -Takže v našom *view* máme vyriešiť dve samostatné situácie. Po prvé: keď prídeme na stránku po prvýkrát a chceme prázdny formulár. Po druhé: keď sa vrátime do *view* so všetkými vyplnenými údajmi formulára. Takže potrebujeme pridať podmienku (na to použijeme `if`). +{% filename %}blog/views.py{% endfilename %} ```python if request.method == "POST": - [...] + [...] else: - form = PostForm() + form = PostForm() ``` -Je čas na vyplnenie bodky `[...]`. Ak `method` je `POST` potom chceme vytvoriť `PostForm` s údajmi z formulára, však? To urobíme takto: +Je čas nahradiť tri bodky `[...]`. Ak ide o `metódu` `POST`, tak chceme vytvoriť `PostForm` s dátami z formulára, však? Urobíme to takto: + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(request.POST) ``` -Ľahké! Ďalej skontrolujme či je formulár v poriadku (všetky povinné polia sú vyplnené a nie sú zadané žiadne nesprávne hodnoty). To urobíme pomocou `form.is_valid()`. +Ďalej skontrolujeme, či je formulár v poriadku (všetky povinné polia sú vyplnené a nie sú zadané žiadne nesprávne hodnoty). To urobíme pomocou `form.is_valid()`. + +Skontrolujeme, či je formulár platný a ak áno, môžeme ho uložiť! -Skonotrolujeme, či je formulár platný a ak áno, môžeme ho uložiť! +{% filename %}blog/views.py{% endfilename %} ```python if form.is_valid(): @@ -202,23 +232,29 @@ if form.is_valid(): post.save() ``` -V podstate urobím dve veci: uložíme formulár pomocou `form.save` a pridáme autora (keďže pole `author` nebolo v `PostForm` nebolo, no toto pole je povinné!). `commit=False` znamená, že ešte nechce uložiť model `Post` - najskôr chceme pridať autora. Väčšinou budeš používať `form.save()` bez `commit=False`, no v tomto prípade, to takto musíme spraviť. `post.Save()` uchová zmeny (pridanie autora) a máme vytvorený nový blog post! +V podstate tu ide o dve veci: uložíme formulár pomocou `form.save` a pridáme autora (keďže pole `author` nebolo v `PostForm`, avšak toto pole je povinné). `commit=False` znamená, že ešte nechceme uložiť model `Post` - najskôr chceme pridať autora. Väčšinou budeš používať `form.save()` bez `commit=False`, no v tomto prípade to musíme tak spraviť. `post.save()` uchová zmeny (pridanie autora) a máme vytvorený nový blogový príspevok! -A bolo by skvelé, keby sme sa potom ihneď dostali na stránku `post_detail` nášho novovytvoreného blog postu, nie? Na to ale budeme potrebovať ešte jeden import: +A nakoniec by bolo super, keby sme mohli ísť rovno na stránku `post_detail` pre náš novovytvorený príspevok, nie? K tomu potrebujeme ešte jeden import: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import redirect ``` -Pridaj to úplne na začiatok súboru. A teraz môžeme povedať: prejdi na stránku `post_detail` novovytvoreného postu. +Pridaj tento riadok úplne na začiatok súboru. A teraz môžeme povedať: "prejdi na stránku `post_detail` novovytvoreného príspevku": + +{% filename %}blog/views.py{% endfilename %} ```python - return redirect('blog.views.post_detail', pk=post.pk) +return redirect('post_detail', pk=post.pk) ``` -`blog.views.post_detail` je názov view - zobrazenia, kam chceme ísť. Spomínaš si, že tento *view* vyžaduje premennú `pk`? Aby sme ju odovzdali zobrazenia, použijeme `pk=post.pk`, kde `post` je novo vytvorený blog post! +`post_detail` je názov viewu, na ktorý chceme ísť. Spomínaš si, že tento *view* vyžaduje premennú `pk`? Aby sme ju odovzdali viewu, použijeme `pk=post.pk`, kde `post` je náš novovytvorený príspevok! + +OK, dosť bolo rečí, už je načase pozrieť sa, ako teraz vyzerá celý *view*, však? -Ok, dosť sme hovorili, ale asi by bolo dobré pozrieť sa ako celý *view* vyzerá, však? +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): @@ -229,74 +265,88 @@ def post_new(request): post.author = request.user post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) ``` -Pozrime sa, či to funguje. Poď na stránku http://127.0.0.1:8000/post/new/, pridaj `title` a `text`, ulož to... and voilà! Nový blog post je pridaný my sme presmerovaní na stránku `post_detail`! +Pozrime sa, či to funguje. Poď na stránku http://127.0.0.1:8000/post/new/, pridaj `title` a `text`, ulož to... a voilà! Nový príspevok je pridaný a my sme presmerovaní na stránku `post_detail`! -Možno si si všimla, že pred uložením postu nastavujeme dátum publikovania. Neskôr v **Django Girls Tutorial: Rozšírenie** sa zoznámime s *tlačidlom Publikovať*. +Možno si si všimla, že pred uložením príspevku nastavujeme dátum publikovania. Neskôr v **DjangoGirls Tutorial: Rozšírenie** sa zoznámime s *tlačidlom Publikovať*. To je úžasné! -## Validácia formuláru +> Keďže sme nedávno použili administrátorské rozhranie Djanga, systém si myslí, že sme stále prihlásení. Existuje zopár situácií, ktoré by mohli spôsobiť odhlásenie (zatvorenie prehliadača, reštart databázy a podobne). Pokiaľ by sa ti zobrazovala chyba pri vytváraní postu, ktorá by sa sťažovala, že nie si prihlásená, choď na adminskú stránku http://127.0.0.1:8000/admin and prihlás sa znova. Toto problém dočasne vyrieši. Čaká však na teba aj permanentné riešenie v kapitole **Domáca úloha: zvýš svojej stránke bezpečnosť!** po skončení hlavného tutoriálu. -Teraz si ukážeme, aké sú Django formuláre super. Príspevok na blogu (post) musí mať polia `title` a `text`. V našom modeli `Post` sme nepovedali (na rozdiel od `published_date`), že tieto polia sú nepovinné, takže Django štandardne očakáva, že budú nastavené. +![Chyba prihlásenia](images/post_create_error.png) -Skús uložiť formulár bez `title` a `text`. Hádaj, čo sa stane! +## Validácia formuláru -![Validácia formuláru][3] +Teraz si ukážeme, aké sú Django formuláre super. Príspevok na blogu musí mať polia `title` a `text`. V našom modeli `Post` sme nepovedali (na rozdiel od `published_date`), že tieto polia sú nepovinné, takže Django štandardne očakáva, že budú nastavené. - [3]: images/form_validation2.png +Skús uložiť formulár bez `title` a `text`. Pokús sa uhádnuť, čo sa stane! -Django overí, či sú všetky polia formulára správne. Nie je to skvelé? +![Validácia formuláru](images/form_validation2.png) -> Keďže sme nedávno použili administrátorské rozhranie Djanga, systém si myslí, že sme prihlásení. Existuje zopár situácií, ktoré by mohli spôsobiť odhlásenie (zatvorenie prehliadača, reštart databázy a podobne). Pokiaľ by sa ti zobrazovala chyba pri vytváraní postu upozorňujúca na neprihláseného užívateľa, choď na adminskú stránku http://127.0.0.1:8000/admin and prihlás sa znova. Toto dočasne vyrieši problém. Čaká však na teba aj permanentné riešenie v kapitole **Domáca úloha: zvýš svojej stránke bezpečnosť!** po skončení hlavného tutorialu. +Django sa postará o to, aby overilo, či sú všetky polia formulára správne. Nie je to skvelé? -![Chyba prihlásenia][4] +## Formulár pre úpravu - [4]: images/post_create_error.png +Teraz už vieme, ako sa pridáva nový príspevok. Ale čo ak chceme upraviť existujúci? Je to veľmi podobné tomu, čo sme práve spravili. Poďme rýchlo vytvoriť niekoľko dôležitých vecí. (Ak niečomu nerozumieš, opýtaj sa svojej mentorky alebo mentora alebo sa pozri na predchádzajúce kapitoly, pretože všetky tieto kroky sme si už prebrali.) -## Úprava formuláru +V prvom rade si uložíme ikonku, ktorá bude reprezentovať tlačidlo na úpravu. Stiahni si [pencil-fill.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/pencil-fill.svg) a ulož ho do adresára `blog/templates/blog/icons/`. -Teraz už vieme, ako sa pridáva nový formulár. Ale čo ak chceme upravovať existujúci? Veľmi podobne, ako to, čo sme práve spravili. Vytvorme rýchlo pár dôležitých vecí (ak niečomu nerozumieš, opýtaj sa svojho trénera alebo sa pozri na predchádzajúce kapitoly, pretože všetky tieto kroky sme si už prebrali). +Otvor si `blog/templates/blog/post_detail.html` v editore a pridaj nasledujúci kód dovnútra elementu `article`: -Otvor `blog/templates/blog/post_detail.html` a pridaj tento riadok: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html - + ``` -takže šablóna teraz bude vyzerať takto: +aby šablóna vyzerala takto: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html {% extends 'blog/base.html' %} {% block content %} -
+
+ {% endblock %} ``` -V `blog/urls.py` pridáme tento riadok: +Otvor si `blog/urls.py` v editore a pridaj tento riadok: + +{% 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'), ``` -Znova použijeme šablónu `blog/templates/blog/post_edit.html`, takže posledná vec, čo nám chýba je *view*. +Znova použijeme šablónu `blog/templates/blog/post_edit.html`, takže posledná vec, čo nám chýba, je *view*. -Otvorme 0>blog/views.py a na úplný koniec súboru pridaj toto: +Otvor `blog/views.py` v editore a na úplný koniec súboru pridaj toto: + +{% filename %}blog/views.py{% endfilename %} ```python def post_edit(request, pk): @@ -308,19 +358,23 @@ def post_edit(request, pk): post.author = request.user post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm(instance=post) return render(request, 'blog/post_edit.html', {'form': form}) ``` -To vyzerá skoro tak isto ako náš view `post_new`, však? Ale nie úplne. Po prvé: odovzdávame navyše parameter `pk` z URL. A ďalej: pomocou `get_object_or_404(Post, pk=pk)` dostaneme model `Post`, ktorý chceme upravovať a potom pri vytváraní formuláru odovzdávame tento post ako parameter `instance`, keď budeme formulár ukladať: +To vyzerá skoro tak isto ako náš view `post_new`, však? Ale nie úplne. Jeden rozdiel je, že posielame navyše parameter `pk` z `urls`. A ďalej: pomocou `get_object_or_404(Post, pk=pk)` získame model `Post`, ktorý chceme upravovať, a následne pri vytváraní formuláru odovzdáme tento príspevok ako parameter `instance`, aj v prípade, keď ukladáme formulár… + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(request.POST, instance=post) ``` -a tiež keď sme formulár otvorili s týmto postom určeným na úpravu: +…aj v prípade, keď sme otvorili formulár za účelom úpravy daného príspevku: + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(instance=post) @@ -328,73 +382,98 @@ form = PostForm(instance=post) OK, vyskúšajme, či to funguje! Poďme na stránku `post_detail`. V pravom hornom rohu by malo byť tlačidlo na úpravu: -![Tlačidlo Upraviť][5] - - [5]: images/edit_button2.png - -Keď naňho klikneš, uvidíš formulár s našim blog postom: +![Tlačidlo Upraviť](images/edit_button2.png) -![Úprava formuláru][6] +Keď naňho klikneš, uvidíš formulár s našim blogovým príspevkom: - [6]: images/edit_form2.png +![Úprava formuláru](images/edit_form2.png) Môžeš si vyskúšať zmeniť názov alebo text a uložiť zmeny! Gratulujeme! Tvoja aplikácia je čím ďalej dokonalejšia! -Ak potrebuješ viac informácií o Django formulároch, prečítaj si dokumentáciu: https://docs.djangoproject.com/en/1.8/topics/forms/ +Ak potrebuješ viac informácií o Django formulároch, prečítaj si dokumentáciu: https://docs.djangoproject.com/en/5.1/topics/forms/ ## Bezpečnosť -Možnosť vytvárať nové posty len kliknutím na link je úžasná! Ale, v tejto chvíli, ktokoľvek, kto navštívi tvoju stránku, bude môcť pridať nový blog post a to asi nie je presne to, čo by si chcela. Urobme to tak, že sa tlačidlo zobrazí nikomu inému okrem teba. +Možnosť vytvárať nové príspevky len kliknutím na link je super! Ale v tomto momente každý, kto navštívi tvoju stránku, bude môcť pridať nový blog post, a to asi nie je to, čo by si chcela. Zmeňme to tak, že tlačidlo sa zobrazí iba tebe a nikomu inému. -V `blog/templates/blog/base.html` nájdi náš `div` `page-header` a kotviaci tag, ktorý si tam umiestnila už predtým. Mal by vyzerať takto: +Otvor `blog/templates/blog/base.html` v editore a nájdi náš `div` vovnútri `header` a tag "a", ktorý si tam umiestnila už predtým. Mal by vyzerať takto: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + + {% include './icons/file-earmark-plus.svg' %} + ``` -Do neho pridáme ďalší tag `{% if %}`, vďaka ktorému sa link zobrazí len užívateľom, ktorí sú prihlásení ako admina. Momentálne si to len ty! Zmeň tag `< >`, aby vyzeral takto: +Do tejto časti pridáme ďalší tag `{% if %}`, vďaka ktorému sa link zobrazí len užívateľovi alebo užívateľke, ktorí sú prihlasení do admina. Momentálne si to len ty! Zmeň element ``, aby vyzeral takto: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% if user.is_authenticated %} - + + {% include './icons/file-earmark-plus.svg' %} + {% endif %} ``` -Tento `{% if %}` zabezpečí, aby bol link odoslaný do prehliadača, len ak je používateľ požadujúci stránku prihlásený. Nezabráni to vytváraniu nových postov úplne, ale je to dobrý prvý krok. Viac o bezpečnosti si povieme v rozširujúcich lekciách. +Tento `{% if %}` spôsobí, že link bude odoslaný do prehliadača len v prípade, ak je používateľka či používateľ požadujúci stránku prihlásená/-ý. Nezabráni to vytváraniu nových príspevkov úplne, ale ako prvý krok je to dobré. Viac o bezpečnosti si povieme v rozširujúcich lekciách. + +Spomínaš si na ikonku na upravovanie, ktorú sme práve pridali na našu stránku s detailmi? Rovnakú zmenu chceme pridať aj sem, aby iní ludia nemohli upravovať existujúce príspevky. + +Otvor `blog/templates/blog/post_detail.html` v editore a nájdi tento riadok: -Keďže si zrejme prihlásená, ak obnovíš stránku, neuvidíš žiadnu zmenu. Načítaj však stránku v inom prehliadači alebo v inkognito okne a uvidíš, že link sa nezobrazí! +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html + + {% include './icons/pencil-fill.svg' %} + +``` + +Zmeň ho na toto: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html +{% if user.is_authenticated %} + + {% include './icons/pencil-fill.svg' %} + +{% endif %} +``` + +Kedže si pravdepodobne prihlásená, ak obnovíš stránku, neuvidíš nič nové. Načítaj stránku v inom prehliadači alebo incognito okne (nazývané "InPrivate" vo Windows Edge) a uvidíš, že odkaz sa nezobrazuje a ikonka tiež nie! ## Ešte jedna vec: čas nasadiť aplikáciu! Pozrime sa, či to všetko funguje na PythonAnywhere. Je čas na ďalšie nasadenie! -* Najprv odovzdaj svoj nový kód a pošli ho na Github +* Najprv commitni svoj nový kód a pošli ho na GitHub: -``` -$ git status -$ git add -A . -$ git status -$ git commit -m "Pridane views na vytvorenie/editovanie blog postu vo vnutri stranky." -$ git push -``` +{% filename %}command-line{% endfilename %} -* Potom v [Bash konzole PythonAnywhere][7]: + $ git status + $ git add . + $ git status + $ git commit -m "Pridane viewy na vytvorenie/editovanie prispevkov priamo zo stranky" + $ git push + - [7]: https://www.pythonanywhere.com/consoles/ +* Potom v [konzole PythonAnywhere](https://www.pythonanywhere.com/consoles/): -``` -$ 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 + [...] + -* A nakoniec preskoč na [kartu Web][8] and klinki na **Reload**. +(Nezabudni nahradiť `` svojou subdoménou na PythonAnywhere bez špicatých zátvoriek.) - [8]: https://www.pythonanywhere.com/web_app_setup/ +* A nakoniec prejdi na stránku ["Web"](https://www.pythonanywhere.com/web_app_setup/) (použi tlačidlo menu v pravej hornej časti konzoly) a stlač **Reload**. Obnov svoj blog na https://subdomena.pythonanywhere.com, aby si videla svoje zmeny. -A to by malo byť všetko! Gratulujeme :) +A to by malo byť všetko! Gratulujeme! :) \ No newline at end of file diff --git a/sk/django_forms/images/csrf2.png b/sk/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/sk/django_forms/images/csrf2.png and b/sk/django_forms/images/csrf2.png differ diff --git a/sk/django_forms/images/drafts.png b/sk/django_forms/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/sk/django_forms/images/drafts.png and b/sk/django_forms/images/drafts.png differ diff --git a/sk/django_forms/images/edit_button2.png b/sk/django_forms/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/sk/django_forms/images/edit_button2.png and b/sk/django_forms/images/edit_button2.png differ diff --git a/sk/django_forms/images/edit_form2.png b/sk/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/sk/django_forms/images/edit_form2.png and b/sk/django_forms/images/edit_form2.png differ diff --git a/sk/django_forms/images/form_validation2.png b/sk/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/sk/django_forms/images/form_validation2.png and b/sk/django_forms/images/form_validation2.png differ diff --git a/sk/django_forms/images/new_form2.png b/sk/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/sk/django_forms/images/new_form2.png and b/sk/django_forms/images/new_form2.png differ diff --git a/sk/django_forms/images/post_create_error.png b/sk/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/sk/django_forms/images/post_create_error.png and b/sk/django_forms/images/post_create_error.png differ diff --git a/sk/django_installation/README.md b/sk/django_installation/README.md old mode 100755 new mode 100644 index 77aace25152..ae3f6452cbe --- a/sk/django_installation/README.md +++ b/sk/django_installation/README.md @@ -1,5 +1,7 @@ -# Inštalácia Django +# Inštalácia Djanga -> **Poznámka** Ak si už prešla krokmi Inštalácie, tak toto už máš hotové a môžeš ísť rovno na ďalšiu kapitolu! +> **Poznámka** Ak používaš Chromebook, preskoč túto kapitolu a postupuj podľa pokynov na [nastavenie Chromebooku](../chromebook_setup/README.md). +> +> **Poznámka** Ak si už prešla [inštalačnými pokynmi](../installation/README.md), tak toto už máš hotové a môžeš ísť rovno na ďalšiu kapitolu! {% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/sk/django_installation/instructions.md b/sk/django_installation/instructions.md old mode 100755 new mode 100644 index b35d55ab25f..add4af1dcdf --- a/sk/django_installation/instructions.md +++ b/sk/django_installation/instructions.md @@ -1,122 +1,229 @@ -> Časť tejto kapitoly je založené na tutorialoch Geek Girls Carrots (http://django.carrots.pl/). -> -> Časť tejto kapitoly je založená na [django-marcador tutorial](http://django-marcador.keimlink.de/) licencovanej pod medzinárodnou licenciou Creative Commons Attribution-ShareAlike 4.0. Tutoriál django-marcador je autorsky chránený Markusom Zapke-Gründemannom et al. +> Časť tejto kapitoly je založená na tutoriáloch Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> +> Časť tejto kapitoly je založená na [django-marcador tutorial](http://django-marcador.keimlink.de/) pod licenciou Creative Commons Attribution-ShareAlike 4.0 International License. Tutoriál django-marcador je autorsky chránený Markusom Zapke-Gründemannom et al. ## Virtuálne prostredie -Skôr ako nainštalujeme Django, nainštalujeme si extrémne užitočný nástroj, ktorý ti pomôže udržiavať poriadok pri kódovaní v tvojom počítači. Je možné tento krok preskočiť, no veľmi ho odporúčame. Začať s najlepším možným nastavením ti ušetrí kopec problémov v budúcnosti! +Skôr, ako nainštalujeme Django, nainštalujeme si extrémne užitočný nástroj, ktorý ti pomôže udržiavať poriadok pri programovaní na tvojom počítači. Je možné tento krok preskočiť, no veľmi ho odporúčame. Začať s najlepším možným nastavením ti ušetrí kopec problémov v budúcnosti! -Takže poďme vytvoriť **virtuálne prostredie** (alebo aj *virtualenv*). Virtualenv oddelí nastavenia Python/Django pre každý projekt zvlášť. To znamená, že zmeny, ktoré urobíš na jednej web stránke, neovplyvnia iné stránky, ktoré vyvíjaš. Šikovné, však? +Takže poďme vytvoriť **virtuálne prostredie** (alebo aj *virtualenv*). Virtualenv oddelí nastavenia Pythonu/Djanga pre každý projekt zvlášť. To znamená, že zmeny, ktoré urobíš na jednej web stránke, neovplyvnia iné stránky, ktoré vyvíjaš. Šikovné, však? -Jediné, čo musíš urobiť je nájsť adresár, v ktorom chceš `virtualenv` vytvoriť, napríklad tvoj domovský adresár. Vo Windowse by mohol vyzerať napríklad `C:\Users\Meno` (kde `Meno` predstavuje tvoj login). +Jediné, čo musíš urobiť, je nájsť priečinok, v ktorom chceš `virtualenv` vytvoriť, napríklad tvoj domovský priečinok. Vo Windowse by mohol vyzerať napríklad `C:\Users\Meno` (kde `Meno` predstavuje tvoj login). -V tomto tutoriale budeme používať nový adresár `djangogirls` v tvojom domovskom adresári: +> **POZNÁMKA:** Vo Windowse sa uisti, že tento priečinok neobsahuje špeciálne znaky alebo znaky s diakritikou; ak tvoje uživateľské meno obsahuje znaky s diakritikou, použi iný priečinok, napr. `C:\djangogirls`. -``` -mkdir djangogirls -cd djangogirls -``` +V tomto tutoriáli budeme používať nový priečinok `djangogirls` v tvojom domovskom priečinku: + +{% filename %}command-line{% endfilename %} + + $ mkdir djangogirls + $ cd djangogirls + Vytvoríme virtualenv s názvom `myenv`. Všeobecný príkaz má takýto formát: -``` -python3 -m venv myvenv -``` +{% filename %}command-line{% endfilename %} -### Windows + $ python3 -m venv myvenv + -Ak chceš vytvoriť nový `virtualenv`, musíš otvoriť konzolu (hovorili sme o tom pár kapitol dozadu, pamätáš?) a spusti `C:\Python34\python -m venv myvenv`. Bude to vyzerať takto: + -``` -C:\Users\Meno\djangogirls> C:\Python34\python -m venv myvenv -``` +Ak chceš vytvoriť nový `virtualenv`, musíš otvoriť príkazový riadok a spustiť `python -m venv myvenv`. Bude to vyzerať takto: -kde `C:\Python34\python` je adresár, v ktorom máš nainštalovaný Python a `myvenv` je názov tvojho `virtualenv`-u. Môžeš použiť aj iný názov, ale používaj malé písmená a žiadne medzery, diakritiku alebo špeciálne znaky. Je tiež dobré použiť krátky názov - budeš naňho často odkazovať! +{% filename %}command-line{% endfilename %} -### Linux a OS X + C:\Users\Name\djangogirls> python -m venv myvenv + -Vytvoriť `virtualenv` na Linuxe a OS X vyžaduje iba jednoduché spustenie `python3 -m venv myvenv`. Bude to vyzerať takto: +`myvenv` je názov tvojho `virtualenvu`. Môžeš použiť aj iný názov, ale používaj malé písmená a žiadne medzery, diakritiku alebo špeciálne znaky. Je tiež dobré použiť krátky názov - budeš naň často odkazovať! -``` -~/djangogirls$ python3 -m venv myvenv -``` + -`myvenv` je názov tvojho `virtualenv`-u. Môžeš použiť aj iný názov, ale ostaň pri malých písmenách a nepoužívaj medzery. Je tiež dorbé použiť krátky názov, pretože naň budeš často odkazovať! + -> **POZNÁMKA:** Inicializácia virtuálneho prostredie na Ubuntu 14,04 týmto spôsobom v súčasnosti dáva takúto chybu: -> -> Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 -> -> -> Obídeme to týmto príkazom `virtualenv`-u. -> -> ~/djangogirls$ sudo apt-get install python-virtualenv -> ~/djangogirls$ virtualenv --python=python3.4 myvenv -> +Vytvoriť `virtualenv` na Linuxe a macOS vyžaduje spustenie `python3 -m venv myvenv`. Bude to vyzerať takto: -## Práca s virtualenv +{% filename %}command-line{% endfilename %} -Vyššie uvedený príkaz vytvorí adresár s názvom `myvenv` (alebo akékoľvek meno si vybrala), ktorý obsahuje naše virtuálne prostredie (v podstate kopec adresárov a súborov). + $ python3 -m venv myvenv + -#### Windows +`myvenv` je názov tvojho `virtualenvu`. Môžeš použiť aj iný názov, ale ostaň pri malých písmenách a nepoužívaj medzery. Je tiež dobré použiť krátky názov, pretože naň budeš často odkazovať! + +> **POZNÁMKA:** Niektoré verzie systému Debian/Ubuntu môžu zobraziť nasledujúcu chybu: +> +> {% filename %}command-line{% endfilename %} +> +> The virtual environment was not created successfully because ensurepip is not available. Na systémoch Debian/Ubuntu budeš musieť nainštalovať balíček python3-venv pomocou nasledujúceho príkazu. +> apt install python3-venv +> Možno budeš musieť pre tento príkaz použiť sudo. Po nainštalovaní balíčku python3-venv si znova vytvor svoje virtuálne prostredie. +> +> +> V tomto prípade postupuj podľa pokynov uvedených vyššie a nainštaluj si balík `python3-venv`: {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python3-venv +> +> +> **POZNÁMKA:** V niektorých verziách Debian/Ubuntu inicializovanie virtuálneho prostredia týmto spôsobom vráti nasledovnú chybu: +> +> {% filename %}command-line{% endfilename %} +> +> Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 +> +> +> Obídeme to príkazom `virtualenv`. +> +> {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python-virtualenv +> $ virtualenv --python=python{{ book.py_version }} myvenv +> +> +> **POZNÁMKA:** Ak sa ti objaví chyba ako +> +> {% filename %}command-line{% endfilename %} +> +> E: Unable to locate package python3-venv +> +> +> potom namiesto toho spusti: +> +> {% filename %}command-line{% endfilename %} +> +> sudo apt install python{{ book.py_version }}-venv +> + + + +## Práca s virtualenvom + +Vyššie uvedený príkaz vytvorí priečinok s názvom `myvenv` (alebo akékoľvek meno si si vybrala), ktorý obsahuje naše virtuálne prostredie (v podstate kopec priečinkov a súborov). + + Virtuálne prostredie spusti príkazom: -``` -C:\Users\Meno\djangogirls> myvenv\Scripts\activate -``` +{% filename %}command-line{% endfilename %} -#### Linux a OS X + C:\Users\Meno\djangogirls> myvenv\Scripts\activate + -Virtuálne prostredie spusti príkazom: +> **POZNÁMKA:** Vo Windowse 10 sa môže vyskytnúť chyba vo Windows PowerShelli, ktorá hovorí `execution of scripts is disabled on this system`. V tomto prípade otvor ďalší Windows PowerShell s možnosťou "Spustiť ako správca". Potom skús spustiť nasledovný príkaz predtým, než spustíš svoj virtualenv: +> +> {% 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 +> + + -``` -~/djangogirls$ source myvenv/bin/activate -``` +> **POZNÁMKA:** Pre používateľky populárneho editora VS Code, ktorý má vlastný zabudovaný terminál založený na Windows PowerShell: ak chcete naďalej používať tento zabudovaný terminál, môžete spustiť nasledovný príkaz na aktiváciu virtuálneho prostredia: +> +> $ . myvenv\Scripts\activate.ps1 +> +> +> Výhoda je, že netreba skákať medzi oknami editoru a príkazovými oknami. -Nezabudni nahradiť `myvenv` názvom svojho `virtualenv`-u! + -> **POZNÁMKA:** niekedy `source` nemusí byť k dispozícii. V takom prípade vyskúšaj použiť: -> -> ~/djangogirls$ . myvenv/bin/activate -> + -To, že je `virtualenv` spustený, zistíš, keď bude príkazový riadok v konzole vyzerať takto: +Virtuálne prostredie spusti príkazom: + +{% filename %}command-line{% endfilename %} -``` -(myvenv) C:\Users\Name\djangogirls> -``` + $ source myvenv/bin/activate + -alebo: +Nezabudni nahradiť `myvenv` názvom svojho `virtualenvu`! -``` -(myvenv) ~/djangogirls$ -``` +> **POZNÁMKA:** Ak príkaz `source` nefunguje, skús namiesto neho toto: +> +> {% filename %}command-line{% endfilename %} +> +> $ . myvenv/bin/activate +> -Všimni si, že sa tam objavila predpona `(myenv)`! + + +To, že je `virtualenv` spustený, zistíš tak, že príkazový riadok v konzole bude mať na začiatku `(myenv)`. Pri práci vo virtuálnom prostredí bude `python` automaticky odkazovať na správnu verziu, takže môžeš pokojne používať `python` namiesto `python3`. OK, všetko potrebné máme prichystané. Konečne môžeme nainštalovať Django! -## Inštalácia Djanga +## Inštalácia Djanga {#django} + +Teraz, keď máš svoj `virtualenv` spustený, môžeš nainštalovať Django. + +Predtým, než to urobíme, mali by sme sa uistiť, že je nainštalovaná najnovšia verzia `pipu`, softvéru, ktorý použijeme na inštalovanie Djanga: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~$ python -m pip install --upgrade pip + + +### Inštalácia balíčkov so závislosťami + +Súbor requirements udržiava zoznam závislostí, ktoré sa nainštalujú, keď spustíš `pip install`: + +Ako prvé vytvor súbor s názvom `requirements.txt` vo vnútri tvojho priečinku `djangogirls/` pomocou editora, ktorý si si nainštalovala. V editore treba otvoriť nový súbor a uložiť ho ako `requirements.txt` v priečinku `djangogirls/`. Tvoj priečinok bude vyzerať takto: + + djangogirls + ├── myvenv + │ └── ... + └───requirements.txt + + +Do súboru `djangogirls/requirements.txt` by si mala pridať nasledujúci text: + +{% filename %}djangogirls/requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +Teraz spusti `pip install -r requirements.txt`, aby si nainštalovala Django. + +{% filename %}command-line{% endfilename %} + + (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 }} + + + + +> Ak sa objaví chyba pri spustení pipu vo Windowse, skontroluj, či cesta/názov tvojho projektu neobsahuje medzery, diakritiku alebo špeciálne znaky (napr. `C:\Users\Tvoje Meno\djangogirls`). Ak obsahuje, mala by si zvážiť použitie iného miesta, bez medzier, diakritiky a špeciálnych znakov (napríklad: `C:\djangogirls`). Vytvor nový virtualenv v tomto novom priečinku, potom odstráň starý a zopakuj vyššie uvedený príkaz. (Presunutie virtualenv priečinku samotného nebude fungovať, lebo virtualenv používa absolútne cesty.) + + -Teraz, keď máš `virtualenv` spustený, môžeš nainštalovať Django pomocou príkazu `pip`. V konzole spusti `pip install django==1.8` (všimni si, že používame dvojité rovná sa: `==`). + -``` -(myvenv) ~$ pip install django==1.8 -Downloading/unpacking django==1.8 -Installing collected packages: django -Successfully installed django -Cleaning up... -``` +> Príkazový riadok môže zamrznúť, keď sa pokúsiš nainštalovať Django. Ak sa to stane, namiesto hore uvedeného príkazu použi: +> +> {% filename %}command-line{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> -vo Windowse + -> Ak sa objaví chyba pri spustení pip vo Windowse, skontroluj, či cesta/názov tvojho projektu neobsahuje medzery, diakritiku alebo špeciálne znaky (napr. `C:\Users\Tvoje Meno\djangogirls`). Ak obsahuje, mala by si zvážiť presun na iné miesto, bez medzier, diakritiky a špeciálnych znakov (napríklad: `C:\djangogirls`). Po presune prosím vyskúšaj vyššie uvedený príkaz znova. + -na Linuxe +> Ak sa objaví chyba pri spustení pipu v Ubuntu 12.04, spusti `python -m pip install - U --force-reinstall pip`, čím sa opraví inštalácia pipu vo virtualenve. -> Ak sa objaví chyba pri spustejní pip v Ubuntu 12.04 spusti `python -m pip install - U --force-reinstall pip`, čím sa opraví inštalácia pip vo virtualenv-e. + -To je všetko! Teraz si už (konečne) pripravená vytvoriť Django aplikáciu! +To je všetko! Teraz si už (konečne) pripravená vytvoriť Django aplikáciu! \ No newline at end of file diff --git a/sk/django_models/README.md b/sk/django_models/README.md old mode 100755 new mode 100644 index c8f52509254..44cf93f06ba --- a/sk/django_models/README.md +++ b/sk/django_models/README.md @@ -1,53 +1,56 @@ # Django modely -Teraz pôjdeme vytvoriť niečo, čo bude uchovávať naše posty v blogu. Aby sme to vedeli spraviť, musíme si najskôr povedať niečo o `objektoch`. +Teraz pôjdeme vytvoriť niečo, čo bude uchovávať naše blogové príspevky. Aby sme to vedeli spraviť, musíme si najskôr povedať niečo o `objektoch`. ## Objekty -V programovaní sa používa pojem `objektovo orientované programovanie`. Myšlienka spočíva v tom, že namiesto vypisovania nudných sekvencií programátorských príkazov môžeme veci modelovať a definovať ako majú navzájom komunikovať. +V programovaní sa používa pojem `objektovo orientované programovanie`. Myšlienka spočíva v tom, že namiesto vypisovania nudných sekvencií programátorských príkazov môžeme veci modelovať a definovať, ako majú navzájom komunikovať. -Takže čo je to objekt? Je to zbierka vlastností a akcií. Znie to čudne, ale ukážeme si príklad. +Takže, čo je to objekt? Je to zbierka vlastností a akcií. Znie to čudne, ale ukážeme si príklad. -Ak chceme modelovať mačku, vytvoríme objekt `Macka`, ktorá má nejaké vlastnosti, napríklad: `farba`, `vek`, `nalada` (t. j. dobra, zla, ospala ;)), a `majitel` (ktorý je objektom `Osoba` alebo možno v prípade túlavej mačky bude táto vlastnosť prázdna). +Ak chceme namodelovať mačku, vytvoríme objekt `Macka`, ktorá má nejaké vlastnosti, napríklad: `farba`, `vek`, `nalada` (t. j. dobrá, zlá, ospalá ;)), a `majitelka` (ktorý je objektom `Osoba`, alebo možno v prípade túlavej mačky bude táto vlastnosť prázdna). -Ďalej má `Macka` niekoľko akcií: `priast`, `skrabat` alebo `krmit` (v ktorej dáme mačke nejaké `MacacieZradlo`, ktoré by mohlo byť samostatným objektom s vlastnosťami, t.j. `chut`). +Ďalej má `Macka` niekoľko akcií: `priast`, `skriabat` alebo `krmit` (v ktorej dáme mačke nejaké `MacacieZradlo`, ktoré by mohlo byť samostatným objektom s vlastnosťami, napr. `chut`). -``` -Macka --------- -farba -vek -nalada -majitel -priast() -skrabat() -krmit(mac_zradlo) - - -MacacieZradlo --------- -chut -``` + Macka + -------- + farba + vek + nalada + majitelka + priast() + skriabat() + krmit(mac_zradlo) + + + MacacieZradlo + -------- + chut + -Takže v podstate myšlienka je popísať reálne veci kódom pomocou vlastností (ktorým hovoríme `vlastnosti objektu/object properties`) a akcií (tie nazývame `metódy`). + MacacieZradlo + -------- + chut + -Ako teda budeme modelovať blog post? Chceme vytvoriť blog, však? +Takže v podstate hlavná myšlienka je popísať reálne veci kódom pomocou vlastností (ktorým hovoríme `vlastnosti objektu/object properties`) a akcií (tie nazývame `metódy`). -Musíme odpovedať na otázku: Čo je vlastne blog post? Aké vlastnosti by mal mať? +Ako teda budeme modelovať blogový príspevok? Chceme predsa vytvoriť blog, nie? -No, náš blog post určite potrebuje nejaký text s obsahom a titulkom, nie? Bolo by tiež fajn vedieť, kto ho napísal - takže potrebujeme autora. A nakoniec, chceme vedieť, kedy bol post vytvorený a zverejnený. +Musíme odpovedať na otázku: Čo je vlastne blogový príspevok? Aké vlastnosti by mal mať? -``` -Post --------- -title -text -author -created_date -published_date -``` +No, náš blogový príspevok určite potrebuje nejaký text s obsahom a titulkom, nie? Bolo by tiež fajn vedieť, kto ho napísal - takže potrebujeme autorku či autora. A nakoniec, chceme vedieť, kedy bol príspevok vytvorený a zverejnený. + + Post + -------- + title + text + author + created_date + published_date + -Čo všetko môžeme s blog postom robiť? Bolo by dobré mať nejakú `metódu`, ktorá post publikuje, však? +Čo všetko môžeme s blogovým príspevkom robiť? Bolo by dobré mať nejakú `metódu`, ktorá príspevok publikuje, však? Takže budeme potrebovať metódu `publish`. @@ -55,44 +58,58 @@ Keďže už vieme, čo chceme dosiahnuť, začnime tvoriť model v Djangu! ## Django model -Keďže už vieme, čo je objekt, môžeme vytvoriť Django model pre náš blog post. +Keďže už vieme, čo je objekt, môžeme vytvoriť Django model pre náš blogový príspevok. -Model v Djangu je špeciálny typ objektu - je uložený v `databáze`. Databáza je súbor údajov. Je to miesto, kde budeš ukladať informácie o užívateľoch, príspevkoch na blogu, atď. Na ukladanie údajov budeme používať databázu SQLite. Je to štandardný východzí databázový adaptér v Djangu -- nateraz nám bude stačiť. +Model v Djangu je špeciálny typ objektu - je uložený v `databáze`. Databáza je súbor údajov. Je to miesto, kde budeš ukladať informácie o užívateľoch/užívateľkách, blogových príspevkoch atď. Na ukladanie údajov budeme používať databázu SQLite. Je to prednastavený databázový adaptér v Djangu -- nateraz nám bude stačiť. Model v databáze si môžeš predstaviť ako tabuľku so stĺpcami (polia) a riadkami (dáta). ### Vytvorenie aplikácie -Aby sme mali všetko pekne upratané, vytvoríme vo vnútri nášho projektu samostatnú aplikáciu. Je dobré mať všetko zorganizované hneď od začiatku. Aby sme vytvorili aplikáciu, musíš v konzole spustiť nasledujúci príkaz (v adresári `djangogirls`, kde sa nachádza súbor `manage.py`): +Aby sme mali všetko pekne upratané, vytvoríme vo vnútri nášho projektu samostatnú aplikáciu. Je dobré mať všetko zorganizované hneď od začiatku. Aby sme vytvorili aplikáciu, musíme v konzole spustiť nasledujúci príkaz (v priečinku `djangogirls`, kde sa nachádza súbor `manage.py`): -``` -~/djangogirls$ (myvenv) python manage.py startapp blog -``` +{% filename %}macOS a Linux:{% endfilename %} -Uvidíš, že bude vytvorený nový adresár `blog`, ktorý obsahuje množstvo súborov. Adresáre a súbory v našom projekte by mali vyzerať takto: + (myvenv) ~/djangogirls$ python manage.py startapp blog + -``` -djangogirls -├── mysite -| __init__.py -| settings.py -| urls.py -| wsgi.py -├── manage.py -└── blog - ├── migrations - | __init__.py - ├── __init__.py - ├── admin.py - ├── models.py - ├── tests.py - └── views.py -``` +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + + +Uvidíš, že pribudne nový priečinok `blog`, ktorý obsahuje množstvo súborov. Priečinky a súbory v našom projekte by mali vyzerať takto: -Po vytvorení aplikácie tiež musíš Djangu povedať, že by ju mal použiť. To urobíme v súbore `mysite/settings.py`. Musíme nájsť `INSTALLED_APPS` a pridať riadok obsahujúci `'blog'` tesne pred uzatváraciu zátvorku`)`. Takže výsledok nášho snaženia bude vyzerať takto: + djangogirls + ├── blog + │   ├── admin.py + │   ├── apps.py + │   ├── __init__.py + │   ├── migrations + │   │   └── __init__.py + │   ├── models.py + │   ├── tests.py + │   └── views.py + ├── db.sqlite3 + ├── manage.py + ├── mysite + │   ├── asgi.py + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + + + +Po vytvorení aplikácie tiež musíš Djangu povedať, že ju má použiť. To spravíme v súbore `mysite/settings.py` - otvor ho vo svojom editore. Musíme nájsť `INSTALLED_APPS` a pridať riadok `'blog',` tesne pred uzatváraciu zátvorku `]`. Takže výsledok nášho snaženia bude vyzerať takto: + +{% filename %}mysite/settings.py{% endfilename %} ```python -INSTALLED_APPS = ( +INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -100,28 +117,29 @@ INSTALLED_APPS = ( 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', -) +] ``` -### Vytvorenie modelu blog postu +### Vytvorenie modelu príspevku + +V súbore `blog/models.py` definujeme všetky objekty, ktoré sa nazývajú `modely` - na tomto mieste definujeme náš príspevok. -V súbore `blog/models.py` definujeme všetky objekty, ktoré sa nazývajú `modely` - na tomto mieste definujeme náš blog post. +Otvor `blog/models.py` v editore, všetko z neho odstráň a napíš nasledovný kód: -Otvor `blog/models.py`, všetko z neho odstráň a napíš tento kód: +{% filename %}blog/models.py{% endfilename %} ```python +from django.conf import settings from django.db import models from django.utils import timezone class Post(models.Model): - author = models.ForeignKey('auth.User') + 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() @@ -131,53 +149,59 @@ class Post(models.Model): return self.title ``` -> Dvakrát skontroluj, či si použila 2 podčiarkovníky (`_`) na oboch stranách `str`. Táto konvencia sa v Pythone často používa a niekedy sa tomu hovorí "dunder" (skratka pre anglické Double-UNDERscore). +> Dvakrát skontroluj, či si použila 2 podčiarkovníky (`_`) na oboch stranách `str`. Táto konvencia sa v Pythone často používa a niekedy sa tomu hovorí "dunder" (skratka pre anglické double-underscore). -Vyzerá to asi strašidelne. Ale neboj sa, vysvetlíme si, čo tieto riadky znamenajú! +Vyzerá to strašidelne, nie? Ale neboj sa, vysvetlíme si, čo tieto riadky znamenajú! -Všetky riadky začínajúce s `from` alebo `import` pridávajú časti z iných súborov. Takže namiesto kopírovania rovnakých vecí v každom súbore môžeme zahrnúť niektoré časti pomocou `from ... import ...`. +Všetky riadky začínajúce na `from` alebo `import` pridávajú časti z iných súborov. Takže namiesto kopírovania tých istých vecí v každom súbore môžeme vložiť niektoré časti pomocou `from ... import ...`. `class Post(models.Model):` - tento riadok definuje náš model (je to `objekt`). -* `class` je špeciálne kľúčové slovo, ktoré naznačuje, že definujeme objekt. -* `Post` je meno nášho modelu. Môžeme mu dať iný názov (ale musíme sa vyhnúť špeciálnym a prázdnym znakom). Názov triedy vždy začnite písmenami. -* `models.Model` znamená, že Post je Django Model, takže Django vie, že by mal byť uložený v databáze. +- `class` je špeciálne kľúčové slovo, ktoré naznačuje, že definujeme objekt. +- `Post` je meno nášho modelu. Môžeme mu dať iný názov (ale musíme sa vyhnúť špeciálnym znakom a medzerám). Názov triedy vždy začni písmenami. +- `models.Model` znamená, že Post je djangový model, takže Django vie, že by mal byť uložený v databáze. -Teraz zadefinujeme vlastnosti, o ktorých sme hovorili: `title` (titulka), `text`, `created_date` (dátum vytvorenia), `published_date` (dátum zverejnenia) a `author` (autor). Na to ale musíme zadefinovať typ každého poľa (Je to text? Číslo? Dátum? Vzťah k inému objektu, t.j. používateľovi?). +Teraz zadefinujeme vlastnosti, o ktorých sme hovorili: `title` (titulka), `text`, `created_date` (dátum vytvorenia), `published_date` (dátum zverejnenia) a `author` (autor(ka)). Na to ale musíme zadefinovať typ každého poľa (Je to text? Číslo? Dátum? Vzťah k inému objektu, napr. objektu User?) -* `modely. CharField` - takto môžeš definovať text s obmedzeným počtom znakov. -* `models.TextField` - toto je pre dlhé texty bez obmedzenia. To znie ideálne pre blogový príspevok, nie? -* `models.DateTimeField` - dátum a čas. -* `models.ForeignKey` - odkaz na iný model. +- `models.CharField` - takto môžeš definovať text s obmedzeným počtom znakov. +- `models.TextField` - toto je pre dlhé texty bez obmedzenia. To znie ideálne pre blogový príspevok, nie? +- `models.DateTimeField` - toto je dátum a čas. +- `models.ForeignKey` - toto je odkaz na iný model. -Nebudeme si tu vysvetľovať každý kúsok kódu, pretože by to zabralo príliš veľa času. Ak chceš vedieť viac o poliach modelu a definovaní ďalších vecí okrem tých, čo sme popísali vyššie, skús sa pozrieť do dokumentácie Djanga (https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-types). +Nebudeme si tu vysvetľovať každý kúsok kódu, pretože by to zabralo príliš veľa času. Ak chceš vedieť viac o modelových poliach a definovaní ďalších vecí okrem tých, čo sme popísali vyššie, skús sa pozrieť do dokumentácie Djanga (https://docs.djangoproject.com/en/5.1/ref/models/fields/#field-types). -A čo `def publish(self):`? To je presne tá metóda `publish`, o ktorej sme hovorili predtým. `def` znamená, že ide o funkciu/metódu a `publish` je názov metódy. Názov metódy môžeš zmeniť, ak chceš. Pravidlo pre názvy je, že používame malé písmená a podčiarkovníky namiesto medzier. Napríklad metóda, ktorá vypočíta priemernú cenu by sa mohla nazývať `pocitaj_priemernu_cenu`. +A čo `def publish(self):`? To je presne tá metóda `publish`, o ktorej sme hovorili predtým. `def` znamená, že ide o funkciu/metódu, a `publish` je jej názov. Názov metódy môžeš zmeniť, ak chceš. Pravidlo pre názvy metód je, že používame malé písmená a podčiarkovníky namiesto medzier. Napríklad metóda, ktorá vypočíta priemernú cenu by sa mohla nazývať `pocitaj_priemernu_cenu`. -Metódy často niečo vracajú (angl. `return`). Príklad nájdeš napríklad v metóde `__str__`. V tomto prípade, keď zavoláme `__str__()`, dostaneme text (**string**) s názvom postu. +Metódy často niečo vracajú (`return`). Príklad nájdeš napríklad v metóde `__str__`. V tomto prípade, keď zavoláme `__str__()`, dostaneme text (**string**) s názvom príspevku. -Ak čokoľvek nie je jasné, neváhaj a spýtaj sa mentora! Je nám jasné, že je to komplikované, najmä ak sa učíš, čo sú objekty a funkcie súčasne. Ale dúfame, že teraz už to vyzerá trochu menej magicky! +Tiež si všimni, že `def publish(self):` a `def __str__(self):` sú odsadené vo vnútri našej triedy. Keďže Python je citlivý na medzery, musíme odsadiť naše metódy vo vnútri triedy. Inak metódy nebudú patriť do triedy a môže dojsť k neočakávanému správaniu. + +Ak čokoľvek nie je jasné, neváhaj a spýtaj sa mentora či mentorky! Vieme, že je to komplikované, najmä ak sa učíš, čo sú objekty a funkcie súčasne. Ale dúfame, že teraz už to vyzerá trochu menej magicky! ### Vytváranie tabuliek pre modely v databáze -Posledným krokom je pridať náš nový model do databázy. Najprv musíme Djangu dať vedieť, že sme urobili nejaké zmeny v našom modeli (práve sme ho vytvorili!). Napíš `python manage.py makemigrations blog`. Bude to vyzerať takto: +Posledným krokom je pridať náš nový model do databázy. Najprv musíme Djangu dať vedieť, že sme urobili nejaké zmeny v našom modeli. (Práve sme ho vytvorili!) Choď do konzoly a zadaj `python manage.py makemigrations blog`. Bude to vyzerať takto: -``` -(myvenv) ~/djangogirls$ python manage.py makemigrations blog -Migrations for 'blog': - 0001_initial.py: - - Create model Post -``` +{% filename %}command-line{% endfilename %} -Django pre nás pripravil migračný súbor, ktorý musíme aplikovať na našu databázu. Napíš `python manage.py migrate blog` a výstup by mal byť: + (myvenv) ~/djangogirls$ python manage.py makemigrations blog + Migrations for 'blog': + blog/migrations/0001_initial.py + + - Create model Post + -``` -(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 -``` +**Poznámka:** Nezabudni uložiť súbory, ktoré upravuješ. Inak počítač spustí starú verziu, ktorá môže skončiť chybou. + +Django pripravil migračný súbor, ktorý musíme aplikovať na našu databázu. Napíš `python manage.py migrate blog` a výstup by mal byť: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py migrate blog + Operations to perform: + Apply all migrations: blog + Running migrations: + Applying blog.0001_initial... OK + -Hurá! Náš Post model je už v databáze! Bolo by fajn ho vidieť, nie? Prejdi na nasledujúcu kapitolu a uvidíš ako vyzerá tvoj Post! +Hurá! Náš model Post je už v databáze! Bolo by fajn ho vidieť, nie? Prejdi na nasledujúcu kapitolu a uvidíš, ako vyzerá tvoj Post! \ No newline at end of file diff --git a/sk/django_orm/README.md b/sk/django_orm/README.md old mode 100755 new mode 100644 index 3a588d17b63..5eac91986a0 --- a/sk/django_orm/README.md +++ b/sk/django_orm/README.md @@ -1,61 +1,72 @@ -# Django ORM a QuerySety +# Django ORM (QuerySety) V tejto kapitole sa naučíš, ako sa Django pripája k databáze a ukladá do nej údaje. Poďme na to! ## Čo je QuerySet? -QuerySet je v podstate zoznam objektov daného modelu. QuerySet ti umožňuje čítať dáta z databázy, filtrovať ich a zoraďovať. +QuerySet je v podstate zoznam objektov daného modelu. QuerySet ti umožňuje čítať dáta z databázy, filtrovať a zoraďovať ich. -Najjednoduchšie bude ukázať si to na príklade. Vyskúšajme si to. +Najjednoduchšie bude ukázať si to na príklade. Vyskúšajme si to, čo povieš? -## Django shell (konzola) +## Django konzola -Otvor svoju lokálnu konzolu (nie na PythonAnywhere) a napíš tento príkaz: +Otvor si lokálnu konzolu (nie na PythonAnywhere) a napíš tento príkaz: -``` -(myvenv) ~/djangogirls$ python manage.py shell -``` +{% filename %}command-line{% endfilename %} -Malo by to mať tento efekt: + (myvenv) ~/djangogirls$ python manage.py shell + -``` +Toto by sa ti malo zobraziť: + +{% filename %}command-line{% endfilename %} + +```python (InteractiveConsole) >>> ``` -Teraz si v interaktívnej Django konzole. Je to ako konzola Pythonu, ale s trochou Django mágie :). Môžeš tu, samozrejme, použiť všetky príkazy Pythonu. +Teraz si v interaktívnej Django konzole. Je to ako konzola Pythonu, ale s trochou Django mágie. :) Môžeš v nej používať všetky pythonové príkazy. ### Všetky objekty -Skúsme najskôr zobraziť všetky naše príspevky. To môžeš urobiť týmto príkazom: +Skúsme najskôr zobraziť všetky naše príspevky. To sa robí nasledovným príkazom: -``` +{% filename %}command-line{% endfilename %} + +```python >>> Post.objects.all() Traceback (most recent call last): File "", line 1, in NameError: name 'Post' is not defined ``` -Ups! Objavila sa chybová hláška! Hovorí nám, že žiaden Post (príspevok) neexistuje. To je správne - zabudli sme ho totiž najskôr naimportovať! +Ups! Objavila sa chybová hláška. Hovorí nám, že nič také ako Post neexistuje. To dáva zmysel - zabudli sme ho totiž najskôr naimportovať! -``` +{% filename %}command-line{% endfilename %} + +```python >>> from blog.models import Post ``` -Je to jednoduché: importujeme model `Post` z `blog.models`. Skúsme teda znova zobraziť všetky príspevky: +Naimportujeme model `Post` z `blog.models`. Skúsme teda znova zobraziť všetky príspevky: -``` +{% filename %}command-line{% endfilename %} + +```python >>> Post.objects.all() -[, ] +, ]> ``` -Je to zoznam príspevkov, ktoré sme už predtým vytvorili! Vytvorili sme ich pomocou Django administrátorského rozhrania. No radi by sme vytvorili nové príspevky pomocou Pythonu, tak ako na to? +Je to zoznam príspevkov, ktoré sme vytvorili dávnejšie! Vytvorili sme ich pomocou Django administrátorského rozhrania. No radi by sme vytvorili nové príspevky pomocou Pythonu, tak ako na to? ### Vytvorenie objektu -Takto vytvoríš nový Post objekt v databáze: +Takto vytvoríš nový objekt typu Post v databáze: -``` +{% filename %}command-line{% endfilename %} + +```python >>> Post.objects.create(author=me, title='Sample title', text='Test') ``` @@ -63,118 +74,148 @@ Chýba nám však jedna prísada: `me`. Ako autorku musíme vložiť inštanciu Najskôr naimportujme User model: -``` +{% filename %}command-line{% endfilename %} + +```python >>> from django.contrib.auth.models import User ``` -Akých užívateľov máme v našej databáze? Skús toto: +Akých užívateľov a užívateľky máme v našej databáze? Skús toto: -``` +{% filename %}command-line{% endfilename %} + +```python >>> User.objects.all() -[] +]> ``` -To je superuser, ktorého sme už vytvorili predtým. Teraz získajme inštanciu tohto užívateľa: +Toto je superuser, ktorého sme vytvorili dávnejšie! Poďme ho dostať ako inštanciu (uprav tento riadok tak, aby obsahoval tvoje vlastné užívateľské meno): + +{% filename %}command-line{% endfilename %} ```python -ja = User.objects.get(username='ola') +>>> me = User.objects.get(username='ola') ``` -Ako vidíš, teraz získame (angl. `get`) užívateľa (angl. `User`) s užívateľským meno (angl. `username`), ktoré sa rovná 'ola'. Aké elegantné! Samozrejme musíš si to upraviť na svoje meno. +Ako môžeš vidieť, teraz sme dostali (`get`) `Usera` s užívateľským menom (`username`) 'ola'. Môže byť! Teraz už konečne môžeme vytvoriť náš prvý príspevok: -``` ->>> Post.objects.create(author=ja, title='titulka', text='Test') +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') + ``` -Hurá! Chceš si overiť, či to fungovalo? +Hurá! Chceš si overiť, či to zabralo? -``` +{% filename %}command-line{% endfilename %} + +```python >>> Post.objects.all() -[, , ] +, , ]> ``` Je to tam, jeden príspevok v zozname pribudol! -### Pridaj viac príspevkov +### Pridanie ďalších príspevkov -Teraz sa môžeš trochu pobaviť a pridať pár ďalších postov, aby si videla, ako to funguje. Pridaj dva-tri ďalšie príspevky a potom poďme na ďalšiu časť. +Teraz sa môžeš trochu zabaviť a pridať pár ďalších príspevkov, aby si si vyskúšala, ako to funguje. Pridaj dva-tri ďalšie príspevky a potom poďme na ďalšiu časť. ### Filtrovanie objektov -Dôležitou vlastnosťou QuerySetov je možnosť ich filtrovať. Povedzme, že chceme nájsť všetky príspevky, ktorých autorom je užívateľ (User) ola. Použijeme `filter` namiesto `all` v príkaze `Post.objects.all()`. V zátvorkách definujeme jednu alebo viac podmienok, ktoré majú byť splnené príspevkom, aby skončil v tvojom querysete. V našom prípade je to `author`, ktorý sa rovná `ja`. V Djangu to napíšeš takto: `author=ja`. Náš kúsok kódu bude teraz vyzerať takto: +Dôležitou vlastnosťou QuerySetov je možnosť ich filtrovať. Povedzme, že chceme nájsť všetky príspevky, ktorých autorkou je užívateľka (User) ola. Použijeme `filter` namiesto `all` v príkaze `Post.objects.all()`. V zátvorkách definujeme jednu alebo viac podmienok, ktoré má príspevok spĺňať, aby skončil v našom querysete. V našom prípade je to `author`, ktorý sa rovná `me`. V Djangu to napíšeš takto: `author=me`. Náš kúsok kódu bude teraz vyzerať takto: -``` ->>> Post.objects.filter(author=ja) -[, , , ] +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(author=me) +, , , ]> ``` -Alebo neskúsime vyhľadať všetky príspevky, ktoré obsahujú slovo 'titulka' v políčku `title`? +Alebo možno chceme vyhľadať všetky príspevky, ktoré obsahujú slovo 'title' v poli `title`? -``` ->>> Post.objects.filter(title__contains='titulka') -[, ] +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(title__contains='title') +, ]> ``` > **Poznámka** Medzi `title` a `contains` sú dva podčiarkovníky (`_`). Django ORM používa túto syntax, aby oddelil názvy polí ("title") a operácie či filtre ("contains"). Ak použiješ iba jeden podčiarkovník, dostaneš chybu "FieldError: Cannot resolve keyword title_contains". -Môžeš tiež získať zoznam všetkých publikovaných postov. To urobíme vyfiltrovaním príspevkov, ktoré majú nastavený `published_date` v minulosti: +Môžeš tiež získať zoznam všetkých publikovaných príspevkov. To urobíme vyfiltrovaním príspevkov, ktorých `published_date` je v minulosti: -``` +{% filename %}command-line{% endfilename %} + +```python >>> from django.utils import timezone >>> Post.objects.filter(published_date__lte=timezone.now()) -[] + ``` -Bohužiaľ, príspevok, ktorý sme pridali z konzoly Pythonu, ešte nie je publikovaný. To môžeme zmeniť! Najskôr získaj inštanciu postu, ktorý chceme publikovať: +Bohužiaľ, príspevok, ktorý sme pridali z konzoly Pythonu, ešte nie je publikovaný. To môžeme zmeniť! Najskôr získaj inštanciu príspevku, ktorý chceme publikovať: -``` +{% filename %}command-line{% endfilename %} + +```python >>> post = Post.objects.get(title="Sample title") ``` -A potom ho publikuj pomocou našej metódy `publish`! +A potom ho zverejni pomocou našej metódy `publish`: -``` +{% filename %}command-line{% endfilename %} + +```python >>> post.publish() ``` Teraz skús získať zoznam publikovaných postov znova (stlač šípku hore trikrát a stlač `enter`): -``` +{% filename %}command-line{% endfilename %} + +```python >>> Post.objects.filter(published_date__lte=timezone.now()) -[] +]> ``` -### Radenie objektov +### Zoradenie objektov QuerySety tiež umožňujú zoradiť zoznamy objektov. Skúsme ich zoradiť podľa dátumu vytvorenia (pole `created_date`): -``` +{% filename %}command-line{% endfilename %} + +```python >>> Post.objects.order_by('created_date') -[, , , ] +, , , ]> ``` -Môžeme ich tiež zoradiť naopak pridaním `-` na začiatok: +Poradie môžeme vymeniť pridaním `-` na začiatok: -``` +{% filename %}command-line{% endfilename %} + +```python >>> Post.objects.order_by('-created_date') -[, , , ] +, , , ]> ``` -### Reťazenie QuerySetov +### Zložité požiadavky pomocou reťazenia metód -QuerySety môžeš dokonca kombinovať pomocou **reťazenia**: +Ako sme videli, niektoré metódy na `Post.objects` vracajú QuerySet. Tie isté metódy môžeš zavolať na ďalšom QuerySete a vrátia ti nový QuerySet. Týmto môžeš kombinovať ich efekt **reťazením**: -``` +```python >>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> ``` -To je skutočne mocný nástroj, s ktorým môžeš písať dosť komplexné požiadavky (queries). +To je skutočne silný nástroj, vďaka ktorému môžeš písať pomerne komplexné požiadavky (queries). -Super! Teraz už si pripravená na ďalšiu časť! Shell zatvoríš príkazom: +Super! Teraz si pripravená na ďalšiu časť! Django konzolu zatvoríš príkazom: -``` +{% filename %}command-line{% endfilename %} + +```python >>> exit() $ -``` +``` \ No newline at end of file diff --git a/sk/django_start_project/README.md b/sk/django_start_project/README.md old mode 100755 new mode 100644 index cedf1ce9682..bf9a9778588 --- a/sk/django_start_project/README.md +++ b/sk/django_start_project/README.md @@ -1,144 +1,266 @@ # Tvoj prvý Django projekt! -> Časť tejto kapitoly je založená na tutoriáli Geek Girls Carrots (http://django.carrots.pl/). -> -> Časti tejto kapiolty sú založená na [django-marcador tutorial][1] pod licenciou Creative Commons Attribution-ShareAlike 4.0 International License. Tutoriál django-marcador je autorsky chránený Markusom Zapke-Gründemannom et al. - - [1]: http://django-marcador.keimlink.de/ +> Časť tejto kapitoly je založená na tutoriáli Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> +> Časti tejto kapitoly sú založené na [django-marcador tutorial](http://django-marcador.keimlink.de/) pod licenciou Creative Commons Attribution-ShareAlike 4.0 International License. Tutoriál django-marcador je autorsky chránený Markusom Zapke-Gründemannom et al. Vytvoríme jednoduchý blog! -Prvý krok je vytvoriť nový Django projekt. To v podstate znamená, že spustíme pár skriptov, poskytovaných Djangom, ktoré pre nás vytvoria kostru Django projektu. Je to len pár zložiek a súborov, ktoré použijeme neskôr. +Prvý krok je vytvoriť nový Django projekt. To v podstate znamená, že spustíme pár skriptov, poskytovaných Djangom, ktoré pre nás vytvoria kostru Django projektu. Je to len pár priečinkov a súborov, ktoré použijeme neskôr. -Mená niektorých súborov a zložiek sú pre Django veľmi dôležité. Súbory, ktoré teraz vytvoríme, by si nemala premenovať. Ich presúvanie na iné miesto taktiež nie je dobrý nápad. Django potrebuje udržovať určitú štruktúru, aby bol schopný nájsť dôležité veci. +Mená niektorých súborov a priečinkov sú pre Django veľmi dôležité. Súbory, ktoré teraz vytvoríme, by si nemala premenovať. Presúvať ich na iné miesto taktiež nie je dobrý nápad. Django potrebuje udržovať určitú štruktúru, aby bolo schopné nájsť dôležité veci. -> Nezabudni všetko spúšťať vo virtualenv. Pokiaľ vo svojej konzole nevidíš prefix `(myvenv)` musíš aktivovať virtualenv. Ako na to bolo vysvetlené v kapitole **Inštalácia Django** v časti **Práca s virtualenv**. Pokiaľ napíšeš `myvenv\Scripts\activate` na Windowsoch, alebo `source myvenv/bin/activate` na Mac OS / Linux, malo by všetko fungovať. +> Nezabudni všetko spúšťať vo virtualenve. Pokiaľ vo svojej konzole nevidíš predponu `(myenv)`, musíš aktivovať virtualenv. Ako na to bolo vysvetlené v kapitole **Inštalácia Djanga** v časti **Práca s virtualenvom**. Pokiaľ napíšeš `myvenv\Scripts\activate` na Windowse alebo `source myvenv/bin/activate` na macOS alebo Linuxe, malo by všetko fungovať. -Vo svojej MacOS alebo Linux konzole spusti tento príkaz; **nezabudni pridať bodku `.` na konci**: + -``` -(myvenv) ~/djangogirls$ django-admin startproject mysite . -``` +Vo svojej macOS alebo Linux konzole spusti tento príkaz. **Nezabudni pridať bodku `.` na konci!** -Na Windowsoch: **nezabudni pridať bodku `.` na konci**: +{% filename %}command-line{% endfilename %} -``` -(myvenv) C:\Users\Name\djangogirls> django-admin.py startproject mysite . -``` + (myvenv) ~/djangogirls$ django-admin startproject mysite . + -> Bodka `.` je dôležitá, pretože hovorí skriptom, aby nainštalovali Django v tvojej aktuálnej zložke (pre ktorú je bodka `.` skratkou) -> -> **Poznámka** Pri písaní predchádzajúcich príkazov nezabudni, že píšeš len časti, ktoré začínajú `django-admin` alebo `django-admin.py`. `(myvenv) ~/djangogirls$` a `(myvenv) C:\Users\Name\djangogirls>` sú len príkladom cesty, kam budeš zadávať svoje príkazy. +> Bodka `.` je dôležitá, pretože hovorí skriptu, aby nainštaloval Django v tvojom aktuálnom priečinku (pre ktorý je bodka `.` skratkou). +> +> **Poznámka** Pri písaní predchádzajúceho príkazu nezabudni, že píšeš len časť, ktorá začína `django-admin`. Časť `(myvenv) ~/djangogirls$` je len príkladom promptu, kam budeš zadávať svoje príkazy. -`django-admin.py` je skript, ktorý pre teba vytvorí zložky a súbory. Momentálne by si mala mať štruktúru adresárov, ktorá vyzerá takto: + -``` -djangogirls -├───manage.py -└───mysite - settings.py - urls.py - wsgi.py - __init__.py -``` + + +Vo Windowse spusti tento príkaz. **(Nezabudni pridať bodku `.` na konci)**: + +{% filename %}command-line{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . + + +> Bodka `.` je dôležitá, pretože hovorí skriptu, aby nainštaloval Django v tvojom aktuálnom priečinku (pre ktorý je bodka `.` skratkou). +> +> **Poznámka** Pri písaní predchádzajúceho príkazu nezabudni, že píšeš len časť, ktorá začína `django-admin.exe`. Časť `(myvenv) C:\Users\Name\djangogirls>` je len príkladom promptu, kam budeš zadávať svoje príkazy. + + + +`django-admin.py` je skript, ktorý pre teba vytvorí priečinky a súbory. Momentálne by si mala mať štruktúru priečinkov, ktorá vyzerá takto: + + djangogirls + ├── manage.py + ├── mysite + │   ├── asgi.py + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + + +> **Poznámka**: v štruktúre priečinkov uvidíš aj adresár `myvenv`, ktorý sme vytvorili dávnejšie. `manage.py` je skript, ktorý pomáha so správou stránky. Okrem iného budeme vďaka nemu môcť spustiť na našom počítači webový server, bez toho, aby sme inštalovali čokoľvek iné. Súbor `settings.py` obsahuje konfiguráciu tvojej webovej stránky. -Pamätáš, keď sme rozprávali o doručovateľovi listov, ktorý zisťuje kam doručiť list? `urls.py` obsahuje zoznam vzorov, ktoré používa `urlresolver`. +Pamätáš, keď sme sa rozprávali o poštárke, ktoré zisťuje, kam doručiť list? `urls.py` obsahuje zoznam vzorov, ktoré používa `urlresolver`. -Zatiaľ ignorujme ostatné súbory, keďže ich teraz aj tak nebudeme meniť. Jediná vec na ktorú netreba zabudnúť je, že ich nesmieš omylom zmazať! +Zatiaľ ignorujme ostatné súbory, keďže ich teraz aj tak nebudeme meniť. Jediná vec, na ktorú netreba zabudnúť, je, že ich nesmieš omylom zmazať! ## Zmena nastavení Spravme pár zmien v `mysite/settings.py`. Otvor súbor v editore kódu, ktorý si si nainštalovala predtým. -Bolo by dobré mať na našej stránke správny čas. Choď na [zoznam časových pásiem na wikipedii][2] a skopíruj svoje časové pásmo (TZ). (napr. `Europe/Bratislava`) +**Poznámka**: Pamätaj, že `settings.py` je obyčajný súbor, ako každý iný. Môžeš ho otvoriť z editoru pomocou možnosti "Súbor -> Otvoriť" v menu. Malo by sa ti zobraziť štandardné okno, v ktorom vyhľadáš svoj `settings.py` súbor a označíš ho. Prípadne môžeš ísť do priečinku djangogirls na pracovnej ploche a kliknúť na súbor pravým tlačidlom myši. Potom vyber editor kódu zo zoznamu. Výber editora je dôležitý, pretože môžeš mať nainštalované iné programy, ktoré dokážu tento súbor otvoriť, ale nedovolia ti ho upravovať. + +Bolo by dobré mať na našej stránke správny čas. Choď na [zoznam časových pásiem na Wikipédii](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) a skopíruj svoje časové pásmo (TZ) (napr. `Europe/Bratislava`). - [2]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +V súbore `settings.py` nájdi riadok, ktorý obsahuje `TIME_ZONE`, a uprav ho tak, aby obsahoval tvoje časové pásmo. Napríklad: -V súbore settings.py, nájdi riadok, ktorý obsahuje `TIME_ZONE` a uprav ho tak, aby obsahoval tvoje časové pásmo: +{% filename %}mysite/settings.py{% endfilename %} ```python TIME_ZONE = 'Europe/Bratislava' ``` -Prípadne zvoľ iné pásmo ako "Europe/Bratislava", ak je to potrebné +Jazykový kód sa skladá z jazyka, napr. `en` pre angličtinu alebo `sk` pre slovenčinu, a kódu krajiny, napr. `de` pre Nemecko alebo `ch` pre Švajčiarsko. Ak angličtina nie je tvoj materinský jazyk, môžeš pridať nasledovné, ak chceš zmeniť nápisy na tlačidlách a pripomienkach do svojho jazyka. Ak to spravíš, bude napríklad tlačidlo "Cancel" preložené do jazyka, ktorý tu definuješ. [Django má zabudovaných veľa prekladov](https://docs.djangoproject.com/en/5.1/ref/settings/#language-code). -Tiež budeme musieť pridať cestu k statickým súborom (všetko o statických súboroch a CSS sa dozvieme neskôr v ďalších kapitolách tutorialu). Prejdi dole na *koniec* súboru a hneď pod záznam `STATIC_URL` pridaj nový s názvom `STATIC_ROOT`: +Ak chceš iný jazyk, zmeň jazykový kód tým, že zmeníš nasledujúci riadok: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +LANGUAGE_CODE = 'de-ch' +``` + +Budeme tiež musieť pridať cestu pre statické súbory. (O statických súboroch a CSS si povieme viac neskôr.) Choď na *koniec* súboru a rovno pod `STATIC_URL` pridaj `STATIC_ROOT`: + +{% filename %}mysite/settings.py{% endfilename %} ```python STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') +STATIC_ROOT = BASE_DIR / 'static' +``` + +Keď `DEBUG` je `True` a `ALLOWED_HOSTS` je prázdne, host sa validuje voči `['localhost', '127.0.0.1', '[::1]']`. Toto sa nebude zhodovať s naším hostname na PythonAnywhere, keď nasadíme našu aplikáciu, preto zmeníme nasledovné nastavenie: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +ALLOWED_HOSTS = ['127.0.0.1', '.pythonanywhere.com'] ``` +> **Poznámka**: Ak používaš Chromebook, pridaj nasledovný riadok na koniec súboru settings.py: `MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'` +> +> Ak používaš Cloud 9, tiež pridaj `.amazonaws.com` do `ALLOWED_HOSTS`. +> +> Ak hostuješ svoj projekt na `Glitch.com`, mali by sme ochrániť tajný kľúč, ktorý by mal zostať skrytý (inak by ho mohol vidieť každý, kto použije tvoj projekt): +> +> - Najprv si musíme vytvoriť nový náhodný tajný kľúč. Otvor Glitch terminál a napíš nasledujúci príkaz: +> +> {% filename %}command-line{% endfilename %} +> +> ```bash +> python -c 'from django.core.management.utils import get_random_secret_key; \ +> print(get_random_secret_key())' +> ``` +> +> Mal by sa ti zobraziť dlhý náhodný reťazec, ktorý je ako stvorený pre tvoju novú Django webstránku. Tento kľúč teraz skopírujeme do súboru `.env`, ktorý Glitch ukáže len autorovi či autorke danej webstránky. +> +> - Vytvor súbor pod názvom `.env` v základnom adresári tvojho projektu a pridaj doň nasledovné: +> +> {% filename %}.env{% endfilename %} +> +> ```bash +> # Tuto pomedzi apostrofy na zaciatku a na konci mozes skopirovat nahodny kluc, ktory si vygenerovala vyssie +> SECRET='3!0k#7ds5mp^-x$lqs2%le6v97h#@xopab&oj5y7d=hxe511jl' +> ``` +> +> - Následne uprav svoj Django settings súbor tým, že doň vložíš túto tajnú hodnotu, a nastav názov tvojej Django webstránky: +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> import os +> +> SECRET_KEY = os.getenv('SECRET') +> ``` +> +> - A ešte trochu nižšie v tom istom súbore doň vložíme meno tvojej novej Glitch stránky: +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> ALLOWED_HOSTS = [os.getenv('PROJECT_DOMAIN') + ".glitch.me"] +> ``` +> +> Hodnota `PROJECT_DOMAIN` je automaticky vygenerovaná Glitchom. Bude taká istá, ako je meno tvojho projektu. + ## Nastavenie databázy -Existuje veľa rôznych databázových softvérov, ktoré umožňujú ukladať údaje pre tvoje web stránky. My budeme používať predvolenú databázu - `sqlite3`. +Existuje veľa rôznych databázových softvérov, ktoré umožňujú ukladať údaje pre tvoje web stránky. My budeme používať predvolenú databázu `sqlite3`. Tá je už nastavená v tejto časti súboru `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', } } ``` -Databázu pre náš blog vytvoríme spustením tohto príkazu v konzole: `python manage.py migrate` (musíme byť v adresári `djangogirls`, ktorý obsahuje súbor `manage.py`). Ak všetko prešlo dobre, mala by si vidieť niečo takéto: +Databázu pre náš blog vytvoríme spustením tohto príkazu v konzole: `python manage.py migrate` (musíme byť v priečinku `djangogirls`, ktorý obsahuje súbor `manage.py`). Ak je všetko ok, mala by si vidieť niečo takéto: -``` -(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... -Running migrations: - Rendering model states... DONE - Applying contenttypes.0001_initial... OK - Applying auth.0001_initial... OK - Applying admin.0001_initial... 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 sessions.0001_initial... OK -``` +{% filename %}command-line{% endfilename %} -A je to! Teraz treba spustiť webový server a uvidíme či je naša web stránka funkčná! + (myvenv) ~/djangogirls$ python manage.py migrate + Operations to perform: + Apply all migrations: admin, auth, contenttypes, sessions + Running migrations: + 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 + -Musíš sa nachádzať v adresári, v ktorom sa nachádza súbor `manage.py` (adresár `djangogirls`). V konzole spustíme webový server zadaním `python manage.py runserver`: +A je to! Teraz treba spustiť webový server a zistiť, či je naša web stránka funkčná! -``` -(myvenv) ~/djangogirls$ python manage.py runserver -``` +## Spustenie webového servera + +Musíš sa nachádzať v priečinku, v ktorom sa nachádza súbor `manage.py` (adresár `djangogirls`). V konzole spustíme webový server zadaním `python manage.py runserver`: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver + + +Ak používaš Chromebook, použi nasledovný príkaz: + +{% filename %}Cloud 9{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0.0.0.0:8080 + + +alebo tento, ak používaš Glitch: + +{% filename %}Glitch.com terminal{% endfilename %} + + $ refresh + + Ak si vo Windowse a padne ti to s chybovou hláškou `UnicodeDecodeError`, použi namiesto toho tento príkaz: -``` -(myvenv) ~/djangogirls$ python manage.py runserver 0:8000 -``` +{% filename %}command-line{% endfilename %} -Teraz už musíš len skontrolovať, či tvoja web stránka funguje. Otvor si prehliadač (Firefox, Chrome, Safari, Internet Explorer alebo čokoľvek používaš) a zadaj adresu: + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + -``` -http://127.0.0.1:8000/ -``` +Teraz už musíš len skontrolovať, či tvoja web stránka beží. Otvor si prehliadač (Firefox, Chrome, Safari, Internet Explorer alebo čokoľvek používaš) a zadaj adresu: + +{% filename %}browser{% endfilename %} + + http://127.0.0.1:8000/ + + +Ak používaš Chromebook alebo Cloud 9, namiesto toho klikni na URL vo vyskakovacom okne, ktoré by sa ti malo objaviť v pravom hornom rohu príkazového okna, kde ti beží web server. Táto URL bude vyzerať nejako takto: + +{% filename %}browser{% endfilename %} + + https://.vfs.cloud9.us-west-2.amazonaws.com + + +alebo na Glitchi: + + https://nazov-tvojho-glitch-projektu.glitch.me + + +Blahoželáme! Práve si vytvorila svoju prvú web stránku, ktorá beží na tvojom webovom serveri! Nie je to úžasné? -Príkazový riadok bude obsadený webovým serverom, až kým ho nezastavíš. Ak chceš zadať viac príkazov, kým je spustený, otvor nové okno terminálu a aktivuj svoj virtualenv. Ak chceš zastaviť webový server, prepni sa späť do okna, v ktorom beží a stlač Ctrl + C súčasne (na Windowse možno budeš musiť stlačiť Ctrl + Break). +![Inštalácia funguje!](images/install_worked.png) -Blahoželáme! Práve si vytvorila svoju prvú web stránku, ktorá beží na tvojom webovom serveri. Nie je to úžasné? +Treba spomenúť, že v príkazovom okne môže naraz bežať len jeden príkaz, a v príkazovom okne, ktoré si otvorila nedávno, teraz beží tvoj web server. Pokým web server beží a čaká na prichádzajúce požiadavky, terminál ti síce dovolí doň písať, ale nedovolí ti vykonávať príkazy. -![Fungovalo to!][3] +> Ako webový server funguje, sme si povedali v kapitole **Ako funguje internet**. - [3]: images/it_worked2.png +Ak chceš spúšťať ďalšie príkazy počas toho, ako beží tvoj web server, treba otvoriť nové terminálové okno a aktivovať svoj virtualenv. Inštrukcie, ako otvoriť nové terminálové okno, nájdeš v [Úvode do príkazového riadku](../intro_to_command_line/README.md). Ak chceš webový server zastaviť, prepni sa späť do okna, v ktorom beží, a stlač Ctrl + C súčasne (na Windowse možno budeš musiť stlačiť Ctrl + Break). -Pripravená na ďalší krok? Je na čase vytvoriť nejaký obsah! +Pripravená na ďalší krok? Prišiel čas vytvoriť nejaký obsah! \ No newline at end of file diff --git a/sk/django_start_project/images/install_worked.png b/sk/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..4354c634ddb Binary files /dev/null and b/sk/django_start_project/images/install_worked.png differ diff --git a/sk/django_start_project/images/it_worked2.png b/sk/django_start_project/images/it_worked2.png index 4412ecfc49e..4efa554e567 100644 Binary files a/sk/django_start_project/images/it_worked2.png and b/sk/django_start_project/images/it_worked2.png differ diff --git a/sk/django_templates/README.md b/sk/django_templates/README.md old mode 100755 new mode 100644 index 8d1a4535bd2..e726ad98739 --- a/sk/django_templates/README.md +++ b/sk/django_templates/README.md @@ -1,36 +1,40 @@ -# Šablóny Django +# Django šablóny -Je na čase zobraziť nejaké údaje! Na to nám Django ponúka užitočné vstavané **šablónové tagy**. +Prišiel čas zobraziť nejaké údaje! Na to nám Django ponúka užitočné zabudované **šablónové tagy**. ## Čo sú to šablónové tagy? -V HTML vlastne nemôžeš písať pythonský kód, pretože prehliadače mu nerozumejú. Poznajú len HTML. Vieme, že HTML je skôr statické, kým Python je oveľa dynamickejší. +Totiž, v HTML nemôžeš písať pythonový kód, pretože prehliadače mu nerozumejú. Poznajú len HTML. Vieme, že HTML je skôr statické, kým Python je oveľa dynamickejší. -**Django šablónové tagy** nám umožňujú previesť Pythonské veci do HTML, takže dynamické webové stránky môžeš vytvoriť rýchlejšie a jednoduchšie. Paráda! +**Šablónové tagy v Djangu** nám umožňujú previesť pythonové veci do HTML, takže dynamické webové stránky môžeš vytvoriť rýchlejšie. Paráda! -## Zobraz šablónu so zoznamom príspevkov +## Zobrazenie šablóny so zoznamom príspevkov -V predchádzajúcej kapitole sme našej šablóne dali zoznam príspevkov v premennej `posts`. Teraz to zobrazíme v HTML. +V predchádzajúcej kapitole sme našej šablóne dali zoznam príspevkov v premennej `posts`. Teraz ich zobrazíme v HTML. Na vypísanie premennej v Django šablónach použijeme dvojitú zloženú zátvorku s názvom premennej vo vnútri, asi takto: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html {{ posts }} ``` -Vyskúšaj to vo svojej šablóne `blog/templates/blog/post_list.html`. Nahraď všetko od druhého `
` po tretí `
` týmto kódom: `{{ posts }}`. Ulož súbor a obnov stránku, aby sme videli výsledky: - -![Obrázok 13.1][1] +Vyskúšaj to vo svojej šablóne `blog/templates/blog/post_list.html`. Otvor ju vo svojom editore a nahraď elementy `
` týmto: `{{ posts }}`. Ulož súbor a obnov stránku, aby si videla výsledky: - [1]: images/step1.png +![Obrázok 13.1](images/step1.png) Ako vidíš, dostali sme len toto: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +, ]> ``` -[, ] -``` -To znamená, že to Django chápe ako zoznam objektov. Pamätáš si z kapitoly **Úvod do Pythonu** ako môžeme zobraziť zoznamy? Áno, cyklami! V Django šablóne ich urobíš takto: +To znamená, že to Django chápe ako zoznam objektov. Pamätáš si z kapitoly **Úvod do jazyka Python**, ako môžeme zobraziť zoznamy? Áno, cyklami! V Django šablóne ich urobíš takto: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %} @@ -40,69 +44,65 @@ To znamená, že to Django chápe ako zoznam objektov. Pamätáš si z kapitoly Vyskúšaj si to vo svojej šablóne. -![Obrázok 13.2][2] +![Obrázok 13.2](images/step2.png) - [2]: images/step2.png +Funguje to! Ale my chceme, aby sa príspevky zobrazili ako tie statické, ktoré sme vytvorili predtým v kapitole **Úvod do HTML**. HTML a šablónové tagy možno kombinovať. Naše `body` bude vyzerať takto: -Funguje to! Ale my chceme, aby sa zobrazili ako tie statické príspevky, ktoré sme vytvorili predtým v kapitole **Úvod do HTML**. Môžeš skombinovať HTML a šablónové tagy. Naše `body` bude vyzerať takto: +{% 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 %}Všetko, čo dáš medzi `{% for %}` a `{% endfor %}` sa bude opakovať pre každý objekt v zozname. Obnov svoju stránku:{% endraw %} -![Obrázok 13.3][3] +![Obrázok 13.3](images/step3.png) - [3]: images/step3.png - -Všimla si si, že sme tentokrát použili trochu odlišné zápisy `{{ post.title }}` alebo `{{ post.text }}`? Pristupujeme k údajom v každom z polí definovanom v našom `Post` modeli. Okrem toho `|linebreaksbr` preposiela texty príspevkov cez filter, ktorý konvertuje zalomenie riadkov na odstavce. +Všimla si si, že sme tentokrát použili trochu iný zápis (`{{ post.title }}` alebo `{{ post.text }}`)? Pristupujeme k údajom v každom z polí definovanom v našom modeli `Post`. Okrem toho, `|linebreaksbr` preposiela texty príspevkov cez filter, ktorý mení zalomenia riadkov na odstavce. ## Ešte jedna vec -Bolo by fajn vidieť či bude tvoja web stránka stále funkčná aj na Internete, však? Skúsme to znova nasadiť na PythonAnywhere. Tu je rekapitulácia postupu... +Bolo by fajn vidieť, či bude tvoja web stránka stále funkčná aj na internete, však? Skúsme ju znova nasadiť na PythonAnywhere. Tu je rekapitulácia postupu… -* Najskôr pošli svoj kód na Github +* Najskôr pošli svoj kód na GitHub -``` -$ git status -[...] -$ git add -A . -$ git status -[...] -$ git commit -m "Modified templates to display posts from database." -[...] -$ git push -``` +{% filename %}command-line{% endfilename %} -* Potom sa prihlás do [PythonAnywhere][4] a choď do **Bash konzoly** (alebo spusti novú) a zadaj: + $ git status + [...] + $ git add . + $ git status + [...] + $ git commit -m "Modified templates to display posts from database." + [...] + $ git push + - [4]: https://www.pythonanywhere.com/consoles/ +* Potom sa prihlás do [PythonAnywhere](https://www.pythonanywhere.com/consoles/) a choď do **Bash konzoly** (alebo spusti novú) a zadaj: -``` -$ cd my-first-blog -$ git pull -[...] -``` +{% filename %}PythonAnywhere command-line{% endfilename %} -* A nakoniec prejdi na [záložku Web][5] a stlač **Reload** na svojej webovej aplikácii. Aktualizácia by mala byť online! + $ cd .pythonanywhere.com + $ git pull + [...] + - [5]: https://www.pythonanywhere.com/web_app_setup/ +(Nezabudni nahradiť `` svojou subdoménou na PythonAnywhere bez špicatých zátvoriek.) -Gratulujeme! Teraz skús pridať nový príspevok v Django adminovi (nezabudni pridať published_date!), potom obnov stránku a pozri sa, či sa príspevok zobrazí. +* A nakoniec prejdi na [záložku Web](https://www.pythonanywhere.com/web_app_setup/) a stlač **Reload** na svojej webovej aplikácii. (Ak sa chceš dostať k ďalším stránkam na PythonAnywhere z konzoly, použi tlačítko v menu v pravom hornom rohu.) Tvoje zmeny by mali byť online na https://subdomena.pythonanywhere.com - over si to vo svojom prehliadači! Pokiaľ sa blogové príspevky na tvojej PythonAnywhere stránke nezhodujú s príspevkami na blogu, ktorý beží na tvojom lokálnom serveri, to je v poriadku. Databázy na tvojom lokálnom počítači a na PythonAnywhere sa nesynchronizujú spolu s tvojimi ostatnými súbormi. -Funguje ako hodinky? Sme hrdí! Teraz si na chvíľku oddýchni od počítača, zaslúžiš si trochu voľna. :) +Gratulujeme! Teraz skús pridať nový príspevok cez Django admina (nezabudni pridať published_date!). Uisti sa, že si v Django admin prostredí na svojej stránke na PythonAnywhere, https://subdomena.pythonanywhere.com/admin. Následne obnov stránku, aby si zistila, či sa tam príspevok objaví. -![Obrázok 13.4][6] +Funguje ako hodinky? Tešíme sa! Teraz si na chvíľku oddýchni od počítača, zaslúžiš si prestávku. :) - [6]: images/donut.png +![Obrázok 13.4](images/donut.png) \ No newline at end of file diff --git a/sk/django_templates/images/donut.png b/sk/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/sk/django_templates/images/donut.png and b/sk/django_templates/images/donut.png differ diff --git a/sk/django_templates/images/step1.png b/sk/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/sk/django_templates/images/step1.png and b/sk/django_templates/images/step1.png differ diff --git a/sk/django_templates/images/step2.png b/sk/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/sk/django_templates/images/step2.png and b/sk/django_templates/images/step2.png differ diff --git a/sk/django_templates/images/step3.png b/sk/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/sk/django_templates/images/step3.png and b/sk/django_templates/images/step3.png differ diff --git a/sk/django_urls/README.md b/sk/django_urls/README.md old mode 100755 new mode 100644 index 358bab87c2e..0a662c0a45f --- a/sk/django_urls/README.md +++ b/sk/django_urls/README.md @@ -1,126 +1,115 @@ -# Django url +# Django URL -Chystáme sa vytvoriť našu prvú web stránku: domovská stránka tvojho blogu! Ale ešte predtým sa poďme naučiť niečo o Django url. +Chystáme sa vytvoriť našu prvú webovú stránku: domovskú stránka tvojho blogu! Ale ešte predtým sa poďme naučiť niečo o Django URL. ## Čo je URL? -URL je jednoducho webová adresa. URL si môžeš všimnúť zakaždým, keď navštíviš webovú stránku - vidno ju v prehliadači v adresnom riadku (áno! `127.0.0.1:8000` je URL! A `https://djangogirls.org` je tiež URL): +URL je webová adresa. URL si môžeš všimnúť zakaždým, keď navštíviš webovú stránku - vidno ju v prehliadači. (Áno! `127.0.0.1:8000` je URL! A `https://djangogirls.org` je tiež URL.) -![Url][1] +![URL](images/url.png) - [1]: images/url.png - -Každá stránka na internete potrebuje svoju vlastnú URL. Týmto spôsobom aplikácia vie, čo by mala ukázať užívateľovi, ktorý otvorí URL. V Djangu používame takzvaný `URLconf` (URL konfigurácia). URLconf je súbor vzorov, ktoré sa Django pokúsi priradiť podľa prijatej URL, aby tak našiel správne zobrazenie. +Každá stránka na internete potrebuje svoju vlastnú URL. Tak aplikácia vie, čo by mala ukázať užívateľke či užívateľovi, ktorý otvorí URL. V Djangu používame takzvaný `URLconf` (URL konfiguráciu). URLconf je súbor vzorov, ktoré sa Django pokúsi porovnať s prijatou URL, aby tak našiel správny view. ## Ako fungujú URL v Djangu? Otvorme súbor `mysite/urls.py` v editore kódu a pozrime sa, ako vyzerá: +{% 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), ] ``` -Ako vidíš, Django sem už pre nás niečo umiestnil. - -Riadky, ktoré začínajú s `#` sú komentáre - to znamená, že tie riadky Python nespustí. Šikovné, nie? - -Adminská URL, ktorú si navštívila v predchádzajúcej kapitole je už tu: - -```python -url(r'^admin/', include(admin.site.urls)), -``` - -To znamená, že pre každú URL, ktorá začína na `admin` Django nájde zodpovedajúce *zobrazenie (view)*. V tomto prípade pridávame množstvo adminských URL, takže to nie je všetko natlačené v jednom malom súbore -- je to čitateľnejšie a čistejšie. +Ako vidíš, Django sem už pre nás niečo umiestnilo. -## Regex +Riadky medzi trojitými uvodzovkami (`'''` or `"""`) sa nazývajú docstringy - môžeš ich pridať na začiatku súboru, triedy alebo metódy, aby si popísala, čo robí. Python ich nebude spúšťať. -Zaujíma ťa, ako Django porovnáva URL so zobrazeniami? No, to je trochu zložitejšie. Django používa `regex`, čo je skratka pre "regulárne výrazy". Regex má veľa (veľa!) pravidiel, ktoré tvoria vzor vyhľadávania. Keďže regexy sú pokročilá téma, nebudeme sa nimi veľmi detailne zaoberať. +Adminovská URL, ktorú si navštívila v predchádzajúcej kapitole, je už tu: -Ak chceš porozumieť tvorbe vzorov, tu je príklad procesu - budeme potrebovať iba obmedzenú množinu pravidiel, ktorými vyjadríme vzor, ktorý hľadáme, konkrétne: +{% filename %}mysite/urls.py{% endfilename %} +```python + path('admin/', admin.site.urls), ``` -^ pre začiatok textu -$ pre koniec textu -\d pre číslicu -+ indikuje, že predchádzajúca položka sa má zopakovať aspoň raz -() ohraničuje časť vzoru -``` - -Všetko ostatné v definícii url bude brané doslovne. - -Teraz si predstav, že máš webovú stránky s adresou napríklad `http://www.mysite.com/post/12345/`, kde `12345` je číslo tvojho postu. - -Písať samostatné views pre všetky čísla postov by bolo vážne otravné. S regulárnym výrazom však vieme vytvoriť vzor, ktorý bude zodpovedať url a vyextrahovať z nej číslo, ktoré potrebujeme: `^post/(\d+)/$`. Rozoberme si to na drobné, aby sme videli, čo sa tu vlastne deje: -* **^post/** hovorí Djangu, aby zobral čokoľvek, čo má na začiatku url `post` (hneď po `^`) -* **(\d+)** znamená, že tam bude číslo (jedna alebo viac číslic) a že chceme číslo zachytiť a extrahovať -* **/** povie Djangu, že bude nasledovať ďalší znak `/` -* **$** potom označuje koniec adresy URL, čo znamená, že vzoru budú zodpovedať iba reťazce s `/` na konci +Tento riadok znamená, že pre každú URL, ktorá začína na `admin`, Django nájde zodpovedajúci *view*. V tomto prípade pridávame množstvo adminovských URL, takže to nie je všetko natlačené v jednom malom súbore - je to čitateľnejšie a čistejšie. -## Tvoja prvá Django url! +## Tvoja prvá Django URL! Je čas vytvoriť našu prvú URL! Chceme, aby 'http://127.0.0.1:8000/' bola domovská stránka nášho blogu a zobrazovala zoznam príspevkov. -Tiež chceme udržiavať súbor `mysite/urls.py` čistý, takže naimportujeme url z našej aplikácie `blog` do hlavného súboru `mysite/urls.py`. +Tiež chceme udržiavať súbor `mysite/urls.py` čistý, takže naimportujeme URL z našej aplikácie `blog` do hlavného súboru `mysite/urls.py`. -Neboj sa, zmaž všetky zakomentované riadky (tie, čo začínajú `#`) a pridaj riadok, ktorý naimportuje `blog.urls` do hlavnej url (`''`). +Poď na to, pridaj riadok, ktorý naimportuje `blog.urls`. Budeš tiež musieť zmeniť riadok `from django.urls…`, pretože v súbore chceme používať funkciu `include`, takže ju musíme pridať k importom. Súbor `mysite/urls.py` by mal teraz vyzerať takto: +{% 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 teraz presmeruje všetko, čo prichádza na 'http://127.0.0.1:8000/' do `blog.urls` a tam bude hľadať ďalšie inštrukcie. - -Pri písaní regulárnych výrazov je vždy dobré pridať pred reťazec `r`. To je užitočný tip pre Python, že reťazec môže obsahovať špeciálne znaky, ktoré nie sú urečené pre Python samotný, ale pre regulárny výraz. +Django teraz presmeruje všetko, čo prichádza na 'http://127.0.0.1:8000/', do `blog.urls` a tam bude hľadať ďalšie inštrukcie. ## blog.urls -Vytvor nový prázdny súbor `blog/urls.py`. Dobre! Pridaj tieto prvé dva riadky: +Vytvor nový prázdny súbor s názvom `urls.py` v priečinku `blog` a otvor ho v editore. Okej! Pridaj tieto prvé dva riadky: + +{% filename %}blog/urls.py{% endfilename %} ```python -from django.conf.urls import url +from django.urls import path from . import views ``` -Tu iba importujeme Django metódy a všetky naše `views` z aplikácie `blog` (zatiaľ žiadne nemáme, ale k tomu sa o chvíľu dostaneme!) +Tu iba importujeme Django metódu `path` a všetky naše `viewy` z aplikácie `blog` (zatiaľ žiadne nemáme, ale k tomu sa o chvíľu dostaneme!) Potom môžeme pridať náš prvý URL vzor: +{% filename %}blog/urls.py{% endfilename %} + ```python urlpatterns = [ - url(r'^$', views.post_list, name='post_list'), + path('', views.post_list, name='post_list'), ] ``` -Ako vidíš, priradili sme `view` s názvom `post_list` tejto URL: `^$`. Tento regulárny výraz sa bude zhodovať iba ak po `^` (začiatku) bude nasledovať `$` (koniec) - takže zodpovedať bude iba prázdny reťazec. To je správne, pretože v Django URL prekladači 'http://127.0.0.1:8000/' nie je súčasťou URL. Tento vzor povie Djangu, že `views.post_list` je to správne miesto, kam treba ísť, ak niekto vstúpi na stránku cez adresu 'http://127.0.0.1:8000/'. - -Posledná časť `name='post_list'` je názov URL, ktorý sa použije na identifikáciu view. Názov URL môže byť rovnaký ako názov view, ale pokojne to môže byť aj niečo úplne iné. Neskôr budeme v projekte používať pomenované URL, takže je dôležité pomenovať všetky URL v aplikácii. Názvy by mali byť unikátne a ľahké na zapamätanie. +Ako vidíš, priradili sme základnej URL `view` pod názvom `post_list`. Takýto URL vzor zaberie na prázdny string a Django URL resolver bude ignorovať meno domény (teda http://127.0.0.1:8000/), ktorá predchádza celej URL ceste. Tento vzor hovorí Djangu, že ak niekto vstúpi na tvoju stránku na adrese "http://127.0.0.1:8000/", má sa oňho postarať `views.post_list`. -Všetko v poriadku? Otvor http://127.0.0.1:8000/ vo svojom prehliadači a pozri sa na výsledok. +Posledná časť `name='post_list'` je názov URL, ktorý sa použije na identifikáciu správneho viewu. Názov URL môže byť rovnaký ako názov viewu, ale pokojne to môže byť aj niečo úplne iné. Neskôr budeme v projekte používať pomenované URL, takže je dôležité pomenovať všetky URL v aplikácii. Názvy by mali byť unikátne a ľahké na zapamätanie. -![Chyba][2] +Ak sa teraz pokúsiš navštiviť http://127.0.0.1:8000/, uvidíš správu, že stránka nie je dostupná ("web page not available"). Toto je z toho dôvodu, že server (spomínaš si, ako si spúšťala `runserver`?) už nebeží. Pozri sa na konzolu svojho serveru, aby si zistila prečo. - [2]: images/error1.png +{% filename %}{{ warning_icon }} command-line{% endfilename %} -"Funguje to!" zmizlo, čo? Neboj sa, je to len chybová stránka, nič, čoho by si sa mala báť! Vlastne bývajú celkom užitočné: + 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' + -Môžeš si prečítať, že neexistuje **žiadny atribút post_list**. Pripomína ti *post_list* niečo? Tak sme nazvali náš view! To znamená, že je všetko v poriadku, len sme ešte nevytvorili náš *view*. Žiadne obavy, aj k tomu sa dostaneme. +Konzola zobrazuje chybu, ale neboj sa - je to práveže nápomocné: hovorí ti, že neexistuje atribút post_list (**no attribute 'post_list'**). To je názov *viewu*, ktorý sa Django pokúša nájsť a použiť, ale my sme ho ešte nevytvorili. V tejto fáze `/admin/` tiež nefunguje. Žiadne obavy, aj k tomu sa dostaneme. Ak vidíš inú chybovú hlášku, skúš reštartovať web server. To môžeš docieliť tak, že v príkazovom okne, kde beží tvoj web server, stlačíš Ctrl + C (klávesy Control a C) naraz. Na Windowse možno bude treba stlačiť Ctrl + Break. Svoj web server potom znova spustíš príkazom `python manage.py runserver`. -> Ak chceš vedieť viac o Django URLconfs, pozri sa na oficiálnu dokumentáciu: https://docs.djangoproject.com/en/1.8/topics/http/urls/ +> Ak chceš vedieť viac o Django URL konfigurácii, pozri sa na oficiálnu dokumentáciu: https://docs.djangoproject.com/en/5.1/topics/http/urls/ \ No newline at end of file diff --git a/sk/django_urls/images/error1.png b/sk/django_urls/images/error1.png index cc17593d19d..50618fca3fe 100644 Binary files a/sk/django_urls/images/error1.png and b/sk/django_urls/images/error1.png differ diff --git a/sk/django_urls/images/url.png b/sk/django_urls/images/url.png index 6cd1bd96291..b59f9dce992 100644 Binary files a/sk/django_urls/images/url.png and b/sk/django_urls/images/url.png differ diff --git a/sk/django_views/README.md b/sk/django_views/README.md old mode 100755 new mode 100644 index 8512c29d0ee..3f8d8799725 --- a/sk/django_views/README.md +++ b/sk/django_views/README.md @@ -1,14 +1,16 @@ -# Django views - čas tvoriť! +# Django viewy - čas tvoriť! -Je čas zbaviť sa toho bugu, čo sme vytvorili v poslednej kapitole :) +Je čas zbaviť sa toho bugu, čo sme vytvorili v poslednej kapitole! :) -*View* je miesto, kam dávame "logiku" našej aplikácie. Bude požadovať informáciu z `modelu`, ktorý si už vytvorila a pošle to do `šablóny`. Šablónu (template) budeme vytvárať v nasledujúcej kapitole. Views sú vlastne len metódy Pythonu, ktoré sú trochu zložitejšie, ako tie, ktoré sme písali v kapitole **Úvod do Pythonu**. +*View* je miesto, kam dávame "logiku" našej aplikácie. Bude požadovať dáta z `modelu`, ktorý si už vytvorila, a pošle ich `šablóne`. Šablónu budeme vytvárať v nasledujúcej kapitole. Viewy sú vlastne len metódy Pythonu, ktoré sú trochu zložitejšie, ako tie, ktoré sme písali v kapitole **Úvod do jazyka Python**. -Views sú umiestnené v súbore `views.py`. Naše *views* budeme pridávať do súboru `blog/views.py`. +Viewy sú umiestnené v súbore `views.py`. Naše *viewy* budeme pridávať do súboru `blog/views.py`. ## blog/views.py -OK, otvorme tento súbor a pozrime sa, čo je v ňom: +OK, otvorme tento súbor v editore a pozrime sa, čo je v ňom: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -16,23 +18,27 @@ from django.shortcuts import render # Create your views here. ``` -Veľa toho nie je. Najjednoduchší *view* môže vyzerať zhruba takto. +Zatiaľ je tu toho málo. + +Ak si spomínaš, riadky začínajúce `#` sú komentáre - to znamená, že ich Python nespustí. + +Vytvorme *view*, ako nám komentár naznačuje. Pridaj pod komentár nasledovný minimálny view: + +{% filename %}blog/views.py{% endfilename %} ```python def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -Ako vidíš, vytvorili sme metódu (`def`) nazvanú `post_list`, ktorá použije `request` (žiadosť) a `return` (vráti) metódu `render`, ktorou vykreslí (spojí dokopy) našu šablónu `blog/post_list.html`. +Ako vidíš, vytvorili sme funkciu (`def`) nazvanú `post_list`, ktorá použije `request` (žiadosť) a `return` (vráti) metódu `render`, ktorá vyplní (vyrenderuje) našu šablónu `blog/post_list.html`. -Ulož súbor, prejdi na http://127.0.0.1:8000 / a pozri sa, čo sa udeje. +Ulož súbor, prejdi na http://127.0.0.1:8000/ a pozri sa, čo sa udeje. Ďalšia chyba! Prečítaj si, o čo ide tentokrát: -![Chyba][1] - - [1]: images/error.png +![Chyba](images/error.png) -To je jednoduché: *TemplateDoesNotExist*. Opravme túto chybu a v nasledujúcej kapitole vytvorme šablónu! +Ukazuje, že server aspoň znovu beží, ale nie je to úplne ono, že? Neboj sa, je to len chybová stránka, nič, čoho sa treba báť! Podobne ako chyby v konzole nám tieto chyby napovedajú, čo treba robiť. Dočítaš sa, že *TemplateDoesNotExist* (šablóna neexistuje). Poďme opraviť túto chybu tým, že vytvoríme šablónu v nasledujúcej kapitole! -> Viac informácií o Django views získaš v oficiálnej dokumentácii: https://docs.djangoproject.com/en/1.8/topics/http/views/ +> Viac informácií o Django viewoch získaš v oficiálnej dokumentácii: https://docs.djangoproject.com/en/5.1/topics/http/views/ \ No newline at end of file diff --git a/sk/django_views/images/error.png b/sk/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/sk/django_views/images/error.png and b/sk/django_views/images/error.png differ diff --git a/sk/domain/README.md b/sk/domain/README.md deleted file mode 100755 index 043aa7a4030..00000000000 --- a/sk/domain/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# Doména - -Heroku ti dala doménu, avšak je dlhá a ťažko si ju zapamätať. Bolo by skvelé mať meno domény, ktoré by bolo krátke a ľahko sa pamätalo, že? - -V tejto kapitole ťa naučíme, ako si zakúpiť domenú a nasmerovať ju na Heroku! - -## Kde si registrovať doménu? - -Typická doména stojí $15 na rok. Existujú lacnejšie aj drahšie možnosti, v závislosti od poskytovateľa. Existuje veľa spoločností, od ktorých si môžeš kúpiť doménu: jednoduché [google vyhľadávanie][1] ti dá stovky možností. - - [1]: https://www.google.com/search?q=register%20domain - -Naša obľúbená je [I want my name][2]. Propagujú "bezbolestný manažment domény" a je to naozaj bezbolestné. - - [2]: https://iwantmyname.com/ - -## Ako registrovať doménu na IWantMyName? - -Choď na [iwantmyname][3] a napíš typ domény akú chceš mať do poľa vyhľadávania. - - [3]: https://iwantmyname.com - -![][4] - - [4]: images/1.png - -Teraz by si mala vidieť zoznam všetkých dostupných domén, s pojmom, ktorý si zadala. Ako vidíš, usmievavá tvár naznačuje, že táto doména je dostupná a môžeš si ju zakúpiť, kým smutná tvár znamená, že už ju niekto vlastní. - -![][5] - - [5]: images/2.png - -Rozhodli sme sa kúpiť `djangogirls.in`: - -![][6] - - [6]: images/3.png - -Prejdi k pokladni. Teraz by si sa mala prihlásiť do iwantmyname, pokiaľ ešte nemáš vytvorený účet. Po tom poskytni informácie o svojej kreditnej karte a kúp si doménu! - -Po tom, klikni na `Domains` v menu a vyber si novo zakúpenú doménu. Následne nájdi a klikni na odkaz `manage DNS records`: - -![][7] - - [7]: images/4.png - -Teraz musíš nájsť tento formulár: - -![][8] - - [8]: images/5.png - -A vyplniť nasledujúce údaje: - Hostname: www - Type: CNAME - Value: tvoja doména z Heroku (napríklad djangogirls.herokuapp.com) - TTL: 3600 - -![][9] - - [9]: images/6.png - -Klikni na tlačidlo Add a Save v spodnej časti stránky. - -Môže trvať niekoľko hodím, kým začne doména pracovať, takže buď trpezlivá! - -## Konfiguruj doménu na Heroku - -Taktiež musíš povedať Heroku, že chceš použiť svoju vlastnú doménu. - -Choď do [Heroku Dashboard][10], prihlás sa na svoj Heroku účet a vyber si svoju aplikáciu. Potom choď do nastavení aplikácie a pridaj svoju doménu v sekcii `Domains` a ulož zmeny. - - [10]: https://dashboard.heroku.com/apps - -To je všetko! \ No newline at end of file diff --git a/sk/dynamic_data_in_templates/README.md b/sk/dynamic_data_in_templates/README.md old mode 100755 new mode 100644 index cb6675ff9ab..c169e8376d1 --- a/sk/dynamic_data_in_templates/README.md +++ b/sk/dynamic_data_in_templates/README.md @@ -1,12 +1,14 @@ # Dynamické dáta v šablónach -Máme rozdielne kúsky na svojom mieste: `Post` model je definovaný v `models.py`, máme `post_list` v `views.py` a pridanú šablónu. Ale ako prinútime HTML šablónu, aby zobrazovala náš príspevok? Pretože to je to, čo chceme: vziať nejaký obsah (modely uložené v databáze) a zobraziť ich pekne v našej šablóne, že? +Niekoľko vecí už máme na svojom mieste: model `Post` je definovaný v `models.py`, máme `post_list` v `views.py` a pridanú šablónu. Ale ako vlastne prinútime HTML šablónu, aby zobrazila naše príspevky? Pretože to je to, čo chceme urobiť - vziať nejaký obsah (modely uložené v databáze) a zobraziť ich pekne v našej šablóne, že? -To je presne to, čo majú *views* robiť: spojiť modely a šablóny. V našom `post_list` *view* potrebujeme vziať modely ktoré chceme zobraziť a posunúť ich do šablóny. Takže sa v podstate rozhodneme vo *view* čo (model) bude zobrazené v šablóne. +To je presne to, čo majú robiť *viewy*: spájať modely a šablóny. V našom *viewe* `post_list` potrebujeme vziať modely, ktoré chceme zobraziť, a posunúť ich šablóne. Čiže vo *viewe* sa rozhodne, čo (resp. ktorý model) bude zobrazené v šablóne. -Dobre, takže ako to dosiahneme? +Dobre, takže ako toto dosiahneme? -Musíme otvoriť náš `blog/views.py`. Zatiaľ `post_list` *view* vyzerá takto: +Musíme otvoriť náš `blog/views.py` v editore. Zatiaľ *view* `post_list` vyzerá takto: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -15,30 +17,34 @@ def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -Pamätáš si, keď sme rozprávali o zahrnutí kódu napísanom v rozdielnych súboroch? Teraz nastal čas kedy musíme zahrnúť model, ktorý sme napísali v `models.py`. Pridáme tento riadok `from .models import Post` takto: +Pamätáš si, keď sme sa rozprávali o vložení kódu napísaného v rozdielnych súboroch? Teraz nastal čas, kedy musíme vložiť model, ktorý sme napísali v `models.py`. Pridáme riadok `from .models import Post` takto: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render from .models import Post ``` -Bodka za `from` znamená *aktuálna zložka* alebo *aktuálna aplikácia*. Pretože `views.py` a `models.py` sú v rovnakej zložke, môžeme jednoducho použiť `.` a meno súboru (bez `.py`). Potom importujeme názov modelu (`Post`). +Bodka za `from` znamená *aktuálny priečinok* alebo *aktuálna aplikácia*. `views.py` aj `models.py` sú v rovnakom priečinku. To znamená, že môžeme použiť `.` a názov súboru (bez `.py`). Potom naimportujeme názov modelu (`Post`). -Ale čo ďalej? Na to aby sme boli schopní vziať konkrétny príspevok blogu z `Post` modelu potrebujeme niečo, čo sa volá `QuerySet`. +Ale čo ďalej? Na to, aby sme mohli zobrať konkrétny príspevok blogu z `Post` modelu, potrebujeme niečo, čo sa volá `QuerySet`. ## QuerySet -Už by si mala vedieť ako funguje QuerySets. Hovorili sme o tom v kapitole [Django ORM (QuerySets)][1]. +Už by si mala vedieť, ako fungujú QuerySety. Hovorili sme o tom v kapitole [Django ORM (QuerySety)](../django_orm/README.md). - [1]: ../django_orm/README.md +Takže teraz chceme zoznam zverejnených príspevkov, ktoré sú zoradené podľa `published_date`, však? To sme už spravili v kapitole QuerySety! -Takže teraz máme záujem o zoznam príspevkov blogu, ktoré sú uverejnené a zoradené podľa `published_date`, však? To sme už spravili v kapitole QuerySets! +{% filename %}blog/views.py{% endfilename %} ```python Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') ``` -Teraz vložíme tento kus kódu do súboru `blog/views.py` pridaním do funkcie `def post_list(request)`: +Takže poďme otvoriť súbor `blog/views.py` v našom editore a pridajme tento kus kódu do funkcie `def post_list(request)`, ale nezabudni najprv pridať `from django.utils import timezone`: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -50,16 +56,19 @@ def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -Vezmi prosím na vedomie, že vytvárame *premennú* pre náš QuerySet: `posts`. Považuj to za meno nášho QuerySetu. Odteraz ho môžeme referovať pod týmto menom. +Ak chceme zobraziť náš QuerySet v našom zozname blog postov, ešte nám zostáva urobiť dve veci: -Taktiež, kód používa funkciu `timezone.now()`, takže musíme pridať import pre `timezone`. +1. Poslať náš QuerySet `posts` šablóne tak, že zmeníme, ako voláme funkciu `render`. To spravíme teraz. +2. Upraviť šablónu, aby nám zobrazila náš QuerySet `posts`. K tomuto sa dostaneme v neskoršej kapitole. -Posledná chýbajúca časť je predanie `posts` QuerySetu do šablóny (v nasledujúcej kapitole si ukážeme ako ju zobraziť). +Vezmi, prosím, na vedomie, že vytvárame *premennú* pre náš QuerySet: `posts`. Ber to ako meno nášho QuerySetu. Odteraz mu môžeme hovoriť týmto menom. -V `render` funkcii už máme parameter `request` (takže všetko čo príjmeme od užívateľa cez Internet) a súbor šablóny `'blog/post_list.html'`. Posledný parameter, ktorý vyzerá takto: `{}` je miesto na ktoré môžeme dať nejaké veci ktoré môže použiť šablóna. Potrebujeme im dať mená (zatiaľ sa budeme držať `'posts'` :)). Malo by to vyzerať takto: `{'posts': posts}`. Všimni si, že časť pred `:` je reťazec: potrebuješ ju obaliť do úvodzoviek `''`. +Vo funkcii `render` už máme jeden parameter `request` (všetko, čo príjmeme od užívateľa či užívateľky cez internet) a ďalší, ktorý hovorí, ktorú šablónu použiť (`'blog/post_list.html'`). Posledný parameter, `{}`, je miestom, kam môžeme pridať veci, ktoré chceme poslať našej šablóne. Potrebujeme im dať mená (zatiaľ sa budeme držať `'posts'`). :) Malo by to vyzerať takto: `{'posts': posts}`. Všimni si, že časť pred `:` je reťazec: potrebuješ ju obaliť do úvodzoviek:`"`. Nakoniec by náš súbor `blog/views.py` mal vyzerať takto: +{% filename %}blog/views.py{% endfilename %} + ```python from django.shortcuts import render from django.utils import timezone @@ -72,4 +81,4 @@ def post_list(request): To je všetko! Čas prejsť na našu šablónu a zobraziť tento QuerySet! -Pokiaľ si chceš prečítať niečo viac o QuerySets v Djangu mala by si sa pozrieť sem: https://docs.djangoproject.com/en/1.8/ref/models/querysets/ +Pokiaľ si chceš prečítať niečo viac o QuerySetoch v Djangu, mala by si sa pozrieť sem: https://docs.djangoproject.com/en/5.1/ref/models/querysets/ \ No newline at end of file diff --git a/sk/extend_your_application/README.md b/sk/extend_your_application/README.md old mode 100755 new mode 100644 index f4f79454546..0f93c6b6255 --- a/sk/extend_your_application/README.md +++ b/sk/extend_your_application/README.md @@ -1,115 +1,136 @@ +{% set warning_icon = '' %} + # Ako rozšíriť aplikáciu -Už sme dokončili všetky kroky potrebné k tomu, aby sme vytvorili našu webovú stránku: vieme ako napísať model, url, view a šablónu. Taktiež vieme ako spraviť našu stránku peknú. +Už sme dokončili všetky kroky potrebné k tomu, aby sme vytvorili našu webovú stránku: vieme, ako napísať model, URL, view a šablónu. Taktiež vieme, ako našu stránku skrášliť. Čas na precvičovanie! -Prvá vec, ktorú potrebujeme na našom blogu je, zjavne, stránka, na ktorej zobrazíme jeden príspevok, že? +Prvá vec, ktorú na našom blogu potrebujeme, je podstránka, ktorá zobrazí iba jeden príspevok, že? -Už máme `Post` model, takže nepotrebujeme do `models.py` pridávať nič iné. +Už máme model `Post`, takže nepotrebujeme do `models.py` pridávať nič nové. -## Vytvorenie šablóny odkazu na post detail +## Vytvorenie odkazu na detail príspevku -Začneme tak, že pridáme link do súboru `blog/templates/blog/post_list.html`. Zatiaľ by mal vyzerať nejako takto: +Začneme tak, že pridáme link do súboru `blog/templates/blog/post_list.html`. Otvor ho vo svojom editore. Zatiaľ by mal vyzerať takto nejako: {% 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 content %} +{% endblock %} ``` -{% raw %}Chceme, aby link z titulku príspevku smeroval na stránku detailov príspevku. Zmeňme `

{{ post.title }}

` tak, aby odkazoval na stránku detailu príspevku:{% endraw %} +{% raw %}Chceme, aby link z titulku príspevku smeroval na stránku s detailami príspevku. Zmeňme `

{{ post.title }}

` tak, aby odkazoval na stránku detailu príspevku:{% endraw %} + +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} ```html -

{{ post.title }}

+

{{ post.title }}

``` -{% raw %}Je na čase vysvetliť záhadné `{% url 'post_detail' pk=post.pk %}`. Ako možno tušíš, `{% %}` notácia znamená, že používame tagy Django šablóny. Tentoraz použijeme jeden, ktorý pre nás vytvorí URL!{% endraw %} +{% raw %}Nadišiel čas vysvetliť si tento záhadný zápis: `{% url 'post_detail' pk=post.pk %}`. Ako možno tušíš, notácia `{% %}` znamená, že používame tagy Django šablóny. Tentoraz použijeme jeden, ktorý pre nás vytvorí URL!{% endraw %} -`blog.views.post_detail` je cesta k `post_detail` *view* ktorý chceme vytvoriť. Poznámka: `blog` je názov aplikácie (zložky `blog`), `views` je meno súboru `views.py` a posledná časť - `post_detail` - je meno *view*. +Časť `post_detail` znamená, že Django bude očakávať URL v `blog/urls.py`, pre ktorú platí name=post_detail -Teraz keď pôjdeme na: http://127.0.0.1:8000/ uvidíme chybu (ako sa dá očakávať, keďže nemáme URL alebo *view* pre `post_detail`). Bude to vyzerať takto: +A čo `pk=post.pk`? `pk` je skratka pre primárny kľúč (primary key), ktorý jednoznačne určuje každý konkrétny záznam v databáze. Každý Django model má pole, ktoré slúži ako jeho primárny kľúč. Bez ohľadu na to, ako sa toto pole volá, dá sa naň vždy odkazovať menom "pk". Keďže sme neurčili žiadny primárny kľúč v našom `Post` modeli, Django ho vytvorí za nás (štandardne sa volá "id" a je to číslo, ktoré sa zvyšuje o jedna pre každý záznam, t.j. 1, 2, 3) a pridá ho ako pole ku každému z našich príspevkov. K primárnemu kľúču môžeme pristupovať napísaním `post.pk` rovnako, ako pristupujeme k iným poliam (`title`, `author`, atď.) v našom `Post` objekte! -![NoReverseMatch error][1] +Teraz keď pôjdeme na http://127.0.0.1:8000/, uvidíme chybu (ako sa dalo očakávať, keďže ešte nemáme URL alebo *view* pre `post_detail`). Bude to vyzerať takto: - [1]: images/no_reverse_match2.png +![Chyba NoReverseMatch](images/no_reverse_match2.png) -## Vytvor URL na detail príspevku +## Vytvorenie URL na detail príspevku -Vytvorme URL v `urls.py` pre náš `post_detail` *view*! +Vytvorme URL v `urls.py` pre náš *view* `post_detail`! -Chceme aby sa detaily nášho prvého príspevku zobrazili na tejto **URL**: http://127.0.0.1:8000/post/1/ +Chceme, aby sa detaily nášho prvého príspevku zobrazili na tejto **URL**: http://127.0.0.1:8000/post/1/ -Vytvorme URL v súbore `blog/urls.py` tak, aby odkazoval Django na *view* nazvaný `post_detail`, ktorý zobrazí celý príspevok blogu. Pridaj riadok `url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'),` do súboru `blog/urls.py`. Súbor by mal vyzerať takto: +Vytvorme URL v súbore `blog/urls.py` tak, aby odkazovala Django na *view* nazvaný `post_detail`, ktorý zobrazí celý príspevok blogu. Otvor súbor `blog/urls.py` v editore a pridaj doň riadok `path('post//', views.post_detail, name='post_detail'),` tak, aby súbor vyzeral takto: + +{% 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'), ] ``` -Táto časť `^post/(?P[0-9]+)/$` vyzerá desivo, ale neboj sa - o chvíľu ti ju vysvetlíme: - znova začína s `^` -- začiatkom - `post/` znamená len, že po začiatku by URL mala obsahovať slová **post** a **/**. Zatiaľ je všetko v poriadku. - `(?P[0-9]+)` - táto časť je zložitejšia. Znamená to, že Django vezme všetko, čo tu vložíš a premiestni to do premennej s názvom `pk`. `[0-9]` nám tiež hovorí, že to môžu byť len čísla, nie písmená (takže všetko medzi 0 a 9). `+` znamená, že musíme mať aspoň jedno číslo. Takže niečo ako `http://127.0.0.1:8000/post//` nie je validné, ale `http://127.0.0.1:8000/post/1234567890/` je úplne v poriadku! - `/` - potom znova potrebujeme **/** - `$` - "koniec"! +Časť `post//` definuje vzor URL – vysvetlime si ho: + +- `post/` znamená, že na začiatku by URL mala obsahovať slovo **post** a **/**. Zatiaľ všetko v poriadku. +- `` – táto časť je trochu záludnejšia. Znamená, že Django očakáva číslo (integer alebo skrátene int) a posunie ho viewu ako premennú pod názvom `pk`. +- `/` – potom potrebujeme znova **/** predtým, ako URL skončí. -To znamená, že ak zadáš `http://127.0.0.1:8000/post/5/` do svojho prehliadača, Django pochopí, že hľadáš *view* s názvom `post_detail` a prenesie informácie z `pk` rovné `5` do toho *view*. +To znamená, že ak zadáš `http://127.0.0.1:8000/post/5/` do svojho prehliadača, Django pochopí, že hľadáš *view* s názvom `post_detail`, a posunie informáciu, že `pk` je `5`, tomuto *viewu*. -`pk` je skratka pre `primárny kľúč (primary key)`. Tento názov je často používaný v Django projektoch. Ale môžeš si pomenovať svoje premenná ako chceš (pamätaj: malé písmená a `_` namiesto medzier!). Napríklad namiesto `(?P[0-9]+)` môžeme mať premennú `post_id`, takže táto časť by vyzerala: `(?P[0-9]+)`. +OK, pridali sme nový vzor URL do `blog/urls.py`! Poďme obnoviť stránku: http://127.0.0.1:8000 / Bum! Server znova prestal bežať. Pozri sa do konzoly - ako sa aj dalo očakávať, je tam ďalšia chyba! -Dobre, pridali sme nový vzor URL do `blog/urls.py`! Obnovme stránku: http://127.0.0.1:8000/ Boom! Ďalšia chyba! Ako sa dalo očakávať! +{% filename %}{{ warning_icon }} command-line{% endfilename %} -![AttributeError][2] + 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' + - [2]: images/attribute_error2.png +Pamätáš si, čo je ďalší krok? Musíme pridať náš nový view! -Pamätáš si, čo je ďalší krok? Samozrejme: pridávanie view! +## Pridanie viewu pre detaily príspevku -## Pridaj view do detailu príspevku +Tentokrát má náš *view* extra parameter s názvom `pk`. Náš *view* ho potrebuje zachytiť, však? Takže definujeme našu funkciu ako `def post_detail(request, pk):`. Pozor na to, že tento parameter musí mať presne rovnaký názov, ako sme špecifikovali v `urls` (`pk`). Vynechanie tejto premmenej je nesprávne a bude mať za následok chybu! -Tentokrát má náš *view* extra parameter `pk`. Náš *view* ho potrebuje zachytiť, že? Takže definujeme našu funkciu ako `def post_detail(request, pk):`. Všimni si, že musíme použiť rovnaké meno, ako to, ktoré sme špecifikovali v Url (`pk`). Vynechanie tejto premmenej je nesprávne a bude mať za následok chybu! +Teraz chceme, aby sme dostali jeden jediný príspevok blogu. Na to môžeme použiť querysety, a to takto: -Teraz chceme aby sme dostali jeden a iba jeden príspevok blogu. Na to môžeme použiť querysets takto: +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} ```python Post.objects.get(pk=pk) ``` -Ale tento kód má problém. Pokiaľ tu nie je žiaden `Post` s daným `primárnym kľúčom`(`pk`) budeme mať super škaredú chybu! +Ale tento kód má problém. Pokiaľ neexistuje žiaden `Post` s daným `primárnym kľúčom`(`pk`), dostaneme veľmi škaredú chybu! -![DoesNotExist error][3] +![Chyba DoesNotExist](images/does_not_exist2.png) - [3]: images/does_not_exist2.png +To nechceme! Našťastie Django má zabudované niečo, čo si s tým poradí: `get_object_or_404`. V prípade, že neexistuje žiaden `Post` s daným `pk`, zobrazí oveľa krajšiu stránku, `Page Not Found 404`. -To nechceme! Ale samozrejme Django prichádza s niečim, čo si s tým poradí: `get_object_or_404`. V príade, že neexistuje žiaden `Post` s daným `pk` zobrazí oveľa krajšiu stránku (nazývanú `Page Not Found 404`). +![Stránka nenájdená](images/404_2.png) -![Page not found][4] +Dobrá správa je, že si môžeš vytvoriť svoju vlastnú `Page not found` stránku a spraviť ju takú peknú, ako len chceš. Ale to nie je momentálne extra dôležité, takže to preskočíme. - [4]: images/404_2.png +Dobre, čas pridať *view* do nášho súboru `views.py`! -Dobrá správa je, že si môžeš vytvoriť svoju vlastnú `Page not found` stránku a spraviť ju tak peknú ako len chceš. Ale to nie je momentálne príliš dôležité, takže to preskočíme. +V `blog/urls.py` sme vytvorili URL pravidlo s názvom `post_detail`, ktoré odkazuje na view s názvom `views.post_detail`. To znamená, že Django očakáva view funkciu s názvom `post_detail` v súbore `blog/views.py`. -Dobre, čas pridať *view* do nášho `views.py` súboru! +Mali by sme otvoriť `blog/views.py` v editore a pridať nasledovný kód k ostatným `from` riadkom: -Mali by sme otvoriť `blog/views.py` a pridať nasledujúci kód: +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render, get_object_or_404 ``` +A na konci súboru pridáme náš *view*: -Blízko riadkov `from`. A na konci súboru pridáme náš *view*: +{% filename %}blog/views.py{% endfilename %} ```python def post_detail(request, pk): @@ -117,82 +138,89 @@ def post_detail(request, pk): return render(request, 'blog/post_detail.html', {'post': post}) ``` - Áno. Nastal čas obnoviť stránku: http://127.0.0.1:8000/ -![Post list view][5] - - [5]: images/post_list2.png +![Post list view](images/post_list2.png) Funguje to! Ale čo sa stane, keď klikneš na odkaz v názve príspevku blogu? -![TemplateDoesNotExist error][6] +![Chyba TemplateDoesNotExist](images/template_does_not_exist2.png) - [6]: images/template_does_not_exist2.png +Ale nie! Ďalšia chyba! Ale už vieme, s čím máme dočinenia, že? Potrebujeme pridať šablónu! -Ale nie! Ďalšia chyba! Ale už vieme, s čim mám dočinenia, že? Potrebujeme pridať šablónu! +## Vytvorenie šablóny pre detaily príspevku -## Vytvor šablónu pre detail príspevku +Vytvoríme súbor v `blog/templates/blog` s názvom `post_detail.html` a otvoríme ho v editore. -Vytvoríme súbor v `blog/templates/blog` s názvom `post_detail.html`. +Vlož doň nasledujúci kód: -Bude to vyzerať takto: +{% 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 %} ``` -Znova raz rozširujeme `base.html`. V bloku `content` chceme zobraziť published_date príspevku (pokiaľ existuje), titulok a text. Ale mali by sme prebrať pár dôležitých vecí, však? - -{% raw %}`{% if ... %} ... {% endif %}` je tag šablóny, ktorý môžeme použiť ak chceme niečo skontrolovať (pamätáš na `if ... else ..` z kapitoly **Úvod do Pythonu**?). V tomto prípade chceme skontrolovať, či `published_date` príspevku nie je prázdny.{% endraw %} +Opäť raz rozširujeme (extend) `base.html`. V bloku `content` chceme zobraziť published_date príspevku (pokiaľ existuje), titulok a text. Ale mali by sme prebrať pár dôležitých vecí, však? -Dobre, môžeme obnoviť našu stránku a pozrieť sa, či `Page not found` zmizlo. +{% raw %}`{% if ... %} ... {% endif %}` je tag šablóny, ktorý môžeme použiť, ak chceme niečo skontrolovať. (Pamätáš si `if ... else ...` z kapitoly **Úvod do jazyka Python**?) V tomto prípade chceme skontrolovať, či pole `published_date` nášho príspevku nie je prázdne.{% endraw %} -![Post detail page][7] +Dobre, môžeme obnoviť našu stránku a pozrieť sa, či `TemplateDoesNotExist` zmizlo. - [7]: images/post_detail2.png +![Post detail stránka](images/post_detail2.png) Jupí! Funguje to! -## Ešte jedna vec: čas nasadiť aplikáciu! +# Je čas nasadiť! -Bolo by dobré vedieť, či tvoja stránka stále funguje na PythonAnywhere, že? Pokúsme sa ju znova nasadiť. +Bolo by dobré vedieť, či tvoja stránka stále funguje na PythonAnywhere, však? Pokúsme sa ju znova nasadiť. -``` -$ git status -$ git add -A . -$ git status -$ git commit -m "Pridaný view a šablóna pre detail príspevku blogu a taktiež CSS pre stránku." -$ git push -``` +{% filename %}command-line{% endfilename %} -* Potom v [Bash konzole PythonAnywhere][8]: + $ git status + $ git add . + $ git status + $ git commit -m "Pridany view a sablona pre detaily prispevku a taktiez CSS pre stranku" + $ git push + - [8]: https://www.pythonanywhere.com/consoles/ +Potom v [Bash konzole PythonAnywhere](https://www.pythonanywhere.com/consoles/): -``` -$ 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 + [...] + + +(Nezabudni nahradiť `` svojou subdoménou na PythonAnywhere bez špicatých zátvoriek.) + +## Aktualizovanie statických súborov na serveri + +Servery ako PythonAnywhere sa ku "statickým súborom" (ako CSS súbory) správajú inak ako ku Python súborom, lebo ich môžu optimalizovať, aby ich bolo možné rýchlejšie načítať. Preto keď meníme naše CSS súbory, musíme spustiť ďalší príkaz na serveri, aby ich aktualizoval. Názov tohto príkazu je `collectstatic`. + +Začni spustením virtualenvu, ak už nie je aktivovaný (PythonAnywhere používa príkaz `workon`, je to presne ako príkaz `source mojenv/bin/activate`, ktorý si použila na vlastnom počítači): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ workon .pythonanywhere.com + (ola.pythonanywhere.com)$ python manage.py collectstatic + [...] + -* A nakoniec preskoč na [kartu Web][9] and klinki na **Reload**. +Tento `manage.py collectstatic` príkaz sa trochu podobá na `manage.py migrate`. Urobíme zmeny v našom kóde a potom povieme Djangu, aby aplikovalo (*apply*) dané zmeny buď na statické súbory na serveri, alebo na databázu. - [9]: https://www.pythonanywhere.com/web_app_setup/ +Každopádne, teraz môžeme prejsť na stránku ["Web"](https://www.pythonanywhere.com/web_app_setup/) (cez menu v pravom hornom rohu konzoly), stlačiť **Reload** a pozrieť sa na náš výsledok na adrese https://subdomena.pythonanywhere.com. -A to by malo byť všetko! Gratulujeme :) +A to by malo byť všetko! Gratulujeme! :) \ No newline at end of file diff --git a/sk/extend_your_application/images/404_2.png b/sk/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/sk/extend_your_application/images/404_2.png and b/sk/extend_your_application/images/404_2.png differ diff --git a/sk/extend_your_application/images/attribute_error2.png b/sk/extend_your_application/images/attribute_error2.png index 6edcd9933c3..4b8262476d9 100644 Binary files a/sk/extend_your_application/images/attribute_error2.png and b/sk/extend_your_application/images/attribute_error2.png differ diff --git a/sk/extend_your_application/images/does_not_exist2.png b/sk/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/sk/extend_your_application/images/does_not_exist2.png and b/sk/extend_your_application/images/does_not_exist2.png differ diff --git a/sk/extend_your_application/images/no_reverse_match2.png b/sk/extend_your_application/images/no_reverse_match2.png index 306926206f8..aba1c9c8980 100644 Binary files a/sk/extend_your_application/images/no_reverse_match2.png and b/sk/extend_your_application/images/no_reverse_match2.png differ diff --git a/sk/extend_your_application/images/post_detail2.png b/sk/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/sk/extend_your_application/images/post_detail2.png and b/sk/extend_your_application/images/post_detail2.png differ diff --git a/sk/extend_your_application/images/post_list2.png b/sk/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/sk/extend_your_application/images/post_list2.png and b/sk/extend_your_application/images/post_list2.png differ diff --git a/sk/extend_your_application/images/template_does_not_exist2.png b/sk/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/sk/extend_your_application/images/template_does_not_exist2.png and b/sk/extend_your_application/images/template_does_not_exist2.png differ diff --git a/sk/how_the_internet_works/README.md b/sk/how_the_internet_works/README.md old mode 100755 new mode 100644 index 0991dbd9c0d..c879f62ccb4 --- a/sk/how_the_internet_works/README.md +++ b/sk/how_the_internet_works/README.md @@ -1,53 +1,47 @@ -# Ako funguje Internet +# Ako funguje internet +> Pre čitateľky a čitateľov doma: Táto kapitola je spracovaná vo videu [How the Internet Works](https://www.youtube.com/watch?v=oM9yAA09wdc). +> > Táto kapitola je inšpirovaná prednáškou "Ako funguje Internet" od Jessicy McKellar (http://web.mit.edu/jesstess/www/). -Stavíme sa, že Internet používaš každý deň. Ale vieš, čo sa deje, keď napíšeš adresu, ako https://djangogirls.org do prehliadača a stlačíš `enter`? +Stavíme sa, že internet používaš každý deň. Ale vieš, čo sa udeje, keď napíšeš adresu ako https://djangogirls.org do prehliadača a stlačíš `enter`? -Prvá vec, ktorú potrebuješ vedieť je, že webové stránky sú len kopa súborov uložených na pevnom disku. Podobne ako tvoje filmy, hudba a obrázky. Ale je tu jedna časť, ktorá je špecifická pre webové stránky: obsahujú počítačový kód nazývaný HTML. +Prvá vec, ktorú musíš vedieť, je, že webová stránka je len kôpka súborov uložených na pevnom disku, presne ako tvoje filmy, hudba či obrázky. Ale je tu jedna vec, ktorá je špecifická pre webové stránky: obsahujú počítačový kód nazývaný HTML. -Pokiaľ nemáš skúsenosti s programovaní, môže byť pochopenie HTML zo začiatku zložité, ale tvoj webový prehliadač (ako Chrome, Safari, Firefox atď.) ho milujú. Webové prehliadače sú navrhnuté na to, aby rozumeli kódu, nasledovali jeho inštrukcie a prezentovali súbory, ktoré tvoria tvoju webovú stránku presne tak, ako to chceš. +Pokiaľ nemáš skúsenosti s programovaním, môže byť pochopenie HTML zo začiatku zložité, ale tvoj webový prehliadač (ako Chrome, Safari, Firefox atď.) HTML miluje. Webové prehliadače sú navrhnuté tak, aby rozumeli tomuto kódu, nasledovali jeho inštrukcie a ukazovali súbory, ktoré tvoria tvoju webovú stránku, presne tak, ako chceš. -Ako s každým súborom, potrebujeme uložiť HTML súbor niekde na pevnom disku. V prípade Interntu používame špeciálne, výkonné počítače nazývane *servery*. Nemajú obrazovku, myš alebo klávesnicu, pretože ich hlavnou úlohou je ukladať dáta a poskytovať ich. Preto ich voláme *servery* -- pretože *poskytujú* (anglicky serve) tvoje dáta. +Ako každý iný súbor, aj HTML súbor musí byť uložený niekde na pevnom disku. V prípade internetu používame špeciálne výkonné počítače nazývané *servery*. Nemajú obrazovku, myš alebo klávesnicu, pretože ich hlavnou úlohou je ukladať dáta a poskytovať ich. Preto ich voláme *servery* -- pretože *poskytujú* (serve) tvoje dáta. -OK, avšak chceš vedieť, ako vyzerá Internet, že? +OK, ale ty chceš vedieť, ako vyzerá internet, že? Nakreslili sme ti obrázok! Vyzerá takto: -![Obrázok 1.1][1] +![Obrázok 1.1](images/internet_1.png) - [1]: images/internet_1.png +Vyzerá to ako neporiadok, že? V skutočnosti je to sieť prepojených strojov (hore spomenutých *serverov*). Stoviek a tisícok strojov! Mnoho, mnoho kilometrov káblov po celom svete! Môžeš navštíviť stránku Submarine Cable Map (http://submarinecablemap.com), ak chceš vidieť, aká komplikovaná sieť to je. Tu je obrázok zo stránky: -Vyzerá to ako neporiadok, že? V skutočnosti je to sieť prepojených strojov (nedávno spomenutých *serverov*). Stoviek a tisícok strojov! Mnoho, mnoho kilometrov káblov po celom svete! Môžeš navštíviť stránku Submarine Cable Map (http://submarinecablemap.com) aby si videla nakoľko komplikovaná sieť to je. Tu je obrázok zo stránky: +![Obrázok 1.2](images/internet_3.png) -![Obrázok 1.2][2] - - [2]: images/internet_3.png - -Nie je to fascinujúce? Ale zjavne nie je možné mať kábel medzi každým strojom pripojeným k Internetu. Takže na to, aby sme boli schopní kontaktovať stroj (napríklad ten na ktorom je uložená stránka https://djangogirls.org) musíme poslať žiadosť cez mnoho, mnoho rozdielnych strojov. +Nie je to fascinujúce? Ale zjavne nie je možné mať kábel medzi každým strojom pripojeným k internetu. Takže na to, aby sme boli schopní kontaktovať nejaký stroj (napríklad ten, na ktorom je uložená stránka https://djangogirls.org), musíme poslať žiadosť cez mnoho, mnoho rozdielnych strojov. Vyzerá to takto: -![Obrázok 1.3][3] - - [3]: images/internet_2.png - -Predstav si, že keď napíšeš https://djangogirls.org, pošleš list, v ktorom stojí: "Drahé Django Girls, chcem vidieť stránku djangogirls.org. Prosím pošli mi ju!" +![Obrázok 1.3](images/internet_2.png) -Tvoj list ide na najbližšiu poštu. Potom ide na ďalšiu, ktorá je o čosi bližšie adresátovi, potom na ďalšiu a ďalšiu až kým nedorazí do svojej destinácie. Jediná unikátna vec je, že ako pošleš mnoho listov (*data paketov*) na rovnaké miesto, môžu ísť cez úplne odlišné pošty (*routy*). Záleží to na tom, ako sú distribuované na každej pošte. +Predstav si, že keď napíšeš https://djangogirls.org, pošleš list, v ktorom stojí: "Drahé Django Girls, chcem vidieť stránku djangogirls.org. Prosím, pošlite mi ju!" -![Obrázok 1.4][4] +Tvoj list ide na najbližšiu poštu. Potom ide na ďalšiu, ktorá je o čosi bližšie adresátovi či adresátke, potom na ďalšiu a ďalšiu, až kým nedorazí do svojej destinácie. Jediná unikátna vec je, že keď pošleš mnoho listov (*dátových paketov*) na rovnaké miesto, môžu ísť cez úplne odlišné pošty (*routery*). Záleží to od toho, ako sú rozdistribuované na každej pošte. - [4]: images/internet_4.png +![Obrázok 1.4](images/internet_4.png) -Áno, je to tak jednoduché. Pošleš správu a očakávaš nejakú odpoveď. Samozrejme, namiesto papiera a pera použijes byty dát, ale myšlienka je rovnaká! +Takto to funguje - posielaš správy a očakávaš nejaké odpovede. Akurát namiesto papiera a pera používaš bajty dát, ale princíp je rovnaký! -Namiesto adries s menom ulice, mesta, PSČ a krajinou používame IP adresy. Tvoj počítač sa najprv opýta DNS (Domain Name System) aby preložil djangogirls.org na IP adresu. Funguje to trocha ako staré dobré telefónne zoznamy, kde si môžeš vyhľadať meno osoby ktorú chceš kontaktovať a nájsť jej telefón a adresu. +Namiesto adries s názvom ulice, mesta, PSČ a krajinou používame IP adresy. Tvoj počítač najprv požiada DNS (Domain Name System), aby preložil djangogirls.org na IP adresu. Funguje to trocha ako staré dobré telefónne zoznamy, kde si môžeš vyhľadať meno osoby, ktorú chceš kontaktovať, a nájsť jej telefón a adresu. -Keď pošleš list, musí mať určité náležitosti, aby ho bolo možné správne doručiť: adresu, známku atď. Taktiež používaš jazyk, ktorému adresát rozumie, že? Rovnako to funguje aj s *data paketmi* ktoré pošleš aby sa ti zobrazila stránka. Používame protokol s názvom HTTP (Hypertext Transfer Protocol). +Keď pošleš list, musí mať určité náležitosti, aby ho bolo možné správne doručiť: adresu, známku atď. Taktiež používaš jazyk, ktorému adresát rozumie, že? Rovnako to funguje aj s *dátovými paketmi*, ktoré posielaš, aby sa ti zobrazila stránka. Používame protokol s názvom HTTP (Hypertext Transfer Protocol). -Takže, v podstate, keď máš webovú stránku, musíš mať *server* (stroj) na ktorom bude žiť. Keď *server* obdrží prichádzajúcu *požiadavku* (v liste), pošle naspäť tvoju webovú stránku (v ďalšom liste). +Takže v podstate keď máš webovú stránku, musíš mať *server* (stroj), na ktorom bude žiť. Keď *server* obdrží prichádzajúcu *požiadavku* alebo request (v liste), pošle naspäť tvoju webovú stránku (v ďalšom liste). -Keďže toto je Django tutoriál, spýtaš sa, čo robí Django. Keď pošleš odpoveď, nechceš vždy poslať rovnaké veci každému. Je oveľa lepšie ak sú tvoje listy osobné, hlavne pre osobu, ktorá ti práve teraz napísala, že? Django ti pomáha vytvoriť tieto osobné, zaujímavé listy :). +Keďže toto je Django tutoriál, možno sa pýtaš, kde do tohto procesu vstupuje Django. Keď pošleš odpoveď, nechceš vždy poslať každému to isté. Je oveľa lepšie, ak sú tvoje listy osobné, presne pre človeka, ktorý ti práve napísal, že? Django ti pomáha vytváriť tieto osobné, zaujímavé listy. :) Dosť bolo rečí, je čas tvoriť! \ No newline at end of file diff --git a/sk/how_the_internet_works/images/internet_1.png b/sk/how_the_internet_works/images/internet_1.png index 9c5bcf0b003..e289eac2b23 100644 Binary files a/sk/how_the_internet_works/images/internet_1.png and b/sk/how_the_internet_works/images/internet_1.png differ diff --git a/sk/how_the_internet_works/images/internet_2.png b/sk/how_the_internet_works/images/internet_2.png index dd5861f376f..e8cf8b77999 100644 Binary files a/sk/how_the_internet_works/images/internet_2.png and b/sk/how_the_internet_works/images/internet_2.png differ diff --git a/sk/how_the_internet_works/images/internet_3.png b/sk/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/sk/how_the_internet_works/images/internet_3.png and b/sk/how_the_internet_works/images/internet_3.png differ diff --git a/sk/how_the_internet_works/images/internet_4.png b/sk/how_the_internet_works/images/internet_4.png index 2661cec1b61..d4748ac48ef 100644 Binary files a/sk/how_the_internet_works/images/internet_4.png and b/sk/how_the_internet_works/images/internet_4.png differ diff --git a/sk/html/README.md b/sk/html/README.md old mode 100755 new mode 100644 index 280869a6940..74654b69e51 --- a/sk/html/README.md +++ b/sk/html/README.md @@ -1,216 +1,227 @@ # Úvod do HTML -Môžno sa pýtaš, čo jej šablóna? +Možno sa pýtaš, čo je to šablóna? -Šablóna je súbor, ktorý môžeme znova opakovane použiť, aby sme prezentovali nové informácie v konzistentnom formáte - šablónu môžeš použiť napríklad ako pomôcku pri písaní listu, pretože aj napriek tomu, že každý list môže obsahovať rozdielnu správu a byť adresovaný inej osobe, budú mať rovnaký formát. +Šablóna (template) je súbor, ktorý môžeme viackrát použiť, aby sme ukazovali rôzne dáta v rovnakom formáte. Šablónu môžeš použiť napríklad ako pomôcku pri písaní listu, pretože aj napriek tomu, že každý list môže obsahovať rozdielnu správu a byť adresovaný inej osobe, bude mať rovnaký formát. -Formát Django šablóny je popísaný v jazyk nazývanom HTML (to je to HTML, ktoré sme spomenuli v prvej kapitole **Ako funguje Internet**). +Formát Django šablóny je popísaný v jazyku nazývanom HTML (to je to HTML, ktoré sme spomenuli v prvej kapitole **Ako funguje internet**). ## Čo je HTML? -HTML je jednoduchý kód, ktorý je interpretovaný tvojím webovým prehliadačom - ako napríklad Chrome, Firefox alebo Safari - aby tak zobrazil užívateľom webové stránky. +HTML je kód, ktorý je interpretovaný tvojím webovým prehliadačom - ako napríklad Chrome, Firefox alebo Safari - aby tak zobrazil užívateľkám a užívateľom webové stránky. -HTML znamená "HyperText Markup Language". **HyperText** znamená, že sa jedná o typ textu, ktorý podporuje hypertextové odkazy medzi stránkami. **Markup** znamená, že sme vzali dokument a označili ho kódom aby sme niečomu povedali (v tomto prípade prehliadaču) ako interpretovať stránku. HTML kód je budovaný za pomoci **tagov**, každý začínajúci znakom `<` a končiaci znakom `>`. Tieto tagy reprezentujú značkovacie (Markup) **elementy**. +HTML znamená "HyperText Markup Language". **HyperText** znamená, že sa jedná o typ textu, ktorý podporuje hypertextové odkazy medzi stránkami. **Markup** znamená, že sme vzali dokument a označili ho kódom, aby sme niečomu povedali (v tomto prípade prehliadaču), ako interpretovať stránku. HTML kód je budovaný pomocou **tagov**, ktoré začínajú znakom `<` a končia znakom `>`. Tieto tagy reprezentujú značkovacie (markup) **elementy**. ## Tvoja prvá šablóna! -Vytvorenie šablóny znamená vytvorenie súboru šablóny. +Vytvorenie šablóny znamená, že najprv musíme vytvoriť šablónový súbor. Všetko je súbor, však? To si si asi už všimla. -Šablóny sú uložené v zložke `blog/templates/blog`. Takže najprv vytvor v zložke blogu zložku s názvom `templates`. Potom vytvor ďalšiu zložku s názvom `blog` v zložke templates: +Šablóny sú uložené v zložke `blog/templates/blog`. Takže najprv vytvor v priečinku blog priečinok s názvom `templates`. Potom vytvor ďalší priečinok s názvom `blog` v priečinku templates: -``` -blog -└───templates - └───blog -``` + blog + └───templates + └───blog + -(Možno sa pýtaš prečo potrebujeme dve zložky s menom `blog` - ako neskôr zistíš, je to len užitočna konvencia, ktorá ti uľahčí život keď veci začnú byť komplikovanejšie.) +(Možno sa pýtaš, prečo potrebujeme dve zložky s menom `blog` - ako neskôr zistíš, je to len užitočná konvencia, ktorá ti uľahčí život, keď sa veci začnú komplikovať.) -A teraz vytvor súbor `post_list.html` (zatiaľ ho ponechaj prázdny) v zložke `blog/templates/blog`. +A teraz vytvor súbor `post_list.html` (zatiaľ ho ponechaj prázdny) v priečinku `blog/templates/blog`. Pozri sa, ako momentálne vyzerá tvoja stránka: http://127.0.0.1:8000/ -> Pokiaľ stále vidíš chybu `TemplateDoesNotExists`, skús reštartovať tvoj server. Použi príkazový riadok, zastav server stlačením Ctrl+C (stlač naraz tlačidlá Control a C) a spusti ho znova pomocou príkazu `python manage.py runserver`. +> Pokiaľ stále vidíš chybu `TemplateDoesNotExist`, skús reštartovať svoj server. Choď do príkazového riadku, zastav server stlačením Ctrl+C (stlač naraz tlačidlá Control a C) a spusti ho znova pomocou príkazu `python manage.py runserver`. -![Obrázok 11.1][1] +![Obrázok 11.1](images/step1.png) - [1]: images/step1.png +Chyba je preč! Gratulujeme :) Avšak tvoja webstránka zatiaľ neukazuje nič, len prázdnu stránku, pretože tvoja šablóna je taktiež prázdna. To musíme napraviť. -Žiadne ďalšie chyby! Gratulujeme :) Avšak tvoja stránka zatiaľ neukazuje nič, okrem prázdnej stránky, pretože tvoja šablóna je taktiež prázdna. To musíme opraviť. +Otvor svoj nový súbor v editore a pridaj doň nasledovné: -Pridaj nasledujúci kód do tvojho súboru šablóny: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + -

Ahoj!

-

Funguje to!

+ +

Hi there!

+

It works!

+ ``` Takže ako momentálne vyzerá tvoja stránka? To môžeš zistiť kliknutím na: http://127.0.0.1:8000/ -![Obrázok 11.2][2] - - [2]: images/step3.png +![Obrázok 11.2](images/step3.png) -Funguje to! Dobrá práca :) +Funguje to. Dobrá práca! :) -* Najzákladnejší tag, ``, je vždy na začiatku každej webovej stránky a `` je vždy na jej konci. Ako môžeš vidieť, celý obsah stránky sa nachádza medzi začínajúcim tagom `` a uzatvárajúcim tagom `` -* `

` je tag pre element odstavca; `

` uzatvára každý odstavec +* Riadok `` nie je HTML tag. Len definuje typ dokumentu. V tomto prípade hovorí prehliadaču, že typ nášho dokumentu je [HTML5](https://html.spec.whatwg.org/#the-doctype). Každý HTML5 súbor začína takto. +* Najzákladnejší tag, ``, je vždy na začiatku každej webovej stránky, a `` je vždy na jej konci. Ako môžeš vidieť, celý obsah stránky sa nachádza medzi začínajúcim tagom `` a uzatvárajúcim tagom `` +* `

` je tag pre element odstavca; `

` každý odstavec uzatvára -## Head & body +## Head a body Každá HTML stránka je taktiež rozdelená do dvoch elementov: **head** a **body**. -* **head** je element, ktorý obsahuje informácie o dokumente, ktoré nie sú zobrazené na obrazovke. +* **head** je element, ktorý obsahuje informácie o dokumente, ktoré nie sú zobrazené na obrazovke. -* **body** je element, ktorý obsahuje všetko ostatné zobrazené ako časť webovej stránky. +* **body** je element, ktorý obsahuje všetko ostatné, zobrazené ako časť webovej stránky. -`` používame, aby sme povedali prehliadaču o konfigurácii stránky a `` aby sme mu povedali, čo na stránke je. +`` používame, aby sme povedali prehliadaču o konfigurácii stránky, a ``, aby sme mu povedali, čo na stránke je. -Napríklad môžeš dať stránke titulok za použitia title elementu vo vnútri `` takto: +Napríklad môžeš dať stránke titulok pomocou elementu title v elemente `` takto: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + Ola's blog -

Ahoj!

-

Funguje to!

+

Hi there!

+

It works!

``` Ulož súbor a znova načítaj svoju stránku. -![Obrázok 11.3][3] - - [3]: images/step4.png +![Obrázok 11.3](images/step4.png) -Všimni si ako prehliadač rozumie, že "Ola's blog" je titulok tvojej stránky? Interpretuje `Ola's blog` a vkladá text ako názov záložky (tento názov bude použitý aj keď si stránku uložíte a tak ďalej). +Všimla si si, ako prehliadač porozumel, že "Ola's blog" je titulok tvojej stránky? Prečítal si slová `Ola's blog` a vložil ich do záhlavia záložky v tvojom prehliadači (tiež ich bude používať, keby si si stránku napríklad uložila, atď.). Pravdepodobne si taktiež všimneš, že každý začínajúci tag má svoj *uzatvárajúci tag* obsahujúci `/`, a že elementy sú *vnorené* (tj. nemôžeš daný tag zatvoriť, kým nie sú taktiež zatvorené všetky tagy, ktoré sú v jeho vnútri). -Je to ako vkladať veci do krabice. Máš jednú veľkú krabicu, ``; vo vnútri je ``, a tá obsahuje menšie krabice: `

`. +Je to, ako keby si vkladala veci do krabice. Máš jednu veľkú krabicu, ``; vo vnútri je ``, a tá obsahuje menšie krabice: `

`. + +Musíš dodržiavať pravidlá *uzatvárania* tagov a *vnorenia* elementov - pokiaľ ich nebudeš dodržiavať, prehliadač nemusí tagy správne interpretovať a tvoja stránka sa zobrazí nesprávne. -Musíš nasledovať tieto pravidlá *uzatvárania* tagov a *vnorenia* elementov - pokiaľ ich nebudeš dodržovať, prehliadač nemusí byť schopný správne interpretovať tagy a tvoja stránka bude zobrazená nesprávne. +## Upravenie tvojej šablóny -## Uprav svoju šablónu +Môžeš sa trocha pohrať s tým, že budeš upravovať svoju šablónu! Tu je zopár užitočných tagov: -Môžeš sa trocha pohrať s tým, že budeš upravovať svoju šablónu! Tu je pár užitočných tagov: +* `

Hlavný nadpis

` - pre tvoj najdôležitejší nadpis +* `

Podnadpis

` pre nadpis na nižšej úrovni +* `

Pod-podnadpis

`... a tak ďalej až do `
` +* `

Odsek textu

` +* `text` zvýrazňuje tvoj text +* `text` zvýrazňuje tvoj text o čosi viac +* `
` vkladá nový riadok (do br nemôžeš nič vložiť a nemá ani uzatvárací tag) +* `link` vytvára odkaz +* `
  • prvá položka
  • druhá položka
` vytvára zoznam, ako je tento! +* `
` definuje sekciu stránky +* `` definuje skupinu navigačných odkazov +* `
` (článok) definuje nezávislý obsah, ktorý má zmysel sám osebe +* `
` definuje sekciu v dokumente +* `
` definuje hlavičku dokumentu alebo sekcie +* `
` definuje hlavný obsah dokumentu +* `` definuje obsah vedľa iného obsahu (napr. bočná lišta) +* `
` definuje pätičku dokumentu alebo sekcie +* `` definuje konkrétny čas (alebo dátum a čas) -* `

Hlavný nádpis

` - pre tvoj najdôležitejší nádpis -* `

Podnádpis

` pre nádpis na nižšej úrovni -* `

Pod-podnádpis

`.. a tak ďalej až do `
` -* `text` zdôrazňuje tvoj text -* `text` zvýrazňuje tvoj text o čosi viac -* `
` vkladá nový riadok (do br nemôžeš nič vložiť) -* `link` vytvára odkaz -* `
  • prvá položka
  • druhá položka
` vytvára zoznam ako tento! -* `
` definuje sekciu stránky +Tu je príklad úplnej šablóny, skopíruj ho do súboru `blog/templates/blog/post_list.html`: -Tu je príklad celej šablóny: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + Django Girls blog - +
+

Django Girls Blog

+
-
-

published: 14.06.2014, 12:14

-

Môj prvý príspevok

+
+ +

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

-

Môj druhý príspevok

+
+ +

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.

-
+ ``` -Vytvorili sme tri `div` sekcie. +Týmto sme vytvorili jednu hlavičkovú `header` sekciu a dve článkové `article` sekcie. -* Prvá `div` sekcia obsahuje titulok nášho blogu - je to nádpis a odkaz -* Ďalšie dva `div` elementy obsahujú príspevky blogu s časom publikovania, `h2` s nádpisom príspevku, na ktorý sa dá kliknúť a dva `p` (odstavce) textu, jeden pre dátum a druhý pre náš príspevok. +* Prvý `header` element obsahuje hlavný nadpis nášho blogu - je to nadpis a odkaz +* Nasledujúce `article` elementy obsahujú naše blogové príspevky, každý s dátumom publikovania v `time` elemente, s nadpisom príspevku v `h2` elemente, na ktorý sa dá kliknúť, a s odstavcovým elementom `p`, ktorý predstavuje text nášho príspevku. -Dá nám to tento efekt: +Výsledok je nasledovný: -![Obrázok 11.4][4] +![Obrázok 11.4](images/step6.png) - [4]: images/step6.png +Jupí! Ale zatiaľ naša šablóna zobrazila len presne **tie isté dáta** - kým pred chvíľou sme hovorili, že nám šablóny dovoľujú zobrazovať **rozdielne** dáta v **rovnakom formáte**. -Jupí! Ale zatiaľ naša šablóna zobrazila len presne **rovnaké informácie** - kým pred chvíľou sme hovorili, že nám šablóny dovoľujú zobrazovať **rozdielne** informácie v **rovnakom formáte**. +To, čo v skutočnosti chceme docieliť, je zobraziť reálne príspevky pridané v Django admin rozhraní - a to teraz aj spravíme. -To čo v skutočnosti chceme spraviť je zobraziť reálne príspevky v našom Django admin rozhraní - a to je to, čo teraz spravíme. +## Ešte jedna vec: nasaďme to! -## Ešte jedna vec: nasaďte to! - -Bolo by skvelé, ak by sme všetky tieto veci mohli vidieť naživo na Internete, že? Spravme ďalšie PythonAnywhere nasadenie: +Bolo by skvelé, ak by sme všetky tieto veci mohli vidieť naživo na internete, že? Spravme ďalšie PythonAnywhere nasadenie: ### Commitni a pošli svoj kód na Github Najprv sa pozrime, ktoré súbory sa zmenili od posledného nasadenia (tieto príkazy spusti lokálne, nie na PythonAnywhere): -``` -$ git status -``` +{% filename %}command-line{% endfilename %} -Uisti sa, že si v zložke `djangogirls` a následne povedzme `gitu` nech zahrnie všetky zmeny v zložke: + $ git status + -``` -$ git add -A . -``` +Uisti sa, že si v priečinku `djangogirls`, a následne povedz `gitu`, nech zahrnie všetky zmeny v priečinku: -> **Poznámka** - `-A` (skratka pre "all" (všetko)) znamená, že `git` rozozná, ak si vymazala súbory (štandardne rozoznáva len nové/modifikované súbory). Pamätaj si tiež (bolo to v kapitole 3), že `.` znamená aktuálny adresár. +{% filename %}command-line{% endfilename %} -Predtým, ako nahrajeme všetky súbory, skontrolujme čo bude `git` nahrávať (všetky súbory, ktoré `git` nahraje by teraz mali byť zelené): + $ git add . + -``` -$ git status -``` +Predtým, ako nahráme všetky súbory, skontrolujme, čo bude `git` nahrávať (všetky súbory, ktoré `git` nahrá, by teraz mali byť zelené): -Už sme skoro tam, teraz nastal čas mu povedať, aby uložil tieto zmeny v jeho histórii. Dáme mu "commit správu", kde popíšeme, čo sme zmenili. V tomto štádiu môžeš napísať čokoľvek, čo chceš, ale je nápomocné napísať čosi, čo je popisné natoľko, že si budeš v budúcnosti pamätať, čo si spravila. +{% filename %}command-line{% endfilename %} -``` -$ git commit -m "Zmeny v HTML pre stránku." -``` + $ git status + -> **Poznámka** - Uisti sa, že si použila dvojité úvodzovky okolo commit správy. +Už sme skoro tam, teraz nastal čas mu povedať, aby uložil tieto zmeny v jeho histórii. Dáme mu "commit správu" (commit message), kde popíšeme, čo sme zmenili. V tomto štádiu môžeš napísať čokoľvek, čo chceš, ale je nápomocné napísať čosi, čo je popisné natoľko, že si budeš v budúcnosti pamätať, čo si spravila. -Po tom, čo sme to dokončili, nahrajeme (push) naše zmeny na Github: +{% filename %}command-line{% endfilename %} -``` -git push -``` + $ git commit -m "Zmeny v HTML pre stranku." + + +> **Poznámka** Uisti sa, že si okolo commit správy použila dvojité úvodzovky. + +Keď to máme hotové, nahráme (push) naše zmeny na GitHub: + +{% filename %}command-line{% endfilename %} + + $ git push + ### Stiahni svoj kód na PythonAnywhere a obnov svoju webovú aplikáciu -* Otvor [konzolovú stránku PythonAnywhere][5] a prejdi do svojej **Bash konzole** (alebo naštartuj novú). Potom zadaj: +* Otvor [konzolovú stránku PythonAnywhere](https://www.pythonanywhere.com/consoles/) a prejdi do svojej **Bash konzoly** (alebo naštartuj novú). Potom zadaj: - [5]: https://www.pythonanywhere.com/consoles/ +{% filename %}PythonAnywhere command-line{% endfilename %} -``` -$ cd ~/my-first-blog -$ source myvenv/bin/activate -(myvenv)$ git pull -[...] -(myvenv)$ python manage.py collectstatic -[...] -``` + $ cd ~/.pythonanywhere.com + $ git pull + [...] + -A sleduj ako sa tvoj kód sťahuje. Pokiaľ chceš skontrolovať, že dorazil, môžeš skočiť do **záložky Files** a pozrieť sa na svoj kód na PythonAnywhere. +Nezabudni nahradiť `` svojou subdoménou na PythonAnywhere bez špicatých zátvoriek. Názov tvojej subdomény je zväčša tvoje užívateľské meno na PythonAnywhere, ale sú prípady, kedy môže byť trochu iný (napríklad, keď tvoje užívateľské meno obsahuje veľké písmená). Čiže ak ti tento príkaz nefunguje, skús spustiť `ls` (list files, alebo vypíš súbory), aby si zistila, ako sa tvoja subdoména/podadresár volá, a potom sa do tohto adresára presuň pomocou `cd`. -* Nakoniec skoč do [záložky Web][6] a stlač **Reload** na tvojej webovej aplikácii. +Sleduj, ako sa tvoj kód sťahuje. Ak si chceš overiť, že už prišiel, prejdi na stránku **"Files"** a pozri sa na svoj kód na PythonAnywhere (po ostatné PythonAnywhere stránky sa vieš potom dostať pomocou tlačidla v menu na stránke s konzolou). - [6]: https://www.pythonanywhere.com/web_app_setup/ +* A nakoniec prejdi na [záložku Web](https://www.pythonanywhere.com/web_app_setup/) a stlač **Reload** na svojej webovej aplikácii. -Tvoj update by mal byť dokončený a funkčný! Obnov svoju stránku v prehliadači. Zmeny by mali byť viditeľné :) +Tvoje zmeny by mali byť online! Obnov svoju stránku v prehliadači. Zmeny by mali byť viditeľné. :) \ No newline at end of file diff --git a/sk/html/images/step1.png b/sk/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/sk/html/images/step1.png and b/sk/html/images/step1.png differ diff --git a/sk/html/images/step3.png b/sk/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/sk/html/images/step3.png and b/sk/html/images/step3.png differ diff --git a/sk/html/images/step4.png b/sk/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/sk/html/images/step4.png and b/sk/html/images/step4.png differ diff --git a/sk/html/images/step6.png b/sk/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/sk/html/images/step6.png and b/sk/html/images/step6.png differ diff --git a/sk/images/application.png b/sk/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/sk/images/application.png and b/sk/images/application.png differ diff --git a/sk/installation/README.md b/sk/installation/README.md old mode 100755 new mode 100644 index 9a12e24590c..cec8354f253 --- a/sk/installation/README.md +++ b/sk/installation/README.md @@ -1,49 +1,68 @@ # Pokiaľ robíš tutoriál doma -Pokiaľ robíš tento tutoriál doma, nie na jednej z [Django Girls akcií](https://djangogirls.org/events/), môžeš úplne preskočiť túto kapitolu a pokračovať rovno s kapitolou [Ako funguje Internet](../how_the_internet_works/README.md). +Pokiaľ robíš tento tutoriál doma, a nie na jednej z [Django Girls akcií](https://djangogirls.org/events/), môžeš úplne preskočiť túto kapitolu a pokračovať rovno na kapitolu [Ako funguje internet](../how_the_internet_works/README.md). -Je to preto, že tieto veci pokryjeme v celom tutoriále a toto je len dodatočná stránka, ktorá zjednocuje všetky inštalačné inštrukcie na jednom mieste. Django Girls akcie obsahujú "Inštalačné večery", kde nainštalujeme všetko, aby sme sa s tým nemuseli trápiť počas workshopu, takže táto stránka je pre nás užitočná. - -Pokiaľ ti táto kapitola príde užitočná, môžeš si ju celú prejsť. Ale pokiaľ sa chceš začať učiť veci predtým, ako si nainštalujete množstvo vecí na svoj počítač, preskoč túto kapitolu a my ti vysvetlíme inštalačnú časť neskôr. +Je to preto, lebo v tutoriáli sa zaoberáme inštaláciou vecí, ktoré sú potrebné - toto je len dodatočná stránka, ktorá zhromažďuje všetky pokyny na inštaláciu na jednom mieste (čo je užitočné pre niektoré formáty workshopov). Ak chceš, môžeš si nainštalovať všetko, čo spomíname na tejto stránke, rovno teraz. Ale pokiaľ sa chceš začať učiť predtým, ako si nainštaluješ množstvo vecí na svoj počítač, preskoč túto kapitolu a my ti vysvetlíme, ako veci nainštalovať, neskôr, priamo keď ich budeš potrebovať. Veľa šťastia! +# Ak sa zúčastníš workshopu + +Ak sa chystáš zúčastniť [Django Girls eventu](https://djangogirls.org/events/): + +* Súčasťou tvojho workshopu môže byť "inštalačná párty" pred samotným workshopom. Ak si na takejto inštalačnej párty, táto stránka je pre teba! Tieto inštrukcie ti pomôžu nainštalovať si všetko potrebné pre workshop. Ak treba, tak s pomocou mentoriek alebo mentorov. Potom na samotnom workshope budeš môcť preskočiť inštalačné inštrukcie, ktoré sa objavia v hlavnom tutoriáli, keď sa k nim dostaneš. +* Organizátorky a organizátori tvojho workshopu ťa možno poprosili, aby si si skúsila všetko nainštalovať na svojom počítači doma predtým, než začne workshop. Ak to je tvoj prípad, táto stránka je pre teba! Nasleduj tieto inštrukcie, ako sa ti bude dať. Pokiaľ sa ti nepodarí niečo konkrétne nainštalovať, môžeš sa spýtať svojej mentorky či mentora neskôr na samotnom workshope, keď sa dostaneš po časť tutoriálu s pokynmi k inštalácii. +* Ak súčasťou tvojho workshopu nie je inštalačná párty (alebo si sa nemohla zúčastniť) a pokiaľ ťa organizátorky a organizátori nepoprosili, aby si si všetko nainštalovala pred príchodom, preskoč túto stránku a prejdi rovno na kapitolu [Ako funguje internet](../how_the_internet_works/README.md). Ako budeš postupovať tutoriálom, budeš si inštalovať všetko potrebné. + # Inštalácia -Počas workshopu budeš vytvárať blog a v tutoriále je pár nastavení, ktoré by bolo dobré prejsť predtým, aby si bola pripravení začať programovať. +V tomto tutoriáli si vytvoríš blog. Aby sa ti to podarilo, počas toho, ako budeš postupovať tutoriálom, budeš dostávať inštrukcie, ako nainštalovať rôzny softvér na svojom počítači a ako si povytváravať zopár online účtov, keď bude treba. Táto stránka združuje všetky pokyny k inštalácii a vytváraniu účtov na jednom mieste (čo je užitočné pre niektoré workshopové formáty). -# Inštalácia Pythonu + {% include "/chromebook_setup/instructions.md" %} -{% include "/python_installation/instructions.md" %} + -# Nastavenie virtualenv a inštalácia Django +# Stručný úvod k príkazovému riadku {#command-line} -{% include "/django_installation/instructions.md" %} +Viacero krokov nižšie spomína "konzolu", "terminál", "príkazové okno", "príkazový riadok" (alebo "command line"). Všetky tieto termíny znamenajú to isté: okno na tvojom počítači, do ktorého môžeš zadávať príkazy. Keď sa dostaneš k hlavnému tutoriálu, dozvieš sa o príkazovom riadku viac. V tejto chvíli je pre teba hlavné vedieť, ako otvoriť príkazové okno a ako vyzerá: {% include "/intro_to_command_line/open_instructions.md" %} + +# Inštalácia Pythonu {#python} -# Inštalácia editoru kódu +{% include "/python_installation/instructions.md" %} + +# Inštalácia editoru kódu {#code-editor} {% include "/code_editor/instructions.md" %} -# Inštalácia Gitu +# Vytvorenie virtualenvu a inštalácia Djanga {#virtualenv} + +{% include "/django_installation/instructions.md" %} + +# Inštalácia Gitu {#git} {% include "/deploy/install_git.md" %} -# Vytvorenie GitHub účtu +# Vytvorenie GitHub účtu {#github-account} -Choď na [GitHub.com](https://www.github.com) a založ (Sign Up) si nový účet zdarma. +Choď na [GitHub.com](https://www.github.com) a zaregistruj si nový bezplatný používateľský účet. Nezabudni si zapamätať heslo (ak používaš správcu hesiel, pridaj si ho doň). -# Vytvor si PythonAnywhere účet +# Vytvorenie PythonAnywhere účtu {#pythonanywhere-account} {% include "/deploy/signup_pythonanywhere.md" %} -# Začni čítať +# Začni si čítať + +Gratulujeme, si pripravená začať! Pokiaľ máš stále zvyšný čas pred začiatkom workshopu, bolo by užitočné prečítať si pár začiatočníckych kapitol: + +* [Ako funguje internet](../how_the_internet_works/README.md) -Gratulujeme, si pripravená začať! Pokiaľ máš stále zvyšný čas pred začiatkom workshopu, bolo by užitočné, ak by si si prečítala pár začiatočníckych kapitol: +* [Úvod do príkazového riadku](../intro_to_command_line/README.md) - * [Ako funguje Internet](../how_the_internet_works/README.md) +* [Úvod do jazyka Python](../python_introduction/README.md) - * [Úvod do príkazového riadku](../intro_to_command_line/README.md) +* [Čo je Django?](../django/README.md) - * [Úvod do jazyka Python](../intro_to_command_line/README.md) +# Uži si workshop! - * [Čo je Django?](../django/README.md) \ No newline at end of file +Keď začne workshop, budeš môcť prejsť priamo na [Tvoj prvý Django projekt!](../django_start_project/README.md), lebo si už absolvovala látku z predchádzajúcich kapitol. \ No newline at end of file diff --git a/sk/intro_to_command_line/README.md b/sk/intro_to_command_line/README.md old mode 100755 new mode 100644 index 704842c5210..c18aa27fd67 --- a/sk/intro_to_command_line/README.md +++ b/sk/intro_to_command_line/README.md @@ -1,180 +1,266 @@ # Úvod do rozhrania príkazového riadku -Hm, je to vzrušujúce, však? Už o pár minút napíšeš svoj prvý riadok kódu :) +> Pre čitateľky a čitateľov doma: Táto kapitola je spracovaná v [How the Internet Works](https://www.youtube.com/watch?v=jvZLWhkzX-8) videu. -**Dovoľ nám predstaviť ti tvojho nového priateľa: príkazový riadok!** +Je to vzrušujúce, však?! Už o pár minút napíšeš svoj prvý riadok kódu! :) -Nasledujúce kroky ti ukážu ako používať tú čiernu obrzovku, čo používajú všetci hackeri. Zo začiatku môže vyzerať trochu desivo, ale je to naozaj len riadok, čo čaká na tvoje príkazy. +**Dovoľ nám predstaviť ti tvojho nového kamaráta: príkazový riadok!** -> **Poznámka** Prosím všimni si, že v knižke používame výrazy 'adresár' aj 'zložka' zameniteľne, no ich význam je rovnaký. +Nasledujúce kroky ti ukážu, ako používať tú čiernu obrzovku, čo používajú všetci hackeri a hackerky. Zo začiatku môže vyzerať trochu desivo, ale je to naozaj len okno, čo čaká na tvoje príkazy. + +> **Poznámka** Prosím, maj na pamäti, že v tomto texte používame výrazy "adresár", "zložka" a "priečinok" zameniteľne - ich význam je rovnaký. ## Čo je to príkazový riadok? -Okno, ktoré sa zvyčajne nazýva **príkazový riadok** alebo **rozhranie príkazového riadku** je textová aplikácia na prehliadanie, spracovanie a manipuláciu so súbormi v tvojom počítači. V podstate ako Prieskumník vo Windowse alebo Finder na Macu, akurát bez grafického rozhrania. Ďalšie názvy pre príkazový riadok môžu byť: *cmd*, *CLI*, *prompt*, *konzola* alebo *terminál*. +Okno, ktoré sa zvyčajne nazýva **príkazový riadok** (command line) alebo **rozhranie príkazového riadku** (command line interface) je textová aplikácia na prehliadanie, spracúvanie a manipuláciu so súbormi v tvojom počítači. V podstate je to ako Prieskumník vo Windowse alebo Finder na Macu, akurát bez grafického rozhrania. Ďalšie názvy pre príkazový riadok môžu byť: *cmd*, *CLI*, *prompt*, *konzola* alebo *terminál*. -## Otvor rozhranie príkazového riadku +## Otvorenie rozhranie príkazového riadku Aby sme mohli trochu experimentovať, musíme najskôr rozhranie príkazového riadku otvoriť. -### Windows +{% include "/intro_to_command_line/open_instructions.md" %} + +## Príkazový riadok -Choď na menu Štart → Všetky programy → Príslušenstvo → Príkazový riadok. +Teraz by si už mala vidieť biele alebo čierne okno, ktoré čaká na tvoje príkazy. -### Mac OS X + -Aplikácie → Nástroje → Terminál. +Ak si na Macu alebo Linuxe, zrejme uvidíš `$`. Takto: -### Linux +{% filename %}command-line{% endfilename %} -Pravdepodobne to nájdeš pod Aplikácie → Príslušenstvo → Terminál, ale to závisí na tvojom systéme. Ak to tam nie je, tak si to jednoducho vygoogli :) + $ + -## Príkazový riadok + -Teraz by si už mala vidieť biele alebo čierne okno, ktoré čaká na tvoje príkazy. + -Ak si na Macu alebo Linuxe, zrejme uvidíš `$`, presne takto: +Na Windowse pravdepodobne vidíš `>`. Takto: -``` -$ -``` +{% filename %}command-line{% endfilename %} -Na Windowse to je znak `>`, takýto: + > + -``` -> -``` +Pozri na sekciu o Linuxe priamo nad touto - niečo také uvidíš neskôr, keď sa v tutoriáli dostaneme k časti o PythonAnywhere. -Každý príkaz budeš zadávať za tento znak a jednu medzeru. Ty to ale písať nemusíš, urobí to za teba tvoj počítač :) + -> Len malá poznámka: v tvojom prípade môže byť pred znakom $ niečo ako `C:\Users\ola>` alebo `Olas-MacBook-Air:~ ola$` a to je úplne v poriadku. V tomto tutoriale to ale zjednodušíme na úplné minimum. +Pred každým príkazom budeš vidieť `$` alebo `>` a jednu medzeru, ale tie nepíš. Tvoj počítač to spraví za teba. :) + +> Len malá poznámka: možno máš pred znakom promptu niečo ako `C:\Users\ola>` alebo `Olas-MacBook-Air:~ ola$`. To je úplne v poriadku. + +Časť od začiatku riadku po `$` alebo `>` (vrátane) sa nazýva *prompt*. Prompt ťa nabáda (angl. prompt), aby si niečo napísala. + +Keď od teba budeme v tomto tutoriáli chcieť, aby si napísala príkaz, budeme v príkladoch písať aj `$` alebo `>`, alebo prípadne aj viac vecí na začiatku riadku. Túto celú ľavú časť ignoruj a napíš len príkaz, ktorý sa začína po prompte. ## Tvoj prvý príkaz (Hurá!) -Začnime s niečím jednoduchým. Napíš tento príkaz: +Začnime tým, že zadáme nasledovný príkaz: + + + +{% filename %}command-line{% endfilename %} -``` -$ whoami -``` + $ whoami + -alebo + -``` -> whoami -``` + -A stlač `enter`. Toto je výsledok: +{% filename %}command-line{% endfilename %} -``` -$ whoami -olasitarska -``` + > whoami + -Ako vidíš, počítač práve vypísal tvoje užívateľské meno. Milé, nie?:) + -> Skús každý príkaz napísať, nielen kopírovať. Viac si tak zapamätáš! +A potom stlač `enter`. Toto je výsledok: + +{% filename %}command-line{% endfilename %} + + $ whoami + olasitarska + + +Ako vidíš, počítač práve vypísal tvoje užívateľské meno. Milé, nie? :) + +> Skús každý príkaz napísať, nielen skopírovať. Viac si tak zapamätáš! ## Základy Každý operačný systém má trochu iné príkazy pre príkazový riadok, takže postupuj podľa inštrukcií pre tvoj operačný systém. Tak čo, vyskúšame to? -### Aktuálny adresár +### Aktuálny priečinok Bolo by fajn vedieť, kde sa nachádzame, však? Zistime to. Napíš tento príkaz a stlač `enter`: -``` -$ pwd -/Users/olasitarska -``` + + +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska + -Ak si vo Windowse: +> Poznámka: 'pwd' je skratka pre 'print working directory' (vypíš pracovný adresár). -``` -> cd -C:\Users\olasitarska -``` + -Na svojom stroji pravdepodobne uvidíš niečo takéto. Keď otvoríš príkazový riadok, zvyčajne začneš vo svojom domovskom adresári. + -> Poznámka: 'pwd' je skratka pre 'print working directory'. +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska + + +> Poznámka: 'cd' znamená 'change directory', teda zmeň priečinok. V PowerShelli môžeš použiť pwd rovnako ako na Linuxe alebo macOS. + + + +Na svojom stroji pravdepodobne uvidíš niečo takéto. Keď otvoríš príkazový riadok, zvyčajne začneš vo svojom domovskom priečinku. * * * -### Zoznam súborov a adresárov +### Ako sa dozvedieť viac o príkaze + +Mnoho príkazov, ktoré píšeš do konzoly, má zabudovanú nápovedu (help), ktorú si môžeš nechať zobraziť! Napríklad, ak sa chceš dozvedieť viac o príkaze z predošlej časti: -Tak čo je v ňom? Bolo by super zistiť to. Pozrime sa na to: + -``` -$ ls -Applications -Desktop -Downloads -Music -... -``` +macOS a Linux majú príkaz `man`, ktorý ti zobrazí nápovedu k iným príkazom. Skús `man pwd` a pozri, čo ti vypíše, alebo napíš `man` v kombinácii s inými príkazmi, aby sa ti zobrazila ich nápoveda. Výstup príkazu `man` má zvyčajne niekoľko strán. Na listovanie použi medzerník a stlačením klávesy `q` nápovedu ukončíš. -Windows: + -``` -> 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 -... -``` + + +Keď pripojíš `/?` na koniec príkazu, vo väčšine prípadov tiež dostaneš nápovedu. Je možné, že budeš musieť trochu poscrollovať vo svojom príkazovom okne, aby si si ju mohla celú prečítať. Skús `cd /?`. + + + +### Zoznam súborov a priečinkov + +Bolo by zaujímavé zistiť, čo taký priečinok obsahuje. Pozrime sa na to: + + + +{% filename %}command-line{% endfilename %} + + $ ls + Applications + Desktop + Downloads + Music + ... + + + + + + +{% filename %}command-line{% endfilename %} + + > dir + Directory of C:\Users\olasitarska + 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 + ... + + +> Poznámka: V PowerShelli môžeš použiť aj 'ls' rovnako ako na Linuxe alebo macOS. * * * -### Zmena aktuálneho adresára +### Zmena aktuálneho priečinku + +Teraz prejdime do priečinku, kde je naša plocha: + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + +Tu je dobré poznamenať, že názov "Desktop" môže byť preložený do jazyka, ktorý máš nastavený vo svojom linuxovom konte. V takom prípade budeš musieť zmeniť `Desktop` na toto preložené meno, napríklad `Schreibtisch` v nemčine. -Teraz prejdime do adresára Plochy: + -``` -$ cd Desktop -``` + -Windows: +{% filename %}command-line{% endfilename %} -``` -> cd Desktop -``` + > cd Desktop + -Skontroluj, či sa adresár skutočne zmenil: + -``` -$ pwd -/Users/olasitarska/Desktop -``` +Skontroluj, či sa priečinok skutočne zmenil: -Windows: + -``` -> cd -C:\Users\olasitarska\Desktop -``` +{% filename %}command-line{% endfilename %} + + $ pwd + /Users/olasitarska/Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + > cd + C:\Users\olasitarska\Desktop + + + A je to! -> Profi tip: ak napíšeš `cd D` a potom stlačíš `tab`, príkazový riadok automaticky doplní zvyšok názvu, takže sa môžeš adresáre prechádzať rýchlejšie. Ak na "D" začína viac ako jeden adresár, stlač `tab` dvakrát a dostaneš zoznam možností. +> Profi tip: ak napíšeš `cd D` a potom stlačíš klávesu `Tab`, príkazový riadok automaticky doplní zvyšok názvu, takže priečinky môžeš prechádzať rýchlejšie. Ak na "D" začína viac ako jeden priečinok, stlač `Tab` dvakrát a dostaneš zoznam možností. * * * -### Vytvoriť adresár +### Vytvorenie priečinku Čo takto vytvoriť pokusný adresár na ploche? Urobíš to takto: -``` -$ mkdir pokus -``` + + +{% filename %}command-line{% endfilename %} + + $ mkdir pokus + + + + + + +{% filename %}command-line{% endfilename %} -Windows: + > mkdir pokus + -``` -> mkdir practice -``` + -Tento príkazík vytvorí adresár s názvom `pokus` na tvojej ploche. Či je adresár naozaj tam môžeš zistiť jednoducho pohľadom na Plochu alebo spustením príkazu `ls` alebo `dir`! Vyskúšaj to :) +Tento príkazík vytvorí adresár s názvom `pokus` na tvojej ploche. Či je priečinok naozaj tam, môžeš zistiť jednoducho pohľadom na plochu alebo spustením príkazu `ls` alebo `dir`! Skús si to. :) > Profi tip: ak sa ti nechce vypisovať stále dookola tie isté príkazy, skús sa stlačením `šípky hore` a `šípky dole` vrátiť k nedávno použitým príkazom. @@ -182,25 +268,33 @@ Tento príkazík vytvorí adresár s názvom `pokus` na tvojej ploche. Či je ad ### Cvičenie! -Malá výzva pre teba: v tvojom čerstvo vytvorenom adresári `pokus` vytvor adresár s názvom `test`. Použi príkazy `cd` a `mkdir`. +Malá výzva pre teba: v čerstvo vytvorenom adresári `pokus` vytvor adresár s názvom `test`. (Použi príkazy `cd` a `mkdir`.) #### Riešenie: -``` -$ cd pokus -$ mkdir test -$ ls -test -``` + -Windows: +{% filename %}command-line{% endfilename %} -``` -> cd pokus -> mkdir test -> dir -03/20/2016 11:05 AM test -``` + $ cd pokus + $ mkdir test + $ ls + test + + + + + + +{% filename %}command-line{% endfilename %} + + > cd pokus + > mkdir test + > dir + 05/08/2020 07:28 PM test + + + Gratulujeme! :) @@ -208,99 +302,140 @@ Gratulujeme! :) ### Upratovanie -Nechceme po sebe nechať neporiadok, takže odstránime všetko, čo sme doteraz vytvorili. +Nechceme po sebe nechať neporiadok, tak poďme odstrániť všetko, čo sme doteraz vytvorili. + +Najskôr sa musíme vrátiť späť na plochu: + + + +{% filename %}command-line{% endfilename %} + + $ cd .. + + + -Najkôr sa musíme vrátiť späť na Plochu: + -``` -$ cd .. -``` +{% filename %}command-line{% endfilename %} -Windows: + > cd .. + -``` -> cd .. -``` + -Pomocou `..` s príkazom `cd` zmeníš svoj aktuálny adresár na rodičovský adresár (to je ten adresár, v ktorom sa nachádza tvoj aktuálny adresár). +Pomocou `..` s príkazom `cd` zmeníš svoj aktuálny priečinok na rodičovský priečinok (čiže priečinok, ktorý obsahuje tvoj súčasný priečinok). Skontroluj, kde sa nachádzaš: -``` -$ pwd -/Users/olasitarska/Desktop -``` + -Windows: +{% filename %}command-line{% endfilename %} -``` -> cd -C:\Users\olasitarska\Desktop -``` + $ pwd + /Users/olasitarska/Desktop + -Je na čase zmazať adresár `pokus`: + -> **Pozor**: mazanie súborov pomocou `del` `rmdir` alebo `rm` je neodvolateľné, teda *odstránené súbory budú navždy preč*! Takže s týmito príkazmi buď opatrná. + -``` -$ rm -r pokus -``` +{% filename %}command-line{% endfilename %} -Windows: + > cd + C:\Users\olasitarska\Desktop + -``` -> rmdir /S pous -pokus, Are you sure ? Y -``` + -Hotovo! Uistime sa, či je to naozaj vymazané: +Je načase zmazať priečinok `pokus`: -``` -$ ls -``` +> **Pozor**: mazanie súborov pomocou `del`, `rmdir` alebo `rm` je neodvolateľné, teda *odstránené súbory budú odstránené navždy*! Takže s týmito príkazmi buď opatrná. -Windows: + -``` -> dir -``` +{% filename %}command-line{% endfilename %} + + $ rm -r pokus + + + + + + +{% filename %}command-line{% endfilename %} + + > rmdir /S pokus + pokus, Are you sure ? Y + + + + +Hotovo! Uistime sa, či je naozaj vymazaný: + + + +{% filename %}command-line{% endfilename %} + + $ ls + + + + + + +{% filename %}command-line{% endfilename %} + + > dir + + + ### Ukončenie -Nateraz je to všetko! Môžeš pokojne zatvoriť príkazový riadok. Urobme to hackersky, dobre?:) +Nateraz je to všetko! Môžeš pokojne zatvoriť príkazový riadok. Urobme to hackersky, čo povieš? :) + + -``` -$ exit -``` +{% filename %}command-line{% endfilename %} -Windows: + $ exit + -``` -> exit -``` + -Super, čo?:) + + +{% filename %}command-line{% endfilename %} + + > exit + + + + +Super, čo? :) ## Zhrnutie Tu je prehľad niektorých užitočných príkazov: -| Príkaz (Windows) | Príkaz (Mac OS / Linux) | Popis | Príklad | -| ---------------- | ----------------------- | ------------------------------- | ------------------------------------------------- | -| exit | exit | zatvorí okno | **exit** | -| cd | cd | zmení adresár | **cd test** | -| dir | ls | vypíše zoznam adresárov/súborov | **dir** | -| copy | cp | kopíruje súbor | **copy c:\test\test.txt c:\windows\test.txt** | -| move | mv | presunie súbor | **move c:\test\test.txt c:\windows\test.txt** | -| mkdir | mkdir | vytvorí nový adresár | **mkdir testdirectory** | -| del | rm | odstráni adresár/súbor | **del c:\test\test.txt** | +| Príkaz (Windows) | Príkaz (Mac OS / Linux) | Popis | Príklad | +| ----------------- | ----------------------- | -------------------------------- | ----------------------------------------------------- | +| exit | exit | zatvorí okno | **exit** | +| cd | cd | zmení priečinok | **cd test** | +| cd | pwd | ukáže aktuálny priečinok | **cd** (Windows) alebo **pwd** (Mac OS / Linux) | +| dir | ls | vypíše zoznam priečinkov/súborov | **dir** | +| copy | cp | skopíruje súbor | **copy c:\test\test.txt c:\windows\test.txt** | +| move | mv | presunie súbor | **move c:\test\test.txt c:\windows\test.txt** | +| mkdir | mkdir | vytvorí nový priečinok | **mkdir testdirectory** | +| rmdir (alebo del) | rm | odstráni súbor | **del c:\test\test.txt** | +| rmdir /S | rm -r | odstráni priečinok | **rm -r testdirectory** | +| [CMD] /? | man [CMD] | ponúkne nápovedu k príkazu | **cd /?** (Windows) alebo **man cd** (Mac OS / Linux) | Toto je len veľmi malá časť príkazov, ktoré môžeš spustiť vo svojom príkazovom riadku, ale dnes budeš potrebovať len tieto. -Ak ťa to zaujalo, na [ss64.com][1] nájdeš kompletný prehľad príkazov pre všetky operačné systémy. - - [1]: http://ss64.com +Ak ťa to zaujalo, na [ss64.com](http://ss64.com) nájdeš kompletný prehľad príkazov pre všetky operačné systémy. ## Pripravená? -Vrhnime sa na Python! +Vrhnime sa na Python! \ No newline at end of file diff --git a/sk/intro_to_command_line/open_instructions.md b/sk/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..6cfd46cb280 --- /dev/null +++ b/sk/intro_to_command_line/open_instructions.md @@ -0,0 +1,28 @@ + + +V závislosti od tvojej verzie Windowsu a tvojej klávesnice by jedna z týchto možností mala otvoriť príkazové okno (možno budeš musieť trochu experimentovať, ale nemusíš skúšať všetky tieto možnosti): + +- Prejdi do ponuky Štart alebo na plochu a do vyhľadávacieho poľa zadaj "Príkazový riadok" alebo "Command Prompt". +- Prejdi na Štart menu → Systém Windows → Príkazový riadok. +- Choď na menu Štart → Všetky programy → Príslušenstvo → Príkazový riadok. +- Prejdi na plochu, podrž myš v ľavom dolnom rohu obrazovky a klikni na šípku nadol, ktorá sa zobrazí (na dotykovej obrazovke namiesto toho rýchlo prejdi prstom z dolnej časti obrazovky nahor). Mal by sa ti zobraziť zoznam aplikácií. Klikni na príkazový riadok (Command Prompt) v sekcii Windows System. +- Podrž špeciálnu klávesu Windows na klávesnici a stlač klávesu "X". Vyber "Príkazový riadok" z kontextového menu. +- Podrž klávesu Windows a stlač tlačidlo "R", kým sa ti nezobrazí okno "Run". Do poľa zadaj "cmd" a klikni na tlačidlo OK. + +![Zadaj "cmd" v okne "Run"](../python_installation/images/windows-plus-r.png) + +Neskôr v tutoriáli budeš potrebovať mať otvorené dve príkazové okná súčasne. Avšak na niektorých verziách Windowsu ak už máš otvorené jedno okno príkazového riadku a pokúsiš sa otvoriť druhé rovnakým spôsobom, len ťa to presmeruje na to, ktoré už máš otvorené. Vyskúšaj si to na svojom počítači! Ak dostaneš len svoje už existujúce príkazové okno, skús nové otvoriť použitím iného spôsobu zo zoznamu vyššie. Aspoň jeden z nich by ti mal otvoriť nové okno. + + + + + +Choď do Aplikácie → Nástroje → Terminál. + + + + + +Cesta je pravdepodobne Aplikácie → Príslušenstvo → Terminál alebo Aplikácie → Systém → Terminál, ale závisí to od tvojho systému. Ak to tam nie je, skús si to vygoogliť. :) + + \ No newline at end of file diff --git a/sk/python_installation/README.md b/sk/python_installation/README.md old mode 100755 new mode 100644 index ad2ee900d15..012aa34c3e5 --- a/sk/python_installation/README.md +++ b/sk/python_installation/README.md @@ -2,12 +2,14 @@ Konečne sme tu! -Na začiatok si povedzme, čo je Python. Python je veľmi obľúbený programovací jazyk, ktorý možno využiť na vytváranie webstránok, hier, vedeckých programov, grafiky a veľa, veľa ďalšieho. +Na začiatok si povedzme, čo je Python. Python je veľmi obľúbený programovací jazyk, ktorý možno využiť na vytváranie webstránok, hier, vedeckých programov, grafiky a mnoho iných vecí. -Python vznikol koncom 80-tych rokov minulého storočia a jeho hlavným cieľom bola čitateľnosť pre ľudí (nie len pre stroje!). To je dôvod, prečo vyzerá oveľa jednoduchšie ako iné programovacie jazyky. Vďaka tomu je ľahké sa ho naučiť, ale nebojte sa, Python je tiež naozaj výkonný! +Python vznikol koncom 80.-tych rokov minulého storočia a jeho hlavným cieľom bola čitateľnosť pre ľudí (nie len pre stroje!). Toto je dôvod, prečo vyzerá jednoduchšie, než ostatné programovacie jazyky, ale netráp sa - napriek tomu Python je fakt schopný! # Inštalácia Pythonu -> **Poznámka** Ak si sa už cez kroky inštalácie prepracovala, nemusíš to robiť znova - môžeš preskočiť rovno na nasledujúcu kapitolu! +> **Poznámka:** Ak používaš Chromebook, preskoč túto kapitolu a postupuj podľa pokynov na [inštaláciu na Chromebookoch](../chromebook_setup/README.md). +> +> **Poznámka** Ak si už prešla [inštalačnými pokynmi](../installation/README.md), tak toto už máš hotové a môžeš ísť rovno na ďalšiu kapitolu! {% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/sk/python_installation/images/add_python_to_windows_path.png b/sk/python_installation/images/add_python_to_windows_path.png index 9510d6f2176..3266efb6177 100644 Binary files a/sk/python_installation/images/add_python_to_windows_path.png and b/sk/python_installation/images/add_python_to_windows_path.png differ diff --git a/sk/python_installation/images/python-installation-options.png b/sk/python_installation/images/python-installation-options.png new file mode 100644 index 00000000000..a0a6c65d81d Binary files /dev/null and b/sk/python_installation/images/python-installation-options.png differ diff --git a/sk/python_installation/images/windows-plus-r.png b/sk/python_installation/images/windows-plus-r.png new file mode 100644 index 00000000000..4f8f7433381 Binary files /dev/null and b/sk/python_installation/images/windows-plus-r.png differ diff --git a/sk/python_installation/instructions.md b/sk/python_installation/instructions.md old mode 100755 new mode 100644 index a1565b278a6..c14068a4033 --- a/sk/python_installation/instructions.md +++ b/sk/python_installation/instructions.md @@ -1,72 +1,117 @@ -> Táto časť je založená na príručke Geek Girls Carrots (http://django.carrots.pl/) +> Pre čitateľov a čitateľky doma: Táto kapitola je spracovaná vo videu [Installing Python & Code Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA). +> +> Táto časť je založená na príručke Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) -Django je napísané v Pythone. Python potrebujeme na všetko, čo chceme robiť v Djangu. Začnime teda s inštaláciou! Chceme, aby si si nainštalovala Python 3.4, takže ak máš staršiu verziu, budeš ju musieť upgradovať. +Django je napísané v jazyku Python. Python potrebujeme na všetko, čo chceme v Djangu robiť. Poďme ho teda najprv nainštalovať! Chceme, aby si si nainštalovala Python 3, takže ak máš staršiu verziu, budeš ju musieť upgradovať. Ak už máš verziu {{ book.py_min_version }} alebo vyššiu, malo by to byť v poriadku. -### Windows +Nainštaluj si, prosím, Python nasledovne, a to aj v prípade, že už máš na svojom počítači nainštalovanú Anacondu. -Python pre Windows si môžeš stiahnuť z webstránky https://www.python.org/downloads/release/python-343/. Po stiahnutí súboru ***.msi***, ho spusti (dvojklikom) a postupuj podľa inštrukcií. Je dôležité zapamätať si cestu (adresár), kde je nainštalovaný Python. Ešte to budeme potrebovať! + -Jedna vec, na ktorú si treba dať pozor: na druhej obrazovke sprievodcu inštaláciou, označenej ako "Prispôsobiť" (Customize), nezabudni prejsť dole a vybrať možnosť "Pridať python.exe do Cesty", takto: +Najprv si zisti, či na tvojom počítači beží 32-bitová alebo 64-bitová verzia Windowsu. Môžeš sa to dozvedieť v Systémových informáciách v časti Typ systému. Vieš sa tam dostať jedným z nasledujúcich spôsobov: -![Nezabudni pridať Python do Cesty](../python_installation/images/add_python_to_windows_path.png) +* Stlač klávesu Windows a klávesu Pause/Break naraz +* Otvor Ovládací panel z windowsového menu, potom prejdi na Systém a zabezpečenia, potom Systém +* Stlač tlačidlo Windows a potom prejdi na položku Nastavenia > Systém > Informácie +* Vyhľadaj "System information" cez Štart menu. Stlač tlačidlo Štart alebo klávesu Windows a začni písať `System Information`. Ako začneš písať, začne ti to dávať tipy. Keď sa položka objaví, vyber ju. -### Linux +Python pre Windows si môžeš stiahnuť z webstránky https://www.python.org/downloads/windows/. Klikni na link "Latest Python 3 Release - Python x.x.x". Ak tvoj počítač beží na **64-bitovej** verzii Windowsu, stiahni si **Windows x86-64 executable installer**. V opačnom prípade si stiahni **Windows x86 executable installer**. Po stiahnutí inštalačného súboru ho spusti (dvojklikom) a postupuj podľa inštrukcií v ňom. + +Jedna vec, na ktorú treba dávať pozor: Počas inštalácie si všimni okno označené "Setup". Uisti sa, že začiarkneš políčko "Pridať Python {{ book.py_version }} do PATH" alebo "Pridať Python do premenných prostredia" (alebo "Add Python {{ book.py_version }} to PATH") a klikneš na "Inštalovať" ("Install Now"), ako je zobrazené tu (môže to vyzerať trochu inak, ak inštaluješ inú verziu): + +![Nezabudni pridať Python do PATH](../python_installation/images/python-installation-options.png) + +Po dokončení inštalácie sa môže zobraziť dialógové okno s odkazom, pomocou ktorého sa môžeš dozvedieť viac o Pythone alebo o verzii, ktorú si nainštalovala. Toto dialógové okno zatvor alebo zruš - na to, aby si sa dozvedela viac, je tu tento tutoriál! + +Poznámka: Ak si na staršej verzii Windowsu (7, Vista alebo niečo staršie) a inštalácia Pythonu {{ book.py_version }} padne s chybou, skús nainštalovať najnovšie updaty Windowsu a pokús sa nainštalovať Python znova. Ak problém pretrváva, skús nainštalovať Python {{ book.py_min_release }} z [Python.org](https://www.python.org/downloads/windows/). + +> Django {{ book.django_version }} vyžaduje Python {{ book.py_min_version }} alebo novší, ktorý nebeží na Windowse XP a nižších verziách. + + + + + +> **Poznámka:** Pred inštaláciou Pythonu na macOS sa uisti, že nastavenia tvojho Macu ti povoľujú inštaláciu balíkov, ktoré nie sú z App Storu. Choď do System Preferences (je to v priečinku Applications), klikni na "Security & Privacy," a potom na záložku "General". Ak možnosť "Allow apps downloaded from:" je nastavená na "Mac App Store," zmeň ho na "Mac App Store and identified developers." + +Potom musíš ísť na stránku https://www.python.org/downloads/ a stiahnuť si najnovší Python: + +* Stiahni si súbor s *macOS inštalátorom*, +* Dvojklikom na *python-{{ book.py_release }}-macos11.pkg* spusti inštalačný program. + + + + Je veľmi pravdepodobné, že Python už máš predinštalovaný. Pre kontrolu, či je naozaj nainštalovaný (a ktorá verzia), spusti konzolu a napíš tento príkaz: -``` -$ python3 -- version -Python 3.4.3 -``` +{% filename %}command-line{% endfilename %} + + $ python3 --version + Python {{ book.py_release }} + + +Ak máš inú verziu Pythonu, a to aspoň {{ book.py_min_version }} (napr. {{ book.py_min_release }}), nemusíš upgradovať. Ak Python nainštalovaný nemáš alebo chceš inú verziu, najprv zisti, akú máš linuxovú distribúciu, nasledovne: + +{% filename %}command-line{% endfilename %} + + $ grep '^NAME=' /etc/os-release + + +Potom podľa toho, čo si zistila, nasleduj konkrétne inštalačné pokyny pod touto sekciou. -Ak nemáš Python nainštalovaný, alebo ak chceš inú verziu, môžeš ho nainštalovať takto: + -#### Debian alebo Ubuntu + Zadaj do konzoly tento príkaz: -``` -$ sudo apt-get install python3.4 -``` +{% filename %}command-line{% endfilename %} -#### Fedora (do verzie 21) + $ sudo apt install python3 + + + + + Použi v konzole tento príkaz: -``` -$ sudo yum install python3.4 -``` +{% filename %}command-line{% endfilename %} -#### Fedora (od verzie 22) + $ sudo dnf install python3 + -Použi v konzole tento príkaz: +Ak používaš staršiu verziu Fedory, možno sa ti objaví chyba, že príkaz `dnf` neexistuje. V tom prípade musíš použiť príkaz `yum`. -``` -$ sudo dnf instal python3.4 -``` + -#### openSUSE + Použi v konzole tento príkaz: -``` -$ sudo zypper install python3 -``` +{% filename %}command-line{% endfilename %} + + $ sudo zypper install python3 + + + -### OS X +Ak si chceš overiť, že inštalácia bola úspešná, otvor príkazový riadok a spusti príkaz `python3`: -Inštalačný program Pythonu si môžeš stiahnuť zo stránky https://www.python.org/downloads/release/python-343/: +{% filename %}command-line{% endfilename %} - * Stiahni si súbor s *Mac OS X 64/32-bitovým inštalátorom*, - * Dvojklikom na *python-3.4.3-macosx10.6.pkg* spusti inštalačný program. + $ python3 --version + Python {{ book.py_release }} + -Ak si chceš overiť, že inštalácia bola úspešná, otvor aplikáciu *Terminal* a spusti príkaz `python3`: +Zobrazená verzia sa môže líšiť od verzie {{ book.py_release }} - mala by zodpovedať verzii, ktorú si nainštalovala. -``` -$ python3 -- version -Python 3.4.3 -``` +**POZNÁMKA:** Ak používaš Windows a objaví sa ti chybová hláška, že `python3` nebol najdený, skús použiť `python` (bez čísla `3`) a over, či to náhodou nie je Python {{ book.py_min_version }} alebo vyšší. Ak ani to nefunguje, otvor si nový príkazový riadok a skús znova - stáva sa to, keď robíš s príkazovým riadkom, ktorý bol otvorený ešte predtým, než sme nainštalovali Python. * * * -V prípade nejakých pochybností, alebo ak sa niečo pokazilo a nemáš tušenie, čo robiť ďalej - opýtaj sa svojho trénera! Niekedy veci nejdú úplne hladko a je lepšie požiadať o pomoc niekoho, kto má viac skúseností. +V prípade pochybností alebo ak sa niečo pokazilo a nemáš tušenie, čo robiť ďalej - opýtaj sa svojej mentorky alebo mentora! Niekedy veci nejdú úplne hladko a je lepšie požiadať o pomoc niekoho, kto má viac skúseností. \ No newline at end of file diff --git a/sk/python_introduction/README.md b/sk/python_introduction/README.md old mode 100755 new mode 100644 index 68c95dbd202..d9a06d0a3e2 --- a/sk/python_introduction/README.md +++ b/sk/python_introduction/README.md @@ -1,200 +1,236 @@ +{% set warning_icon = '' %} + # Úvod do jazyka Python -> Časť tejto kapitoly je založená na tutoriáli Geek Girls Carrots (http://django.carrots.pl/). +> Časť tejto kapitoly je založená na tutoriáli Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). Poďme napísať nejaký kód! -## Python prompt - -Aby sme mohli začať s Pythonom, musíte otvoriť *príkazový riadok* (angl. command line) na svojom počítači. Už by ste mali vedieť ako sa to robí -- naučili ste sa to v jednom z predchádzajúcich kapitol. - -Ak ste hotoví, pokračujte s inštrukciami nižšie. +{% include "/python_introduction/prompt.md" %} -Chceme otvoriť Python konzolu, takže napíšte `python` na Windowse alebo `python3` na Mac alebo OS/Linux a stlačte `enter`. +## Tvoj prvý príkaz v Pythone! -``` -$ python3 -Python 3.4.3 (...) -Type "help", "copyright", "credits" or "license" for more information. ->>> -``` +Po spustení príkazu python sa začiatok nášho príkazového riadku (nazývaný aj prompt) zmenil na `>>>`. Toto pre nás znamená, že odteraz by sme mali písať príkazy iba v jazyku Python. Ty sama nemusíš vždy písať `>>>`, Python to urobí za teba. -## Váš prvý príkaz v Pythone! +Ak chceš z pythonovej konzoly kedykoľvek odísť, napíš `exit()` alebo použi skratku `Ctrl + Z` vo Windowse a `Ctrl + D` v Macu/Linuxe. Potom už nebudeš vidieť `>>>`. -Po spustení príkazu Python sa prompt zmenil na `>>>`. Pre nás to znamená že odteraz by sme mali písať príkazy iba v jazyku Python. Nemusíte písať `>>>` - Python to urobí pre Vás. +Zatiaľ ale z pythonovej konzoly odchádzať nechceme. Chceme sa o nej dozvedieť viac! Začnime tým, že napíšeme niečo jednoduché matematické ako `2 + 3` a stlačíme `enter`. -Ak by ste chceli kedykoľvek ukončiť konzolu Pythonu, len napíšte `exit()` alebo môžete použiť aj skratku `Ctrl + Z` vo Windowse alebo `Ctrl + D` pre Mac/Linux. Potom už nebudete vidieť toto: `>>>`. +{% filename %}command-line{% endfilename %} -Ale teraz ešte vôbec nechceme ukončiť konzolu Python. Chceme sa o ňom naučiť viac. Začínajme s niečím jednoduchým. Napríklad skúste napísať nejaký matematický výraz, ako `2 + 3` a stlačte `enter`. - -``` +```python >>> 2 + 3 5 ``` -Super! Vidíte ako vyskočilo riešenie? Python vie počítať! Môžete skúsiť aj ďalšie príkazy, ako: - `4 * 5` - `5 - 1` - `40 / 2` +Pekne! Vidíš, ako vyskočilo riešenie? Python vie počítať! Môžeš skúsiť iné príkazy ako: -Bavte sa s tým trošku, potom sa vráťte späť k nám :). +- `4 * 5` +- `5 - 1` +- `40 / 2` -Ako vidíte, Python je dobrá kalkulačka. A ak ste zvedaví, čo všetko vie ešte... +Aby sme vypočítali mocninu, povedzme 2 na tretiu, zadáme: {% filename %}command-line{% endfilename %} + +```python +>>> 2 ** 3 +8 +``` + +Trošku sa s tým pohraj a potom sa vráť späť . :) + +Ako môžeš vidieť, Python je skvelá kalkulačka. A ak si zvedavá, čo všetko ešte dokáže... ## Reťazce -Čo tak vaše meno? Napíšte svoje meno v úvodzovkách: +Čo tak napríklad tvoje meno? Napíš svoje meno v úvodzovkách: -``` +{% filename %}command-line{% endfilename %} + +```python >>> "Ola" -"Ola" +'Ola' ``` -Práve ste vytvorili svoj prvý reťazec! Je postupnosť znakov, ktoré môžu byť spracované počítačom. Reťazec musí vždy začínať a končíť s rovnakým znakom. Sú to jednoduché (`'`) alebo dvojité (`"`) úvodzovky (nie je medzi nimi žiadny rozdiel!). Úvodzovky naznačujú, že to čo je medzi nimi je reťazec (string). +Práve si vytvorila svoj prvý reťazec (string)! Je to postupnosť znakov, ktoré môžu byť spracované počítačom. Reťazec musí vždy začínať a končiť rovnakým znakom. Buď jednoduchými (`'`) alebo dvojitými (`"`) úvodzovkami (nie je medzi nimi žiadny rozdiel!). Úvodzovky naznačujú, že to, čo je medzi nimi, je reťazec. Reťazce možno spájať dohromady. Skús toto: -``` ->>> "Ahoj" + "Ola" +{% filename %}command-line{% endfilename %} + +```python +>>> "Ahoj " + "Ola" 'Ahoj Ola' ``` -Reťazce môžete násobiť aj s číslom: +Reťazce môžeš tiež vynásobiť číslom: -``` +{% filename %}command-line{% endfilename %} + +```python >>> "Ola" * 3 'OlaOlaOla' ``` -Ak potrebujete dať apostrof do vnútra reťazca, máte dva spôsoby, ako to urobiť. +Ak potrebuješ mať vo vnútri reťazca apostrof, máš dve možnosti, ako to spraviť. Použitím dvojitých úvodzoviek: -``` +{% filename %}command-line{% endfilename %} + +```python >>> "Runnin' down the hill" "Runnin' down the hill" ``` -alebo pomocou spätného lomítka - tento znak (ak je napísaný pred úvodzovkou) povie, že ona je súčasťou reťazca a nie koniec / začiatok reťazca (``): +alebo pomocou spätného lomítka (`\`) - tomuto sa anglicky hovorí escaping: -``` +{% filename %}command-line{% endfilename %} + +```python >>> 'Runnin\' down the hill' "Runnin' down the hill" ``` -Pekné, hm? Ak chcete vidieť svoje meno veľkými písmenami, jednoducho zadajte: +Fajn, nie? Ak chceš vidieť svoje meno napísané veľkými písmenami, zadaj: -``` +{% filename %}command-line{% endfilename %} + +```python >>> "Ola".upper() 'OLA' ``` -Práve ste použili `upper` **funkciu** na svoj reťazec! Funkcia (ako `upper()`) je postupnosť inštrukcií, ktoré Python vykonáva na danom objekte (`"Ola"`), potom, čo ju zavoláte. +Práve si na svojom reťazci použila **metódu** `upper`! Metóda (ako `upper()`) predstavuje postupnosť inštrukcií, ktoré Python vykoná na danom objekte (`"Ola"`), keď ju zavoláš. -Ak chcete poznať počet písmen, ktoré sú obsiahnuté vo vašom mene, tak na to má Python funkciu tiež! +Ak chceš vedieť, koľko má tvoje meno písmen, aj na to máme **funkciu**! -``` +{% filename %}command-line{% endfilename %} + +```python >>> len("Ola") 3 ``` -Ste zvedaví, prečo voláme niekedy funkciu s bodkou (`.`) na konci reťazca (ako `"Ola".upper()`) a niekedy najprv voláme funkciu a reťazec vložíme do zátvoriek? V niektorých prípadoch funkcie patria k objektom, ako napr. `upper()`, čo môže byt vykonaná len na reťazcoch. V takomto prípade sa tieto funkcie volajú **metódy**. Inokedy funkcie nepatria k žiadnemu konkrétnemu objektu a môžu byť použité na rôzne typy objektov, rovnako ako `len()`. Preto zadáme `"Ola"` ako parameter pre funkciu `len`. +Rozmýšľaš, prečo občas voláme funkcie pomocou `.` na konci reťazca (napr. `"Ola".upper()`) a inokedy najprv zavoláme funkciu a reťazec dáme do zátvoriek? Ide o to, že v niektorých prípadoch funkcie patria k objektom, ako napríklad `upper()`, čo je funkcia, ktorá môže byť vykonaná len na reťazcoch. V takomto prípade sa tieto funkcie volajú **metódy**. Inokedy funkcie nepatria k žiadnemu konkrétnemu objektu a môžu byť použité na rôzne typy objektov, ako je to v prípade `len()`. Preto posielame reťazec `"Ola"` ako parameter funkcii `len`. ### Zhrnutie -OK, dosť už reťazcoch. Zatiaľ ste sa naučili o: +OK, dosť už o reťazcoch. Zatiaľ sme sa niečo naučili o nasledovnom: -* **prompt** - píšeme príkazy (kód) do Python promptu, z čoho dostaneme výsledky zase v jazyku Python -* **čísla a reťazce** - v Pythone sú čísla použité pre počítanie a reťazce pre textové objekty -* **operátory** - ako + alebo *, z daných hodnôt vyrobia novú hodnotu (číslo či reťazec...) -* **funkcie** - napr. upper() alebo len(), vykonávajú činnosti na objektoch. +- **prompt** - píšeme príkazy (kód) do Python promptu, z čoho dostaneme výsledky zase v jazyku Python +- **čísla a reťazce** - v Pythone sú čísla použité pre počítanie a reťazce pre textové objekty +- **operátory** - ako `+` alebo `*`, z daných hodnôt vyrobia novú hodnotu +- **funkcie** - napr. `upper()` alebo `len()`, vykonávajú činnosti na objektoch. -Toto sú základy každého programovacieho jazyka. Ste pripravení na niečo ťažšie? Stavíme sa, že áno! +Toto sú základy každého programovacieho jazyka. Si pripravená na niečo ťažšie? Stavíme sa, že áno! ## Chyby -Teraz skúsme niečo nové. Je možné zistiť dĺžku nejakého čísla rovnako ako sme to robili s našim menom? Napíšte `len(304023)` a stlačte `enter`: +Teraz skúsme niečo nové. Keď už vieme zistiť dĺžku reťazca, vieme to isté spraviť s číslom? Skús napísať `len(304023)` a stlač `enter`: -``` +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python >>> len(304023) Traceback (most recent call last): File "", line 1, in TypeError: object of type 'int' has no len() ``` -Dostali sme našu prvú chybovú hlášku! Hovorí nám, že objekty typu "int" (celé čísla, angl. integers) nemajú dĺžku. Tak čo môžeme teraz robiť? Možno by sme mohli napísať naše číslo ako reťazec? Reťazce majú dĺžku, pravda? +Dostali sme našu prvú chybu! Keď uvidíš ikonku {{ warning_icon }}, ber to ako znamenie, že kód, ktorý ideš spustiť, nebude bežať tak, ako by sa dalo očakávať. Robenie chýb (aj úmyselných) je dôležitá súčasť učenia sa! -``` +Správa nám hovorí, že objekty typu "int" (integer, alebo slovensky celé číslo) nemajú dĺžku. Čo s tým? Možno by sme mohli naše číslo zapísať ako reťazec? Reťazce predsa dĺžku majú, nie? + +{% filename %}command-line{% endfilename %} + +```python >>> len(str(304023)) 6 ``` -Funguje to! Použili sme funkciu `str` vo vnútri funkcie `len`. Funkcia `str()` prevedie všetko na reťazce. +Funguje to! Použili sme funkciu `str` vovnútri funkcie `len`. `str()` zmení všetko na reťazec. -* Funkcia `str` prevedie (konvertuje) všetko na **reťazce** (angl. string) -* Funkcia `int` prevedie všetko na **int** (celé čísla) +- Funkcia `str` prevedie všetko na **reťazec** +- Funkcia `int` prevedie všetko na **int** (celé čísla) -> Dôležité: je možné konvertovať čísla na reťazce, ale opačne sa to nedá vždy - inak čo by bolo napr. `int('hello')`? +> Dôležité: čísla vieme premeniť na text, ale text nevieme vždy previesť na číslo - veď čo by vôbec malo byť `int('ahoj')`? ## Premenné -Veľmi dôležitý pojem v programovaní je pojem premennej. Premenná je nič iné ako názov niečoho, čo môžeme použiť aj neskoršie v programe. Programátori používajú premenné aby v nich ukladali dáta, aby ich zdrojový kód bol prehľadnejší a aby nemuseli všetko držať v hlave. +Veľmi dôležitý koncept v programovaní je pojem premennej (variable). Premenná nie je nič iné ako priradenie názvu niečomu, aby sme to mohli použiť neskôr. Programátorky a programátori používajú premenné, aby v nich ukladali dáta, aby ich zdrojový kód bol prehľadnejší, a aby nemuseli všetko držať v hlave. Povedzme, že chceme vytvoriť novú premennú s názvom `meno`: -``` ->>> name = "Ola" +{% filename %}command-line{% endfilename %} + +```python +>>> meno = "Ola" ``` -Vidíte? Je to jednoduché: meno rovná sa Ola. +Napíšeme, že meno sa rovná Ola. -Ako ste si to zbadali už, váš program nič nevrátil späť ako to robil v predchádzajúcich príkladoch. Tak ako vieme, či tá premenná existuje? Jednoducho napíšte `meno` a stlačte `enter`: +Asi si si všimla, že tentokrát program nič nevypísal. Ako teda vieme, že naša premenná naozaj existuje? Napíš `meno` a stlač `enter`: -``` ->>> name +{% filename %}command-line{% endfilename %} + +```python +>>> meno 'Ola' ``` -Hurá! Vaša prvá premenná :)! Vždy je možné zmeniť jej obsah: +Jupí! Tvoja prvá premenná! :) Vždy môžeš zmeniť, na čo ukazuje: -``` ->>> name = "Sonja" ->>> name -'Sonja' +{% filename %}command-line{% endfilename %} + +```python +>>> meno = "Sona" +>>> meno +'Sona' ``` -Môžete ju použiť aj vo funkciách: +Môžeš ju tiež použiť vo funkciách: -``` ->>> len(name) -5 +{% filename %}command-line{% endfilename %} + +```python +>>> len(meno) +4 ``` -Úžasné, že? Samozrejme premenné môžu byť hocičo, takže aj čísla! Skúste toto: +Super, nie? Premenné môžu obsahovať čokoľvek, aj čísla! Skús toto: -``` +{% filename %}command-line{% endfilename %} + +```python >>> a = 4 >>> b = 6 >>> a * b 24 ``` -Ale čo by sa stalo, keby sme použili zlý názov? Uhádnete, čo sa stane? Skúsme! +Ale čo by sa stalo, keby sme použili nesprávny názov? Uhádneš, čo sa stane? Vyskúšajme! -``` ->>> mesto = "Tokyo" +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python +>>> mesto = "Tokio" >>> mseto Traceback (most recent call last): File "", line 1, in NameError: name 'mseto' is not defined ``` -Chyba! Ako vidíte, Python má viacero chýb a táto jedna sa volá **NameError**. Python vám hodí túto chybu ak sa pokúsite použiť premennú ktorá ešte nebola definovaná. Ak sa stretnete s touto chybou v budúcnosti, vždy skontrolujte svoj kód, či nemáte preklep v niektorom názve. +Chyba! Ako vidíš, Python má viacero druhov chýb a táto konkrétna sa volá **NameError**. Python ti ju vyhodí, pokiaľ sa pokúsiš použiť premennú, ktorá ešte nebola definovaná. Ak sa s touto chybou stretneš v budúcnosti, skontroluj si kód, či nemáš preklep v nejakom názve. -Bavte sa s tým trošku, a potom uvidíme čo môžeme ešte urobiť! +Pohraj sa s tým trošku a vyskúšaj si, čo všetko sa s tým dá urobiť! ## Funkcia print -Vyskúšajte toto: +Skús toto: -``` +{% filename %}command-line{% endfilename %} + +```python >>> meno = 'Maria' >>> meno 'Maria' @@ -202,193 +238,235 @@ Vyskúšajte toto: Maria ``` -Ak zadáte len `meno`, Python interpreter odpovie reťazcovou *reprezentáciou* premennej 'meno', teda písmenami M-a-r-i-a medzi jednoduchými úvodzovkami, ''. Keď napíšete `print(meno)`, Python vypíše obsah premennej na obrazovku, bez úvodzoviek, čo vyzerá krajšie. +Ak napíšeš len `meno`, pythonový interpreter ti odpovie reťazcovou *reprezentáciou* premennej "meno", čo sú písmená M-a-r-i-a, obklopené jednoduchými úvodzovkami ''. Keď povieš `print(meno)`, Python vypíše (print) obsah premennej na obrazovku bez úvodzoviek, čo vyzerá úhľadnejšie. -Ako uvidíme neskôr, funkcia `print()` je tiež užitočná, keď chceme tlačiť veci z funkcií, alebo ak chceme tlačiť veci na viacerých riadkoch. +Ako uvidíme neskôr, funkcia `print()` tiež príde vhod, keď chceme vypisovať niečo zvnútra funkcie alebo keď chceme vypisovať veci na viacerých riadkoch. ## Zoznamy -Okrem reťazcov a celých čísel, má Python všetky možné typy objektov. Teraz sa zoznámime s typom, ktorý sa volá **zoznam** (list). Zoznamy sú presne to, čo si myslíte, že sú: objekty, ktoré sú zoznamami iných objektov :) +Okrem reťazcov a celých čísel má Python všemožné typy objektov. Teraz sa zoznámime s typom, ktorý sa volá **zoznam** (list). Zoznamy sú presne to, čo by si povedala, že sú: objekty, ktoré sú zoznamami iných objektov. :) -Poďme na to, vytvorte zoznam: +Poď na to, vytvor zoznam: -``` +{% filename %}command-line{% endfilename %} + +```python >>> [] [] ``` -Áno, tento zoznam je prázdny. Nie veľmi užitočné, však? Vytvorme zoznam s číslami lotérie. Nechceme sa dokola opakovať, takže ho hneď aj priradíme do premennej: +Áno, tento zoznam je prázdny. To nám nie je na veľa, že? Vytvorme radšej zoznam s číslami do lotérie. A keďže sa nechceme stále opakovať, hneď ho aj uložíme do premennej: -``` +{% filename %}command-line{% endfilename %} + +```python >>> loteria = [3, 42, 12, 19, 30, 59] ``` -OK, máme zoznam! Čo s ním môžeme urobiť? Pozrime sa, koľko čísel lotérie máme v zozname. Máte predstavu, ktorú funkciu by sme mohli použiť? Toto už predsa viete! +OK, máme zoznam! Čo s ním môžeme urobiť? Pozrime sa, koľko čísel máme v zozname. Tušíš, akú funkciu by sme na také niečo mohli použiť? Už ju poznáš! -``` +{% filename %}command-line{% endfilename %} + +```python >>> len(loteria) 6 ``` -Áno! `len()` vám vráti počet objektov v zozname. Šikovné, nie? Možno by sme to teraz mohli usporiadať: +Presne! `len()` ti vráti počet objektov v zozname. Šikovné, nie? Teraz by sme ho možno mohli usporiadať: -``` +{% filename %}command-line{% endfilename %} + +```python >>> loteria.sort() ``` -Nič nám to nevrátilo, iba sa zmenilo poradie poradie, v ktorom sa čísla zobrazia v zozname. Vytlačme to znova a pozrime sa, čo sa stalo: +Nič nám to nevrátilo, iba sa zmenilo poradie, v ktorom sa čísla vyskytujú v zozname. Vypíšme ho znova a pozrime sa, čo sa stalo: -``` +{% filename %}command-line{% endfilename %} + +```python >>> print(loteria) [3, 12, 19, 30, 42, 59] ``` -Ako vidíte, čísla vo vašom zozname sú teraz zoradené od najnižšej po najvyššiu hodnotu. Gratulujeme! +Ako vidíš, čísla v tvojom zozname sú teraz zoradené od najnižšej po najvyššiu hodnotu. Gratulujeme! -Chceli by sme otočiť poradie? Urobme to! +Možno by sme chceli toto poradie otočiť? Urobme to! -``` +{% filename %}command-line{% endfilename %} + +```python >>> loteria.reverse() >>> print(loteria) [59, 42, 30, 19, 12, 3] ``` -Jednoduché, však? Ak chcete pridať niečo do svojho zoznamu, môžete tak urobiť zadaním tohto príkazu: +Ak chceš do zoznamu niečo pridať, môžeš to urobiť zadaním tohto príkazu: -``` +{% filename %}command-line{% endfilename %} + +```python >>> loteria.append(199) >>> print(loteria) [59, 42, 30, 19, 12, 3, 199] ``` -Ak chcete zobraziť iba prvé číslo, môžete to urobiť pomocou **indexov**. Index je číslo, ktoré hovorí, kde v zozname sa položka nachádza. Programátori radi počítajú od nuly, takž eprvý objekt vo vašom zozname je na indexe 0, ďalší je na 1 a tak ďalej. Vyskúšajte toto: +Ak chceš zobraziť len prvé číslo, môžeš na to použiť **index**. Index je číslo, ktoré hovorí, kde v zozname sa položka nachádza. Programátorky a programátori radi počítajú od 0, takže prvý objekt v našom liste je na indexe 0, druhý na indexe 1 a tak ďalej. Skús toto: -``` +{% filename %}command-line{% endfilename %} + +```python >>> print(loteria[0]) 59 >>> print(loteria[1]) 42 ``` -Ako vidíte, k rôznym objektom vo vašom zozname môžete pristupovať použitím názvu zoznamu a indexom objektu v hranatých zátvorkách. +Ako môžeš vidieť, môžeš pristupovať k rôznym objektom vo svojom zozname pomocou názvu zoznamu a indexu daného objektu v hranatých zátvorkách. -Aby ste odstránili niečo zo svojho zoznamu, budete potrebovať **indexy**, ako sme sa dozvedeli vyššie a príkaz **del** (del je skratka pre odstránenie, angl. delete). Vyskúšajme to na príklade a zopakujme si, čo sme sa už naučili; zmažeme prvé číslo v našom zozname. +Ak chceš niečo zo svojho zoznamu odstrániť, budeš potrebovať **indexy**, ako sme sa dozvedeli vyššie, a metódu `pop()`. Vyskúšajme si to na príklade a zopakujme si, čo sme sa už naučili - ideme vymazať prvé číslo v našom zozname. -``` +{% filename %}command-line{% endfilename %} + +```python >>> print(loteria) [59, 42, 30, 19, 12, 3, 199] >>> print(loteria[0]) 59 ->>> del loteria[0] +>>> loteria.pop(0) +59 >>> print(loteria) [42, 30, 19, 12, 3, 199] ``` Funguje to ako hodinky! -Pre zábavu vyskúšajte aj nejaké iné indexy: 6, 7, 1000, -1, -6 alebo -1000. Skúste predpovedať výsledok predtým ako príkaz použijete. Dávajú výsledky zmysel? +Pre tú srandu vyskúšaj iné indexy, napr. 6, 7, 1000, -1, -6 či -1000. Skús, či sa ti podarí predpovedať, aký bude výsledok, ešte pred tým, ako príkaz spustíš. Dávajú ti výsledky zmysel? -Zoznam všetkých dostupných metód pre zoznamy v tejto kapitole dokumentácie Pythonu: https://docs.python.org/3/tutorial/datastructures.html +Zoznam všetkých dostupných metód pre zoznamy nájdeš v tejto kapitole dokumentácie Pythonu: https://docs.python.org/3/tutorial/datastructures.html ## Slovníky -Slovník je podobný ako zoznam, ale k jeho hodnotám pristupujete vyhľadaním kľúča namiesto indexu. Kľúč môže byť akýkoľvek reťazec alebo číslo. Syntax na definovanie prázdneho slovníka je: +> Pre čitateľky a čitateľov doma: Táto kapitola je spracovaná vo videu [Python Basics: Dictionaries](https://www.youtube.com/watch?v=ZX1CVvZLE6c). -``` +Slovník (dictionary, skrátene dict) je podobný zoznamu, ale k hodnotám pristupuješ pomocou kľúča namiesto číselného indexu. Kľúč môže byť hocijaký reťazec alebo číslo. Syntax na definovanie prázdneho slovníka je: + +{% filename %}command-line{% endfilename %} + +```python >>> {} {} ``` -To znamená, že ste práve vytvorili prázdny slovník. Hurá! +Toto ti hovorí, že si práve vytvorila prázdny slovník. Hurá! -Teraz skúste napísať nasledujúci príkaz (skúste ale nahradiť hodnoty vlastnými údajmi): +Teraz skús napísať nasledujúci príkaz (skús nahradiť hodnoty vlastnými údajmi): -``` ->>> ucastnicka = {'meno': 'Ola', 'krajina': 'Slovensko', 'oblubene_cisla': [7, 42, 92]} +{% filename %}command-line{% endfilename %} + +```python +>>> ucastnicka = {'meno': 'Ola', 'krajina': 'Polsko', 'oblubene_cisla': [7, 42, 92]} ``` -Týmto príkazom ste práve vytvorili premennú s názvom `ucastnicka` s tromi pármi kľúč-hodnota: +Týmto príkazom si práve vytvorila premennú s názvom `ucastnicka` s tromi pármi kľúč-hodnota (key-value): -* Kľúč `meno` odkazuje na hodnotu `"Ola"` (objekt typu `reťazec/string`), -* `krajina` odkazuje na `"Slovensko"` (ďalší `reťazec`), -* a `oblubene_cisla` smeruje na `[7, 42, 92]` (`zoznam` s tromi číslami). +- Kľúč `meno` odkazuje na hodnotu `"Ola"` (objekt typu `reťazec`), +- `krajina` odkazuje na `"Polsko"` (ďalší `reťazec`), +- a `oblubene_cisla` ukazuje na `[7, 42, 92]` (`zoznam` s tromi číslami). -Obsah jednotlivých kľúčov môžete skontrolovať touto syntaxou: +Obsah jednotlivých kľúčov môžeš skontrolovať použitím tejto syntaxe: -``` +{% filename %}command-line{% endfilename %} + +```python >>> print(ucastnicka['meno']) Ola ``` -Ako vidíte, podobá sa to na zoznam. Ale nemusíte si pamätať index - stačí meno. +Vidíš, podobá sa to na zoznam. Akurát si nemusíš pamätať index - stačí názov. -Čo sa stane ak si od Pythonu vypýtame hodnotu kľúča, ktorý neexistuje? Uhádnete? Vyskúšajme to a uvidíme! +Čo sa stane, ak si od Pythonu vypýtame hodnotu kľúča, ktorý neexistuje? Uhádneš? Vyskúšame a uvidíme! -``` +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python >>> ucastnicka['vek'] Traceback (most recent call last): File "", line 1, in KeyError: 'vek' ``` -Aha, ďalšia chyba! Táto sa volá **KeyError** (chyba kľúča). Python je nápomocný a povie vám, že kľúč `'vek'` v tomto slovníku neexistuje. - -Kedy by používať slovník alebo zoznam? No, to je dobrá otázka. Porozmýšľaj predtým, ako si pozrieš odpoveď v nasledujúcom riadku. +Aha, ďalšia chyba! Táto sa volá **KeyError**. Python je nápomocný a povie ti, že kľúč (key) `'vek'` v tomto slovníku neexistuje. -* Potrebuješ zoradenú postupnosť položiek? Vyber si zoznam (list). -* Potrebuješ priraďovať hodnoty kľúčovým slovám, aby si si ich mohla efektívne (podľa kľúča) neskôr vyhľadať? Použi slovník (dictionary). +Kedy je dobré použiť slovník a kedy zoznam? No, to je dobrá otázka. Porozmýšľaj predtým, ako si pozrieš odpoveď v nasledujúcom riadku. -Slovníky, rovnako ako zoznamy sú *premenlivé*, čo znamená, že ich môžeme zmeniť po ich vytvorení. Po vytvorení môžeš do slovníka pridať nové dvojice kľúč/hodnota takto: +- Potrebuješ zoradenú postupnosť vecí? Vyber si zoznam. +- Potrebuješ priraďovať hodnoty kľúčom, aby si ich mohla efektívne (podľa kľúča) neskôr vyhľadať? Použi slovník. -``` ->>> ucastnicka['oblubeny_jazyk'] = 'Python' -``` +Tak ako pri zoznamoch, aj pri slovníkoch funkcia `len()` vracia počet párov kľúč-hodnota v danom slovníku. Poď, zadaj tento príkaz: -Tak ako pri zoznamoch, použitím metódy `len()` na slovníkoch dostaneš počet párov kľúč-hodnota v slovníku. Poďme na to, zadaj tento príkaz: +{% filename %}command-line{% endfilename %} -``` +```python >>> len(ucastnicka) -4 +3 ``` -Dúfam, že to dáva zmysel. :) Pripravená na trochu zábavy so slovníkmi? Tak šup na ďalší riadok za úžasnými vecami. +Slovníky, podobne ako zoznamy, sú *mutable* (premenlivé), čo znamená, že ich možno zmeniť po tom, ako boli vytvorené. Do existujúceho slovníka môžeš pridať nový pár kľúč-hodnota takto: -Na odstránenie položky zo slovníka môžeš použiť príkaz `del`. Napríklad ak chceš odstrániť položku zodpovedajúcu kľúču `'oblubene_cisla'`, zadaj nasledujúci príkaz: +{% filename %}command-line{% endfilename %} +```python +>>> ucastnicka['oblubeny_jazyk'] = 'Python' ``` ->>> del ucastnicka['oblubene_cisla'] + +Dúfam, že to dáva zmysel. :) Pripravená na trochu zábavy so slovníkmi? Čakajú nás ďalšie úžasné veci. + +Na odstránenie položky zo slovníka môžeš tiež použiť metódu `pop()`. Napríklad, ak chceš odstrániť položku zodpovedajúcu kľúču `'oblubene_cisla'`, zadaj nasledujúci príkaz: + +{% filename %}command-line{% endfilename %} + +```python +>>> ucastnicka.pop('oblubene_cisla') +[7, 42, 92] >>> ucastnicka -{'krajina': 'Slovensko', 'oblubeny_jazyk': 'Python', 'meno': 'Ola'} +{'meno': 'Ola', 'krajina': 'Polsko', 'oblubeny_jazyk': 'Python'} ``` -Ako vidíš z výstupu, pár kľúč-hodnota zodpovedajúci kľúču 'oblubene_cisla' bol vymazaný. +Ako vidíš z výstupu, pár kľúč-hodnota zodpovedajúci kľúču 'oblubene_cisla' zmizol. Taktiež môžeš zmeniť hodnotu priradenú k už vytvorenému kľúču v slovníku. Napíš: -``` +{% filename %}command-line{% endfilename %} + +```python >>> ucastnicka['krajina'] = 'Nemecko' >>> ucastnicka {'krajina': 'Nemecko', 'oblubeny_jazyk': 'Python', 'meno': 'Ola'} ``` -Ako vidíš, hodnota kľúča `"krajina"` sa zmenila z `"Poľsko"` na `"Nemecko"`. :) Vzrušujúce? Hurá! Práve si sa naučila ďalšiu úžasnú vec. +Ako vidíš, hodnota kľúča `"krajina"` sa zmenila z `"Polsko"` na `"Nemecko"`. :) Vzrušujúce? Hurá! Práve si sa naučila ďalšiu úžasnú vec. ### Zhrnutie Skvelé! Teraz už vieš o programovaní dosť veľa. Pozrime sa, čo sme si vysvetlili v poslednej časti: -* **chyby** (angl. error) - teraz už vieš ako čítať a rozumieť chybám, ktoré sa zobrazia, ak Python nerozumie príkazu, ktorý mu zadáš -* **premenné** - názvy objektov, ktoré ti uľahčujú písanie kódu a robia tiež kód zrozumiteľnejším -* **zoznamy** (angl. list) - zoznam objektov uložených v určitom poradí -* **slovníky** (angl. dictionary) - objekty uložené v pároch kľúč-hodnota +- **chyby** - teraz už vieš, ako čítať a rozumieť chybám, ktoré sa zobrazia, ak Python nerozumie príkazu, ktorý mu zadáš +- **premenné** - názvy objektov, ktoré ti uľahčujú písanie kódu a robia tiež kód zrozumiteľnejším +- **zoznamy** - zoznamy objektov uložených v určitom poradí +- **slovníky** - objekty uložené v pároch kľúč-hodnota Tešíš sa na ďalšiu časť? :) ## Porovnávanie vecí -Veľkú časť programovania predstavuje porovnávanie veci. Čo je najjednoduchšia vec na porovnanie? Čísla, samozrejme. Pozrime sa, ako to funguje: +> Pre čitateľky a čitateľov doma: Táto kapitola je spracovaná vo videu [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4). -``` +Veľkú časť programovania predstavuje porovnávanie veci. Čo sa porovnáva najjednoduchšie? Čísla! Pozrime sa, ako to funguje: + +{% filename %}command-line{% endfilename %} + +```python >>> 5 > 2 True >>> 3 < 1 @@ -399,31 +477,37 @@ True True >>> 5 != 2 True +>>> len([1, 2, 3]) > len([4, 5]) +True ``` -Dali sme Pythonu pár čísiel na porovnanie. Ako vidíš, Python vie porovnávať nielen čísla, ale vie porovnávať aj výsledky metód. Pekné, nie? +Dali sme Pythonu na porovnanie zopár čísel. Ako vidíš, Python vie porovnávať nielen čísla, ale aj výsledky matematických výrazov ako `2 * 2` a výsledky funkcií ako `2`, ktorú vrátila funkcia `len([4, 5])`. Fajn, nie? -Zaujíma ťa, prečo sme použili dve "rovná sa" `==` vedľa seba, aby sme porovnali, či sú čísla rovnaké? Jeden znak `=` používame na priraďovanie hodnôt premenným. Takže, ak chceš skontrolovať, či sú veci rovnaké, musíš vždy, úplne **vždy** použiť dve `==`. Taktiež môžeme zisťovať, či sa veci navzájom líšia. Na to použijeme symbol `!=`, ako bolo uvedené v príklade vyššie. +Zaujíma ťa, prečo sme použili dve znamenienka rovnosti `==` vedľa seba, aby sme porovnali, či sú čísla rovnaké? Jeden znak `=` používame na priraďovanie hodnôt premenným. Takže ak chceš skontrolovať, či sú veci rovnaké, musíš vždy, úplne **vždy** použiť dve `==`. Taktiež môžeme vyjadriť, že sa veci navzájom líšia. Na to použijeme symbol `!=`, ako bolo uvedené v príklade vyššie. -Zadaj Pythonu ešte dve úlohy: +Dajme Pythonu dve ďalšie úlohy: -``` +{% filename %}command-line{% endfilename %} + +```python >>> 6 >= 12 / 2 True >>> 3 <= 2 False ``` -`>` a `<` sú jasné, ale čo znamenajú `>=` a `<=`? Prečítať ich môžeš takto: +`>` a `<` sme už videli, ale čo znamenajú `>=` a `<=`? Môžeš ich čítať takto: -* x `>` y znamená: x je väčšie ako y -* x `<` y znamená: x je menšie ako y -* x `<=` y znamená: x je menšie alebo sa rovná y -* x `> =` y znamená: x je väčšie alebo sa rovná y +- x `>` y znamená: x je väčšie ako y +- x `<` y znamená: x je menšie ako y +- x `<=` y znamená: x je menšie alebo rovné y +- x `> =` y znamená: x je väčšie alebo rovné y -Skvelé! Chceš vyskúšať ešte jeden? Skús toto: +Skvelé! Ešte si dáme jeden príklad? Skús toto: -``` +{% filename %}command-line{% endfilename %} + +```python >>> 6 > 2 and 2 < 3 True >>> 3 > 2 and 2 < 1 @@ -432,33 +516,40 @@ False True ``` -Môžeš dať Pythonu toľko čísel, koľko chceš a on ti dá vždy odpoveď! Vcelku šikovné, nie? +Môžeš dať Pythonu toľko čísel, koľko chceš, a on ti dá vždy odpoveď! Vcelku šikovné, nie? -* **and** - ak použiješ operátor `and`, obidve porovnávané veci musia byť pravdivé (True), aby príkaz bol pravda (True) -* **or** - ak použiješ operátor `or`, stačí aby jedna z porovnávaných vecí bola pravdivá, aby bol celý príkaz pravda (True) +- **and** - ak použiješ operátor `and`, obidve porovnávané veci musia byť pravdivé (True), aby príkaz bol pravdivý (True) +- **or** - ak použiješ operátor `or`, stačí, aby jedna z porovnávaných vecí bola pravdivá, aby bol celý príkaz pravda (True) -Už ste počula výraz "porovnávať hrušky s jablkami"? Skúsme pythonský ekvivalent: +Už si počula výraz "porovnávať hrušky s jablkami"? Skúsme ekvivalent v Pythone: -``` +{% filename %}{{ warning_icon }} command-line{% endfilename %} + +```python >>> 1 > 'django' Traceback (most recent call last): File "", line 1, in -TypeError: unorderable types: int() > str() +TypeError: '>' not supported between instances of 'int' and 'str' ``` -Tu vidíš, že tak ako nevieme porovnávať hrušky s jablkami, ani Python neviem porovnať číslo (`int`) s reťazcom (`str`). Namiesto toho vypíše chybu **TypeError** a povie nám, ktoré dva typy sa nedajú porovnať. +Tu vidíš, že tak, ako nevieme porovnávať hrušky s jablkami, ani Python nevie porovnať číslo (`int`) s reťazcom (`str`). Namiesto toho vypíše chybu **TypeError** a povie nám, že tieto dva typy sa nedajú porovnať. -## Logické hodnoty (Boolean) +## Logické hodnoty -Práve si spoznala nový typ objektov v Pythone. Volá sa **logická hodnota** (po anglicky im hovoríme Boolean), pravdepodobne najjednoduchší typ, ktorý existuje. +Mimochodom, práve si sa naučila nový typ objektu v Pythone. Volá sa **boolean** (logická hodnota). -Existujú iba dva typy Booleovských objektov: - True (Pravda) - False (Nepravda) +Existujú iba dva typy boolean objektov: -Aby ich Python spoznal, musíš vždy napísať 'True' (s veľkým písmenom na začiatku a zvyšok malým písmom). **true, TRUE, tRUE nebudú fungovať -- iba True je správne.** (Samozrejme, to isté platí aj pre 'False'.) +- True (pravda) +- False (nepravda) -Logické hodnoty môžu byť aj premenné. Aha: +Aby ich Python spoznal, musíš vždy napísať "True" (s veľkým písmenom na začiatku a zvyšok malým písmom). **true, TRUE, tRUE nebudú fungovať -- iba True je správne.** (To isté platí aj pre 'False'.) -``` +Premenné môžu tiež obsahovať booleany. Aha: + +{% filename %}command-line{% endfilename %} + +```python >>> a = True >>> a True @@ -466,124 +557,180 @@ True Môžeš to urobiť aj takto: -``` +{% filename %}command-line{% endfilename %} + +```python >>> a = 2 > 5 >>> a False ``` -Precvič si to a zabav sa s logickými premennými - skús spustiť tieto príkazy: +Precvič si to a zabav sa s booleanmi - skús spustiť tieto príkazy: -* `True and True` -* `False and True` -* `True or 1 == 1` -* `1 != 2` +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` -Gratulujeme! Logické hodnoty patria k tomu najužitočnejšiemu z programovania a ty si sa práve naučila, ako sa používajú! +Gratulujeme! Booleany patria k tomu najzaujímavejšiemu v programovaní a ty si sa práve naučila, ako sa používajú! # Ulož to! -Zatiaľ sme písali všetok pythonský kód do konzoly interpretera, čiže môžeme na jedenkrát zadať iba jeden riadok kódu. Normálne programy sú uložené v súboroch, ktoré spúšťa buď **interpreter** alebo **kompilátor**. Doteraz sme spúšťali naše programy riadok po riadku v **interpreteri** Pythonu. Na ďalšie úlohy budeme potrebovať viac ako jeden riadok kódu, takže teraz rýchlo musíme: +> Pre čitateľky a čitateľov doma: Táto kapitola je spracovaná vo videu [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk). -* Ukončiť interpreter Pythonu -* Otvoriť si zvolený editor kódu -* Uložiť v ňom nejaký kód do nového pythonského súboru -* Spustiť ho! +Zatiaľ sme písali všetok kód v Pythone do konzoly interpretera, kde môžeme naraz zadať iba jeden riadok kódu. Bežné programy bývajú uložené v súboroch, ktoré spúšťa náš programovací jazyk buď pomocou **interpretera**, alebo **kompilátora**. Doteraz sme spúšťali naše programy riadok po riadku v **interpreteri** Pythonu. Na ďalšie úlohy budeme potrebovať viac ako jeden riadok kódu, takže teraz rýchlo musíme: -Pre opustenie interpretera Pythonu, ktorý sme doteraz používali, zadaj jednoducho funkciu ~~~ exit()~~~: +- Ukončiť interpreter Pythonu +- Otvoriť si náš zvolený editor kódu +- Uložiť v ňom trochu kódu do nového Python súboru +- Spustiť ho! -``` +Ak chceš odísť z Python interpretera, ktorý sme doteraz používali, zadaj funkciu `exit()` + +{% filename %}command-line{% endfilename %} + +```python >>> exit() $ ``` Tak sa dostaneš späť na príkazový riadok. -Už skôr si si vybrala editor kódu v kapitole [editor kódu][1]. Teraz ho potrebujeme otvoriť a napísať v ňom do nového súboru nejaký kód: +V jednej z [predošlých častí](../code_editor/README.md) sme si vybrali editor kódu. Teraz budeme chcieť tento editor otvoriť a napísať pár riadkov kódu do nového súboru (alebo ak používaš Chromebook, vytvoriť nový súbor v Cloud IDE a otvoriť ho, čo sa udeje v zabudovanom editore kódu): - [1]: ../code_editor/README.md +{% filename %}editor{% endfilename %} ```python -print('Hello, Django girls!') +print('Ahoj, Django Girls!') ``` -> **Poznámka** Všimni si jednu z najúžasnejších vecí editorov kódu: farby! V pythonskej konzole bolo všetko napísané jednou farbou, teraz však vidíš, že funkcia `print` je napísaná inou farbou ako reťazec. Toto sa nazýva "zvýraznenie syntaxe" a pri programovaní je to fakt užitočná vec. Farba výrazov ti môže pomôcť, ak máš neuzavretý reťazec či preklep v názve špeciálnych slov (ako napríklad `def` vo funkcii, ktorú uvidíme neskôr). Toto je jedným z dôvodov, prečo používame editor kódu :) +Prirodzene, teraz si už poriadne skúsená Python vývojárka, takže pokojne napíš nejaký kód, ktorý si sa dnes naučila. + +Teraz súbor musíme uložiť a dať mu nejaký zrozumiteľný názov. Nazvime ho **python_intro.py** a uložme ho na plochu. Súbor môžeš nazvať, akokoľvek chceš, ale dôležité je, aby jeho názov končil na **.py**. Prípona **.py** nášmu operačnému systému hovorí, že je to **spustiteľný pythonovský súbor** a Python ho vie spustiť. -Samozrejme, teraz si už vcelku skúsená Python developerka, takže kľudne napíš nejaký kód, ktorý si sa dnes naučila. +> **Poznámka** Všimni si jednu z najlepších vecí na editoroch kódu: farby! V Python konzole bolo všetko jednou farbou, teraz by si ale mala vidieť, že funkcia `print` je napísaná inou farbou ako reťazec. Toto sa nazýva "zvýraznenie syntaxe" (syntax highlighting) a pri programovaní je to fakt užitočná vec. Farba výrazov ti môže niečo napovedať, ak máš niekde neuzavretý reťazec či preklep v názve špeciálnych slov (ako napríklad `def` vo funkcii, ktorú uvidíme neskôr). Toto je jeden z dôvodov, prečo používame editor kódu. :) -Teraz uložíme súbor a dáme mu nejaký zrozumiteľný názov. Nazvime ho **python_intro.py** a ulož ho plochu. Tento súbor môžeš nazvať akokoľvek chceš, ale dôležité je, aby jeho názov končil **.py**. Prípona **.py** nášmu operačnému systému hovorí, že je to **súbor spustiteľný Pythonom** a môže ho spustiť Pythonom. +Súbor máme uložený, je čas ho spustiť! Pomocou poznatkov z kapitoly o príkazovom riadku **zmeň adresár** na plochu terminálovým príkazom. -Súbor máme uložený, je čas ho spustiť! Pomocou poznatkov z kapitoly o príkazovom riadku, pomocou Terminálu **zmeň adresár** na plochu. + Na Macu bude príkaz vyzerať takto: -``` -$ cd ~/Desktop -``` +{% filename %}command-line{% endfilename %} -Na Linuxe to bude takto (slovo "Desktop" bude možno preložené): + $ cd ~/Desktop + -``` -$ cd ~/Desktop -``` + -A vo Windowse bude príkaz vyzerať takto: + -``` -> cd %HomePath%\Desktop -``` +Na Linuxe bude takýto: + +{% filename %}command-line{% endfilename %} + + $ cd ~/Desktop + + +(Pripomíname, že slovo "Desktop" alebo "Plocha" môže bude preložené.) + + -Ak máš akékoľvek ťažkosti, stačí požiadať o pomoc. + + +Vo windowsovom Command Prompte to bude takto: + +{% filename %}command-line{% endfilename %} + + > cd %HomePath%\Desktop + + + + + + +A vo windowsovom PowerShelli to bude takto: + +{% filename %}command-line{% endfilename %} + + > cd $Home\Desktop + + + + +Ak sa zasekneš, neboj sa spýtať. Na to presne tu máš mentorky a mentorov! Teraz použi Python na spustenie kódu v súbore: -``` -$ python3 python_intro.py -Hello, Django girls! +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Ahoj, Django Girls! + + +Poznámka: na Windowse "python3" ako príkaz neexistuje. Na spustenie súboru použi "python": + +{% filename %}command-line{% endfilename %} + +```python +> python python_intro.py ``` -Výborne! Práve si spustila svoj prvý pythonský program uložený v súbore. Skvelý pocit, však? +Okej! Práve si spustila svoj prvý program v Pythone zo súboru. Skvelý pocit, nie? -Teraz sa môžeš posunúť na ďalší základný nástroj v programovaní: +Teraz sa môžeš posunúť na základný nástroj v programovaní: -## If...elif...else +## If … elif … else -Kopec vecí v kóde sa má spúšťať len ak sú splnené nejaké podmienky. Práve na to používa Python príkaz **if**. +Kopec vecí v kóde sa má spúšťať, len ak sú splnené určité podmienky. Práve na to používa Python príkaz **if**. Nahraď kód v súbore **python_intro.py** týmto: +{% filename %}python_intro.py{% endfilename %} + ```python if 3 > 2: ``` Ak to uložíš a spustíš, dostaneš túto chybu: -``` -$ python3 python_intro.py -File "python_intro.py", line 2 - ^ -SyntaxError: unexpected EOF while parsing -``` +{% filename %}{{ warning_icon }} command-line{% endfilename %} + + $ python3 python_intro.py + File "python_intro.py", line 2 + ^ + SyntaxError: unexpected EOF while parsing + -Python očakáva, že od nás dostane ďalšie inštrukcie, ktoré majú byť vykonané ak je podmienka `3 > 2` pravdivá (teda ak bude mať hodnotu `True`). Skúsme zariadiť, aby Python napísal "Funguje to!". Zmeň svoj kód v súbore **python_intro.py** takto: +Python očakáva, že od nás dostane ďalšie inštrukcie, ktoré má vykonať, ak je podmienka `3 > 2` pravdivá (teda ak bude mať hodnotu `True`). Skúsme Pythonu povedať, aby vypísal "Funguje to!". Zmeň svoj kód v súbore **python_intro.py** takto: + +{% filename %}python_intro.py{% endfilename %} ```python if 3 > 2: print('Funguje to!') ``` -Všimla si si, ako sme odsadili druhý riadok o 4 medzery? To musíme urobiť preto, aby Python vedel, ktorú časť kódu má spustiť ak je výsledok pravdivý. Môžeš použiť len jednu medzeru, ale takmer všetci programátori v Pythone používajú 4 medzery, aby bol kód dobre čitateľný. Jeden `tab` sa tiež počíta ako 4 medzery. +Všimla si si, ako sme odsadili druhý riadok o 4 medzery? To musíme urobiť preto, aby Python vedel, ktorú časť kódu má spustiť, ak je výsledok pravdivý. Môžeš použiť len jednu medzeru, ale takmer všetci programátori a programátorky v Pythone používajú 4 medzery, aby bol kód dobre čitateľný. Jedno stlačenie klávesy Tab sa tiež bude rátať ako 4 medzery, pokiaľ je tvoj editor tak nastavený. Keď sa pre jedno rozhodneš, zostaň pri tom! Ak si už začala odsádzať 4 medzerami, daj si záležať, aby aj ďalšie odsadenia boli 4 medzerami, inak ti to môže spôsobovať problémy. -Ulož to a spusti to znova: +Ulož to a spusti znova: -``` +{% filename %}command-line{% endfilename %} + +```python $ python3 python_intro.py Funguje to! ``` +Poznámka: Pamätaj, že Windows nepozná príkaz "python3". Odteraz vždy pri spúšťaní súborov nahraď "python3" príkazom "python". + ### Čo ak podmienka nie je pravdivá? -V predchádzajúcich príkladoch, bol kód vykonaný len vtedy, keď podmienky boli pravdivé. Ale Python má tiež príkazy `elif` a `else`: +V predcházajúcich príkladoch sa náš kód vykonal, len keď podmienka bola pravdivá (True). Ale Python má aj príkazy `elif` a `else`: + +{% filename %}python_intro.py{% endfilename %} ```python if 5 > 2: @@ -594,253 +741,316 @@ else: Keď to spustíš, vypíše to: -``` -$ python3 python_intro.py -5 je naozaj viac ako 2 -``` +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + 5 je naozaj viac ako 2 + -Ak by 2 bolo väčšie ako 5, spustil by sa druhý príkaz. Jednoduché, nie? Pozrime sa, ako funguje `elif`: +Ak by 2 bolo viac ako 5, spustil by sa druhý príkaz. Pozrime sa, ako funguje `elif`: + +{% filename %}python_intro.py{% endfilename %} ```python -name = 'Sonja' -if name == 'Ola': - print('Ahoj Ola!') -elif name == 'Sonja': - print('Ahoj Sonja!') +meno = 'Sona' +if meno == 'Ola': + print('Cau Ola!') +elif meno == 'Sona': + print('Cau Sona!') else: - print('Ahoj neznama!') + print('Cau neznama!') ``` a po spustení: -``` -$ python3 python_intro.py -Ahoj Sonja! -``` +{% filename %}command-line{% endfilename %} -Všimla si si, čo sa stalo? `elif` ti dovolí pridať dodatočné podmienky, ktoré sa spustia, ak sú predchádzajúce nesplnené. + $ python3 python_intro.py + Cau Sona! + -Za prvý `if` môžeš dať `elif` toľkokrát, koľko len chceš. Napríklad: +Všimla si si, čo sa stalo? `elif` ti dovolí pridať dodatočné podmienky, ktoré sa spustia, ak predchádzajúce podmienky nie sú splnené. + +Za prvý `if` môžeš dať `elifov` toľko, koľko len chceš. Napríklad: + +{% filename %}python_intro.py{% endfilename %} ```python hlasitost = 57 if hlasitost < 20: - print("Vcelku ticho.") + print("Je to pomerne tiche.") elif 20 <= hlasitost < 40: - print("Fajn na hudbu v pozadi") + print("Je to fajn ako hudba na pozadi") elif 40 <= hlasitost < 60: print("Super, pocujem vsetky detaily") elif 60 <= hlasitost < 80: - print("Vyborne na party") + print("Fajn na party") elif 80 <= hlasitost < 100: - print("Trochu hlucne!") + print("Trochu hlasne!") else: print("Bolia ma usi! :(") ``` -Python prejde všetkými podmienkami v poradí a vypíše: +Python prejde všetkými podmienkami poporade a vypíše: +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Super, pocujem vsetky detaily + + +## Komentáre + +Komentáre (comments) sú riadky, ktoré sa začínajú znakom `#`. Po `#` môžeš napísať hocičo, Python to bude ignorovať. Komentáre môžu spraviť tvoj kód čitateľnejším pre iných ludí. + +Pozrime sa, ako to vyzerá: + +{% filename %}python_intro.py{% endfilename %} + +```python +# Zmen hlasitost, ak je prilis silna alebo slaba +if hlasitost < 20 or hlasitost > 80: + hlasitost = 50 + print("Lepsie!") ``` -$ python3 python_intro.py -Super, pocujem vsetky detaily -``` + +Nemusíš písať komentár pre každý riadok kódu, čo napíšeš, ale je užitočné vysvetliť, prečo tvoj kód niečo robǐ, alebo stručne zhrnúť, čo sa deje, keď robí niečo zložité. ### Zhrnutie -V posledných troch cvičeniach si sa naučila: +V posledných pár cvičeniach si sa naučila: -* **porovnávať veci** - v Pythone môžeš porovnávať veci pomocou znamienok `>`, `>=`, `==`, `<=`, `<` a operátorov `and`, `or` -* **Booleovské/logické premenné** - typ objektu, ktorý môže mať len jednu z dvoch hodnôt: `True` (pravda) alebo `False` (nepravda) -* **Ukladať súbory** - ukladanie kódu v súboroch, takže môžete spúšťať väčšie programy. -* **Ak... elif... inde** - príkazy, ktoré ti umožňujú spustiť kód, iba ak sú splnené určité podmienky. +- **porovnávať veci** - v Pythone môžeš porovnávať veci pomocou znamienok `>`, `>=`, `==`, `<=`, `<` a operátorov `and`, `or` +- **boolean** - typ objektu, ktorý môže mať len jednu z dvoch hodnôt: `True` (pravda) alebo `False` (nepravda) +- **ukladať súbory** - ukladanie kódu v súboroch, vďaka čomu môžeme spúšťať väčšie programy +- **if... elif... else** - príkazy, ktoré ti umožňujú spustiť kód, iba ak sú splnené určité podmienky. +- **komentáre** - riadky, ktoré Python nebude spúšťať, vďaka ktorým môžeš svoj kód zdokumentovať -Teraz je čas na poslednú časť tejto kapitoly! +Prišiel čas na poslednú časť tejto kapitoly! ## Tvoje vlastné funkcie! -Pamätáš si funkcie ako napríklad `len()`, ktoré môžeš v Pythone spúšťať? Máme pre teba dobrú správu - teraz sa naučíš ako napísať vlastnú funkciu! +> Pre čitateľky a čitateľov doma: Táto kapitola je spracovaná vo videu [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0). -Funkcia je postupnosť inštrukcií, ktoré by mal Python spustiť. Každá funkcia v Pythone začína kľúčovým slovom `def`, má svoje meno a môže mať nejaké parametre. Začnime s niečím ľahkým. Nahraď kód v **python_intro.py** týmto: +Pamätáš si funkcie ako napríklad `len()`, ktoré môžeš v Pythone spúšťať? Máme pre teba dobrú správu - teraz sa naučíš, ako napísať vlastnú funkciu! + +Funkcia je postupnosť inštrukcií, ktoré by mal Python spustiť. Každá funkcia v Pythone začína kľúčovým slovom `def`, má svoje meno a môže mať nejaké parametre. Vyskúšajme si to. Nahraď kód v **python_intro.py** týmto: + +{% filename %}python_intro.py{% endfilename %} ```python -def hi(): +def ahoj(): print('Ahoj!') print('Ako sa mas?') -hi() +ahoj() ``` -OK, naša prvá funkcia je pripravená! +OK, naša prvá funkcia je hotová! -Možno sa čuduješ prečo sme na koniec súboru napísali názov funkcie. To preto, lebo Python číta súbor a vykonáva kód od vrchu po spodok. Takže aby sme mohli našu funkciu použiť, musíme jej názov napísať opäť. +Možno sa čuduješ, prečo sme na koniec súboru napísali názov funkcie. Keď sme napísali `def ahoj():` a za tým odsadené riadky, písali sme inštrukcie, čo má funkcia `ahoj()` robiť. Python tieto inštrukcie prečíta a zapamätá si ich, ale funkciu zatiaľ nespustí. Aby sme Pythonu povedali, že funkciu má spustiť, musíme ju zavolať (call) pomocou `ahoj()`. Python číta a spúšťa obsah nášho súboru zhora nadol, takže funkciu musíme najprv definovať a až potom zavolať. -Spusťme to a pozrime sa, čo sa stane: +Poďme to spustiť a pozrime sa, čo sa stane: -``` -$ python3 python_intro.py -Ahoj! -Ako sa mas? -``` +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Ahoj! + Ako sa mas? + + +Poznámka: Ak to nefunguje, žiadne strachy! Výstup ti pomôže zistiť prečo: + +- Ak sa ti zjaví `NameError`, znamená to, že si niečo chybne napísala, takže by si si mala overiť, že si použila rovnaký názov, keď si funkciu vytvárala pomocou `def ahoj()` a keď si ju zavolala pomocou `ahoj()`. +- Ak sa ti zjaví `IndentationError`, uisti sa, že oba `print` riadky majú rovnaký počet medzier od začiatku riadku: Python vyžaduje, aby všetky riadky boli pedantne zarovnané. +- Ak nevidíš žiaden výstup, tak sa pozri, či posledné `ahoj()` *nie je* odsadené - ak je, tento riadok sa stal súčasťou funkcie a nikdy sa nespustí. -To bolo ľahké! Poďme vytvoriť našu prvú funkciu s parametrami. Použijeme predchádzajúci príklad - funkcia, ktorá hovorí "ahoj" osobe, ktorá ju spustí - s menom: +Poďme vytvoriť našu prvú funkciu s parametrami. Použijeme predchádzajúci príklad - funkciu, ktorá hovorí "ahoj" osobe, ktorá ju spustí - s menom: + +{% filename %}python_intro.py{% endfilename %} ```python -def hi(meno): +def ahoj(meno): ``` Ako vidíš, dali sme našej funkcii parameter, ktorý sme nazvali `meno`: +{% filename %}python_intro.py{% endfilename %} + ```python -def hi(meno): +def ahoj(meno): if meno == 'Ola': print('Ahoj Ola!') - elif meno == 'Sonja': - print('Ahoj Sonja!') + elif meno == 'Sona': + print('Ahoj Sona!') else: print('Ahoj neznama!') -hi() +ahoj() ``` -Zapamätaj si: Funkcia `print` je odsadená o 4 medzery vo vnútri príkazu `if`. Je to preto, lebo funkcia sa spustí, len ak je splnená podmienka. Pozrime sa ako to funguje: +Pamätaj: Funkcia `print` je odsadená o 4 medzery vo vnútri príkazu `if`. Je to preto, lebo funkcia sa spustí, len ak je splnená podmienka. Pozrime sa, ako to funguje: -``` -$ python3 python_intro.py -Traceback (most recent call last): -File "python_intro.py", line 10, in - hi() -TypeError: hi() missing 1 required positional argument: 'meno' -``` +{% filename %}{{ warning_icon }} command-line{% endfilename %} + + $ python3 python_intro.py + Traceback (most recent call last): + File "python_intro.py", line 10, in + ahoj() + TypeError: ahoj() missing 1 required positional argument: 'meno' + + +Ups, chyba. Našťastie, Python nám dáva veľmi užitočnú chybovú hlášku. Hovorí nám, že funkcia `ahoj()` (tá, čo sme definovali) má jeden povinný argument (s názvom `meno`) a že sme mu ju zabudli zadať pri volaní funkcie. Opravme to na konci súboru: -Ups, chyba. Našťastie Python nám dáva vcelku užitočnú chybovú hlášku. Hovorí nám, že funkcia `hi()` (tá, čo sme definovali) má jeden povinný argument (s názvom `meno`) a že sme mu ju zabudli zadať pri volaní funkcie. Opravme to na konci súboru: +{% filename %}python_intro.py{% endfilename %} ```python -hi("Ola") +ahoj("Ola") ``` -A znova ho spusti: +A znova ho spustime: -``` -$ python3 python_intro.py -Ahoj Ola! -``` +{% filename %}command-line{% endfilename %} + + $ python3 python_intro.py + Ahoj Ola! + A čo ak zmeníme meno? +{% filename %}python_intro.py{% endfilename %} + ```python -hi("Sonja") +ahoj("Sona") ``` A spustíme to: -``` -$ python3 python_intro.py -Ahoj Sonja! -``` +{% filename %}command-line{% endfilename %} -No a čo si myslíš, čo sa stane, ak tam napíšeš iné meno? (Nie Ola ani Sonja.) Vyskúšaj to a uvidíš, či bol tvoj predpoklad správny. Malo by ti vypísať toto: + $ python3 python_intro.py + Ahoj Sona! + -``` -Ahoj neznáma! -``` +No a čo si myslíš, čo sa stane, ak tam napíšeš iné meno? (Nie Ola, ani Sona.) Vyskúšaj a uvidíš, či bol tvoj predpoklad správny. Malo by ti to vypísať toto: + +{% filename %}command-line{% endfilename %} + + Ahoj neznama! + -Úžasné, nie? Vďaka tomu nemusíš prepisovať dokola to isté zakaždým, keď chceš zmeniť meno osoby, ktorú má funkcia pozdraviť. A to je presne dôvod, prečo potrebujeme funkcie - aby sme nemuseli opakovať svoj kód! +Nie je to super? Vďaka tomu nemusíš písať dookola to isté zakaždým, keď chceš zmeniť meno človeka, ktorého má funkcia pozdraviť. A to je presne dôvod, prečo potrebujeme funkcie - aby sme sa nemuseli v kóde opakovať! -Urobme to teda trochu rozumnejšie - existujú viac ako dve mená a písať podmienku pre každé by bolo trochu náročné, však? +Skúsme to trochu inak. Existuje viac mien ako len dve a písať samostatnú podmienku pre každé jedno by bolo ťažké, nie? Nahraď obsah svojho súboru týmto: + +{% filename %}python_intro.py{% endfilename %} ```python -def hi(meno): +def ahoj(meno): print('Ahoj ' + meno + '!') -hi("Katka") +ahoj("Kika") ``` -Teraz spusťme kód: +Teraz tento kód spustime: -``` -$ python3 python_intro.py -Ahoj Katka! -``` +{% filename %}command-line{% endfilename %} -Gratulujeme! Práve si sa naučila ako sa píšu funkcie! :) + $ python3 python_intro.py + Ahoj Kika! + + +Gratulujeme! Práve si sa naučila, ako sa píšu funkcie! :) ## Cykly +> Pre čitateľky a čitateľov doma: Táto kapitola je spracovaná vo videu [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0). + Toto je už posledná časť. Išlo to rýchlo, však? :) -Programátori sa neradi opakujú. Programovanie je o automatizácii vecí, takže nechceme zdraviť každú osobu manuálne, nie? A vtedy nám prídu vhod cykly. +Programátori a programátorky sa neradi opakujú. Programovanie je o automatizácii vecí, takže nechceme zdraviť každú osobu manuálne, však? A tu nám prídu vhod cykly (loops). -Ešte si spomínaš na zoznamy? Pripravme zoznam dievčat: +Ešte si spomínaš na zoznamy? Spravme si zoznam dievčat: + +{% filename %}python_intro.py{% endfilename %} ```python -dievcata = ['Katka', 'Monika', 'Zuzka', 'Ola', 'Ty'] +dievcata = ['Katka', 'Kika', 'Zuza', 'Ola', 'Ty'] ``` -Chceme ich pozdraviť všetky menom. Na to máme funkciu `hi`, tak ju použime v cykle: +Chceme ich pozdraviť všetky menom. Na to máme funkciu `ahoj`, tak ju použime v cykle: + +{% filename %}python_intro.py{% endfilename %} ```python for meno in dievcata: ``` -Príkaz ~~~ for ~~~ sa správa podobne ako príkaz ~~~ if ~~~ ; kód pod oboma z nich musí byť odsadený o štyri medzery. +Príkaz `for` sa správa podobne ako `if`; kód pod oboma z nich musí byť odsadený o štyri medzery. -Tu je plný kód, ktorý napíšeme do súboru: +Tu je celý kód, ktorý napíšeme do súboru: + +{% filename %}python_intro.py{% endfilename %} ```python -def hi(meno): +def ahoj(meno): print('Ahoj ' + meno + '!') -dievcata = ['Katka', 'Monika', 'Zuzka', 'Ola', 'Ty'] +dievcata = ['Katka', 'Kika', 'Zuza', 'Ola', 'Ty'] for meno in dievcata: - hi(meno) + ahoj(meno) print('Dalsie dievca') ``` A keď to spustíme: -``` -$ python3 python_intro.py -Ahoj Katka! -Dalsie dievca -Ahoj Monika! -Dalsie dievca -Ahoj Zuzka! -Dalsie dievca -Ahoj Ola! -Dalsie dievca -Ahoj Ty! -Dalsie dievca -``` +{% filename %}command-line{% endfilename %} -Ako vidíš, všetko, čo dáš do príkazu `for` s oddsadením sa bude opakovať pre každý prvok zoznamu `dievcata`. + $ python3 python_intro.py + Ahoj Katka! + Dalsie dievca + Ahoj Kika! + Dalsie dievca + Ahoj Zuza! + Dalsie dievca + Ahoj Ola! + Dalsie dievca + Ahoj Ty! + Dalsie dievca + + +Ako vidíš, všetko, čo dáš do príkazu `for` s tým, že to odsadíš, sa zopakuje pre každý prvok zoznamu `dievcata`. `for` môžeš pomocou funkcie `range` použiť aj na čísla: +{% filename %}python_intro.py{% endfilename %} + ```python for i in range(1, 6): - print(i) + print(i) ``` Čo vypíše: -``` -1 -2 -3 -4 -5 -``` +{% filename %}command-line{% endfilename %} + + 1 + 2 + 3 + 4 + 5 + -`range` je funkcia, ktorá vytvára zoznam čísel s postupnosťou čísel (krajné čísla funkcii poskytneš ako parametre). +`range` je funkcia, ktorá vytvára zoznam s postupnosťou čísel (krajné čísla funkcii poskytneš ako parametre). -Všimni si, že druhé číslo sa nenachádza vo výstupnom zozname (teda `range(1, 6)` počíta od 1 po 5, ale neobsahuje číslo 6). To je preto, lebo "range" je jednostranne otvorený, čo znamená, že obsahuje prvú hodnotu, ale nie poslednú. +Všimni si, že druhé číslo sa nenachádza vo výstupnom zozname (teda `range(1, 6)` počíta od 1 po 5, ale neobsahuje číslo 6). To preto, lebo "range" je jednostranne otvorený, čo znamená, že obsahuje prvú hodnotu, ale nie poslednú. ## Zhrnutie -To je všetko. **Si úplne geniálna!** Toto bola náročná kapitola, takže by si mala byť na seba pyšná. My sme rozhodne hrdí na teba, že si to zvládla až potiaľto! +To je všetko. **Si úplne super!** Toto bola náročná kapitola, takže by si mala byť na seba pyšná. My sme na teba rozhodne hrdí, že si to zvládla až potiaľto! -Teraz možno krátko rob niečo iné - natiahni sa trochu, poprechádzaj sa, nechaj svoje oči oddýchnuť si - a potom prejdeme na ďalšiu kapitolu. :) +Oficiálnu verziu tutoriálu najdeš na https://docs.python.org/3/tutorial/. Prevedie ťa jazykom podrobnejšie. Nech sa darí! :) -![Koláčik][2] +Teraz na chvíľu si daj pauzu - natiahni sa trochu, poprechádzaj sa, nech si tvoje oči oddýchnu - a potom prejdeme na ďalšiu kapitolu. :) - [2]: images/cupcake.png +![Koláčik](images/cupcake.png) diff --git a/sk/python_introduction/images/cupcake.png b/sk/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/sk/python_introduction/images/cupcake.png and b/sk/python_introduction/images/cupcake.png differ diff --git a/sk/python_introduction/prompt.md b/sk/python_introduction/prompt.md new file mode 100644 index 00000000000..d92d1575a16 --- /dev/null +++ b/sk/python_introduction/prompt.md @@ -0,0 +1,17 @@ +## Pythonový príkazový riadok + +> Pre čitateľky a čitateľov doma: Táto kapitola je spracovaná vo videu [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U). + +Aby sme sa mohli začať hrať s Pythonom, musíme na svojom počítači otvoriť *príkazový riadok*. Už by si mala vedieť, ako sa to robí - naučili sme sa to v [Úvode do príkazového riadku](../intro_to_command_line/README.md). + +Keď si pripravená, pokračuj inštrukciami nižšie. + +Chceme otvoriť Python konzolu, takže napíš `python` na Windowse alebo `python3` na Mac OS a Linuxe a stlač `enter`. + +{% filename %}command-line{% endfilename %} +``` +$ python3 +Python {{ book.py_release }} (...) +Type "help", "copyright", "credits" or "license" for more information. +>>> +``` diff --git a/sk/template_extending/README.md b/sk/template_extending/README.md old mode 100755 new mode 100644 index 192d0c710d6..3cd8197fb10 --- a/sk/template_extending/README.md +++ b/sk/template_extending/README.md @@ -1,124 +1,151 @@ # Rozširovanie šablón -Ďalšou milou vecou, ktorú ti Django ponúka je **rozširovanie šablón**. Znamená to, že môžeš použiť rovnaké časti HTML kódu na rôznych stránkach svojho webu. +Ďalšia super možnosť, ktorú ti Django ponúka, je **rozširovanie šablón** (template extending). Znamená to, že môžeš použiť rovnaké časti HTML kódu na rôznych stránkach svojho webu. -Vďaka tomu nemusíš všetko opakovať v každom súbore, ak chceš použiť rovnakú informáciu alebo layout. A ak chceš niečo zmeniť, nemusíš to robiť v každej šablóne zvlášť, ale iba raz! +Šablóny ti pomôžu, keď chceš použiť rovnaké informácie alebo formát obsahu na viac ako jednom mieste. Nemusíš dokola opakovať to isté. A ak chceš niečo zmeniť, nemusíš to urobiť v každej šablóne, len v jednej! ## Vytvorenie základnej šablóny -Základná šablóna je jednoducho šablóna, ktorú rozširuješ na každej stránke svojej web stránky. +Základná šablóna (base template) je najzákladnejšia šablóna, ktorú rozširuješ na každej stránke svojej web stránky. -Vytvorme súbor `base.html` v `blog/templates/blog/`: +Vytvorme súbor `base.html` v priečinku `blog/templates/blog/`: -``` -blog -└───templates - └───blog - base.html - post_list.html -``` + blog + └───templates + └───blog + base.html + post_list.html + + +Otvor ho v editore a skopíruj všetko z `post_list.html` do `base.html` takto: -Otvor ho a skopíruj doň všetko z `post_list.html` do súboru `base.html`: +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} + Django Girls blog - - + - + -
+
-
+
{% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %}
-
+
``` Potom v `base.html` nahraď celé `` (všetko medzi `` a ``) týmto: +{% filename %}blog/templates/blog/base.html{% endfilename %} + ```html - -
+ +
-
+
{% block content %} {% endblock %}
-
+
``` -V podstate sme nahradili všetko medzi `{% for post in posts %}{% endfor %}` týmto: +{% raw %}Možno si si všimla, že toto nahradilo všetko od `{% for post in posts %}` po `{% endfor %}` týmto: {% endraw %} + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% block content %} {% endblock %} ``` -Čo to znamená? Práve si vytvorila `block` (blok), čo je vlastne šablóna tagov, ktorá ti umožní vkladať HTML v tomto bloku do ďalších šablón, ktoré rozširujú `base.html`. Hneď ti ukážeme, ako sa to robí. +Ale prečo? Práve si vytvorila `blok`! Použila si šablónový tag `{% block %}`, aby si vytvoila časť, do ktorej bude vložené HTML. To HTML bude pochádzať z inej šablóny, ktorá rozšíri túto šablónu (`base.html`). Hneď ti ukážeme, ako sa to robí. + +Teraz ulož `base.html` a znova otvor `blog/templates/blog/post_list.html` v editore. {% raw %}Odstrániš všetko nad `{% for post in posts %}` a pod `{% endfor %}`. Keď skončíš, súbor bude vyzerať nasledovne:{% endraw %} -Teraz to ulož a znova otvor `blog/templates/blog/post_list.html`. Zmaž všetko, okrem toho, čo je vnútri body a tiež zmaž ``, takže súbor bude vyzerať takto: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} ``` -A teraz pridaj tento riadok na začiatok súboru: +Chceme toto použiť ako súčasť našej šablóny pre všetky bloky. Je načase pridať blokové tagy do tohto súboru! + +{% raw %}Blokový tag by sa mal zhodovať s tagom v `base.html` súbore. Taktiež by mal obsahovať celý kód, čo patrí do tvojich obsahových blokov. To docieliš tak, že vložíš všetko medzi `{% block content %}` a `{% endblock %}`. Takto:{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -{% extends 'blog/base.html' %} +{% block content %} + {% for post in posts %} +
+ +

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} ``` -{% raw %}To znamená, že rozširujeme šablónu `base.html` v `post_list.html`. Už ostáva len jedna vec: daj všetko (teda okrem riadku, ktorý sme práve pridali) medzi `{% block content %}` a `{% endblock content %}`. Takto:{% endraw %} +Už zostáva len jediná vec. Potrebujeme tieto dve šablóny prepojiť. To je celá podstata rozširovania šablón! Urobíme to pridaním "extends" tagu na začiatku súboru. Nasledovne: + +{% 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 content %} +{% endblock %} ``` -A je to! Skontroluj či tvoja web stránka funguje tak, ako má :) +A je to! Súbor ulož a skontroluj, či tvoja web stránka stále funguje tak, ako má. :) -> Ak sa ti zobrazí chyba `TemplateDoesNotExists`, ktorá hovorí, že súbor `blog/base.html` neexistuje a v konzole ti beží `runserver`, skús ho zastaviť (stlačením Ctrl + C) a reštartuj ho spustením príkazu `python manage.py runserver`. +> Ak sa ti zobrazí chyba `TemplateDoesNotExist`, znamená to, že neexistuje súbor `blog/base.html` a `runserver` beží v konzole. Skús ho zastaviť (stlačením Ctrl+C – tlačidiel Control a C spolu) a spustiť znova pomocou príkazu `python manage.py runserver`. \ No newline at end of file diff --git a/sk/whats_next/README.md b/sk/whats_next/README.md old mode 100755 new mode 100644 index d6bd138cb37..f3413c3eff9 --- a/sk/whats_next/README.md +++ b/sk/whats_next/README.md @@ -1,40 +1,43 @@ # Čo ďalej? -Môžeš si zablahoželať! **Si úplne úžasná**. Sme hrdí! <3 +Môžeš si zablahoželať! **Si úplne úžasná**. Sme na teba hrdí! <3 ### Čo robiť teraz? Daj si pauzu a oddýchni si. Práve si urobila niečo ohromné. -Potom nezabudni: +Potom určite začni sledovať Django Girls na [Facebooku](http://facebook.com/djangogirls) alebo [Twitteri](https://twitter.com/djangogirls) pre najnovšie informácie. -* Sledovať Django Girls na [Facebooku][1] alebo [Twitteri][2] a zostať informovaná +### Viete odporučiť ďalšie zdroje? - [1]: http://facebook.com/djangogirls - [2]: https://twitter.com/djangogirls +Áno! Na webe nájdeš *obrovské množstvo* materiálov na trénovanie všemožných programátorských zručností. V tomto momente môže byť ťažké rozhodnúť sa, ako pokračovať, ale radi ti pomôžeme. Bez ohľadu na to, čo ťa zaujímalo pred Django Girls a čo ťa zaujalo počas tutoriálu, tu je niekoľko materiálov zdarma (alebo s veľkými časťami zadarmo), ktoré ti poslúžia na to, aby ťa dostali tam, kde chceš byť. -### Viete odporučiť ďalšie zdroje? +#### Django + +- Naša knižka [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org/) +- [Oficiálny Django návod](https://docs.djangoproject.com/en/5.1/intro/tutorial01/) +- [Video návod Getting Started With Django](http://www.gettingstartedwithdjango.com/) +- [Django for Everybody Specialization](https://www.coursera.org/specializations/django) – niektoré z prednášok možno sledovať zdarma a môžeš za ne dostať Coursera certifikát + +#### HTML, CSS a JavaScript + +- [Kurz webového vývojárstva na Codecademy](https://www.codecademy.com/learn/paths/web-development) +- [freeCodeCamp](https://www.freecodecamp.org/) + +#### Python + +- [Python kurz na Codeacademy](https://www.codecademy.com/learn/learn-python) +- [Google Python kurz](https://developers.google.com/edu/python/) +- [Learn Python The Hard Way book](http://learnpythonthehardway.org/book/) – základné cvičenia sú voľne dostupné +- [New Coder tutorials](http://newcoder.io/tutorials/) – množstvo praktických príkladov, ako sa dá použiť Python +- [edX](https://www.edx.org/course?search_query=python) – väčšina kurzov je voľne dostupná, ale ak za ne chceš certifikát alebo kredity, za tie sa už platí +- [Python špecializácia](https://www.coursera.org/specializations/python) na Coursere – niektoré video prednášky sú voľne dostupné a môžeš za ne dostať Coursera certifikát +- [Python for Everybody](https://www.py4e.com/) - voľne dostupná verzia špecializácie Python for Everybody na Coursere + +#### Práca s dátami + +- [Kurz data science na Codecademy](https://www.codecademy.com/learn/paths/data-science) +- [edX](https://www.edx.org/course/?search_query=python&subject=Data%20Analysis%20%26%20Statistics) – väčšina kurzov je voľne dostupná, ale ak chceš certifikát alebo kredity, za tie sa už platí +- [Dataquest](https://www.dataquest.io/) – prvých 30 "misií" je zdarma -Áno! Ako prvé, neváhaj a vyskúšaj našu ďalšiu knihu [Django Girls Tutorial: Rozšírenie][3]. - - [3]: http://djangogirls.gitbooks.io/django-girls-tutorial-extensions/ - -Neskôr môžeš skúsiť zdroje uvedené nižšie. Všetky veľmi odporúčame! - -- [Django's official tutorial][4] -- [New Coder tutorials][5] -- [Code Academy Python course][6] -- [Code Academy HTML & CSS course][7] -- [Django Carrots tutorial][8] -- [Learn Python The Hard Way book][9] -- [Getting Started With Django video lessons][10] -- [Two Scoops of Django: Best Practices for Django 1.8 book][11] - - [4]: https://docs.djangoproject.com/en/1.8/intro/tutorial01/ - [5]: http://newcoder.io/tutorials/ - [6]: https://www.codecademy.com/en/tracks/python - [7]: https://www.codecademy.com/tracks/web - [8]: http://django.carrots.pl/en/ - [9]: http://learnpythonthehardway.org/book/ - [10]: http://gettingstartedwithdjango.com/ - [11]: https://twoscoopspress.com/products/two-scoops-of-django-1-8 +Už sa nevieme dočkať, čo vytvoríš nabudúce! \ No newline at end of file diff --git a/tr/GLOSSARY.md b/tr/GLOSSARY.md old mode 100755 new mode 100644 index b295b284780..1e503fa6881 --- a/tr/GLOSSARY.md +++ b/tr/GLOSSARY.md @@ -1,3 +1,3 @@ # kod editörü -Kod editörü, kodunuza sonradan geri dönebilmeniz için kodu kaydeden bir uygulamadır. Nereden edinebileceğinizi [Kod editörü bölümü](./code_editor/README.md)nde bulabilirsiniz +Kod editörü, kodunuza sonradan geri dönebilmeniz için kodu kaydeden bir uygulamadır. Nereden edinebileceğinizi [Kod editörü bölümü](./code_editor/README.md)nde bulabilirsiniz \ No newline at end of file diff --git a/tr/README.md b/tr/README.md old mode 100755 new mode 100644 index e4c6a64ada9..2595ff42e6a --- a/tr/README.md +++ b/tr/README.md @@ -1,16 +1,18 @@ # Django Girls Eğitimi -[![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) -> Bu çalışma Creative Commons Attribution-ShareAlike 4.0 International License altında lisanslanmıştır. Lisansın bir kopyasını görmek için http://creativecommons.org/licenses/by-sa/4.0/ adresini ziyaret edin. +> Bu eser Creative Commons Attribution-ShareAlike 4.0 International License ile lisanslıdır. Bu lisansın bir örneğini görmek için https://creativecommons.org/licenses/by-sa/4.0/ adresine gidebilirsiniz -## Çeviri +## Hoşgeldiniz -Bu döküman İngilizce'den Türkçe'ye 28 kişiden oluşan tamamen gönüllü bir ekip tarafından çevrildi: Elif T. Kuş, Şirin Saygılı, Suzan Üsküdarlı, Oğuzcan Küçükbayrak, Mehmet Ragıp Altuncu, Şahin B., Kıvanç Yazan, Adil Öztaşer, olasitarska, Oğuz Erdoğmuş, ophelia, Tuğçe Şirin, Fazilet Çilli, Özge Barbaros, Evin Pınar Örnek, Yiğit Bekir Baya, Berna Erden, Akın Toksan, Çağıl, Berat Doğan, Taha Yusuf, Helin Ece Akgül, Müge Kurtipek, Nezihe Pehlivan, Can Güler, Wert Yuio, Barış Arda Yılmaz ve Aybüke Özdemir! Emeği geçen herkese sonsuz teşekkürler! Ellerinize sağlık! +Django Girls Eğitimi'ne hoşgeldin! Seni burada görmekten mutluyuz :) Bu eğitimde, seni web teknolojileri dünyasında bir yolculuğa çıkaracak, internetin bildiğimiz haliyle çalışması için bir araya gelmesi gereken tüm parçalara bir göz atacağız. + +Bilinmeyen şeylerde hep olduğu gibi, bu bir macera olacak. Ama hiç endişelenme, buraya gelme azmini gösterdiğine göre devamı da iyi gidecek :) ## Giriş -Hiç dünyanın her geçen gün daha fazla teknoloji ile alakalı olduğunu ve bir şekilde geride kaldığınızı hissettiniz mi ? Hiç web sayfalarının nasıl yapıldığını merak edip başlamak için gereken motivasyona sahip olmadığınız oldu mu? Yazılım dünyasının sizin için, kendi başınıza bir şeyler yapmayı denemek için bile, çok karmaşık olduğunu düşündünüz mü? +Hiç senin (henüz) yakın ilişki kuramadığın teknolojinin dünyayı giderek daha fazla kapladığını hissettiğin oldu mu? Hiç web sayfalarının nasıl yapıldığını merak edip başlamak için gereken motivasyona sahip olmadığınız oldu mu? Yazılım dünyasının sizin için, kendi başınıza bir şeyler yapmayı denemek için bile, çok karmaşık olduğunu düşündünüz mü? Öyleyse, sizin için iyi haberlerimiz var! Programlama göründüğü kadar zor değil ve size ne kadar keyifli olabileceğini göstermek istiyoruz. @@ -20,33 +22,30 @@ Bu eğitim sihirli bir şekilde sizi bir programcıya dönüştürmeyecek. Eğer ## Bu eğitim ile ne öğreneceksiniz? -Eğitimi bitirdiğinizde, basit fakat çalışan bir web uygulamasına sahip olacaksınız: kendi blog uygulamanız. Size blogunuzu nasıl canlıya alabileceğinizi de göstereceğiz ki başkaları da çalışmanızı görebilsin! +Eğitimi bitirdiğinizde, küçük bir çalışan web uygulamanız olacak: kendi blogunuz. Size çevrimiçi olarak nasıl yayınlandığını göstereceğiz, böylece başkaları çalışmanızı görecek! Aşağı yukarı şu şekilde gözükecek: -![Şekil 0.1][2] +![Şekil 0.1](images/application.png) - [2]: images/application.png +> Eğer eğitimi kendi başınıza takip ediyorsanız ve bir problem yaşadığınızda size yardım edebilecek bir mentörünüz yoksa, size yardım edebileceğimiz bir sohbet sistemimiz var:[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial). Daha önce katılmış olan kişilerden ve eğitmenlerimizden zaman zaman chat odasında bulunmalarını ve eğitimi takip eden kişilere yardımcı olmalarını istedik! Chat odasında sorularınızı sormaktan çekinmeyin! -> Eğer eğitimi kendi başınıza takip ediyorsanız ve bir problem yaşadığınızda yardım edebilecek bir eğitmeniniz yoksa, sizin için bir chat odamız var:[![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). Daha önce katılmış olan kişilerden ve eğitmenlerimizden zaman zaman chat odasında bulunmalarını ve eğitimi takip eden kişilere yardımcı olmalarını istedik! Chat odasında sorularınızı sormaktan çekinmeyin! +Tamam, [hadi en baştan başlayalım...](./how_the_internet_works/README.md) -Tamam, [hadi en baştan başlayalım...][3] +## Eğitimi evden takip etmek - [3]: ./how_the_internet_works/README.md +Bir Django Girls atölyesine katılmak harika, ama katılmanın her zaman mümkün olmayabileceğinin farkındayız. Bu nedenle, bu eğitimi evde takip etmeyi denemenizi tavsiye ediyoruz. Evde okuyanlar için, şu anda eğitimi kendi başına izlemeyi kolaylaştıracak videolar hazırlıyoruz. Bu hala devam eden bir çalışma, ancak yakında [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed) Youtube kanalında (İngilizce) giderek daha da fazla konu ele alınacak. -## Hakkında ve katkıda bulunma +Ele alınmış olan her bölümde, ilgili videoya ait bir bağlantı var. -Bu eğitim [DjangoGirls][4] tarafından sürdürülmektedir. Eğer hatalar bulursanız ve eğitimi güncellemek isterseniz lütfen [katkıda bulunma kılavuzunu takip edin][5]. +## Hakkında ve katkıda bulunma - [4]: http://djangogirls.org/ - [5]: https://github.com/DjangoGirls/tutorial/blob/master/README.md +Bu eğitim [DjangoGirls](https://djangogirls.org/) tarafından sürdürülmektedir. Eğer hatalar bulursanız ve eğitimi güncellemek isterseniz lütfen [katkıda bulunma kılavuzunu takip edin](https://github.com/DjangoGirls/tutorial/blob/master/README.md). -## Bu eğitimi başka dillere çevirmemize yardımcı olmak ister misiniz? +## Bu eğitimi diğer dillere çevirmemize yardımcı olmak ister misiniz? -Hali hazırda, çeviriler crowdin.com platformunda tutuluyor: +Şuan çeviriler crowdin.com platformunda tutuluyor: https://crowdin.com/project/django-girls-tutorial -Eğer diliniz crowdin'de listelenmemiş ise, lütfen GitHub'da dilinizle alakalı bilgi veren bir [konu açın][6] böylece dilinizi ekleyebilelim. - - [6]: https://github.com/DjangoGirls/tutorial/issues/new +Eğer diliniz [crowdin](https://crowdin.com/)'de listelenmemişse, lütfen [yeni bir konu aç](https://github.com/DjangoGirls/tutorial/issues/new) aracılığıyla bizi bilgilendirin ki dilinizi ekleyebilelim. \ No newline at end of file diff --git a/tr/SUMMARY.md b/tr/SUMMARY.md old mode 100755 new mode 100644 index 612133adbb6..08e572a478e --- a/tr/SUMMARY.md +++ b/tr/SUMMARY.md @@ -2,6 +2,7 @@ * [Giriş](README.md) * [Kurulum](installation/README.md) +* [Kurulum (chromebook)](chromebook_setup/README.md) * [İnternet nasıl çalışır](how_the_internet_works/README.md) * [Komut satırına giriş](intro_to_command_line/README.md) * [Python kurulumu](python_installation/README.md) @@ -17,10 +18,10 @@ * [Django views - yaratma zamanı geldi!](django_views/README.md) * [HTML'ye giriş](html/README.md) * [Django ORM ve QuerySets (Sorgu Setleri)](django_orm/README.md) -* [Template içerisinde dinamik veri](dynamic_data_in_templates/README.md) -* [Django template](django_templates/README.md) -* [CSS - sayfanı güzelleştir](css/README.md) +* [Template içinde dinamik veri](dynamic_data_in_templates/README.md) +* [Django templateleri](django_templates/README.md) +* [CSS - Güzelleştirin](css/README.md) * [Template genişletmek](template_extending/README.md) * [Uygulamanı genişlet](extend_your_application/README.md) -* [Django formları](django_forms/README.md) -* [Sırada ne var?](whats_next/README.md) +* [Django Formları](django_forms/README.md) +* [Sırada ne var?](whats_next/README.md) \ No newline at end of file diff --git a/tr/chromebook_setup/README.md b/tr/chromebook_setup/README.md new file mode 100644 index 00000000000..7e5c75d9265 --- /dev/null +++ b/tr/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# Chromebook kurulumu + +> **Not** Zaten yükleme adımlarını uyguladıysanız, bunu tekrar yapmanıza gerek yok - doğrudan [Python'a Giriş](../python_introduction/README.md)'e atlayabilirsiniz. + +{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/tr/chromebook_setup/instructions.md b/tr/chromebook_setup/instructions.md new file mode 100644 index 00000000000..667fec70ca4 --- /dev/null +++ b/tr/chromebook_setup/instructions.md @@ -0,0 +1,75 @@ +Chromebook kullanmıyorsanız, [bu bölümü atlayabilirsiniz](http://tutorial.djangogirls.org/en/installation/#install-python). Chromebook kullanıyorsanız kurulum deneyiminiz biraz farklı olacaktır. Diğer yükleme yönergelerini göz ardı edebilirsiniz. + +### Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9) + +Cloud IDE, size İnternette yazılım yükleyebileceğiniz, yazabileceğiniz ve çalıştırabileceğiniz bir kod düzenleyicisi ve çalışan bir bilgisayara erişim sağlayan bir araçtır. Eğitim boyunca, Cloud IDE sizin *yerel makinanız* gibi davranacak. macOS, Ubuntu veya Windows'daki sınıf arkadaşlarınız gibi terminal arayüzünde komut çalıştırmaya devam edeceksiniz, ancak terminaliniz Cloud IDE'nin sizin yerinize kuracağı başka bir bilgisayara bağlanacaktır. Cloud IDE'ler (PaizaCloud bulut IDE, AWS Cloud9) için talimatlar burada. Cloud IDE'lerden birini seçin ve o IDE'nin talimatlarini takip edin. + +#### PaizaCloud Cloud IDE + +1. [PaizaCloud Cloud IDE](https://paiza.cloud/)'ye gidin +2. Bir hesap oluşturun +3. *New Server*'a tiklayalim +4. Pencerenin sol tarafındaki Terminal butonuna tıklayalım + +Şimdi arayüzün sol tarafında bir takım buttonları görmeniz gerekiyor. "Terminal" buttonuna tıklayıp aşağıdaki komut satırını gösteren bir ekran açın: + +{% filename %}Terminal{% endfilename %} + + $ + + +Terminal Cloud 9 in hazırladığı komutları gösterecek. Ekranın boyunu değiştirebilir veya maxize edebilirsiniz. + +#### AWS Cloud9 + +1. [AWS Cloud9](https://aws.amazon.com/cloud9/)'a gidin +2. Bir hesap oluşturun +3. *Create Environment* a tıklayın + +Şimdi bir kenar çubuğu, bazı metinlerin olduğu büyük bir ana pencere ve en altta da buna benzer küçük penceresi olan bir arayüz görmelisiniz: + +{% filename %}bash{% endfilename %} + + yourusername:~/workspace $ + + +Bu alt alan * terminalinizdir , Cloud 9'un sizin için hazırladığı talimatlarınızı yazacağınız yer. Biraz daha büyük yapmak için bu pencereyi yeniden boyutlandırabilirsiniz.

+ +### Sanal ortam (Virtual environment) + +Bir sanal ortam(virtualenv diye de bilinir), üzerinde çalıştığımız proje için kullanışlı kodlarımızı yazabileceğimiz özel bir kutudur. Bunları çeşitli projelerimizi ayrı tutmak için kullanırız, böylece farklı projeler arasında işler karışmaz. + +Cloud 9 arayüzünün altındaki terminalinizde şunu çalıştırın: + +{% filename %}Cloud 9{% endfilename %} + + sudo apt update + sudo apt install python3.6-venv + + +Eğer hala çalışmıyorsa eğitmeninizden yardım isteyin. + +Sonra, bunu çalıştırın: + +{% filename %}Cloud 9{% endfilename %} + + mkdir djangogirls + cd djangogirls + python3.6 -mvenv myvenv + source myvenv/bin/activate + pip install django~={{ book.django_version }} + + +(son satırda bir tilde ve eşitlik işareti kullandığımıza dikkat edin: ~=). + +### GitHub + +Bir [Github](https://github.com) hesabı açın. + +### PythonAnywhere + +Django Girls eğitimi, yeni web uygulamanızı güçlendiren ve onu herkesin görebileceği şekilde herkes tarafından erişilebilen bir bilgisayara (sunucu olarak adlandırılır) taşıyan bir kod olan Deployment (Dağıtım) adlı bir bölümü içerir. + +Kılavuzu Chromebook üzerinden kullanırken bu bölüm biraz garip oluyor; zaten internet üzerindeki bir bilgisayar kullanılıyor (laptop dışında). Bununla birlikte, Cloud 9'u çalışma alanımız veya "devam etmekte" olan işlerimizin bulunduğu bir yer olarak, Python Anywhere'i de işlerimizi daha eksiksiz hale getirdiğimizde gösterebileceğimiz bir yer olarak düşündüğümüzde hala kullanışlıdır. + +Bu nedenle, [www.pythonanywhere.com](https://www.pythonanywhere.com) adresinden yeni bir Python Anywhere hesabı açın. \ No newline at end of file diff --git a/tr/code_editor/README.md b/tr/code_editor/README.md old mode 100755 new mode 100644 index e3b494bdc7b..f9ccff465bf --- a/tr/code_editor/README.md +++ b/tr/code_editor/README.md @@ -1,7 +1,11 @@ # Kod editörü +> Evden takip edenler için: Bu bölüm [Pythonu kurma & Kod Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s) videosunda işlenmiştir. + İlk kod satırınızı yazmak üzeresiniz, bu yüzden önce bir kod editörü edinme zamanı! -> **Not**: Bunu daha önceki Kurulum bölümünde yaptıysanız, doğrudan bir sonraki bölüme geçebilirsiniz! +> **Note** Eğer Chromebook kullanıyorsanız bu bölümü atlayın ve [Chromebook Kurulum](../chromebook_setup/README.md) u takip edin. +> +> **Note** Bunları Kurulum bölümünde yapmış olabilirsin, öyle ise hemen bir sonraki bölüme atlayabilirsin! -{% include "/code_editor/instructions.md" %} +{% include "/code_editor/instructions.md" %} \ No newline at end of file diff --git a/tr/code_editor/instructions.md b/tr/code_editor/instructions.md old mode 100755 new mode 100644 index da81c69e2d7..d10b40034cc --- a/tr/code_editor/instructions.md +++ b/tr/code_editor/instructions.md @@ -1,6 +1,6 @@ Birçok farklı kod editörü var, hangi editörü kullanacağınız kişisel tercihinize bağlı. Çoğu Python programcısı PyCharm gibi karmaşık fakat son derece güçlü IDE'leri (Integrated Development Environments-Entegre Geliştirme Ortamları) kullanır. Başlangıç seviyesi için bunlar muhtemelen pek uygun olmayacaktır. Bizim önerdiklerimiz aynı derecede güçlü fakat çok daha basit editörler olacak. -Bizim önerilerimizi aşağıda bulabilirsiniz, fakat eğitmenlerinize onların tercihlerini sormaktan çekinmeyin - onlardan yardım almak daha kolay olacaktır. +Bizim tavsiyelerimiz aşağıdakiler, ama mentörünüze danışmak isteyebilirsiniz. ## Gedit @@ -8,15 +8,15 @@ Gedit açık kaynaklı, ücretsiz bir editördür. Tüm işletim sistemlerinde k [Buradan indirin](https://wiki.gnome.org/Apps/Gedit#Download) -## Sublime Text 2 +## Sublime Text -Sublime Text ücretsiz deneme sürümüne sahip oldukça popüler bir editördür. Kurulumu ve kullanımı basittir, tüm işletim sistemlerinde kullanılabilir. +Sublime Text, ücretsiz deneme süresi olan çok popüler bir editördür ve tüm işletim sistemleri için mevcuttur. -[Buradan indirin](http://www.sublimetext.com/2) +[Buradan indirin](https://www.sublimetext.com/) ## Atom -Atom [GitHub](http://github.com/) tarafından geliştirilen oldukça yeni bir editör. Atom ücretsiz, açık kaynak kodlu, kurulumu ve kullanımı basit bir editördür. Windows, OSX ve Linux işletim sistemlerinde kullanılabilir. +Atom başka bir popüler editör. Ücretsiz, açık kaynaklı ve Windows, macOS ve Linux için kullanılabilir. Atom GitHub tarafından geliştirilmiştir.

[Buradan indirin](https://atom.io/) @@ -24,8 +24,8 @@ Atom [GitHub](http://github.com/) tarafından geliştirilen oldukça yeni bir ed Neden Word ya da Notepad kullanmak yerine, özel bir kod editörü yazılımı kurduğumuzu merak ediyor olabilirsiniz. -Birinci nedeni, kodun **düz metin** olması gerekliliği. Word ve TextEdit gibi programlar [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format) gibi özel formatları kullanarak düz metin yerine zengin metin (fontlu ve formatlı metin) üretiyorlar. +Birinci nedeni yazdığımız kodun **sade yazı** olması gerektiği içindir ki Word gibi programlar sade yazı üretmezler (font ve şekillendirme desteklerler) ve [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format) gibi özel formatlar kullanılar. -İkinci neden, kod editörleri kod düzenlemek için özelleşmişlerdir, dolayısıyla kodu anlamına göre renklerle öne çıkarma (highlighting) veya tırnakları otomatik kapama gibi yararlı özellikler sağlar. +İkinci sebep ise kod editörlerinin kod düzenlemeye destek vermek - örneğin özel kelimeleri renklendirme ve otomatik parantez kapatma gibi - için özelleşmiş olmasıdır. -Bütün bunları ileride uygulama içerisinde göreceğiz. Yakında güvenilir ihtiyar kod editörünü favori araçlarınız arasında görmeye başlayacaksınız :) +Bütün bunları birazdan deneyimleyeceğiz. Yakında kod editörünüz güvenilir bir eski dostunuz gibi olacaktır :) diff --git a/tr/css/README.md b/tr/css/README.md index 6967653c6db..17fcb07d06b 100644 --- a/tr/css/README.md +++ b/tr/css/README.md @@ -1,117 +1,116 @@ -# CSS - güzelleştir! +# CSS – sayfanı güzelleştir! Blogumuz hala epey çirkin gözüküyor, değil mi? Güzelleştirme zamanı! Bunun için CSS kullanacağız. ## CSS Nedir? -Basamaklı Stil Sayfaları (Cascading Style Sheets - CSS) bir websayfasının görünüm ve biçimlendirmelerini tanımlamak için kullanılan bir işaretleme (markup) dilidir (HTML gibi). CSS'i websayfanızın makyajı olarak görebilirsiniz ;). +Cascading Style Sheets (yani stil şablonu, kısaca CSS) bir işaretleme dili (örneğin HTML) ile yazılmış bir web sitesinin görünüm ve biçimini tanımlamakta kullanılan bir dildir. Bunu, web sayfamızın bir tür makyajı gibi düşünün ;) -Fakat tekrar en baştan başlamak istemiyoruz, değil mi? Bir kez daha, programcılar tarafından önceden hazırlanmış ve internette ücretsiz olarak yayınlanmış bir şeyi kullanacağız. Bilirsiniz tekerleği yeniden icat etmek eğlenceli değildir. +Fakat tekrar sıfırdan başlamak istemiyoruz, değil mi? Bir kez daha, programcıların internette ücretsiz sundukları bir şeyi kullanacağız. Bilirsiniz, tekerleği yeniden icat etmek pek eğlenceli değil. -## Hadi Bootstrap kullanalım! +## Haydi Bootstrap kullanalım! -Bootstrap güzel websayfaları geliştirmek için kullanılan en popüler HTML ve CSS çerçevesidir(framework) : http://getbootstrap.com/ +Bootstrap HTML and CSS tabanlı çok güzel websiteleri geliştirmek için en yaygın olarak kullanılan çözümlerden biridir https://getbootstrap.com/ -Twitter yazılımcıları tarafından geliştirilmeye başlanmış ve şu anda dünyanın her yerinden gönüllüler tarafından geliştirilmektedir. +Twitter yazılımcıları tarafından geliştirilmeye başlanmış ve şu anda dünyanın her yerinden gönüllüler tarafından geliştirilmektedir! ## Bootstrap kurulumu -Bootstrap kurmak için `.html` dosyanızda `` kısmına şunları eklemeniz gerekli (`blog/templates/blog/post_list.html`): +Bootstrap yüklemek için `.html` uzantılı dosyamızı kod düzenleyicisinde açalım ve `` bölümüne şunları ekleyelim: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - - + ``` - -Bu, projemize hiçbir yeni dosya eklemez. Yalnızca internet üzerinde var olan dosyalara işaret eder. Şimdi websitenizi açın ve sayfayı yenileyin. İşte oldu! +Bu satırlar projeye yeni dosya eklemez. Ancak İnternet'te var olan dosyalara işaret eder. Şimdi websitenizi açın ve sayfayı yenileyin. İşte oldu! -![Şekil 14.1][1] - - [1]: images/bootstrap1.png +![Şekil 14.1](images/bootstrap1.png) Şimdiden daha güzel gözüküyor! ## Django'da statik dosyalar -Son olarak **statik dosyalar** diye bahsettiğimiz şeylere daha yakından bakalım. Statik dosyalar, CSS ve resimlerindir -- dinamik olmayan, bu nedenle içerikleri istek bağlamından bağımsız ve her kullanıcı için aynı dosyalar. +Son olarak **statik dosyalar** diye bahsettiğimiz şeylere daha yakından bakalım. Statik dosyalar, tüm CSS dosyaları ve resimlerindir. İçerikleri istek bağlamından (request context) bağımsızdır ve her kullanıcı için aynıdır. ### Django'da statik dosyaları nereye koymalı -Sunucuda `collectstatic` komutunu çalıştırdığımız zaman gördüğün gibi, Django dahili "admin" uygulaması için statik dosyaların nerede olduğunu biliyor. Şimdi de bizim kendi `blog` uygulamamız için bazı statik dosyalar eklememiz gerekiyor. +Django dahili "admin" uygulaması için statik dosyaları nerede bulacağını biliyor. Şimdi sadece kendi `blog` uygulamamız için bazı statik dosyalar eklememiz gerekiyor. -Bunu blog uygulamamızın içerisinde `static` isimli bir klasör oluşturarak yapacağız: +Bunu blog uygulamamızın içine `static` isimli bir klasör oluşturarak yapacağız: -``` -djangogirls -├── blog -│ ├── migrations -│ └── static -└── mysite -``` + djangogirls + ├── blog + │ ├── migrations + │ ├── static + │ └── templates + └── mysite + -Django uygulama klasörlerinizin altındaki "static" isimli tüm klasörleri otomatik olarak bulacak ve içindekileri statik dosya olarak kullanabilecektir. +Django otomatik olarak uygulama klasörlerinizdeki "static" adlı klasörleri bulur. Böylece bunların içerikleri statik dosya olarak kullanabilir. ## İlk CSS dosyanız! -Şimdi web sayfamıza kendi stilimizi eklemek için bir CSS dosyası oluşturalım. `static` klasörü içinde `css` adlı yeni bir klasör oluşturalım. Şimdi de `css` klasörü içinde `blog.css` adlı yeni bir dosya oluşturalım. Hazır mısınız? +Şimdi web sayfana kendi stilini eklemen için bir CSS dosyası oluşturalım. `static` klasörü içinde `css` adlı yeni bir klasör oluştur. Şimdi de `css` klasörü içinde `blog.css` adlı yeni bir dosya oluşturalım. Hazır mısınız? -``` -djangogirls -└─── blog - └─── static - └─── css - └─── blog.css -``` + djangogirls + └─── blog + └─── static + └─── css + └─── blog.css + Şimdi CSS yazma zamanı! `blog/static/css/blog.css` dosyasını kod editöründe açın. -Biz burada özelleştirme ve CSS'in detaylarına çok fazla girmeyeceğiz, çünkü gerçekten kolay ve workshop'tan sonra kendinizi bu konuda geliştirebilirsiniz. Web sitelerini CSS'le güzelleştirmek hakkında bilmen gerekenleri öğrenmek için, [Codeacademy HTML & CSS kursu][2]nu özellikle öneriyoruz. +Burada CSS'yi özelleştirme ve öğrenmeyle ilgili çok derinlemesine gidemeyeceğiz. Daha fazla bilgi edinmek isterseniz, bu sayfanın sonunda ücretsiz CSS kursu için bir tavsiye var. - [2]: http://www.codecademy.com/tracks/web - -Ancak az da olsa yapalım. Acaba başlığımızın rengini mi değiştirsek? Bilgisayarlar renkleri anlamak için özel kodlar kullanır. Bu kodlar `#` ile başlar ve arkasından 6 harf (A-F) ve numaralarda (0-9) gelir. Renk kodlarını örneğin burada bulabilirsin: http://www.colorpicker.com/. Ayrıca [önceden tanımlanmış renkler][3]i de kullanabilirsin, `red` (kırmızı) ve `green` (yeşil) gibi. - - [3]: http://www.w3schools.com/cssref/css_colornames.asp +Ama, biraz da yapalım. Acaba başlığımızın rengini mi değiştirsek? Bilgisayarlar renkleri anlamak için özel kodlar kullanır. Bu kodlar `#` ile başlar ve 6 harf(A-F) ve sayıyla(0-9) devam eder. Örneğin, mavinin renk kodu `#0000FF` dur. Birçok renk için renk kodlarını buradan bulabilirsiniz: http://www.colorpicker.com/. Ayrıca [tanımlı renkler](http://www.w3schools.com/colors/colors_names.asp)i de kullanabilirsin, `red` (kırmızı) ve `green` (yeşil) gibi. `blog/static/css/blog.css` dosyanıza şu kodu eklemelisiniz: +{% filename %}blog/static/css/blog.css{% endfilename %} + ```css h1 a { color: #FCA205; } -``` +``` -`h1 a` bir CSS Seçicisidir (Selector). Bu demek oluyor ki biz stilimizi, bir `h1` öğesi içerisinde olan tüm `a` öğelerine (örneğin kodumuzun içerisinde `

link

` gibi bir şey olduğunda) uyguluyoruz. Bu durumda, rengi `#FCA205` yani turuncu yapmasını söylüyoruz. Elbette, buraya kendi arzu ettiğin rengi koyabilirsin! +`h1 a` bir CSS seçicisidir (selector). Bu, stillerimizi `h1` öğesi içerisindeki `a` öğelerine uyguladığımız anlamına geliyor. Yani `

bağlantı

` gibi bir öğemiz olduğunda, ona `h1 a` stilimiz uygulanıyor. Bu durumda, rengi `#FCA205` yani turuncu yapmasını söylüyoruz. Ya da buraya kendi istediğin rengi koyabilirsin! -Bir CSS dosyasında, HTML dosyasındaki öğeler için stil belirleriz. Öğeler, öğenin ismi (örn. `a`, `h1`, `body`), `sınıf` özniteliği (attribute) ya da `id` özniteliği ile tanımlanırlar. Sınıf ve id (kimlik), bir elemente senin tarafından verilen isimlerdir. Sınıflar bir öğe grubunu tanımlar, id'ler ise belirli bir öğeye işaret ederler. Örneğin şu aşağıdaki etiket CSS tarafından, `a` etiket adı, `external_link` sınıfı ya da `link_to_wiki_page` id'si kullanılarak tanımlanabilir: +Bir CSS dosyasında, HTML dosyasındaki öğeler için stil belirleriz. Öğeleri tanımlamanın ilk yolu öğe adıdır. Bunları HTML bölümünden etiket olarak hatırlıyor olabilirsiniz. Bunların hepsi öğe adına örnektir: `a`, `h1` ve `body`. Öğeleri aynı zamanda `class` ve `id` öznitelikleri ile tanımlarız. Sınıf ve id (kimlik), bir elemente senin tarafından verilen isimlerdir. Sınıflar bir öğe grubunu tanımlar, id'ler ise belirli bir öğeye işaret ederler. Örneğin şu aşağıdaki etiket CSS tarafından, `a` etiket adı, `external_link` class'ı ya da `link_to_wiki_page` id'si kullanılarak tanımlanabilir: ```html - -``` + +``` -Daha fazla bilgi için [w3schools'da CSS seçicileri][4]ni okuyabilirsin. +CSS hakkında daha fazla bilgi edinmek için [CSS Selectors at w3schools](http://www.w3schools.com/cssref/css_selectors.asp) u okuyabilirsin. - [4]: http://www.w3schools.com/cssref/css_selectors.asp +Sonrasında, ayrıca HTML şablonumuza (template) birtakım CSS eklemeleri yaptığımızı bildirmemiz gerekiyor. `blog/templates/blog/post_list.html` dosyasını açıp en başına şu satırı ekleyelim: -Sonrasında, ayrıca HTML şablonumuza (template) bir takım CSS eklemeleri yaptığımızı bildirmemiz gerekiyor. `blog/templates/blog/post_list.html` dosyasını açın ve en başına şu satırı ekleyin: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -{% load staticfiles %} -``` +{% load static %} +``` -Burada yaptığımız yalnızca statik dosyaları yüklemek. :) Sonrasında, `` ve ``, tagları arasına, Bootstrap CSS dosyalarına yönelik bağlantılardan sonra (web tarayıcımız dosyaları yazıldıkları sırasıyla okuduğundan, bizim dosyamızdaki kodlar Bootstrap dosyasının içerisindekileri geçersiz kılabilir), şu satırı ekleyin: +Burada sadece statik dosya ekliyoruz :) `` ve `` etiketleri arasına, bootstrap linklerinden sonra, şu satırı ekleyelim: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -``` +``` -Az evvel şablonumuza (template) CSS dosyamızın nerede olduğunu söylemiş olduk. +Tarayıcı, dosyaları verilen sırada okuyor. O yüzden doğru yerde olduğundan emin olmalıyız. Aksi takdirde dosyadaki kod, Bootstrap dosyası tarafından üzerine yazılabilir. Az evvel şablonumuza (template) CSS dosyamızın nerede olduğunu söylemiş olduk. -Dosyanız şu şekilde gözüküyor olmalı: +Şimdi dosyanız şöyle olmalı: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} Django Girls blog @@ -126,81 +125,86 @@ Dosyanız şu şekilde gözüküyor olmalı: {% for post in posts %}
-

yayınlanma tarihi: {{ post.yayinlanma_tarihi }}

-

{{ post.baslik }}

-

{{ post.yazi|linebreaks }}

+

Yayın tarihi: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

{% endfor %} -``` +``` Tamamdır, dosyayı kaydedip sayfayı yenileyebilirsiniz. -![Şekil 14.2][5] +![Şekil 14.2](images/color2.png) - [5]: images/color2.png +Güzel! Şimdi de sitemizi biraz rahatlatıp sol kenar boşluğunu arttırsak mı? Hadi deneyelim! -Güzel! Şimdi de sitemizi biraz rahatlatıp sol kenar boşluğunu (margin'i) arttırsak mı? Hadi deneyelim! +{% filename %}blog/static/css/blog.css{% endfilename %} ```css body { padding-left: 15px; } ``` - - -Bunu CSS dosyanıza ekleyin, dosyayı kaydedin ve nasıl çalıştığını görelim! -![Şekil 14.3][6] +Bunu CSS dosyana ekleyip kaydet ve bak bakalım! Nasıl da oldu! - [6]: images/margin2.png +![Şekil 14.3](images/margin2.png) Belki de başlığımızın yazı tipini özelleştirebiliriz? Aşağıdaki satırı `blog/templates/blog/post_list.html` dosyasının içinde `` bölümüne yapıştırın: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html - -``` + +``` + +Daha önce yaptığımız gibi, sıralamayı ve yerini kontrol edelim `blog/static/css/blog.css` den önce olmalı. Bu satır Google Fonts'tan *Lobster* adlı bir font yükler (https://www.google.com/fonts). -Bu satır *Lobster* adlı bir fontu Google Fonts (https://www.google.com/fonts) sitesinden sayfamıza aktarır. +`blog/static/css/blog.css` CSS dosyasında `h1 isimli ` tanımlama bölümünü bulalım ( `{` ve `}` sembolleri arasındaki kod). `font-family: 'Lobster';` satırını parantezler arasına kopyalayıp sayfayı yenileyelim: -Şimdi `blog/static/css/blog.css` dosyamızdaki `h1 a` deklarasyon bloğunun içine (`{` ve `}` kodları arasına) `font-family: 'Lobster';` satırını ekleyip sayfayı yenileyin: +{% filename %}blog/static/css/blog.css{% endfilename %} ```css h1 a { color: #FCA205; font-family: 'Lobster'; } -``` - -![Şekil 14.3][7] +``` - [7]: images/font.png +![Şekil 14.3](images/font.png) Harika! -Yukarıda bahsettiğimiz üzere, CSS'te class (sınıf) diye bir kavram var. Class'lar, temel olarak HTML kodunuzun bir parçasına isim vermenize yarar ve yalnızca o parçanın stilini değiştirirken diğer parçaların etkilenmemesini sağlar. İki div'iniz var diyelim; fakat çok farklı şeyler yapıyorlarsa (örneğin biri başlık diğeri gönderinin metni) ve bu nedenle de aynı şekilde gözükmelerini istemiyorsanız, sınıflar müthiş yararlıdır. +Yukarıda bahsettiğimiz üzere, CSS'te class (sınıf) diye bir kavram var. Class'lar, temel olarak HTML kodunuzun bir kısmına isim vermenize yarar ve diğer kısımların stilini değiştirmeden yalnızca o kısmın stilini değiştirmenizi sağlar. Bu süper yararlı olabilir! Çok farklı şeyler yapan iki div'iniz var diyelim (örneğin biri başlık diğeri gönderinin metni). Class, farklı görünmelerini sağlamana yardımcı olur. Devam edelim ve HTML kodumuzun bir kısmına isim verelim. Başlığı içeren `div`'e `page-header` isimli bir class ekleyelim: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html -``` +``` Şimdi de gönderi metnini içeren `div`'e `post` isimli bir sınıf ekleyelim. +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html
-

yayınlanma tarihi: {{ post.yayinlanma_tarihi }}

-

{{ post.baslik }}

-

{{ post.yazi|linebreaks }}

+

Yayın tarihi: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

-``` +``` Şimdi farklı seçicilere (selectors) bildirim (deklarasyon) blokları ekleyeceğiz. `.` ile başlayan seçiciler sınıflara işaret eder. Web'de, aşağıdaki kodu anlamanıza yardımcı olacak pek çok güzel CSS öğreticisi ve açıklama mevcut. Şimdilik sadece bu kodu kopyalayıp `blog/static/css/blog.css` dosyamıza yapıştıralım: +{% filename %}blog/static/css/blog.css{% endfilename %} + ```css .page-header { background-color: #ff9400; @@ -208,65 +212,66 @@ Devam edelim ve HTML kodumuzun bir kısmına isim verelim. Başlığı içeren ` padding: 20px 20px 20px 40px; } - .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 { font-family: 'Lobster', cursive; } - + .date { - float: right; color: #828282; } - + .save { float: right; } - + .post-form textarea, .post-form input { width: 100%; } - + .top-menu, .top-menu:hover, .top-menu:visited { color: #ffffff; float: right; font-size: 26pt; margin-right: 20px; } - + .post { margin-bottom: 70px; } - + .post h1 a, .post h1 a:visited { color: #000000; } ``` - -Sonrasında blog postlarımızı gösteren HTML kodunun etrafını class deklarasyonları ile saralım. Aşağıdaki kodları değiştirin: +Sonra, blog gönderilerini gösteren HTML kodunu, class bildirimleri içine alın. <0>blog/templates/blog/post_list.html içindeki şu kısmı, + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %}
-

yayınlanma tarihi: {{ post.yayinlanma_tarihi }}

-

{{ post.baslik }}

-

{{ post.yazi|linebreaks }}

+

Yayın tarihi: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

{% endfor %} -``` +``` bununla değiştirelim: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html
@@ -274,27 +279,25 @@ bununla değiştirelim: {% for post in posts %}
- {{ post.yayinlanma_tarihi }} +

Yayın tarihi: {{ post.published_date }}

-

{{ post.baslik }}

-

{{ post.yazi|linebreaks }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

{% endfor %}
-``` +``` Bu dosyaları kaydedin ve web sayfanızı yenileyin. -![Şekil 14.4][8] - - [8]: images/final.png +![Şekil 14.4](images/final.png) -Heyo! Harika görünüyor, değil mi? Yapıştırdığımız bu kodları anlamak pek de zor değil. Büyük bir kısmını sırf okuyarak anlayabilirsiniz. +Yaşasın! Harika görünüyor değil mi? Şimdi yapıştırdığımız koda bakıp CSS tarafından kullanılan ve HTML eklenmiş olan nesneleri bulalım. Tarihi turkuaz rengine çevirmek için nereyi değiştirmen gerekir? -CSS ile biraz oynamaktan korkmayın ve bazı şeyleri değiştirmeyi deneyin. Bir şeyi bozarsanız tasalanmayın, yaptığınızı her zaman geri alabilirsiniz! +CSS ile biraz oynamaktan çekinme ve birkaç şeyi değiştirmeye calış. CSS ile oynamak neyin neyi etkilediğini anlamak için çok faydalı. Bir şeyleri bozarsan dert etme, her zaman geri alabilirsin! -Her durumda atölye sonrası ödevi olarak ücretsiz [Codeacademy HTML & CSS Kursu][2]'nu, websayfanızı CSS ile güzelleştirmeyi öğrenmek için almanızı tavsiye ediyoruz. +Ücretsiz [Codeacademy HTML & CSS kursu](https://www.codecademy.com/tracks/web)nu izlemeni gerçekten öneririz. Web sitelerini CSS'le güzelleştirmeyi iyice öğrenmene yardımcı olabilir. -Sonraki bölüm için hazır mısınız? :) +Sonraki bölüm için hazır mısın?! :) diff --git a/tr/css/images/bootstrap1.png b/tr/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/tr/css/images/bootstrap1.png and b/tr/css/images/bootstrap1.png differ diff --git a/tr/css/images/color2.png b/tr/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/tr/css/images/color2.png and b/tr/css/images/color2.png differ diff --git a/tr/css/images/final.png b/tr/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/tr/css/images/final.png and b/tr/css/images/final.png differ diff --git a/tr/css/images/font.png b/tr/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/tr/css/images/font.png and b/tr/css/images/font.png differ diff --git a/tr/css/images/margin2.png b/tr/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/tr/css/images/margin2.png and b/tr/css/images/margin2.png differ diff --git a/tr/deploy/README.md b/tr/deploy/README.md old mode 100755 new mode 100644 index ebbe63d71c4..cccb685cbea --- a/tr/deploy/README.md +++ b/tr/deploy/README.md @@ -1,325 +1,223 @@ # Yayına alın! -> **Not** Bir sonraki bölüm ara ara zor gelebilir. Dayanın ve bölümü bitirin; yayına alma, website geliştirme sürecinin önemli bir parçasıdır. Biraz daha uğraşmalı olan websitesini canlıya alma işine eğitmeninizin yardım edebilmesi için bu bölümü tutorial'ın ortasına yerleştirdik. Böylece eğer zaman yetmezse tutorial'ı kendi başınıza bitirebilirsiniz. +> **Not** Bir sonraki bölüm ara ara zor gelebilir. Dayanın ve bölümü bitirin; yayına alma, website geliştirme sürecinin önemli bir parçasıdır. Biraz daha uğraştırıcı olan websitesini canlıya alma işine eğitmeninizin yardım edebilmesi için bu bölümü tutorial'ın ortasına yerleştirdik. Böylece eğer zaman yetmezse tutorial'ı kendi başınıza bitirebilirsiniz. -Şimdiye kadar websiteniz sadece kendi makinanızda idi, şimdi yayına nasıl alacağınızı öğreneceksiniz! Yayına alma uygulamanızı internette yayınlama sürecidir, böylelikle insanlar sonunda gidip uygulamanızı görebilirler :). +Şimdiye kadar web sitenize sadece kendi bilgisayarınızdan girilebiliyordu. Şimdi onu nasıl canlıya alacağınızı öğreneceksiniz! Yayına alma uygulamanızı internette yayınlama sürecidir, böylelikle insanlar sonunda gidip uygulamanızı görebilirler. :) -Öğrendiğimiz üzere, bir websitesi bir sunucunun üstünde olmalıdır. Internette birçok sunucu sağlayıcı bulunuyor. Görece kolay bir yayına alma süreci olanlardan birini kullanacağız: [PythonAnywhere][1]. PythonAnymwhere çok fazla ziyaretçisi olmayan ufak uygulamalar için ücretsiz yani sizin için kesinlikle yeterli olacaktır. +Öğrendiğimiz üzere, bir websitesi bir sunucunun üstünde olmalıdır. İnternette birçok sunucu sağlayıcısı var, biz bunlardan [PythonAnywhere](https://www.pythonanywhere.com/) i kullanacağız. PythonAnywhere ücretsiz olduğu ve çok fazla ziyaretçisi olmayan küçük uygulamalar için uygun olduğu için kesinlikle yeterli olacaktır. - [1]: http://pythonanywhere.com/ +Dışarıdan kullanacağımız diğer servis bir kod barındırma hizmeti olan [Github](https://www.github.com). Başkaları da var, ama neredeyse her programcının bir Github hesabı var, sizin de olacak! -Dışarıdan kullanacağımız diğer servis bir kod barındırma hizmeti olan [Github][2]. Başkaları da var, ama nerdeyse her programcının bir Github hesabı var, sizin de olacak! - - [2]: http://www.github.com - -Github'ı kodumuzu PythonAnywhere'e taşımak için bir atlama tahtası olarak kullanacağız. +Bu üç yer sizin için önemli olacak. Lokal bilgisayarınız geliştirme ve test yaptığınız yer olacak. Değişikliklerden memnun olduğunuzda programınızın bir kopyasını Github'a koyacaksınız. Web siteniz PythonAnywhere üzerinde olacak ve onu kodunuzun bir kopyasını Github'dan alarak güncelleyeceksiniz. # Git -Git, birçok programcı tarafından kullanılan bir "sürüm kontrol sistemi"dir. Bu yazılım dosyaların zaman içindeki değişimlerini izler, böylelikle sonradan eski sürümlere ulaşabilirsiniz. Biraz Microsoft Word'deki "değişiklikleri izle" özelliği gibi, ama çok daha güçlü. - -## Git'i kurmak - -> **Not** Kurulum adımlarını halihazırda yaptıysanız, bunu tekrar yapmanıza gerek yok - bir sonraki alt bölüme geçip Git reponuzu oluşturabilirsiniz. +> **Not** Eğer kurulum adımlarını zaten yaptıysanız, bunu tekrar yapmanıza gerek yok - bir sonraki bölüme geçip Git reponuzu oluşturabilirsiniz. {% include "/deploy/install_git.md" %} -## Git repomuzu oluşturmak - -Git, kod reposu (veya "repository") denen belli dosyaların değişikliklerini izler. Projemiz için bir tane oluşturalım. Konsolunuzu açın ve `djangogirls` klasöründe aşağıdaki komutları çalıştırın: - -> **Not** Reponuzu başlatmadan önce, `pwd` (OS/Linux) veya `cd` (Windows) komutu ile bulunduğunuz dizini kontrol edin. `djangogirls` dizininde olmanız gerekiyor. - -Hatırlatma: Kullanıcı adı seçerken özel Türkçe karakter kullanmayın. -``` -$ git init -Initialized empty Git repository in ~/djangogirls/.git/ -$ git config --global user.name "Adınız" -$ git config --global user.email you@example.com -``` - -Git reposunu başlatma işi, proje başına bir kere yapmamız gereken birşey (ayrıca kullanıcı adı ve eposta adresini tekrar girmenize gerek olmayacak). - -Git bu dizindeki tüm dizin ve dosyalardaki değişiklikleri kaydedecek, ama takip etmemesini istediğimiz bazı dosyalar var. Bunu dizinin dibinde `.gitignore` adında bir dosya oluşturarak yapıyoruz. Editörünüzü açın ve aşağıdaki içeriklerle yeni bir dosya yaratın: - - -``` -*.pyc -__pycache__ -myvenv -db.sqlite3 -.DS_Store -``` - -Ve "djangogirls" dizinin en üst seviyesine `.gitignore` olarak kaydedin. +## Git repomuzu oluşturalım -> **Not** Dosya adının başındaki nokta önemli! Eğer dosyayı oluştururken zorlanırsanız (örneğin Mac'ler Finder ile nokta ile başlayan dosya yaratmanızdan hoşlanmıyor), editörünüzdeki "Farklı Kaydet" özelliğini kullanın, kesin çalışır. +Git, bir kod deposu (repository veya kısaca "repo") olarak adlandırılan belirli dosyalardaki değişiklikleri izler. Projemiz için bir tane oluşturalım. Konsolunuzu açın ve `djangogirls` klasöründe aşağıdaki komutları çalıştırın: -`git add` kullanmadan önce veya nelerin değiştiğinden emin değilseniz, `git status` komutunu kullanmakta yarar var. Bu, yanlış dosyaların eklenmesi ve gönderilmesi gibi istenmeyen sürprizlerin engelenmesine yardımcı olacak. `git status` komutu, takip edilmeyen/değişen/gönderilecek dosyalar (staged), dal durumu (branch status) gibi bilgiler verir. Çıktının aşağıdaki gibi olması gerekiyor: +> **Not** Reponuzu oluşturmadan önce `pwd` (macOS/Linux) ya da `cd` (Windows) komutu ile şu an çalışmakta olan dizininizi kontrol edin. `djangogirls` dizininde olmanız gerekiyor. -``` -$ git status -On branch master +{% filename %}komut-satırı{% endfilename %} -Initial commit + Hatırlatma: Kullanıcı adı seçerken Türkçe karakter kullanmayın. + $ git init + Initialized empty Git repository in ~/djangogirls/.git/ + $ git config --global user.name "Adınız" + $ git config --global user.email you@example.com + -Untracked files: - (use "git add ..." to include in what will be committed) +Git reposunu başlatmak proje başına sadece bir kere yapmamız gereken bir şeydir (ve kullanıcı adınız ve mailinizi tekrar girmeniz gerekmeyecek). - .gitignore - blog/ - manage.py - mysite/ +Git bu dizindeki tüm dizin ve dosyalardaki değişiklikleri kaydedecek, ama takip etmemesini istediğimiz bazı dosyalar var. Bunu dizinin dibinde `.gitignore` adında bir dosya oluşturarak yapıyoruz. Editörünüzü açın ve aşağıdaki içeriklerle yeni bir dosya yaratın: -nothing added to commit but untracked files present (use "git add" to track) -``` +{% filename %}.gitignore{% endfilename %} + + *.pyc + *~ + __pycache__ + myvenv + db.sqlite3 + /static + .DS_Store + + +Ve onu `.gitignore` ismi ile "djangogirls" dizinine kaydedin. + +> **Not** Dosya adının başındaki nokta önemli! Eğer dosyayı oluştururken zorluk yaşarsanız (örneğin Mac'ler Finder'dan nokta ile başlayan bir dosya oluşturmanızdan hoşlanmazlar), editörünüzdeki "Farklı Kaydet" özelliğini kullanın böylece çalışacaktır. +> +> **Not** `.gittignore` dosyasında belirttiğiniz dosyalardan biri `db.sqlite3` dosyası. Bu dosya tüm gönderilerinizin saklandığı yerel veritabanınızdır. Bunu reponuza eklemek istemiyoruz çünkü PythonAnywhere'deki web siteniz farklı bir veritabanı kullanacak. Bu veritabanı geliştirme makinenizdeki gibi SQLite olabilir ama genelde sitenizdeki çok daha fazla ziyaretçiyi kaldırabilecek MySQL adı verilen bir veritabanı kullanacaksınız. Her iki durumda da, GitHub kopyası için SQLite veritabanınızı yok saymanız, şu ana kadar oluşturduğunuz tüm gönderilerin lokalinizde kalması ve yalnızca lokal olarak kullanılabilmeniz anlamına geliyor. Canlıda onlara ulaşabilmeniz için yeniden eklemek zorundasınız. Lokal veritabanınızı farklı şeyleri test edebileceğiniz ve blogunuzdaki gerçek gönderilerinizi silmekten korkmayacağınız iyi bir oyun alanı olarak düşünmelisiniz. + +`git add` kullanmadan önce veya nelerin değiştiğinden emin değilseniz, `git status` komutunu kullanmakta yarar var. Bu, yanlış dosyaların eklenmesi ve gönderilmesi gibi istenmeyen sürprizlerin engelenmesine yardımcı olacak. `git status` komutu, takip edilmeyen/değişen/gönderilecek dosyalar (staged), dal durumu (branch status) gibi bilgiler verir. Çıktıda aşağıdakine benzer olmalıdır: + +{% filename %}komut-satırı{% endfilename %} + + $ git status + On branch master + + 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) + Ve son olarak değişikliklerimizi kaydediyoruz. Komut satırına gidin ve aşağıdaki komutları çalıştırın: -``` -$ git add -A -$ git commit -m "Django Girls uygulamam, ilk commit" - [...] - 13 files changed, 200 insertions (+) - create mode 100644 .gitignore - [...] - create mode 100644 mysite/wsgi.py -``` - -## Kodunuzu Github'a gönderme +{% filename %}komut-satırı{% endfilename %} -[GitHub.com>][2] adresine gidin ve kendinize yeni bedava bir kullanıcı hesabı açın. (Bunu atölye hazırlıklarında zaten yaptıysanız, harika!) + $ git add --all . + $ git commit -m "Django Girls uygulamam, ilk commit" + [...] + 13 files changed, 200 insertions(+) + create mode 100644 .gitignore + [...] + create mode 100644 mysite/wsgi.py + -Arkasından "ilk-blogum" (veya "my-first-blog") isminde yeni bir repo oluşturun. "Initialize with a README" kutucuğunu işaretlemeden bırakın, .gitignore opsiyonunu boş bırakın (onu elle yaptık) ve 'License'ı 'None' olarak bırakın. +## Kodunu GitHub'a yollama (Push) -![][3] +Şimdi [Github.com](https://www.github.com) adresine gidip bir Github hesabı açmalıyız. (Eğer daha önceden hesap açtıysanız süper!) - [3]: images/new_github_repo.png +Sıra depomuzu oluşturmaya geldi. 'New Repository' tuşuna tıklayıp "my-first-blog" adında bir Github deposu oluşturalım. "initialize with a README" ve ".gitignore" kutularının seçili olmadığından emin olalım (zaten .gitignore dosyamızı kendimiz oluşturmuştuk). Son olarak License seçeneğinde 'None'yi seçelim. -> **Not** `ilk-blogum` ismi önemli -- başka birşey de seçebilirsiniz, ama aşağıdaki yönergelerde çok geçiyor, her seferinde değiştirmeniz gerekir. En kolayı `ilk-blogum` ismi ile devam etmek. +![](images/new_github_repo.png) -Bir sonraki ekranda, repo'yu klonlamak için gereken URL'yi göreceksiniz. "HTTPS"li versiyonunu seçin, kopyalayın. Birazdan onu komut penceresine yapıştıracağız: +> **Not** `my-first-blog` ismi önemli -- başka birşey de seçebilirsiniz, ama aşağıdaki yönergelerde çok geçiyor, her seferinde değiştirmeniz gerekir. En kolayı `my-first-blog` ismi ile devam etmek. -![][4] +Bir sonraki ekranda, reponuzun klonlama URL'ini goreceksiniz, bu URL takip eden bir kac komutta kullanacagiz: - [4]: images/github_get_repo_url_screenshot.png +![](images/github_get_repo_url_screenshot.png) Şimdi bilgisayarınızdaki Git reposunu Github'daki repo ile ilişkilendirmemiz gerekiyor. -Aşağıdakini komut satırına yazın (`` kısmını Github hesabını yarattığınız sırada kullandığınız kullanıcı adı ile değiştirin, büyüktür küçüktür işaretlini eklemeyin): +Aşağıdakini komut satırına yazın (`< your-github-username>`) kısmını Github hesabını yarattığınız sırada kullandığınız kullanıcı adı ile değiştirin, büyüktür küçüktür işaretlerini eklemeyin): -``` -$ git remote add origin https://github.com//ilk-blogum.git -$ git push -u origin master -``` +{% filename %}komut-satırı{% endfilename %} -Github kullanıcı adı ve şifrenizi girin, arkasından aşağıdakine benzer bir şey görmeniz gerekiyor: + $ git remote add origin https://github.com//my-first-blog.git + $ git push -u origin master + -``` -Username for 'https://github.com': zeynep -Password for 'https://zeynep@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/zeynep/ilk-blogum.git - * [new branch] master -> master -Branch master set up to track remote branch master from origin. -``` +Github kullanıcı adı ve şifrenizi girin, ardından aşağıdakine benzer bir şey görmeniz gerekiyor: - +{% filename %}komut satırı{% endfilename %} -Kodunuz artık Github'da. Siteye girin ve kontrol edin! İyi bir çevrede olduğunu göreceksiniz - [Django][5], the [Django Girls Tutorial][6], ve daha birçok harika açık kaynak yazılım projesi de kodlarını Github'da tutuyor :) + Username for 'https://github.com': zeynep + Password for 'https://zeynep@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/zeynep/my-first-blog.git + + * [new branch] master -> master + Branch master set up to track remote branch master from origin. + - [5]: https://github.com/django/django - [6]: https://github.com/DjangoGirls/tutorial + + +Kodunuz artık Github'da. Hemen gidip bak! İyi bir çevrede olduğunu göreceksiniz - [Django](https://github.com/django/django), the [Django Girls Tutorial](https://github.com/DjangoGirls/tutorial), ve daha birçok harika açık kaynak yazılım projesi de kodlarını Github'da tutuyor. :) # Blogumuzun PythonAnywhere üzerinde kurulumu +## PythonAnywhere hesabı oluşturma + > **Not** En baştaki kurulum adımlarında PythonAnywhere hesabını açmış olabilirsiniz - öyleyse bu kısmı tekrar yapmanıza gerek yok. {% include "/deploy/signup_pythonanywhere.md" %} -## Kodunuzu PythonAnywhere üzerine çekmek - -PythonAnywhere'de hesap açtığınızda, 'dashboard' (gösterge paneli) sayfanıza veya "Consoles" sayfasına yönlendirileceksiniz. "Bash" konsolu başlatma seçeneğini seçin -- bu bilgisayarınızdaki konsolun PythonAnywhere versiyonu. - -> **Not** PythonAnywhere Linux tabanlı, o yüzden kendi makinanız Windows ise konsol biraz farklı gözükecektir. - -Reponuzun bir klonunu yaratarak kodumuzu Github'dan PythonAnywhere üzerine çekelim. Aşağıdakileri PythonAnywhere konsoluna yazın (`` yerine kendi Github kullanıcı adınızı yazmayı unutmayın): - -``` -$ git clone https://github.com//ilk-blogum.git -``` - -Bu kodunuzun bir kopyasını PythonAnywhere üzerine indirecektir. `tree ilk-blogum` yazarak kontrol edin: - -``` -$ tree ilk-blogum -ilk-blogum/ -├── 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 -``` - - -### PythonAnywhere üzerine bir virtualenv (sanal ortam) oluşturmak - -Bilgisayarınızda nasıl bir virtualenv (sanal ortam) oluşturduysanız, aynı şekilde PythonAnywhere üzerinde de oluşturabilirsiniz. Bash konsoluna, aşağıdakileri yazın: +## Sitemizin PythonAnywhere üzerinde yapılandırılması -``` -$ cd ilk-blogum +Ana [PythonAnywhere Dashboard](https://www.pythonanywhere.com/) a logosuna tıklayarak dönelim ve bir "Bash" console başlatalım – bu bilgisayarınızdaki komut satırının PythonAnywhere versiyonudur. -$ virtualenv --python=python3.4 myvenv -Running virtualenv with interpreter /usr/bin/python3.4 -[...] -Installing setuptools, pip...done. +![PythonAnywhere web arayüzündeki 'New Console' bölümünde, 'bash' için butona tıkla](images/pythonanywhere_bash_console.png) -$ source myvenv/bin/activate +> **Not:** PythonAnywhere Linux tabanlıdır, eğer Windows kullanıyorsan, bilgisyarındaki konsoldan biraz farklı görünür. -(myvenv) $ pip install django whitenoise -Collecting django -[...] -Successfully installed django-1.10 whitenoise-2.0 -``` +PythonAnywhere'de bir web yazılımı konuşlandırmak için kodun GitHub'dan çekilmesi ve PythonAnywhere'in bu kodu tanıyabilmesi ve çalıştırması için yapılandırmamız gerekiyor. Bu iş manuel olarak yapabilir ama PythonAnywhere bunu kolaylıkla yapabilmek için yardımcı bir araç sunar. İlk önce bu aracı kuralım: -> **Not** `pip install` birkaç dakika sürebilir. Sabır, sabır! Ama 5 dakikadan uzun sürüyorsa, birşeyler yanlış olmuştur. Eğitmeninize sorun. +{% filename %}PythonAnywhere command-line{% endfilename %} - + $ pip3.6 install --user pythonanywhere + -### Statik dosyaların toplanması. +Bu komut ekrana bir takım şeyler yazar, mesela `Collecting pythonanywhere`, and eventually end with a line saying `Successfully installed (...) pythonanywhere- (...)`. -"whitenoise"un ne olduğunu merak ettiniz mi? "Statik dosyalar" için kullanılan bir araç. Statik dosyalar, HTML veya CSS dosyaları gibi düzenli olarak değişmeyen veya kod çalıştırmayan dosyalardır. Bu dosyalar sunucularda bilgisayarımızdakinden farklı çalışırlar. Bu yüzden onları sunucudan yayınlamak için "whitenoise" gibi bir araca ihtiyacımız var. +Şimdi, programımızı otomatik olarak yapılandırmak için bu komutu calıştıralım. Aşağıdakileri PythonAnywhere konsoluna yazın (`` yerine kendi Github kullanıcı adınızı yazmayı unutmayın): -Tutorial'ın ilerleyen kısımlarında sitemizin CSS'ini düzenlerken statik dosyalar konusuna biraz daha fazla gireceğiz. +{% filename %}PythonAnywhere komut satırı{% endfilename %} -Şimdilik sadece sunucuda `collectstatic` diye ek bir komut çalıştıracağız. Bu komut, Django'ya sunucdaki bütün statik dosyaları toparlamasını söyler. An itibariyle bunlar çoğunlukla admin sitesini güzelleştiren dosyalar. + $ pa_autoconfigure_django.py https://github.com//my-first-blog.git + -``` -(myvenv) $ python manage.py collectstatic +Bu komut çalışırken neler olup bittiğini izleyebilirsiniz: -You have requested to collect static files at the destination -location as specified in your settings: +- Kodunuz GitHub'dan çekiliyor +- Tıpkı kendi bilgisayarındaki gibi PythonAnywhere üzerinde bir virtualenv oluşturuluyor +- Yayına almak için gerekli ayarlar (settings) dosyası güncelleniyor +- Yine `manage.py migrate` komutu ile PythonAnywhere üzerinde veritabanı oluşturuluyor +- Sabit dosyaların (bunları daha sonra öğreneceğiz) oluşturuluyor +- Ve web uygulamanızın API sinin PythonAnywhere tarafından sunulması için ayarlar yapılıyor - /home/zeynep/ilk-blogum/static +Bu adımlar PythonAnywhere'de otomatikleştirilmiştir, fakat farklı herhangi bir sunucu sağlayacısıyla da aynı adımlar yapılmalıdır. Anlaşılması önemli olan nokta şu ki PythonAnywhere üzerinde yaratılan veritabanı ile kendi bilgisayarımızda yarattığımız veritabanı birbirinden tamamen ayrı -- dolayısı ile bu iki veritabanında saklanmış olan postlar ve kullanıcılar da farklı olabilir. -This will overwrite existing files! (Bu işlem halihazırdaki dosyalarınız üzerinde değişiklik yapar!) -Are you sure you want to do this? (Bu işlemi yapmak istediğinizden emin misiniz?) +Bu nedenle, aynen kendi bilgisayarımızda yapmış olduğumuz gibi, `createsuperuser` ile bir admin kullacısını oluşturmamız gerekiyor. PythonAnywhere otomatik olarak virtualenv i başlatmış olduğu için, bu kullanıcıyı hemen oluşturabiliriz: -Type 'yes' to continue, or 'no' to cancel: yes (Onaylıyorsanız 'yes', vazgeçtiyseniz 'no' yazın) -``` +{% filename %}PythonAnywhere komut satırı{% endfilename %} -"yes" yazın ve işte başladı! Bilgisayarlara sayfa sayfa yazı yazdırmayı sevmiyor musunuz? Ben hep beraberinde küçük küçük sesler çıkarırım. Trr, trr, trr... + (.pythonanywhere.com) $ python manage.py createsuperuser + -``` -Copying '/home/zeynep/ilk-blogum/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/actions.min.js' -Copying '/home/zeynep/ilk-blogum/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/inlines.min.js' -[...] -Copying '/home/zeynep/ilk-blogum/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/css/changelists.css' -Copying '/home/zeynep/ilk-blogum/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/css/base.css' -62 static files copied to '/home/zeynep/ilk-blogum/static'. -``` +Admin kullanıcısının detaylarını girin. Daha önce kendi bilgisayarınızda oluşturduğunuz kullanıcı detayları ile aynı olması hatırlamak açısından faydalı olacaktır, tabii PythonAnywhere üzerindeki şifreyi daha zor olarak tanımlamak isteyebiliriz. -### PythonAnywhere üzerinde veritabanının oluşturulması +Şimdi, isterseniz, PythonAnywhere üzerindeki kodlara `ls` komutu ile göz atabilirsiniz: -Bilgisayarınız ve sunucu arasında farklı olan bir başka şey daha: farklı bir veritabanı kullanıyor. Dolayısıyla bilgisayarınızdaki ve sunucudaki kullanıcı hesapları ve blog yazıları farklı olabilir. +{% filename %}PythonAnywhere komut satırı{% endfilename %} -Sunucudaki veritabanına aynen bilgisayardaki gibi `migrate` (taşımak) ve `createsuperuser` (yetkili bir kullanıcı oluşturmak) komutlarıyla oluşturup ilk örnek verilerle ile doldurabiliriz: + (ola.pythonanywhere.com) $ ls + blog db.sqlite3 manage.py mysite requirements.txt static + (ola.pythonanywhere.com) $ ls blog/ + __init__.py __pycache__ admin.py forms.py migrations models.py static + templates tests.py urls.py views.py + -``` -(myvenv) $ python manage.py migrate -Operations to perform: -[...] -Applying sessions.0001_initial... OK -(myvenv) $ python manage.py createsuperuser -``` +"Files" sekmesine giderek de PythonAnywhere in sunduğu arayüz ile dosyaları gezinebilirsiniz. (Sağ üst köşedeki menü butonunu kullanarak, konsol sayfasından diğer PythonAnywhere sayfalarına geçebilirsiniz. Bu sayfaların birindeyken, sayfanın yukarısında diğer sayfalara olan linkleri görebilirsiniz.) -## Blog'umuzu web uygulaması olarak yayınlama +## Şimdi Canlı Yayındasınız! -Artık kodumuz PythonAnywhere üzerinde, virtualenv'imiz hazır, statik dosyalar toplandı, ve veritabanı hazırlandı. Blogumuzu bir web uygulaması olarak yayınlamaya hazırız! +Web siteniz şimdi İnternet üzerinden erişilebilir olmalı! PythonAnywhere "Web" tabına tıklayarak linki kopyalayın. Bu linki istediğiniz herkes ile paylaşabilirsiniz :) -PythonAnywhere logosuna tıklayarak 'dashboard'a geri gidin, burda **Web** sekmesine tıklayın. En son **Add a new web app** (yeni bir web uygulaması yaratın) linkine tıklayın. - -Açılan pencerede alan adınızı kontrol edin, **manual configuration** (elle konfigürasyon)'ı seçin ("Django" opsiyonunu *değil*). Arkasından **Python 3.4**'ü seçin ve işlemi bitirmek için 'Next'e basın. - -> **Not** "Manual configuration" seçeneğini seçtiğinizden emin olun, "Django" seçeneğini değil. Hazır PythonAnywhere Django kurulumunu seçmek için fazla havalıyız ;-) - -### virtualenv'in (sanal ortamın) ayarlanması - -Son bahsettiğimiz adım sizi web uygulamanızın PythonAnywhere ayar ekranına getirecek. Sunucudaki uygulamanızda değişiklik yapmak istediğinizde bu ekranı kullanmanız gerekiyor. - -![][7] - - [7]: images/pythonanywhere_web_tab_virtualenv.png - -"Virtualenv" bölümünde "Enter the path to a virtualenv" (virtualenv için dizin yolu girin) linkini tıklayın ve şunu yazın: `/home//ilk-blogum/myvenv`. Devam etmeden önce, dizin yolunu kaydetmek için tik işareti olan mavi kutuyu tıklayın. - -> **Not** İlgili yeri kendi kullanıcı adınızı yazın. Eğer hata yaparsanız, PythonAnywhere size bir uyarı gösterecektir. - -### WSGI dosyasının ayarlanması - -Django, "WSGI protokolü"nü kullanarak çalışır. WSGI, PythonAnywhere'in de desteklediği Python kullanan websitelerinin servis edilmesi için kullanılan bir standart. PythonAnywhere'in Django blogumuzu anlaması için WSGI ayar dosyasını düzenleyiyoruz. - -"WSGI Configuration file" (WSGI ayar dosyası) linkine tıklayın ("Code" denen kısımda, sayfanın üst tarafında -- adı `/var/www/_pythonanywhere_com_wsgi.py`'a benzer birşey olacak). Burdan bir edöitöre yönlendirileceksiniz. - -Tüm içeriği silin ve onların yerine aşağıdakileri yazın: - -```python -import os -import sys - -path = '/home//ilk-blogum' # burada kendi kullanıcı adınızı yazın -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()) -``` - -> **Not** `` diye geçen kısıma kendi kullanıcı adınızı yazmayı unutmayın - -Bu dosyanın işi, PythonAnywhere'e web uygulamamızın nerde yaşadığını ve Django ayar dosyasının adının ne olduğunu söylemek. Aynı zamanda "whitenoise" statik dosya aracını ayarlıyor. - -**Save** (kaydet)'e basın. Arkasından **Web** sekmesine geri gidin. - -Hazırız! Yeşil ve büyük **Reload** (Yeniden yükle) butonuna tıklayın. Uygulamanıza girip görebileceksiniz. Sayfanın tepesinde uygulamaya giden linki bulabilirsiniz. +> **Not** Bu kılavuz başlangıçlara yönelik olduğu için basit tutmak amacıyla siteyi yayına alırken güvenlik açısından ideal olmayan bir kaç seçim yaptık. Bu projeyi ilerletmeye karar verirseniz veya yeni bir proje oluşturursanız, güvenlik tavsiyeleri için [Django deployment checklist](https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/) i inceleyin. ## Hata ayıklama önerileri -Eğer sitenize girdiğinizde bir hata görürseniz, hata ayıklama bilgileri için ilk bakacağınız yer, **error log**'unuz (hata kayıtlarınız). Buraya olan linki PythonAnywhere'deki [Web sekme][8]sinde bulabilirsiniz. Burda hata mesajları olup olmadığına bakın; en yeni mesajlar en altta. Sık karşılaşılan problemler şunlar: - - [8]: https://www.pythonanywhere.com/web_app_setup/ - -* Konsolda yaptığımız adımlardan birinin unutulması: virtualenv'in oluşturulması, çalışır hale getirilmesi, içine Django'nun kurulumu, collectstatic'in çalıştırılması, veritabanının taşınması (migrate ettirilmesi). +`pa_autoconfigure_django.py` komut dosyasını çalıştırırken bir hata görürseniz, bunun yaygın birkaç nedeni vardır: -* Web sekmesinde virtualenv dizin yolunda bir hata yapılması -- eğer problem varsa, ilgili yerde küçük kırmızı bir hata mesajı olur. +- PythonAnywhere API tokeni oluşturmayı unutmak. +- GitHub URL'nizde bir hata yapmak +- *"Could not find your settings.py"* hatası genellikle tüm gerekli dosyaların Git'e eklenmemiş ve/veya GitHub'a başarılı olarak push edilmemiş olmasından kaynaklanır. Tekrar Git bölümüne bakın -* WSGI ayar dosyasına bir hata yapmak -- ilk-blogum dizinine olan yolu doğru yazdığınızdan emin misiniz? +Websitenizi ziyaret ettğiniz zaman bir hata ile karşılaşıtsanız ilk bakacağınız yer **error log** dosyasıdır. PythonAnywhere [Web](https://www.pythonanywhere.com/web_app_setup/) sekmesinde bu dosyaya link bulabilirsiniz. Hata mesajlarını buradan kontrol edebilrisiniz; en yakın zamandaki hatalar en sonda yer alır. -* Virtualenv'ınız için seçtiğiniz Python versiyonu web uygulamanız için seçtiğiniz Python versiyonu ile aynı mı? İkisinin de 3.4 olması gerekiyor. - -* [Python Anywhere vikisinde (bilgi sayfalarında) genel hata ayıklama önerileri][9] bulunuyor. - - [9]: https://www.pythonanywhere.com/wiki/DebuggingImportError +[PythonAnywhere wiki üzerinde bazı genel hata giderme tüyoları](http://help.pythonanywhere.com/pages/DebuggingImportError) mevcuttur. Ve eğitmeniniz size yardıma hazır, unutmayın! -# Siteniz canlıda! +# Sitenize göz atın! + +Siteniz için bulunan varsayılan sayfa ''İşe yaradı!'' demelidir. Tıpkı yerel bilgisayarınızda olduğu gibi. URL'nin sonuna `/admin/` yazın, 'giriş' tuşuna bastığınızda admin sitesi açılacak. Kullanıcı adı ve şifrenizle giriş yapın, sunucuda yeni blog yazıları girebildiğinizi göreceksiniz. -Sitenizin varsayılan sayfası "Welcome to Django" diyor olmalı, aynen bilgisayarınızda olduğu gibi. URL'nin sonuna `/admin/` yazın, 'giriş' tuşuna bastığınızda admin sitesi açılacak. Kullanıcı adı ve şifrenizle giriş yapın, sunucuda yeni blog yazıları girebildiğinizi göreceksiniz. +Birkaç gönderi oluşturduktan sonra, lokalinize (PythonAnywhere'e değil) geri dönebilirsiniz. Değişiklikleri lokalinizde yapacaksınız. Bu web geliştirmekte yaygın bir akışıdır - değişiklikleri yerel olarak yapınız, bu değişiklikleri GitHub'a gönderin, değişikliklerinizi canlı Web sunucusuna çekin. Bu canlı web sitenizi bozmadan çalışmanızı ve yeni şeyler denemenizi sağlar. Bayağı havalı, di mi? Kendinize *KOCAMAN* bir aferin diyin! Yayına alma web geliştirme işinin en uğraştırmalı kısımlarından biridir ve genelde çalışana kadar insanların birkaç gününü alır. Ama işte siteniz canlıda, gerçek internette! diff --git a/tr/deploy/images/github_get_repo_url_screenshot.png b/tr/deploy/images/github_get_repo_url_screenshot.png index 62a29f5f8d7..ee1560b1e85 100644 Binary files a/tr/deploy/images/github_get_repo_url_screenshot.png and b/tr/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/tr/deploy/images/new_github_repo.png b/tr/deploy/images/new_github_repo.png index 64011e59a52..d1f82e5d863 100644 Binary files a/tr/deploy/images/new_github_repo.png and b/tr/deploy/images/new_github_repo.png differ diff --git a/tr/deploy/images/pythonanywhere_bash_console.png b/tr/deploy/images/pythonanywhere_bash_console.png new file mode 100644 index 00000000000..0100aa4390a Binary files /dev/null and b/tr/deploy/images/pythonanywhere_bash_console.png differ diff --git a/tr/deploy/images/pythonanywhere_beginner_account_button.png b/tr/deploy/images/pythonanywhere_beginner_account_button.png new file mode 100644 index 00000000000..c1be0a14132 Binary files /dev/null and b/tr/deploy/images/pythonanywhere_beginner_account_button.png differ diff --git a/tr/deploy/images/pythonanywhere_create_api_token.png b/tr/deploy/images/pythonanywhere_create_api_token.png new file mode 100644 index 00000000000..abae45ae37a Binary files /dev/null and b/tr/deploy/images/pythonanywhere_create_api_token.png differ diff --git a/tr/deploy/images/pythonanywhere_web_tab_virtualenv.png b/tr/deploy/images/pythonanywhere_web_tab_virtualenv.png index 97e87e7b07b..6069f6da831 100644 Binary files a/tr/deploy/images/pythonanywhere_web_tab_virtualenv.png and b/tr/deploy/images/pythonanywhere_web_tab_virtualenv.png differ diff --git a/tr/deploy/install_git.md b/tr/deploy/install_git.md old mode 100755 new mode 100644 index af163ac1ac3..1dc6070f63c --- a/tr/deploy/install_git.md +++ b/tr/deploy/install_git.md @@ -1,17 +1,52 @@ -### Windows +Git, birçok programcı tarafından kullanılan bir "sürüm kontrol sistemi"dir. Bu yazılım dosyaların zaman içindeki değişimlerini izler, böylelikle sonradan eski sürümlere ulaşabilirsiniz. Biraz Microsoft Word'deki "değişiklikleri izle" özelliği gibi, ama çok daha güçlü. -Git'i [git-scm.com](http://git-scm.com/) adresinden indirebilirsiniz. 5. adıma kadar "next"e basarak geçebilirsiniz. 5. adımda "Adjusting your PATH environment" dediği yerde, "Run Git and associated Unix tools from the Windows command-line" (en alttaki opsiyonu) seçin. Onun dışında, varsayılanlar iyi. Kodu çekerken Windows-stili, kodu gönderirken Unix-stili satır sonları iyidir. +## Git'i kurmak -### MacOS + -Git'i [git-scm.com](http://git-scm.com/)'den indirin ve yönergeleri izleyin. +Git'i [git-scm.com](https://git-scm.com/) adresinden indirebilirsiniz. Bir adım hariç bütün adımları "next"e basarak geçebilirsiniz. Bu adımda "Adjusting your PATH environment" dediği yerde, "Run Git and associated Unix tools from the Windows command-line" (en alttaki opsiyonu) seçin. Onun dışında varsayılanları seçebilirsiniz. Satır sonları için kodu çekerken Windows-stilini, kodu gönderirken Unix-stilini kullanın. -### GNU/Linux +Kurulum başarı ile tamamlandıktan sonra komut istemini veya powershelli yeniden başlatmayı unutmayın. -Halihazırda yüklü değilse, git'i paket yöneticinizle indirebilirsiniz. Şunlardan birini deneyin: + +Git'i [git-scm.com](https://git-scm.com/)'den indirin ve yönergeleri izleyin. + +> **Not** Eğer OS X 10.6, 10.7 ya da 10.8 kullanıyorsanız, giti buradan indirmeniz gerekmektedir: [OS X Snow Leopard için Git Kurulumu](https://sourceforge.net/projects/git-osx-installer/files/git-2.3.5-intel-universal-snow-leopard.dmg/download) + + + + + +{% filename %}komut-satırı{% endfilename %} + +```bash +$ sudo apt install git ``` -sudo apt-get install git -# veya -sudo yum install git + + + + + +{% filename %}komut-satırı{% endfilename %} + +```bash +$ sudo dnf install git ``` + + + + + +{% filename %}komut-satırı{% endfilename %} + +```bash +$ sudo zypper install git +``` + + \ No newline at end of file diff --git a/tr/deploy/signup_pythonanywhere.md b/tr/deploy/signup_pythonanywhere.md old mode 100755 new mode 100644 index 86ec0f9f316..02d896740bc --- a/tr/deploy/signup_pythonanywhere.md +++ b/tr/deploy/signup_pythonanywhere.md @@ -1,5 +1,15 @@ -Sırada PythonAnywhere sitesinde bedava bir "Beginner" ( yeni başlayan) hesabı açma işi var. +PythonAnywhere, "bulutta" bulunan sunucularda Python kodunu çalıştırmak için kullanılan bir hizmettir. Sitemizi, canlı ve internette barındırmak için bunu kullanacağız. - * [www.pythonanywhere.com](https://www.pythonanywhere.com/) +PythonAnywhere'de bir "Beginner" hesabı için açın (ücretsiz seviye yeterli, kredi kartına ihtiyacınız yok). -> **Not** Burada kullanıcı isminizi seçerken bilin ki blogunuzun URL'si `kullanıcıadınız.pythonanywhere.com` şeklinde olacak. O yüzden ya kendi rumuzunuzu(nickname) seçin ya da blogunuzun konusu ile ilgili bir isim seçin. +* [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +![Ücretsiz 'Beginner' hesabı oluşturmak için PythonAnywhere kayıt sayfası düğmesi](../deploy/images/pythonanywhere_beginner_account_button.png) + +> **Not** Burada kullanıcı adınızı seçerken, blogunuzun URL'sinin `yourusername.pythonanywhere.com`, şeklini alacağını unutmayın, bu nedenle blogunuzun neyle ilgili olduğu için kendi takma adınızı veya bir adınızı seçin. + +## PythonAnywhere API token oluşturma + +Bu sadece bir kez yapmanız gereken bir şey. PythonAnywhere'e kaydolduğunuzda, dashboard sayfasına yönlendirileceksiniz. "Account" sayfanızın sağ üstüne yakın link'i bulun ve "API token" isimli sekmeyi seçerek "Create new API token" butonuna basın. + +![Hesaplar sayfasındaki API token sekmesi](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/tr/django/README.md b/tr/django/README.md old mode 100755 new mode 100644 index ec57420a187..c76b588dd98 --- a/tr/django/README.md +++ b/tr/django/README.md @@ -1,27 +1,27 @@ # Django nedir? -Django (*/ˈdʒæŋɡoʊ/ jang-goh*) Python ile yazılmış ücretsiz ve açık kaynak bir web uygulama iskeletidir (framework). Bir web iskeleti, websitesi geliştirmeyi hızlandıran ve kolaylaştıran bir grup bileşendir. +Django (/ˈdʒæŋɡoʊ/ *jang-goh*) Python ile yazılmış özgür ve açık kaynak bir web uygulama iskeletidir (framework). Bir web iskeleti, websitesi geliştirmeyi hızlandıran ve kolaylaştıran bir grup bileşendir. -Bir websitesi geliştirdiğinizde benzer türde bileşenlere her zaman ihtiyacınız olur: kullanıcılar için kimlik denetimi (üye olma, üye girişi, üye çıkışı), websiteniz için bir yönetim paneli, formlar, dosyaları yüklemek için bir yol, vs. +Bir web sitesi geliştirdiğinizde benzer türde bileşenlere her zaman ihtiyacınız olur: kullanıcılar için kimlik denetimi (üye olma, üye girişi, üye çıkışı), websiteniz için bir yönetim paneli, formlar, dosyaları yüklemek için bir yol, vs. -Şansınıza çok önceden başka insanlar yeni bir site oluştururken web geliştiricilerinin benzer problemlerle karşı karşıya kaldığını fark etti ve bir araya gelip iskeletler (Django bunlardan biri) oluşturdular. Bu iskeletler size kullanabileceğiniz hazır bileşenler verir. +Şanslısınız ki, uzun zaman önce başkaları web geliştiricilerinin yeni bir site yaratırken benzer problemlerle karşı karşıya geldiğini farkettiler ve takım kurup, kullanmanız için hazır bileşenleri olan iskeletler (ki Django bunlardan bir tanesi) oluşturdular. -İskeletler sizi tekerleği yeniden icat etmekten kurtarır ve websitesi geliştirirken yükünüzün bir kısmını hafifletmekte yardımcı olur. +Frameworkler, siz yeni bir site oluştururken yükünüzü hafifletmek için tekerleği yeniden icat etmek zorunda. ## Neden bir iskelete ihtiyacınız var? -Django'nun tam olarak ne işe yaradığını anlamak için sunucular konusuna daha çok girmemiz gerekiyor. İlk bilmeniz gereken şey, sunucunuzun ondan bir web sayfası sunmasını istediğinizi bilmesi gerektiği. +Django'nun aslında ne işe yaradığını anlamak için, sunuculara daha yakından bakmamız gerekiyor. İlk olarak sunucunun, onun size bir web sitesi sunmasını istediğinizi bilmesi gerekiyor. -Bir posta kutusunun (port) gelen mektuplar (requests) için izlendiğini düşünün. Bu bir web sunucusu tarafından yapılıyor. Sunucu mektubu okuyor ve bir web sayfası göndererek cevap veriyor. Ama bir şey gönderecekseniz, içeriğe ihtiyacınız var. Django içeriği oluşturmanıza yardımcı olan bir şeydir. +Bir posta kutusunun (port) gelen mektuplar (requests) için izlendiğini düşünün. Bu bir web sunucusu tarafından yapılıyor. Web sunucusu mektubu okur ve ardından bir web sayfası ile cevap verir. Ama bir şey gönderecekseniz, içeriğe ihtiyacınız var. Django içeriği oluşturmanıza yardımcı olan bir şeydir. ## Birisi sunucunuzdan bir web sitesi istediğinde ne olur? -Web sunucusuna bir istek geldiğinde tam olarak ne istendiğini çıkarmak için Django'ya geçirilir. O da önce web sayfasının adresini alır ve ne yapması gerektiğini çıkarmaya çalışır. Bu kısım Django'nun **url çözücüsü** (urlresolver) tarafından yapılıyor (websitesi adresine URL - Uniform Resource Locator - deniyor, dolayısıyla *url çözücü* ismi mantıklı oluyor). Çok akıllı değil - bir kalıp listesi alıyor ve URL'yi bunlarla eşleştirmeye çalışıyor. Django kalıpları yukarıdan aşağı kontrol ediyor ve eşleşen bir şey varsa isteği (request'i) ilişkilendirilmiş işleve (fonksiyona) geçiriyor. Bu işlev bir *view*'a karşılık geliyor. View kelimesi Türkçe'de görünüm anlamına gelir. Django'da özel bir terim olduğu için, biz sadece <1>view kelimesini kullanacağız.). +Bir istek bir web sunucusuna geldiğinde, Django'ya aktarılır aslında ve Django da istenin ne olduğunu anlamaya çalışır. O da önce bir web sayfası adresi alır ve ne yapacağını anlamaya çalışır. Bu kısım Django'nun **url çözücüsü** (urlresolver) tarafından yapılıyor (websitesi adresine URL - Uniform Resource Locator - deniyor, dolayısıyla *url çözücü* ismi mantıklı oluyor). Çok akıllı değildir - kalıpların bir listesini alır ve URL'yi eşleştirmeye çalışır. Django kalıpları üstten alta doğru denetler ve eşleşen bir şey varsa isteği ilgili işleve (*view* olarak adlandırılan) aktarır. Mektup dağıtan bir postacı düşünün. Sokak boyunca yürüyor ve her evin numarasını mektubun üstündeki numara ile karşılaştırıyor. Eğer eşleşirse, mektubu oraya koyuyor. Url çözücü işte böyle çalışır! -*view* işlevinde her türlü ilginç şey yapılıyor: Bir bilgi için veritabanına bakabiliriz. Belki de kullanıcı veride bir şeyin değişmesini istemiştir? "Lütfen iş tanımımı değiştirin" diyen bir mektup gibi. *view* buna yapmaya izniniz olup olmadığını kontrol edebilir, sonra da sizin için iş tanımınızı güncelleyip geriye "Yapıldı!" diye bir ileti gönderir. Arkasından *view* bir cevap üretir ve Django bunu kullanıcının web tarayıcısına gönderebilir. +Tüm ilginç şeyler *view (görünüm)* fonksiyonunda yapılır: bir bilgi için veritabanına bakabiliriz. Belki de kullanıcı veride bir şeyin değişmesini istemiştir? "Lütfen iş tanımımı değiştirin." diyen bir mektup gibi. *View* bunu yapmaya izninizin olup olmadığını kontrol eder, iş tanımınızı sizin için günceller ve geri "Tamamdır!" mesajı yollar. Sonra *view* bir yanıt üretir ve Django bunu kullanıcının web tarayıcısına gönderebilir. -Tabi ki yukardaki biraz basitleştirilmiş bir açıklama, ama şimdilik bütün teknik ayrıntıyı bilmene gerek yok. Genel bir fikrin olması yeterli. +Tabi ki yukarıdaki biraz basitleştirilmiş bir açıklama, ama şimdilik bütün teknik ayrıntıyı bilmene gerek yok. Genel bir fikrin olması yeterli. -Doğrudan çok fazla detaya girmek yerine, Django ile birşeyler oluşturacağız ve önemli kısımları yolda öğreneceğiz! +Doğrudan çok fazla detaya girmek yerine, Django ile bir şeyler oluşturacağız ve önemli kısımları yolda öğreneceğiz! \ No newline at end of file diff --git a/tr/django_admin/README.md b/tr/django_admin/README.md old mode 100755 new mode 100644 index 71feb394084..642e2e56c5d --- a/tr/django_admin/README.md +++ b/tr/django_admin/README.md @@ -1,49 +1,57 @@ # Django admin -Modelini hazırladığımız yazıları eklemek, düzenlemek ve silmek için Django admin'i kullanacağız. +Az önce modellediğimiz gönderilere ekleme, düzenleme ya da silme işlemi yapmak için Django admini kullanacağız. -Hadi `blog/admin.py` dosyasını açalım ve içeriğini şununla değiştirelim: +Şimdi `blog/admin.py` dosyasını açarak içeriğini aşağıdaki şekilde değiştirelim: + +{% filename %}blog/admin.py{% endfilename %} ```python from django.contrib import admin from .models import Post admin.site.register(Post) -``` +``` -Gördüğünüz gibi, bir önceki bölümde tanımladığımız Post modelini admin.py dosyamıza dahil (import) ettik. Modelimizi admin sayfasında görünür yapmak için modeli `admin.site.register(Post)` ile belirtmemiz gerekir.. +Gördüğünüz gibi, bir önceki bölümde tanımladığımız gönderi modelini admin.py dosyamıza dahil (import) ettik. Admin sayfasında modelimizi görünür kılabilmek için, modeli `admin.site.register(Post)` ile kaydetmemiz gerekiyor. -Tamam, artık admin sayfasında Post modelimize göz atabiliriz. Web sunucusunu çalıştırmak için komut satırında `python manage.py runserver` komutunu çalıştırmayı unutmayın. Tarayıcınızda http://127.0.0.1:8000/admin/ adresini adres çubuğuna yazın. Aşağıdaki gibi bir giriş sayfası göreceksiniz: +Tamam, artık admin sayfasında gönderi modelimize göz atabiliriz. Web sunucusunu çalıştırmak için komut satırında `python manage.py runserver` komutunu çalıştırmayı unutmayın. Tarayıcınıza gidin ve adresi yazın http://127.0.0.1:8000/admin/. Bunun gibi bir giriş ekranı göreceksiniz: -![Giriş sayfası][1] +![Giriş sayfası](images/login_page2.png) - [1]: images/login_page2.png +Giriş yapabilmek için, sitedeki her şey üzerinde kontrolü olan *superuser* - bir kullanıcı hesabı oluşturmanız gerekiyor. Komut satırına geri giderek `python manage.py createsuperuser` yazın ve enter'a basın. -Giriş yapmak için, sitede her şeyin üzerinde kontrolü olan bir kullanıcı, yani bir *superuser* oluşturmanız gerekiyor. Komut satırında `python manage.py createsuperuser` yazın ve enter tuşuna basın. Giriş satırı geldiğinde, kullanıcı adınızı (küçük harfler ile ve boşluksuz), email adresinizi ve parolanızı girin. Parolayı yazarken ekranda bir şey çıkmayacaktır. Sadece yazın ve `enter` tuşuna basıp devam edin. Çıktısı aşağıdaki formatta olacaktır (kullanıcı adı ve email sizinki olacak): +> Ağ sunucusu açıkken yeni komut yazmak için, yeni bir terminal penceresi açıp sanal ortamınızı (virtualenv) aktive etmeniz gerekmektedir. **Web sunucusu başlatma** bölümünün, **Sizin ilk Django projeniz!** kısmında yeni komutların nasıl yazılacağını gözden geçirdik. -``` -(myvenv) ~/djangogirls$ python manage.py createsuperuser -Username: admin -Email address: admin@admin.com -Password: -Password (again): -Superuser created successfully. -``` +{% filename %}macOS veya Linux:{% endfilename %} -Tarayıcınıza dönün. Oluşturduğunuz superuser'ın bilgileri ile giriş yaptığınızda Django'nun admin panelini göreceksiniz. + (myvenv) ~/djangogirls$ python manage.py createsuperuser + -![Django admin][2] +{% filename %}Windows:{% endfilename %} - [2]: images/django_admin3.png + (myvenv) C:\Users\Name\djangogirls> python manage.py createsuperuser + -Posts'a tıklayın ve biraz kurcalayın. Mesela üç beş tane blog yazısı ekleyin ve ne yazacağım diye düşünmeyin - zaman kazanmak için bu tutorial'dan kopyalayıp yapıştırabilirsiniz. :) +Giriş satırı geldiğinde, kullanıcı adınızı (küçük harfler ile ve boşluksuz), email adresinizi ve parolanızı girin. **Yazdığınız şifreyi göremezseniz endişelenmeyin - olması gereken budur.** Devam etmek için şifreyi yazıp `enter` 'a basın. Çıktı şunun gibi olmalıdır ( belirtilen kullanıcı adı ve eposta size ait olmalı): -En azından iki ya da üç yazıya (ama hepsinin değil) yayınlama tarihi girdiğinizden emin olun. Bunu ileriki adımlarda kullanacağız. + Username: admin + Email address: admin@admin.com + Password: + Password (again): + Superuser created successfully. + -![Django admin][3] +Tarayıcınıza dönün. Oluşturduğunuz superuser'ın bilgileri ile giriş yaptığınızda Django'nun admin panelini göreceksiniz. + +![Django admin](images/django_admin3.png) + +Posts linkine tıklayın ve biraz kurcalayın. Beş altı blog yazısı ekleyin. İçeriği kafanıza takmayın - tutorial'dan bir kaç paragraf kopyalayıp yapıştırabilirsiniz. :) + +En azından iki ya da üç yazıya (ama hepsinin değil) yayınlama tarihi girdiğinizden emin olun. Bunu ileriki adımlarda kullanacağız. - [3]: images/edit_post3.png +![Django admin](images/edit_post3.png) -Eğer Django admin ile ilgili daha fazla şey öğrenmek istiyorsanız Django'nun belgelerine göz atabilirsiniz: https://docs.djangoproject.com/en/1.10/ref/contrib/admin/ +Eğer Django admin ile ilgili daha fazla şey öğrenmek istiyorsanız, Django dokümantasyonuna göz atabilirsiniz: https://docs.djangoproject.com/en/2.0/ref/contrib/admin/ -Şimdi enerjinizi toplamak için kendinize bir çay veya kahve alabilirsiniz. Ne de olsa ilk Django modelinizi oluşturdunuz - biraz molayı hak ediyorsunuz. :) +Şu an muhtemelen enerjinizi geri toplamak için bir şeyler yemek veya kahve( ya da çay) içmek için iyi bir zaman. İlk Django modelinizi yarattınız. Küçük bir molayı hak ettiniz! \ No newline at end of file diff --git a/tr/django_admin/images/django_admin3.png b/tr/django_admin/images/django_admin3.png index 25bcc4edda8..fb221bd18e1 100644 Binary files a/tr/django_admin/images/django_admin3.png and b/tr/django_admin/images/django_admin3.png differ diff --git a/tr/django_admin/images/edit_post3.png b/tr/django_admin/images/edit_post3.png index 34f2a195ec5..57299b6f5af 100644 Binary files a/tr/django_admin/images/edit_post3.png and b/tr/django_admin/images/edit_post3.png differ diff --git a/tr/django_admin/images/login_page2.png b/tr/django_admin/images/login_page2.png index 85137f4d162..c16d1aa4289 100644 Binary files a/tr/django_admin/images/login_page2.png and b/tr/django_admin/images/login_page2.png differ diff --git a/tr/django_forms/README.md b/tr/django_forms/README.md old mode 100755 new mode 100644 index 03854efcf5d..a44c776675b --- a/tr/django_forms/README.md +++ b/tr/django_forms/README.md @@ -1,6 +1,6 @@ # Django Forms -Günlüğümüzde son olarak yapmak istediğimiz şey, günlük yazılarını eklemek ve düzenlemek için güzel bir yapı oluşturmak. Django'nun `admin` arayüzü çok havalı, ama özelleştirilmesi ve güzelleştirilmesi oldukça zor. Bunu `forms` (formlar) kullanarak kendi arayüzümüz üstünde mutlak bir güce sahip olacağız - neredeyse hayal ettiğimiz her şeyi yapabiliriz! +Blogumuzda yapmak istediğimiz son şey blog yazılarını eklemek ve düzenlemek için güzel bir yapı oluşturmak. Django'nun `admin` arayüzü çok havalı, ama özelleştirilmesi ve güzel hale getirilmesi oldukça zor. `forms` (formlar) ile kendi arayüzümüz üstünde mutlak bir güce sahip olacağız - neredeyse hayal ettiğimiz her şeyi yapabiliriz! Django formlarının güzel yanı, hem sıfırdan bir form tanımlayabilmemiz hem de sonuçları modele kaydedecek bir `ModelForm` oluşturabilmemizdir. @@ -10,13 +10,14 @@ Django'nun diğer önemli parçaları gibi, formların da kendi dosyası var: `f `blog` dizinimizde bu isimde bir dosya oluşturmalıyız. -``` -blog -└── forms.py -``` + blog + └── forms.py + Tamam, hadi dosyayı açalım ve aşağıdaki kodu yazalım: +{% filename %}blog/forms.py{% endfilename %} + ```python from django import forms @@ -26,37 +27,41 @@ class PostForm(forms.ModelForm): class Meta: model = Post - fields = ('baslik', 'yazi',) -``` + fields = ('title', 'text',) +``` -Önce Django formları (`from django import forms`) ve tabii ki `Post` modelimizi içe aktarmalıyız (`from .models import Post`). +Önce Django formları (`from django import forms`) ve tabii ki `Post` modelimizi (`from .models import Post`) import komutu ile dahil etmeliyiz. -`PostForm`, tahmin etmiş olabileceğiniz gibi, formumuzun ismi. Django'ya bu formun bir `ModelForm` olduğunu belirtmeliyiz. Bunu `forms.ModelForm` sayesinde Django bizim için yapacaktır. +Tahmin etmiş olabileceğiniz gibi, formumuzun ismi `PostForm`. Django'ya bu formun bir `ModelForm` olduğunu belirtmeliyiz. Bunu `forms.ModelForm` sayesinde Django bizim için yapacaktır. -Sırada Django'ya bu formu (`model = Post`) oluşturmak için hangi modelin kullanılması gerektiğini anlattığımız `class Meta` var). +Sırada Django'ya bu formu oluşturmak için hangi modelin kullanılması gerektiğini (`model = Post`) anlattığımız `class Meta` var. -Son olarak, formumuzda hangi alan(lar)ın bulunması gerektiğini söyleyebiliriz. Bu senaryoda sadece `baslik` ve `yazi` alanlarının gösterilmesini istiyoruz - `yazar` şu anda giriş yapmış olması gereken kişidir (yani siz!) ve biz ne zaman yeni bir yazı oluşturursak `yaratilma_tarihi` otomatik olarak (örn. kod içinde) ayarlanmalıdır, değil mi? +Son olarak, formumuzda hangi alan(lar)ın bulunması gerektiğini söyleyebiliriz. Bu senaryoda sadece `title` ve `text` alanlarının gösterilmesini istiyoruz - `author` şu anda giriş yapmış olması gereken kişidir (yani siz!) ve biz ne zaman yeni bir yazı oluşturursak `created_date` otomatik olarak (örn. kod içinde) ayarlanmalıdır, değil mi? Ve hepsi bu kadar! Şimdi tek yapmamız gereken formu bir *view* içinde kullanıp, template (şablon) içinde göstermek. -Bir kez daha: sayfaya bir bağlantı, bir URL, bir view ve bir template üreteceğiz. +Bir kere daha sayfaya bir bağlantı, bir url, bir view ve bir template oluşturacağız. ## Formun bulunduğu sayfaya bağlantı oluşturma -Şimdi `blog/templates/blog/base.html` şablonunu açma zamanı. Öncelikle `page-header` adlı `div` öğesinin içine bir bağlantı ekleyeceğiz: +Şimdi `blog/templates/blog/base.html` isimli template'i açma zamanı. Öncelikle `page-header` adlı `div` öğesinin içine bir bağlantı ekleyeceğiz: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html -``` +``` -Yeni view'i `post_new` olarak isimlendirdik. +Yeni view'in (görünümün) adını `post_new` koymak istiyoruz. `"glyphicon glyphicon-plus"` class'ı kullandığımız bootstrap teması tarafından sağlanıyor ve bizim için bir artı işareti gösterecek. -Yukarıdaki satırı ekledikten sonra html dosyanız böyle görünmeli: +Satırı ekledikten sonra, HTML dosyanız bu şekilde görünmelidir: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% load staticfiles %} - - +< html> + Django Girls blog @@ -78,146 +83,166 @@ Yukarıdaki satırı ekledikten sonra html dosyanız böyle görünmeli:
-``` +``` -Dokümanı kaydedip http://127.0.0.1:8000 sayfasını yeniledikten sonra, siz de tanıdık `NoReverseMatch` hatasını görüyor olmalısınız, değil mi? +Dosyayı kaydedip http://127.0.0.1:8000 sayfasını yeniledikten sonra, siz de bilindik `NoReverseMatch` hatasını görüyor olmalısınız, görüyorsunuz değil mi? Güzel! ## URL -`blog/urls.py` dosyasını açalım ve yeni bir satır ekleyelim: +`blog/urls.py` dosyasını açıp şu satırı ekleyelim: + +{% filename %}blog/urls.py{% endfilename %} ```python - url(r'^post/new/$', views.post_new, name='post_new'), -``` +path('post/new', views.post_new, name='post_new'), +``` Ve kodun son hali şu şekilde görünecektir: +{% filename %}blog/urls.py{% endfilename %} + ```python -from django.conf.urls import include, 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'), ] -``` +``` -Sayfayı yeniledikten sonra, `AttributeError` şeklinde bir hata görürüz, bunun sebebi de henüz `post_new` view'ını (görünümünü) kodlamamış olmamız. Şimdi bu dosyayı da ekleyelim. +Sayfayı yeniledikten sonra `post_new` view'ını oluşturmadığımız için `AttributeError` hatası alacağız. Şimdi onu ekleyelim. ## post_new view Şimdi `blog/views.py` dosyasını açıp aşağıdaki satırları diğer `from` satırlarının olduğu yere ekleyelim: +{% filename %}blog/views.py{% endfilename %} + ```python from .forms import PostForm -``` +``` + +Ve sonra bizim *view*'ımız: -ve bizim *view*'ımız: +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) -``` +``` -Yeni bir `Post` formu oluşturmak için `PostForm()` fonksiyonunu çağırmak ve template'e iletmek gerekir. Bu *view*'a geri döneceğiz, fakat öncesinde form için hızlıca bir şablon oluşturalım. +Yeni bir `Post` formu oluşturmak için `PostForm()` fonksiyonunu çağırmak ve template'e iletmek gerekir. *view* kısmına geri döneceğiz, ancak şimdilik form için bir template oluşturalım. ## Template Öncelikle `blog/templates/blog` dizininde `post_edit.html` isimli bir dosya oluşturmalıyız. Bir formu çalışır hale getirmek için birkaç şeye ihtiyacımız var: -* form'u görüntülemeliyiz. Bunu basitçe bu şekilde yapabiliriz: `{% raw %}{{ form.as_p }}{% endraw %}`. -* yukarıdaki örnek satır HTML form etiketi içine alınmalı: `...` -* bir `Kaydet` butonuna ihtiyacımız var. Bunu bir HTML butonu ile yapıyoruz: `` -* son olarak, hemen `
` etiketinden sonra `{% raw %}{% csrf_token %}{% endraw %}` satırını eklememiz lazım. Formlarımızın güvenliğini sağladığı için bu çok önemlidir! Bunu koymayı unutup formu kaydedersek Django hata verecektir: +* Formu göstermek zorundayız. Örneğin bunu şu şekilde yapabiliriz {% raw %}`{{ form.as_p }}`{% endraw %}. +* Yukarıdaki örnek satır HTML form etiketi içine alınmalı: `...
`. +* Bir `Kaydet` butonuna ihtiyacımız var. Bunu Bir HTML butonu ile yapıyoruz: ``. +* Ve son olarak, açılıştan hemen sonra `
` etiketini eklememiz gerekiyor {% raw %}`{% csrf_token %}`{% endraw %}. Formlarımızın güvenliğini sağladığı için bu çok önemlidir! Eğer bu kısmı unutursak, formu kaydetmeye çalıştığımızda Django şikayet edecektir: -![CSFR Korumalı sayfa][1] +![CSFR Korumalı sayfa](images/csrf2.png) - [1]: images/csrf2.png +Tamam, hadi `post_edit.html` deki HTML'e bakalım: -Peki, şimdi de `post_edit.html` in içindeki HTML kodunun nasıl görünmesi gerektiğine bakalım: +{% filename %}blog/templates/blog/post_edit.html{% endfilename %} ```html {% extends 'blog/base.html' %} {% block content %} -

Yeni gönderi

+

Yeni post

{% csrf_token %} {{ form.as_p }}
{% endblock %} -``` +``` Yenileme zamanı! Hey! Formun görüntülendi! -![Yeni form][2] +![Yeni form](images/new_form2.png) - [2]: images/new_form2.png +Ama, bekle bir dakika! `title` ve `text` alanlarına bir şey yazdığımızda ve kaydetmeye çalıştığımızda, ne olacak? -Ama, bir dakika! `baslik` ve `yazi` alanlarına bir şey yazıp kaydettiğimizde ne olacak? +Hiçbir şey! Bir kere daha aynı sayfadayız, metnimiz gitmiş ve yeni gönderi de eklenmemiş. Peki neyi yanlış yaptık? -Hiçbir şey! Yine aynı sayfaya döndük ve bütün yazdıklarımız kayboldu... ve yeni bir gönderi de eklenmemiş. Yanlış giden ne? - -Yanıt: hiçbir şey. Sadece *view*'ımızda biraz daha iş yapmamız gerekiyor. +Yanıt: hiçbir şeyi. Sadece *view*'ımızda biraz daha iş yapmamız gerekiyor. ## Formu kaydetme -Tekrar `blog/views.py` dosyasını açalım. Şuan `post_new` view'ı içinde sadece bunlar var: +Bir kez daha `blog/views.py`'yi açalım. Hali hazırda `post_new` view'ının tamamı aşağıdaki gibi olmalı: + +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) -``` +``` + +Formu gönderdiğimizde, aynı view'a yönlendirileceğiz, bu sefer `request` içinde daha fazla bilgi olacak, özellikle `request.POST` içinde (isimlendirmenin blog gönderisiyle bir bağlantısı yoktur; daha fazla veri göndermemizle ilgilidir). HTML dosyasında `
` tanımımızdaki `method="POST"` değişkenini hatırlıyor musunuz ? Formdan gelen tüm alanlar şimdi `request.POST`'un içerisinde. `POST`'un ismini değiştirmememiz lazım (`method` için geçerli diğer değer sadece `GET`'dir, ama şimdi ikisi arasındaki farkın ne olduğunu anlatacak kadar vaktimiz yok). -Formu kaydettiğimizde tekrar aynı view'a yönlendirileceğiz, ama bu sefer `request` nesnesinde, daha doğrusu `request.POST` (isimlendirmesinin, bizim blog uygulamasının "post" modeli ile alakası yok, gerçekte veri gönderdiğimiz (İngilizcede "post" işlemi) için isimlendirme bu şekilde) içerisinde, daha fazla verimiz olacak. HTML dosyasında `` tanımımızdaki `method="POST"` değişkenini hatırlıyor musun? Formdan gelen tüm alanlar şimdi `request.POST`'un içerisinde. `POST`'un ismini değiştirmememiz lazım (`method` için geçerli diğer değer sadece `GET`'dir, ama şimdi ikisi arasındaki farkın ne olduğunu anlatacak kadar vaktimiz yok). +*view* içinde ele almamız gereken iki farklı durum var: ilki, sayfaya ilk kez eriştiğimizde boş bir form döndürmek isteğimiz durum, ikincisi ise *view*'e forma girdiğimiz form verisiyle geri döndüğümüz durum. Yani bir koşul eklememiz gerekiyor (bunun için `if` kullanacağız): -Oluşturduğumuz *view*'da iki ayrı durumu halletmemiz gerek. Birincisi: sayfaya ilk eriştiğimiz ve boş bir form istediğimiz zaman. İkincisi: henüz yazdığımız tüm form verileriyle *view*'a geri döndüğümüz zaman. Yani bir koşul eklememiz gerekiyor (bunun için `if` kullanacağız). +{% filename %}blog/views.py{% endfilename %} ```python if request.method == "POST": [...] else: form = PostForm() -``` +``` -Şimdi boşluğu `[...]` doldurma zamanı geldi. `method`, `POST` ise o zaman `PostForm`u verilerle oluşturmamız lazım, değil mi? Bunu yapmak için: +Boşlukları doldurma zamanı `[...]`. Eğer `method` `POST` ise `PostForm`'u forma girilen veri ile oluşturmalıyız, değil mi? Bunu şu şekilde yapacağız: -``` python +{% filename %}blog/views.py{% endfilename %} + +```python form = PostForm(request.POST) ``` -Çok kolay! Şimdi de formu (yani tüm gerekli alanların doldurulduğu ve hatalı değerlerin kaydedilmeyeceğini) kontrol etmemiz lazım. Bunu da `form.is_valid()` ile yapıyoruz. +Bir sonraki işimiz formun doğru olup olmadığını kontrol etmek (tüm gerekli alanlar ayarlanmış ve yanlış değer verilmediyse). Bunu şu şekilde yaparız `form.is_valid()`. Formun doğruluğunu kontrol ediyoruz ve doğru ise kaydedebiliriz! +{% filename %}blog/views.py{% endfilename %} + ```python if form.is_valid(): post = form.save(commit=False) - post.yazar = request.user - post.yayinlanma_tarihi = timezone.now() + post.author = request.user + post.published_date = timezone.now() post.save() -``` +``` -Temel olarak, burada iki şey yaptık: formu `form.save` ile kaydettik ve bir yazar ekledik (`PostForm`'da bir `yazar` tanımlı olmadığı ve bu zorunlu bir alan olduğu için!). `commit=False`, `Post` modelini henüz kaydetmek istemediğimizi belirtir - ilk önce yazarı eklemek istiyoruz. Genellikle `form.save()`, `commit=False` olmadan kullanacaksınız, ama bu durumda, bunu kullanmamız gerekiyor. `post.save()` değişiklikleri (yazarı ekleme) koruyacaktır ve yeni bir blog gönderisi oluşturulur! +Temel olarak, burada iki şey yaptık: formu `form.save` ile kaydettik ve bir author (yazar) ekledik (`PostForm`'da bir `author` tanımlı olmadığı ve bu zorunlu bir alan olduğu için). `commit=False` `Post` modelini henüzkaydetmek istemiyoruz demektir - öncelikle yazarı eklemeliyiz. Çoğu zaman `form.save()`'i `commit=False` olmadan kullanacağız, fakat bu durumda bu parametre ile kullanmalıyız. `post.save()` değişiklikleri saklar (author ekleyerek) ve yeni blog yazısı oluşturulur! -Hemen `post_detail` sayfasına gidip yeni yaratmış olduğumuz blog postunu görsek harika olur, degil mi? Bunu yapabilmek için önemli bir şey daha lazım: +Son olarak hızlı bir şekilde yeni oluşturulmuş blog gönderimiz için `post_detail` sayfasına gidebilirsek harika olurdu değil mi? Bunu yapmak için bir tane daha import yapmamız gerekli: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import redirect -``` +``` -Bunu dosyanın en başına ekleyelim. Şimdi yeni yarattığımız blog postu için `post_detail` sayfasına gidebiliriz. +Bunu dosyanın en başına ekleyelim. Şimdi yeni yarattığımız blog postu için "`post_detail` sayfasına git" diyebiliriz: + +{% filename %}blog/views.py{% endfilename %} ```python - return redirect('blog.views.post_detail', pk=post.pk) +return redirect('post_detail', pk=post.pk) ``` -`blog.views.post_detail` gitmek istediğimiz görünümün ismidir. Unutmayalım ki bu *view* için bir `pk` değişkeni lazım. Bu değeri görünümlere aktarmak için `pk=post.pk` yazarız. Burada `post` yeni yarattığımız blog postudur! +`post_detail`, gitmek istediğimiz view'ın adı. Unutmayalım ki bu *view* için bir `pk` değişkeni lazım. Bu değeri viewlere aktarmak için `pk=post.pk` yazarız. Burada `post` yeni yarattığımız blog postudur! + +Çok şey söyledik ama artık *view*'ı tümüyle bir görmek isteriz, değil mi? -Çok şey söyledik ama herhalde *view* u tümüyle bir görmek isteriz artık, değil mi? +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): @@ -225,78 +250,82 @@ def post_new(request): form = PostForm(request.POST) if form.is_valid(): post = form.save(commit=False) - post.yazar = request.user - post.yayinlanma_tarihi = timezone.now() + post.author = request.user + post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm() - return render(request, 'blog/post_edit.html', {'form': form})yazar - + return render(request, 'blog/post_edit.html', {'form': form}) +``` -Bakalım çalışacak mı? http://127.0.0.1:8000/post/new/ sayfasına gidip bir `baslik` ve `yazi` ekleyelim, sonra da kaydedelim... ve işte! Yeni blog postu eklenmiş ve `post_detail` sayfasına yönlendirildik! +Bakalım çalışacak mı? http://127.0.0.1:8000/post/new/ sayfasına gidelim, bir `title` ve `text` ekleyelim, kaydedelim... ve işte oldu! Yeni blog postu eklendi ve `post_detail` sayfasına yönlendirildik! -Postu kaydetmeden önce yayin tarihine değer atandığını fark etmiş olabilrsin. Daha sonra *yayınla butonu* nu **Django Girls Tutorial: Ek konular** da anlatacağız. +Postu kaydetmeden önce publish date'e değer atandığını fark etmiş olabilirsin. Daha sonra *publish button*'nı **Django Girls Tutorial: Ek konular**'da anlatacağız. Süper! -## Form doğrulama - -Şimdi de Django formlarının ne kadar havalı olduğunu görelim. Bir blog postunun `baslik` ve `yazi` alanları olmalı. `Post` modelimizde bu alanlar mecburi değil demedik ( `yayinlanma_tarihi` demiş olduğumuz gibi), dolayısı ile Django bu alanlara değer atanması gerektiğini varsayar. +> Yakın zamanda Django'nun admin arayüzünü kullandığımız için, sistem hala giriş yaptığımızı düşünüyor. Bazı durumlar bizim oturumdan çıkmamıza neden olabilir (web tarayıcısını kapatmak, veritabanını tekrar başlatmak, vb). Eğer oturum açık olmadığı için post yaratmada hata alırsak admin sayfası olan http://127.0.0.1:8000/admin adresine gidip tekrar oturum açmalıyız. Bu sorunu geçici olarak düzeltecektir. Kalıcı çözüm, ana tutorialdan sonra **Ödev: Web sitene güvenlik ekleme!** bölümünde anlatılacak. -`baslik` veya `yazi` olmadan formu kaydetmeye çalışın. Ne olacak, tahmin et! +![Oturum hatası](images/post_create_error.png) -![Form doğrulama][3] - - [3]: images/form_validation2.png +## Form doğrulama -Django tüm alanlara doğru tür değerlerin atandığını bizim için kontrol ediyor. Ne güzel, değil mi? +Şimdi de Django formlarının ne kadar havalı olduğunu görelim. Bir blog postunun `title` ve `text` alanları olmalı. `Post` modelimizde bu alanların gerekli olmadığını söylemedik (`published_date`'te yaptığımızın tersine), bu yüzden Django varsayılan olarak bu alanın dolu olmasını bekliyor. -> Yakın zamanda Django'nun admin arayüzünü kullandığımız için, sistem bizi hala oturumda varsayıyor. Bazı durumlar bizim oturumdan çıkmamıza neden olabilir (web tarayıcısını kapatmak, veritabanını tekrar başlatmak, vb). Eğer oturumda olan kullanıcı olmadığı için post yaratmada hata alırsak admin sayfası olan http://127.0.0.1:8000/admin gidip tekrar bir oturum açmalıyız. Bu durumu geçici de olsa da halleder. Kalıcı çözüm, ana tutorialdan sonra **Ödev: Web sitene güvenlik ekleme!** bölümünde anlatılacak. +Formu `title` ve `text` olmadan kaydetmeye çalışalım. Ne olacak, tahmin edin! -![Oturum hatası][4] +![Form doğrulama](images/form_validation2.png) - [4]: images/post_create_error.png +Django tüm alanların doğruluğunu bizim için kontrol ediyor. Ne güzel, değil mi? ## Form düzenleme -Artık yeni bir form oluşturmayı biliyoruz. Peki, mevcut bir formu güncellemek için ne yapmalı? Demin yaptığımıza çok benziyor. Şimdi, hızlıca bir kaç şey yaratalım (anlamadığın bir şey olduğu zaman, mentöre veya önceki bölümlere danışabilirsin, çünkü bu adımları daha önce yaptık). +Artık yeni bir form oluşturmayı biliyoruz. Peki, mevcut bir formu güncellemek için ne yapmalı? Bu az önce yaptığımız şeyle çok benzer. Hızlıca bazı önemli şeyleri oluşturalım. (Eğer birşeyi anlamazsan, mentörüne sormalısın veya önceki bölümlere bakmalısın, çünkü bütün bu adımları daha önce bitirdik.) -`blog/templates/blog/post_detail.html` dosyasını açıp şu satırı ekleyelim: +`blog/templates/blog/post_detail.html` dosyasını açalım ve şu satırı ekleyelim -```python +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + +```html -``` +``` + +böylece şablon şöyle görünecektir: -ki template buna benzesin: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html {% extends 'blog/base.html' %} {% block content %}
- {% if post.yayinlanma_tarihi %} + {% if post.published_date %}
- {{ post.yayinlanma_tarihi }} + {{ post.published_date }}
{% endif %} -

{{ post.baslik }}

-

{{ post.yazi|linebreaks }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

{% endblock %} -``` +``` + +`blog/urls.py` dosyasını açıp şu satırı ekleyelim: -`blog/urls.py` dosyasına şu satırı ekleyelim: +{% 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'), +``` -Daha önce kullandığımız `blog/templates/blog/post_edit.html` template'i tekrar kullanacağız, tek eksik bir *view*. +Daha önce kullandığımız `blog/templates/blog/post_edit.html` template'ini tekrar kullanacağız, geriye bir tek *view* kalıyor. Şimdi `blog/views.py` dosyasını açıp en sonuna şu satırı ekleyelim: +{% filename %}blog/views.py{% endfilename %} + ```python def post_edit(request, pk): post = get_object_or_404(Post, pk=pk) @@ -304,96 +333,117 @@ def post_edit(request, pk): form = PostForm(request.POST, instance=post) if form.is_valid(): post = form.save(commit=False) - post.yazar = request.user - post.yayinlanma_tarihi = timezone.now() + post.author = request.user + post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm(instance=post) return render(request, 'blog/post_edit.html', {'form': form}) -``` +``` + +Bu nerdeyse bizim `post_new` view'inin aynısı, değil mi? Ama, tam da değil. Özellikle url'lerden ekstra bir `pk` parametresi geçiriyoruz. Sonra,`get_object_or_404(Post, pk=pk)` ile düzenlemek istediğimiz `Post` modelini alıyoruz ve daha sonra bir form oluşturduğumuzda bu yazı objesini `instance` olarak geçiriyoruz, aynı şekilde formu kaydettiğimizde de… -Bu nerdeyse bizim `post_new` view'e benziyor, değil mi? Ama, tam da değil. İlk önce: Url'den ekstra bir `pk` parameteresi yolladık. Sonra: güncellemek istediğimiz `Post` modelini `get_object_or_404(Post, pk=pk)` ile alıp, bir form yarattığımızda bu postu bir `örnek kopya` (instance) olarak hem formu kaydettiğmizde yolluyoruz: +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(request.POST, instance=post) -``` +``` -hem de güncellemek istediğimiz postu görmek için form açtığımız zaman yolluyoruz: +…ve düzenlemek için bu post ile ilgili bir form açtığımızda: + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(instance=post) ``` -Haydi, deneyelim. Bakalım çalışacak mı? `post_detail` sayfasına gidelim. Sağ üst köşede bir edit (güncelleme) butonu olmalı: - -![Düzenle butonu][5] +Tamam, çalışıp çalışmadığını test edelim! `post_detail` sayfasına gidelim. Sağ üst köşede bir düzenleme butonu olmalı: - [5]: images/edit_button2.png +![Düzenle butonu](images/edit_button2.png) Butona tıklarsak blog postunu görmemiz lazım: -![Formu düzenle][6] +![Form düzenleme](images/edit_form2.png) - [6]: images/edit_form2.png +İstediğimiz gibi title ve text'i değiştirebilir ve sonra da kaydedebiliriz! -İstediğimiz gibi başlık ve yazıyı değiştirebilir ve sonra da kaydedebilriz! +Tebrikler! Uygulamamız gittikçe tamamlanıyor! -Tebrikler! Uygulaman gittikçe tamamlanıyor! - -Django formları hakkında daha fazla bilgi bulmak için https://docs.djangoproject.com/en/1.10/topics/forms/ adresindeki dokümanlara bakabilirsin +Eğer Django formlarıyla ilgili daha çok bilgiye ihtiyacın varsa, dökümanı okumalısın: https://docs.djangoproject.com/en/2.0/topics/forms/ ## Güvenlik -Bir bağlantıya (link) tıklayarak yeni bir blog oluşturabilmek harika! Ancak, şu haliyle siteye gelen herkes bir blog yaratıp kaydedebilir. Bu da istenen bir durum değil. Butonun sadece sana görünmesini sağlayalım. +Bir linke tıklayarak yeni bir blog oluşturabilmek harika! Ama şu anda sizin sitenizi ziyaret eden herkes yeni bir blog post yapabilecek ve bu muhtemelen isteyeceğiniz bir şey değil. Butonun sadece bize görünmesini sağlayalım. `blog/templates/blog/base.html` dosyasında yarattığımız `page-header` `div` ve anchor etiketlerini (tags) bulalım. Şuna benziyor olmalı: +{% filename %}blog/templates/blog/base.html{% endfilename %} + ```html -``` +``` + +Linkin sadece admin olarak giriş yapmış kullanıcılara gözükmesi için başka bir `{% if %}` etiketi ekleyeceğiz. Şu anda bu kişi sensin! `` etiketini şöyle değiştirelim: -Şimdi bir `{% if %}` etiketi daha ekleyeceğiz ki link sadece admin olarak oturum açmış kişilere görünsün. Şimdilik, bu kişi sadece sensin! `` etiketini şöyle değiştirelim: +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% if user.is_authenticated %} {% endif %} -``` - -Bu `{% if %}` linkin tarayıcıya ancak kullanıcı oturum açmış ise gönderilmesini sağlar. Bu yeni post yaratılmasını kesin olarak engellemese de iyi bir başlangıç. Güvenlik konusu ek derslerde daha çok ele alınacak. +``` -Oturum içi olduğumuz için, şimdi sayfayı yenilersek, farklı bir şey görmeyeceğiz. Sayfayı farklı bir tarayıcıda veya incognito bir pencerede yükleyelim. O zaman bu link görünmeyecek! +Bu `{% if %}` linkin sadece sayfayı görüntüleyen kullanıcı oturum açtıysa görüntülenmesini sağlayacak. Bu yeni post yaratılmasını kesin olarak engellemese de iyi bir başlangıç. Güvenlik konusu ek derslerde daha çok ele alınacak. -## Bir şey daha: deployment (yayına alma) zamanı! +Az evvel detay sayfamıza eklediğimiz düzenle ikonunu hatırladınız mı? Aynı değişikliği oraya da eklemek istiyoruz. Böylelikle başka insanlar var olan gönderileri düzenleyemeyecekler. -Bakalım PythonAnywhere'de calışacak mı? Tekrar yayına alalım! +`blog/templates/blog/post_detail.html` dosyasını açalım ve şu satırı ekleyelim: -* İlk önce kodumuzu commit edelim, sonra Github'a push edelim +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} +```html + ``` -$ git status -$ git add -A . -$ git status -$ git commit -m "Web sitesine güncelleme ve yaratma için view eklendi." -$ git push -``` -* Sonra bir [PythonAnywhere Bash konsol][7] una gidip: +Bu şekilde değiştirelim: - [7]: https://www.pythonanywhere.com/consoles/ +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} +```html +{% if user.is_authenticated %} + +{% endif %} ``` -$ cd ilk-blogum -$ source myvenv/bin/activate -(myvenv)$ git pull -[...] -(myvenv)$ python manage.py collectstatic -[...] -``` -* Nihayet, [Web tab][8] ına gidip **Reload** edelim. +Yüksek olasılıkla login yapmış olduğunuz için sayfayı yenilediğinizde farklı bir şey göremeyeceksiniz. Sayfayı farklı bir tarayıcı veya görünmez pencere ile yükleyelim (Windows Edge üzerinde "InPrivate" olarak adlandırılan), göreceksiniz ki bağlantı ve ikon artık görüntülenmiyor! + +## Son bir şey daha: deployment (yayına alma) zamanı! + +Bakalım PythonAnywhere'de de çalışacak mı? Tekrar yayına alalım! + +* İlk önce kodumuzu commit edelim, sonra Github'a push edelim: + +{% filename %}komut-satırı{% endfilename %} + + $ git status + $ git add --all . + $ git status + $ git commit -m "Sitede gönderi oluşturmak ve düzenlemek için view'ler eklendi." + $ git push + + +* Sonra bir [PythonAnywhere Bash konsol](https://www.pythonanywhere.com/consoles/) una gidip: + +{% filename %}komut-satırı{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Açı parantezleri olmadan ``'i gerçek PythonAnywhere kullanıcı isminizle değiştirmeyi unutmayın). - [8]: https://www.pythonanywhere.com/web_app_setup/ +* Son olarak, ["Web" page](https://www.pythonanywhere.com/web_app_setup/) bölümüne geçin (konsolun sağ üst tarafındaki menü düğmesini kullanın) ve **Yeniden yükle** tuşuna basın. Değişiklikleri görmek için https://yourname.pythonanywhere.com blogunuzu yenileyin. -O kadar! Tebrikler :) +İşte bu kadar! Tebrikler :) \ No newline at end of file diff --git a/tr/django_forms/images/csrf2.png b/tr/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/tr/django_forms/images/csrf2.png and b/tr/django_forms/images/csrf2.png differ diff --git a/tr/django_forms/images/drafts.png b/tr/django_forms/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/tr/django_forms/images/drafts.png and b/tr/django_forms/images/drafts.png differ diff --git a/tr/django_forms/images/edit_button2.png b/tr/django_forms/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/tr/django_forms/images/edit_button2.png and b/tr/django_forms/images/edit_button2.png differ diff --git a/tr/django_forms/images/edit_form2.png b/tr/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/tr/django_forms/images/edit_form2.png and b/tr/django_forms/images/edit_form2.png differ diff --git a/tr/django_forms/images/form_validation2.png b/tr/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/tr/django_forms/images/form_validation2.png and b/tr/django_forms/images/form_validation2.png differ diff --git a/tr/django_forms/images/new_form2.png b/tr/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/tr/django_forms/images/new_form2.png and b/tr/django_forms/images/new_form2.png differ diff --git a/tr/django_forms/images/post_create_error.png b/tr/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/tr/django_forms/images/post_create_error.png and b/tr/django_forms/images/post_create_error.png differ diff --git a/tr/django_installation/README.md b/tr/django_installation/README.md old mode 100755 new mode 100644 index b51a96fe065..957b9722f9c --- a/tr/django_installation/README.md +++ b/tr/django_installation/README.md @@ -1,5 +1,7 @@ # Django kurulumu -> **Not** Eğer kurulum adımlarını zaten yaptıysanız sonraki bölüme geçebilirsiniz! +> **Not** Eğer Chromebook kullanıyorsanız, bu bölümü atlayın ve [Chromebook Kurulumu](../chromebook_setup/README.md)'ndaki talimatları takip ettiğinizden emin olun. +> +> **Not** Eğer kurulum aşamalarını başarıyla tamamladıysanız, Django kurulumunu o esnada yapmışsınızdır - direkt olarak diğer aşamaya geçebilirsiniz! -{% include "/django_installation/instructions.md" %} +{% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/tr/django_installation/instructions.md b/tr/django_installation/instructions.md index 743b9a853e5..20429332b59 100644 --- a/tr/django_installation/instructions.md +++ b/tr/django_installation/instructions.md @@ -1,99 +1,150 @@ -> Bu bölümün bir kısmı Geek Girls Carrots tarafından hazırlanmış eğitimlere dayanılarak hazırlanmıştır (http://django.carrots.pl/). -> -> Bu bölümün bir parçası Creative Commons Attribution-ShareAlike 4.0 International License ile lisanslı [django-marcador tutorial](http://django-marcador.keimlink.de/)'a dayanılarak hazırlanmıştır. Django-marcador tutorial'ının hakları Markus Zapke-Gründemann'e aittir. +> Bu bölümün bir kısmı Geek Girls Carrots tarafından hazırlanmış eğitimlere dayanılarak hazırlanmıştır (https://github.com/ggcarrots/django-carrots). +> +> Bölümün bu kısmı [django-marcador tutorial](http://django-marcador.keimlink.de/) e dayandırılmış ve Creative Commons Attribution-ShareAlike 4.0 International License koruması altında lisansı alınmıştır. Django-marcador tutorial'ının hakları Markus Zapke-Gründemann'e aittir. -## Virtual environment (Sanal ortam) +## Sanal ortam (Virtual environment) Django'yu yüklemeden önce kod ortamınızı düzenli tutmak için son derece yararlı bir araç yükleyeceğiz. Bu adımı atlayabilirsiniz, fakat atlamamanızı tavsiye ederiz. En iyi olası kurulum ile başlamanız sizi gelecekteki bir sürü sorundan koruyacaktır! -Öyleyse bir **virtual environment**(diğer adıyla *virtualenv*) kuralım. Virtualenv Python/Django kurulumunuzu her proje için ayrı tutup izole eder. Bu, bir websitesine yapacağınız değişikliklerin diğer geliştirdiklerinize yansımayacağı anlamına gelir. Muazzam, değil mi? +Öyleyse bir **virtual environment** (diğer adıyla *virtualenv*) kuralım. Virtualenv Python/Django kurulumunuzu her proje için ayrı tutup izole eder. Bu, bir websitesine yapacağınız değişikliklerin diğer geliştirdiklerinize yansımayacağı anlamına gelir. Muazzam, değil mi? -Yapmanız gereken tek şey `virtualenv` oluşturmak için bir dizin bulmak; örneğin giriş dizininiz. Windows'da bu `C:\Users\isim` olabilir (`isim` kısmı kullanıcı adınız olacak şekilde). +Yapmanız gereken tek şey `virtualenv` oluşturmak için bir dizin bulmak; örneğin giriş dizininiz. Windows'ta şöyle görünebilir: `C:\Users\Name` (`Name` yerine kullanıcı adınız gelir). + +> **NOTE:** Windows'ta bu dizinin özel karakterler içermediğinden emin olun; eğer kullanıcı adınız özel karakterler içeriyorsa, farklı bir dizin kullanın. Örneğin: `C:\djangogirls`. Bu eğitim için giriş dizininizde yeni açtığımız `djangogirls` adlı bir klasör kullanacağız: -``` -mkdir djangogirls -cd djangogirls -``` +{% filename %}komut-satırı{% endfilename %} + + $ mkdir djangogirls + $ cd djangogirls + `myvenv` adında bir virtualenv oluşturacağız. Genel komut aşağıdaki şekilde olacak: -``` -python3 -m venv myvenv -``` +{% filename %}komut-satırı{% endfilename %} + + $ python3 -m venv myvenv + + + + +Yeni bir `virtualenv` yaratmak için, komut satırını açmanız ve `python -m venv myvenv`'u çalıştırmanız gerekir. Böyle görünecektir: -### Windows +{% filename %}komut-satırı{% endfilename %} -Yeni bir `virtualenv` oluşturmak için konsolu açıp (nasıl yapıldığını birkaç adım önce anlatmıştık - hatırlıyorsunuz değil mi?) `C:\Python34\python -m venv myvenv` komutunu çalıştırın. Şöyle görünmeli: + C:\Users\Name\djangogirls> python -m venv myvenv + -``` -C:\Users\isim\djangogirls> C:\Python34\python -m venv myvenv -``` +Burada `myvenv`, `virtualenv`'inizin ismidir. İstediğiniz herhangi bir ismi kullanabilirsiniz, ama küçük harfle yazılmasına ve boşluk, aksan karakterleri (örn: å) ve özel karakterleri kullanmamaya dikkat edin. Ayrıca ismi kısa tutmak işinize yarayacaktır zira bu ismi çokça kullanıyor olacaksınız! -`C:\Python34\python` dizini önceden Python'u kurduğunuz dizin ve `myvenv` ise `virtualenv`'inizin ismi olacaktır. İstediğiniz herhangi bir ismi kullanabilirsiniz, ama küçük harfle yazılmasına ve boşluk, aksan karakterleri (örn: å) ve özel karakterleri kullanmamaya dikkat edin. Ayrıca ismi kısa tutmak iyi bir fikir olabilir, zira bu ismi çok kullanıyor olacaksınız! + -### GNU/Linux ve OS X + -Linux ve OS X işletim sistemlerinde `virtualenv` oluşturmak için `python3 -m venv myvenv` komutunu çalıştırmak yeter. Komut şu şekilde görünecektir: +Hem Linux hem de macOS 'teyken `python3 -m venv myvenv` komutuyla bir `virtualenv` oluşturabiliriz. Şu şekilde gözükecektir: -``` -~/djangogirls$ python3 -m venv myvenv -``` +{% filename %}komut-satırı{% endfilename %} -Burada `myvenv` sizin `virtualenv`'inizin ismi. Dilerseniz istediğiniz herhangi bir isim kullanabilirsiniz, ama büyük harf ve boşluk kullanmamaya dikkat edin. İsmi çok fazla kullanacağınız için kısa tutmak da işinize yarayacaktır. + $ python3 -m venv myvenv + -> **NOT:** Ubuntu 14.04 işletim sisteminde sanal ortam yaratmaya çalışırken şu hatayla karşılaşabilirsiniz: -> +Burada `myvenv` sizin `virtualenv`'inizin ismi. Dilerseniz istediğiniz herhangi bir isim kullanabilirsiniz, ama büyük harf ve boşluk kullanmamaya dikkat edin. Ayrıca ismi kısa tutmak işinize yarayacaktır zira bu ismi çokça kullanıyor olacaksınız! + +> **NOT:** Debian/Ubuntu'nun bazı sürümlerinde aşağıdaki hatayı alabilirsiniz: +> +> {% filename %}komut-satırı{% endfilename %} +> +> Ensurepip kullanılamadığından sanal ortam başarıyla oluşturulamadı. Debian/Ubuntu sistemlerinde, aşağıdaki komutu kullanarak python3-venv paketini yüklemeniz gerekir. +> apt install python3-venv +> sudo komutu ile kullanmanız gerekebilir. python3-venv paketini indirdikten sonra, virtualenv'inizi yeniden oluşturun. +> +> +> Bu durumda, yukarıdaki yönergeleri izleyin ve `python3-venv` paketini yükleyin: +> +> $ sudo apt install python3-venv +> +> +> Bu şekilde Debian/Ubuntu'nun bazı sürümlerinde sanal ortamı başlatırken o anda aşağıdaki hatayı alabilirsiniz: +> +> {% filename %}komut-satırı{% endfilename %} +> > Error: Command '['/home/zeynep/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 > -> +> > Bu sorunu çözmek için `virtualenv` komutunu kullanabilirsiniz. -> -> ~/djangogirls$ sudo apt-get install python-virtualenv -> ~/djangogirls$ virtualenv --python=python3.4 myvenv +> +> {% filename %}komut-satırı{% endfilename %} +> +> $ sudo apt install python-virtualenv +> $ virtualenv --python=python3.6 myvenv +> +> +> **NOT:** Eğer aşağıdaki gibi bir hata alırsanız +> +> {% filename %}komut-satırı{% endfilename %} +> +> E: Unable to locate package python3-venv > +> +> o zaman yerine bunu çalıştırın: +> +> {% filename %}komut-satırı{% endfilename %} +> +> sudo apt install python3.6-venv +> + + ## Virtualenv ile çalışmak Yukarıdaki komutlar `myvenv` (veya seçtiğiniz isimde) bir klasör oluşturacaktır. Bu klasörde birçok dosya ve klasör bulunur. -#### Windows + Şu komutu çalıştırarak virtualenv'i başlatın: -``` +{% filename %}komut-satırı{% endfilename %} + C:\Users\Name\djangogirls> myvenv\Scripts\activate -``` + + +> **NOT:** Windows 10'da , Windows PowerShell tarafından `bu senaryoların uygulanması bu sistemde devre dışıdır` diyen bir hata alabilirsiniz. Bu durumda, başka bir Windows PowerShell'i, "Yönetici Olarak Çalıştır" seçeneğiyle açın. Bundan sonra sanal ortamınızı başlatmadan önce aşağıdaki komutları yazmayı deneyin: +> +> {% filename %}komut-satırı{% 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 +> + + -#### GNU/Linux ve OS X + Şu komutu çalıştırarak virtualenv'i başlatın: -``` - ~/djangogirls$ source myvenv/bin/activate -``` +{% filename %}komut-satırı{% endfilename %} + + $ source myvenv/bin/activate + `myvenv` yerine kendi seçtiğiniz `virtualenv` ismini koymayı unutmayın! > **NOT:** bazen `source` komutu kullanılamıyor durumda olabilir. Böyle durumlarda onun yerine aşağıdaki komutu da kullanabilirsiniz: -> -> ~/djangogirls$ . myvenv/bin/activate +> +> {% filename %}komut-satırı{% endfilename %} +> +> $ . myvenv/bin/activate > -Konsolunuzda şuna benzer bir şey gördüğünüzde `virtualenv`'in başladığını anlayabilirsiniz: - -``` -(myvenv) C:\Users\Name\djangogirls> -``` - -ya da: - -``` -(myvenv) ~/djangogirls$ -``` + -En başta beliren `(myvenv)`'e dikkat edin! +Konsolunuzda komut isteminizin başında `(myvenv)` gördüğünüzde `virtualenv`'in çalıştığını anlayabilirsiniz. Virtualenv ile çalışırken `python` otomatik olarak doğru sürümü çalıştıracaktır. Yani `python3` yerine `python` yazabilirsiniz. @@ -101,22 +152,67 @@ Artık bütün gerekli uygulamaları bir araya getirdiğimize göre sonunda Djan ## Django'yu yüklemek -`virtualenv`'i başlattığınız için artık Django'yu `pip` kullanarak yükleyebiliriz. Konsola `pip install django==1.10` komutunu yazın. (İki tane eşittir işareti kullandık: `==`). +`virtualenv`'i çalıştırdığınıza göre, şimdi Django'yu yükleyebilirsiniz. -``` -(myvenv) ~$ pip install django==1.10 -Downloading/unpacking django==1.10 -Installing collected packages: django -Successfully installed django -Cleaning up... -``` +Bunu yapmadan önce, bilgisayarımızın, Django yüklemek için kullanacağımız yazılım olan `pip`'in en son versiyonuna sahip olduğundan emin olmalıyız: -Windows'ta +{% filename %}komut-satırı{% endfilename %} -> Eğer Windows işletim sisteminde pip komutunu kullanırken bir hatayla karşılaştıysanız proje adresinizin boşluk, aksan veya özel karakter içerip içermediğini (`C:\Users\User Name\djangogirls` gibi) kontrol edin. Eğer durum buysa projenizi boşluk veya özel karakter içermeyen bir adrese taşıyın; önerimiz `C:\djangogirls` olacaktır. Taşıma işleminden sonra yukarıdaki komutu tekrar deneyin. + (myvenv) ~$ python3 -m pip install --upgrade pip + -Linux'ta +### Requirements ile paketleri yüklemek + +Bir requirements dosyası `pip install` ile yüklenmesi gereken paketlerin listesini tutar: + +Önce `djangogirls /` klasörü içinde `requirements.txt` dosyası oluşturalım: + + djangogirls + └───requirements.txt + + +`djangogirls/requirements.txt` dosyanıza şu kodu eklemelisiniz: + +{% filename %}djangogirls/requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +Simdi, Django kurmak için `pip install -r requirements.txt` komutunu çalıstırın. + +{% filename %}komut-satırı{% endfilename %} + + (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.1MB) + Installing collected packages: Django + Successfully installed Django-{{ book.django_version }} + + + + +> Eğer Windows'ta pip komutunu kullanırken bir hata aldıysanız, lütfen projenizin isminin özel karakter içerip içermediğini kontrol edin (örneğin `C:\Users\User Name\djangogirls`). Eğer böyleyse, lütfen boşluksuz veya özel karaktersiz bir yer kullanmayı düşünün (öneri: `C:\djangogirls`). Yeni dizinde yeni bir virtualenv oluşturun, arkasından eskisini silin ve yukarıdaki komutu yeniden deneyin. (virtualenv dizinini taşımak işe yaramayacaktır çünkü virtualenv mutlak yollar kullanır.) + + + + + +> Django kurmaya çalışırken komut satırınız donabilir. Bu durumda, yukarıdaki komut yerine şu komutu kullanın: +> +> {% filename %}komut-satırı{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> + + + + > Eğer Ubuntu 12.04 işletim sisteminde pip komutunu çağırırken bir hata iletisiyle karşılaştıysanız `python -m pip install -U --force-reinstall pip` komutunu çalıştırarak pip kurulumunu onarmayı deneyin. -İşte bu kadar! Sonunda Django uygulamanızı oluşturmaya hazırsınız! + + +İşte bu kadar! Sonunda Django uygulamanızı oluşturmaya hazırsınız! \ No newline at end of file diff --git a/tr/django_models/README.md b/tr/django_models/README.md old mode 100755 new mode 100644 index 19589d08a34..46fc539514b --- a/tr/django_models/README.md +++ b/tr/django_models/README.md @@ -1,54 +1,53 @@ # Django modelleri -Şimdi blogumuzdaki bütün yazıları kaydedebileceğimiz bir şey oluşturmak istiyoruz. Ama bunu yapabilmek için önce `nesneler` denen şeylerden bahsetmemiz gerekiyor. +Şimdi blogumuzdaki bütün yazıları kaydedebileceğimiz bir şey oluşturmak istiyoruz. Ama bunu yapabilmek için önce `nesne` dediğimiz şeylerden (objects) bahsetmemiz gerekiyor. -## Nesneler +## Nesneler (Objects) -Programlamada `Nesneye yönelik programlama` denen bir kavram bulunuyor. Buradaki ana fikir her şeyi sıkıcı bir düzende programlama komutları ile yazmak yerine şeyleri modelleyip birbirleri ile nasıl etkileşime geçeceklerini tanımlayabileceğimiz. +Programlamada `nesneye yönelik programlama` denen bir kavram bulunuyor. Buradaki ana fikir her şeyi sıkıcı program komutları dizisi şeklinde yazmak yerine, konseptleri modelleyip birbirleri ile nasıl etkileşime geçeceklerini tanımlamak. -Peki bir nesne nedir? Özelliklerin ve hareketlerin bir bütünüdür. Kulağa garip geliyor olabilir ama bir örnekle açıklayacağız. +Peki bir nesne nedir? Nesne bir özellikler ve hareketler bütünüdür. Kulağa garip geliyor olabilir, bir örnekle açıklayalım. -Eğer bir kediyi modellemek istiyorsak `Kedi` nesnesini oluştururuz ve bu nesne şöyle özelliklere sahip olur:`renk`, `yas`, `ruh_hali` (örneğin; iyi, kötü, uykulu ;)) ve `sahibi` (ki bu da bir `İnsan` nesnesi olur ya da eğer sokak kedisi ise bu özellik boş olabilir). +Eğer bir kediyi modellemek istiyorsak, `Kedi` nesnesini oluştururuz ve bu nesne şöyle özelliklere sahip olur: `renk`, `yas`, `ruh_hali` (örneğin; iyi, kötü, uykulu ;)) ve `sahibi` (ki bu da bir `insan` nesnesi olur ya da eğer sokak kedisi ise bu özellik boş olabilir). -`Kedi` bazı hareketlere sahiptir: `miyavla`, `tirmala` ya da `beslen` (bu durumda kediye biraz `KediMamasi` vermemiz gerekir ki o da kendine ait özellikleri olan başka bir nesne olur. Özelliklere örnek olarak `tat` verilebilir). +Ayrıca `Kedi` bazı hareketlere sahiptir: `miyavla`, `tirmala` ya da `beslen` (bu durumda kediye biraz `KediMamasi` vermemiz gerekir ki o da kendine ait özellikleri olan başka bir nesne olarak tanımlanabilir, bu durumda onun özellikleri arasında da `tat` yer alabilir). -``` -Kedi --------- -renk -yas -ruh_hali -sahibi -miyavla() -tirmala() -beslen(kedi_mamasi) + Kedi + -------- + renk + yas + ruh_hali + sahibi + miyavla() + tirmala() + beslen(kedi_mamasi) + -KediMamasi --------- -tat -``` + KediMamasi + -------- + tat + -Yani aslında ana fikir, gerçek nesneleri kod içinde özellikleriyle (`nesne özellikleri`) ve hareketleriyle (`metodlar`) tanımlamak.). +Yani aslında ana fikir, gerçek nesneleri kod içinde özellikleri (`nesne özellikleri`) ve hareketleri (`metodlar`) ile tanımlamak. -Öyleyse blog gönderilerini nasıl modelleyeceğiz? Bir blog tasarlamak istiyoruz degil mi? +Öyleyse blog gönderilerini nasıl modelleyeceğiz? Bir blog tasarlamak istiyoruz, degil mi? -Cevaplamamız gereken soru: Blog gönderisi nedir? Özellikleri ne olmalıdır? +Cevaplamamız gereken soru: Bir blog gönderisi nedir? Özellikleri ne olmalıdır? -Tabii ki blog gönderimizin içeriği için yazı ve bir de başlık lazım, değil mi? Kimin yazdığını da bilsek iyi olur - dolayısı ile bir yazara da ihtiyacımız var. Son olarak, gönderinin ne zaman yaratıldığını ve yayınlandığını bilmek isteriz. +Tabii ki blog gönderimizin içeriği için yazı ve bir de başlık lazım, değil mi? Kimin yazdığını da bilsek iyi olur - dolayısı ile bir de yazara ihtiyacımız var. Son olarak, gönderinin ne zaman yaratıldığını ve yayınlandığını da bilmek isteyebiliriz. -``` -Post ------- -baslik -yazi -yazar -yaratilma_tarihi -yayinlanma_tarihi -``` + Post + -------- + title + text + author + created_date + published_date + Bir blog gönderisi ile ne tür şeyler yapılabilir? Gönderiyi yayınlayan bir `method` olması güzel olurdu, değil mi? -Bu yüzden `yayinla` metoduna ihtiyacımız olacak. +Bu yüzden `publish` metoduna ihtiyacımız olacak. Ne elde etmek istediğimizi bildiğimize göre, haydi bunu Django'da modellemeye başlayalım! @@ -56,42 +55,52 @@ Ne elde etmek istediğimizi bildiğimize göre, haydi bunu Django'da modellemeye Nesnenin ne olduğunu bildiğimize göre, blog gönderimiz için bir Django modeli oluşturabiliriz. -Django'da bir model özel bir çeşit nesnedir - `veritabanı`'na kaydedilir. Veritabanı veri topluluğuna verilen isimdir. Burası, kullanıcıları, blog gönderileri gibi bilgileri saklayacağımız yerdir. Verilerimizi depolamak için SQLite veritabanını kullanacağız. Bu varsayılan Django veritabanı adaptörüdür - şimdilik bizim için yeterli olacaktır. +Django'da modeller özel bir çeşit nesnedir - `veritabanı`'na kaydedilir. Veritabanı (database) belirli bir veri topluluğuna verdiğimiz isim. Veritabanında, kullanıcılar, blog gönderileri, vs. ile ilgili bilgileri saklarız. Verilerimizi depolamak için SQLite veritabanını kullanacağız. Bu varsayılan Django veritabanı adaptörü - şimdilik bizim için yeterli olacaktır. -Veritabanındaki bir modeli sütunları (alan adı) ve satırları (veri) olan bir hesap çizelgesi olarak düşünebiliriz. +Veritabanındaki bir modeli, sütunları (alan adı) ve satırları (veri) olan bir hesap çizelgesi olarak düşünebilirsiniz. ### Uygulama oluşturma -Her şeyi derli toplu tutmak için, projemizin içinde ayrı bir uygulama oluşturacağız. Her şeyin en başından düzenli olması çok iyidir. Bir uygulama oluşturmak için aşağıdaki komutu konsolda çalıştırmamız gerekiyor ( `djangogirls` dizininden `manage.py` dosyasının bulunduğu yer): +Her şeyi derli toplu tutmak için, projemizin içinde ayrı bir uygulama oluşturacağız. Her şeyin en başından düzenli olması çok iyidir. Bir uygulama oluşturmak için aşağıdaki komutu konsolda çalıştırmamız gerekiyor (`djangogirls` dizininden `manage.py` dosyasının bulunduğu yer): -``` -(myvenv) ~/djangogirls$ python manage.py startapp blog -``` +{% filename %}macOS ve Linux:{% endfilename %} -İçinde birkaç dosya olan yeni bir `blog` klasörü fark edeceksiniz. Projemizdeki klasörler ve dosyalar şöyle olmalı: + (myvenv) ~/djangogirls$ python manage.py startapp blog + -``` -djangogirls -├── mysite -| __init__.py -| settings.py -| urls.py -| wsgi.py -├── manage.py -└── blog -├── migrations -| __init__.py -├── __init__.py -├── admin.py -├── models.py -├── tests.py -└── views.py -``` +{% filename %}Windows:{% endfilename %} -Uygulamamızı oluşturduktan sonra, Django'ya bunu kullanmasını da söylememiz lazım. Bunu `mysite/settings.py` dosyası ile yapıyoruz. `INSTALLED_APPS` dosyasını bulup `'blog'` u tam `)` karakterinin üzerine yazmamız lazım. Sonunda dosya şuna benzemelidir: + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + -``` -INSTALLED_APPS = ( +Yeni bir `blog` dizininin oluşturulduğunu ve bir dizi dosya içerdiğini fark edeceksiniz. Projemizdeki dizinler ve dosyalar şu sekilde görünüyor olmalı: + + djangogirls + ├── blog + │   ├── __init__.py + │   ├── admin.py + │   ├── apps.py + │   ├── migrations + │   │   └── __init__.py + │   ├── models.py + │   ├── tests.py + │   └── views.py + ├── db.sqlite3 + ├── manage.py + ├── mysite + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + └── requirements.txt + + +Uygulamamızı oluşturduktan sonra, Django'ya bunu kullanmasını söylememiz lazım. Bunu `mysite/settings.py` dosyasından yapacağız -- kod editörümüzde açalım. `INSTALLED_APPS`'ı bulup `]` karakterinin üzerindeki satıra `'blog',` yazmamız lazım. Sonuç aşağıdaki gibi görünmeli: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -99,84 +108,93 @@ INSTALLED_APPS = ( 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', -) -``` +] +``` ### Post (Blog gönderisi) modeli oluşturma -`blog/models.py` dosyasında `Models` deki tüm nesneler tanımlanır - burası bizim blog postunu tanımlayacağımız yerdir. +`blog/models.py` dosyasında `Models` denilen bütün nesneleri tanımlıyoruz - burası blog postumuzu tanımlayacağımız yer. Şimdi `blog/models.py` dosyasını açalım ve içindeki her şeyi silip şu kodu yazalım: +{% filename %}blog/models.py{% endfilename %} + ```python +from django.conf import settings from django.db import models from django.utils import timezone class Post(models.Model): - yazar = models.ForeignKey('auth.User') - baslik = models.CharField(max_length=200) - yazi = models.TextField() - yaratilma_tarihi = models.DateTimeField( - default=timezone.now) - yayinlanma_tarihi = models.DateTimeField( - blank=True, null=True) - - def yayinla(self): - self.yayinlanma_tarihi = timezone.now() + 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) + + def publish(self): + self.published_date = timezone.now() self.save() def __str__(self): - return self.baslik -``` + return self.title +``` + +> `str`'nin her iki tarafında da 2 tane alt çizgi (`_`) kullandığımızdan emin olalım. İki alt çizgi Python dilinde sık kullanılır, bazen "dunder" olarak da anılır ("double-underscore"un kısaltması). -> `str` nin her iki tarafında 2 tane alt çizgi (`_`) kullandığınızı kontrol edin. İki alt çizgi Python dilinde sık kullanılır. +Biraz korkunç görünüyor, değil mi? Ama merak etmeyin - hepsinin ne anlama geldiğini tek tek anlatacağız! -Biraz korkunç görünüyor, değil mi? Ama merak etmeyin, her şeyin ne demek olduğunu tek tek anlatacağız! +`from` veya `import` ile başlayan tüm satırlar başka yerlerden bir şeyleri projemize dahil eder. Yani, başka yerlerde tanımlanmış kodları dosyalarımıza kopyalamak yerine, bu kodların bir kısmını `from ... import ...` kullanarak kodumuza dahil edebiliriz. -`from` veya `import` ile başlayan tüm satırlar başka yerlerden bir şeyleri projemize dahil eder. Yani, başka yerlerde tanımlanmış kodları dosyalarımıza kopyalamak yerine, bu kodların bir kısmını `from ... import ...` ile projemize dahil edebiliriz. +`class Post(models.Model):` - bu satır modelimizi tanımlıyor (bir `nesne`). -`class Post(models.Model):` - bu satır modelimizi tanımlar (bir `nesne` dir). +- `class` bir nesne tanımladığımızı belirten anahtar kelime. +- `Post` modelimizin ismi. Başka bir isim de verebilirdik (yeter ki özel karakterler ve boşluk kullanmayalım). class isimleri her zaman büyük harf ile başlamalıdır. +- `models.Model` Post'un bir Django Modeli olduğunu belirtir, bu şekilde Django onu veritabanında tutması gerektiğini bilir. -* `class` bir nesne tanımladığımızı belirten bir anahtar kelimedir. -* `Post` modelimizin ismidir. Başka bir isim de verebilirdik (yeter ki özel karakterler ve boşluk kullanmayalım). Class isimleri her zaman büyük harf ile başlamalıdır. -* `models.Model` Post'un bir Django Modeli olduğunu belirtir, bu şekilde Django onu veritabanında tutması gerektiğini bilir. +Şimdi daha önce bahsettiğimiz özellikleri tanımlayabiliriz: `title`, `text`, `created_date`, `published_date` ve `author`. Bunun için her alanın türünü tanımlamamız gerekir (Bir metin mi? Bir numara mı? Bir tarih mi? Başka bir nesneye referans mı, örneğin User?) -Şimdi daha önce bahsettiğimiz özellikleri tanımlayabiliriz: `baslik`, `yazi`, `yaratilma_tarihi`, `yayinlanma_tarihi` ve `yazar` (Türkçe karakterleri kullanamadığımızı unutmayalım). Bunun için her alanın tipini belirtmemiz lazım (metin mi? Sayı mı? Tarih mi? Başka bir nesneye referans mı, ör. Kullanıcı?). +- `models.CharField` - belirli bir uzunluktaki metinleri tanımlamak için kullanılır. +- `models.TextField` - bu da uzun metinleri tanımlar. Blog gönderileri için biçilmiş kaftan, değil mi? +- `models.DateTimeField` - bu da gün ve saati tanımlamada kullanılır. +- `models.ForeignKey` - başka bir modele referans tanımlar. -* `models.CharField` - kısıtlı uzunlukta metin tanımlamak için kullanılır. -* `models.TextField` - bu da uzun metinleri tanımlar. Blog gönderileri için biçilmiş kaftan, değil mi? -* `models.DateTimeField` -bu da gün ve saati tanımlamada kullanılır. -* `models.ForeignKey` - başka bir model ile bağlantı içerir. +Burada her detayı anlatmıyoruz, çünkü çok fazla vakit alır. Model alanları (model fields) hakkında daha fazla bilgi edinmek ve yukarıda açıklananların dışındaki alanları nasıl tanımlayacağınızı öğrenmek istiyorsanız Django dokümantasyonuna bir göz atabilirsiniz (https://docs.djangoproject.com/en/2.0/ref/models/fields/#field -types). -Burada her detayı anlatmıyoruz, çünkü çok fazla vakit alır. Eğer detayları merak ederseniz veya farklı tür alanlar tanımlamak isterseniz Django'nun dokümantasyonlarına bakabilirsiniz (https://docs.djangoproject.com/en/1.10/ref/models/fields/#field-types). +Peki ya `def publish(self):` nedir? Bu, daha önce bahsettiğimiz `publish` metodu. `def` bunun bir fonksiyon/method olduğunu söylüyor. `publish` ise methodumuzun ismi. Eğer isterseniz metodun adını değiştirebilirsiniz. Methodlara isim verirken küçük harf kullanmaya ve boşluk yerine alt çizgi kullanmaya dikkat ediyoruz. Örneğin ortalama fiyatı hesaplayan bir methoda `ortalama_fiyati_hesapla` ismi verilebilir. -Peki `def yayinla(self):` nedir? Daha önce bahsettiğimiz `yayinla` methodudur. `def` bir fonksiyon/method olduğunu belirtir, `yayinla` ise bu methodun adıdır. İstersen methodun ismini değiştirebilirsin. Methodlara isim verirken küçük harf kullanmaya ve boşluk yerine alt çizgi kullanmaya dikkat etmemiz gerekiyor. Örneğin ortalama fiyatı hesaplayan bir methoda `ortalama_fiyati_hesapla` ismi verilebilir. +Genellikle methodlar bir şeyler döndürür (`return` anahtar kelimesi döndür anlamına gelir). `__str__` methodunda bunun örneğini görebiliriz. Bu durumda, `__str__()` methodunu çağırdığımızda Post başlığını içeren bir metin (**string**) elde ederiz. -Genellikle methodlar bir şey geri döndürür (`return` anahtar kelimesi döndür anlamına gelir). `__str__` methodunda bunun örneğini görebiliriz. Bu durumda `__str__()` methodunu çağırdığımızda Post başlığının yazısını (**string**) elde ederiz. +Aynı zamanda hem `def publish(self):` satırının, hem de `def __str__(self):` satırının sınıfımızın içinde girintili (indented) bir şekilde yazıldığına dikkat edin. Python boşluklara duyarlı olduğu için class'ın içindeki metodları girintili olarak yazmamız gerekiyor. Aksi takdirde methodlar class'a ait olmaz ve beklenmedik davranışlarla karşılaşabilirsiniz. Buraya kadar model hakkında anlamadığın bir şeyler varsa mentörüne sormaktan çekinme! Bu konuların biraz karmaşık olduğunun farkındayız. Özellikle hem nesneleri hem de fonksiyonları aynı anda öğrenmek kolay değil. Umarız gizemi biraz azalmaya başlamıştır! ### Modeller için veritabanında tablo oluşturma -Son adımımız yeni modelimizin veritabanına eklenmesini sağlamak. İlk önce Django'ya modelde bir takım değişiklikler yaptığımızı haber vermemiz gerekiyor (modeli yeni oluşturduk!). `python manage.py makemigrations blog` yazın. Şöyle görünmeli: +Son adımımız yeni modelimizin veritabanına eklenmesini sağlamak. Öncelikle Django'nun modelimizde bazı değişiklikler yaptığımızı bilmesini sağlamalıyız. (Daha yeni oluşturduk!) Komut satırına gidelim ve `python manage.py makemigrations blog` yazalım. Şöyle görünmeli: -``` -(myvenv) ~/djangogirls$ python manage.py makemigrations blog -Migrations for 'blog': -0001_initial.py: - - Create model Post -``` +{% filename %}komut-satırı{% endfilename %} -Django bize veritabanımıza uygulayabileceğimiz bir taşıma (migrasyon) dosyası oluşturdu. `python manage.py migrate blog` yazdığın zaman şunu görmelisin: + (myvenv) ~/djangogirls$ python manage.py makemigrations blog + Migrations for 'blog': + blog/migrations/0001_initial.py: + + - Create model Post + -``` -(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 -``` - -Yaşasın! Post modelimiz artık veritabanımızda! Görsek ne güzel olur, değil mi? Gelecek bölümde Post'un nasıl göründügünü göreceğiz! +**Not:** Düzenlediğiniz dosyaları kaydetmeyi unutmayın. Aksi takdirde, bilgisayarınız önceki sürümü çalıştırarak beklenmedik hatalar verebilir. + +Django bize veritabanımıza uygulayabileceğimiz bir taşıma (migration) dosyası oluşturdu. `python manage.py migrate blog` yazdığın zaman şunu görmelisin: + +{% filename %}komut-satırı{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py migrate blog + Operations to perform: + Apply all migrations: blog + Running migrations: + Applying blog.0001_initial... OK + + +Yaşasın! Post modelimiz artık veritabanımızda! Görsek ne güzel olur, değil mi? Gelecek bölümde Post'un nasıl göründügünü göreceğiz! \ No newline at end of file diff --git a/tr/django_orm/README.md b/tr/django_orm/README.md old mode 100755 new mode 100644 index f1cd023b7bb..426062ecd83 --- a/tr/django_orm/README.md +++ b/tr/django_orm/README.md @@ -1,178 +1,221 @@ -# Django ORM ve QuerySets (Sorgu Setleri) +# Django ORM ve QuerySets (SorguSetleri) Bu bölümde Django'nun veritabanına nasıl bağlandığını ve veriyi nasıl sakladığını öğreneceğiz. Hadi başlayalım! ## QuerySet (SorguSeti) Nedir? -QuerySet (SorguSeti), esas olarak, verilen bir modelin nesnelerinin listesidir. QuerySet veritabanından veri okumamıza, veriyi filtrelememize ve sıralamamıza imkan sağlar. +QuerySet (SorguSeti), esas olarak, verilen bir modele ait nesnelerin listesidir. QuerySet veritabanından veri okumamıza, veriyi filtrelememize ve sıralamamıza imkan sağlar. -En kolayı örnekle öğrenmektir. Hadi deneyelim, olur mu? +En kolayı örnek ile öğrenmektir. Hadi deneyelim, olur mu? ## Django shell (kabuk) -Yerel konsolumuzu açalım (PythonAnywhere'dekini değil) ve şu komutu yazalım: -``` -(myvenv) ~/djangogirls$ python manage.py shell -``` +Bilgisayarımızdaki konsolu açalım (PythonAnywhere'dekini değil) ve şu komutu yazalım: + +{% filename %}komut-satırı{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py shell + Etkisi aşağıdaki gibi olmalı: -``` + +{% filename %}komut-satırı{% endfilename %} + +```python (InteractiveConsole) >>> -``` +``` Şu an Django'nun etkileşimli konsolundayız. Python istemine benziyor, ama biraz Django büyüsü eklenmiş :) Kuşkusuz burada da Python komutlarının tümünü kullanabiliriz. ### Tüm nesneler -Önce tüm gönderilerimizi görüntülemeyi deneyelim. Bunu aşağıdaki komut ile yapabiliriz: +Önce tüm post'larımızı görüntülemeyi deneyelim. Bunu aşağıdaki komut ile yapabiliriz: -``` +{% filename %}komut-satırı{% endfilename %} + +```python >>> Post.objects.all() Traceback (most recent call last): - File "", line 1, in + File "", line 1, in NameError: name 'Post' is not defined -``` +``` -Aman! Bir hata meydana geldi. Bize bir gönderi olmadığını söylüyor. Doğru - önce gönderiyi almayı unuttuk! +Ahh! Bir hata meydana geldi. Bize Post'un tanımlı olmadığını söylüyor. Bu doğru, öncesinde post'u dahil etmeyi (import) unuttuk! -``` +{% filename %}komut-satırı{% endfilename %} + +```python >>> from blog.models import Post -``` +``` -`Post` modelini `blog.models` model havuzundan kolayca kodumuza dahil ettik. Şimdi bütün gönderileri tekrar göstermeyi deneyelim: +`blog.models`'dan `Post` modelini dahil ettik (import). Tekrar bütün post'ları görüntülemeyi deneyelim: -``` +{% filename %}komut-satırı{% endfilename %} + +```python >>> Post.objects.all() -[, ] -``` +, ]> +``` -Daha önce yarattığımız gönderilerin listesi! Bu gönderileri Django yönetici arayüzü kullanarak yaratmıştık. Şimdi ise Python kullanarak yeni gönderiler yaratmak istiyoruz, bunu nasıl yapabiliriz? +Bu daha önce oluşturduğumuz post'ların listesi! Bu post'ları Django admin arayüzü ile oluşturduk. Fakat şimdi Python kullanarak yeni post'lar oluşturmak istiyoruz, peki bunu nasıl yaparız? ### Nesne oluşturma Veritabanına yeni bir gönderi eklemek için: +{% filename %}komut-satırı{% endfilename %} + +```python +>>> Post.objects.create(author=ben, title='Harika bir gönderi', text='Ne desem bilemedim') ``` ->>> Post.objects.create(yazar=ben, baslik='Harika bir gönderi', yazi='Ne desem bilemedim') -``` -Ancak bir eksiğimiz var: `ben`. Gönderinin yazar özelliğine `User` modelinden türetilen bir nesneyi parametre olarak vermemiz gerekiyor. Nasıl verebiliriz? +Ancak bir eksiğimiz var: `ben`. Gönderinin author (yazar) özelliğine `User` (kullanıcı) modelinden türetilen bir nesneyi parametre olarak vermemiz gerekiyor. Nasıl verebiliriz? -Öncelikle kullanıcı modelini dahil edelim: +Öncelikle User (kullanıcı) modelini dahil edelim: -``` +{% filename %}komut-satırı{% endfilename %} + +```python >>> from django.contrib.auth.models import User -``` +``` Veritabanımızda hangi kullanıcılar var? Şu şekilde görebiliriz: -``` +{% filename %}komut-satırı{% endfilename %} + +```python >>> User.objects.all() -[] -``` +]> +``` -Daha önce yarattığımız ayrıcalıklı kullanıcı! Şimdi veritabanından kullanıcı nesnesi alalım: +Bu daha önce yarattığımız süper kullanıcı (superuser)! Şimdi bu kullanıcının örneğini (instance) alalım (bu satırı kendi kullanıcı adınızı kullanmak için değiştirin): -``` +{% filename %}komut-satırı{% endfilename %} + +```python ben = User.objects.get(username='zeynep') -``` +``` -Gördüğünüz gibi, `username` özelliği 'zeynep' olan `User` nesnesini `get` ile aldık. Müthiş! Tabiki, kullanıcı adını kendi kullanıcı adınıza göre ayarlamalısınız. +Görebildiğiniz gibi, şimdi `kullanıcı adı` 'zeynep' olan bir `User` aldık. Temiz! Gönderimizi artık kaydedebiliriz: +{% filename %}komut-satırı{% endfilename %} + +```python +>>> Post.objects.create(author=ben, title='Harika bir gönderi', text='Ne desem bilemedim') + ``` ->>> Post.objects.create(yazar=ben, baslik='Harika bir gönderi', yazi='Ne desem bilemedim') -``` Yaşasın! Çalışıp çalışmadığını kontrol etmek ister misin? -``` +{% filename %}komut-satırı{% endfilename %} + +```python >>> Post.objects.all() -[, , ] -``` +, ,]> +``` İşte bu kadar, listede bir gönderi daha! -### Daha fazla gönderi ekle +### Daha fazla post ekle -Şimdi biraz eğlenenebiliriz ve nasıl çalıştığını görmek için daha fazla gönderi ekleyebiliriz. 2-3 tane daha ekleyin ve bir sonraki kısma devam edin. +Şimdi daha fazla post ekleyerek biraz eğlenebilir ve nasıl çalıştığını görebiliriz. İki veya üç tane daha ekleyelim ve sıradaki bölüme geçelim. ### Nesneleri filtrelemek -QuerySets in büyük bir parçası nesneleri filtreleyebilme kabiliyetidir. Diyelim ki, Zeynep tarafından yazılmış tüm gönderileri bulmak istiyoruz. `Post.objects.all()` içindeki `all` yerine `filter` kullanacağız. Parantez içine istediğimiz blog gönderilerinin sağlaması gereken şartları belirteceğiz. Örneğimizde, `yazar` `ben`'e eşitti. Django'da bu filtre şöyle yazılır: `yazar=ben`. Şu an kod parçacığımız şöyle görünüyor: +QuerySet'lerin büyük bir bölümü nesneleri filtreleme yeteneğidir. Diyelim ki, Zeynep tarafından yazılmış tüm post'ları (gönderileri) bulmak istiyoruz. `Post.objects.all()` içindeki `all` yerine `filter` kullanacağız. Parantez içine istediğimiz blog gönderilerinin sağlaması gereken şartları belirteceğiz. Örneğimizde, `author` `ben`'e eşitti. Django'da bu filtreyi şöyle yazıyoruz: `author=ben`. Şu an kod parçacığımız şöyle görünüyor: -``` ->>> Post.objects.filter(yazar=ben) +{% filename %}komut-satırı{% endfilename %} + +```python +>>> Post.objects.filter(author=ben) [, , , ] -``` +``` -Ya da belki `baslik` alanında içinde 'Nefis' kelimesini içeren tüm gönderileri görmek istiyoruz? +Ya da belki `title` (başlık) alanında içinde 'Nefis' kelimesini içeren tüm gönderileri görmek istiyoruz? -``` ->>> Post.objects.filter(baslik__contains='Nefis') +{% filename %}komut-satırı{% endfilename %} + +```python +>>> Post.objects.filter(title__contains='Nefis') [] -``` +``` -> **Not** `baslik` ve `contains` arasında iki tane alt çizgi (`_`) var. Django'nun ORM'i bu söz dizimini, özelliği ("baslik") ve operasyon veya filtreyi ("contains") ayırmak için kullanır. Sadece tek alt çizgi kullanırsanız, "FieldError: Cannot resolve keyword baslik_contains" hatası alırsınız. +> **Not** `title` ve `contains` arasında iki tane alt çizgi (`_`) var. Django'nun ORM'i bu söz dizimini, özelliği ("title") ve operasyon veya filtreyi ("contains") ayırmak için kullanır. Eğer sadece tek bir alt çizgi kullanırsanız, "FieldError: Cannot resolve keyword title_contains" şeklinde bir hata alacaksınız. -Ayrıca yayınlanmış tüm gönderilerin bir listesini alabiliriz. Bunu geçmişte `yayinlanma_tarihi` alanı belirtilmiş tüm gönderileri filtreleyerek yapıyoruz: +Ayrıca yayınlanmış tüm post'ların bir listesini alabiliriz. Bunu `published_date` (yayinlanma_tarihi) alanı geçmiş bir tarih olan tüm gönderileri filtreleyerek yapıyoruz: -``` +{% filename %}komut-satırı{% endfilename %} + +```python >>> from django.utils import timezone ->>> Post.objects.filter(yayinlanma_tarihi__lte=timezone.now()) ->>> +>>> Post.objects.filter(published_date__lte=timezone.now()) + ``` -Maalesef, Python konsolundan eklediğimiz gönderi henüz yayınlanmadı. Bunu değiştirebiliriz! İlk olarak yayınlamak istediğimiz gönderinin bir örneğini alalım: +Maalesef python konsolundan eklediğimiz post (gönderi) henüz yayınlanmadı. Fakat bunu değiştirebiliriz! Önce yayınlamak istediğimiz bir gönderi nesnesi bulalım: +{% filename %}komut-satırı{% endfilename %} + +```python +>>> post = Post.objects.get(title="Harika bir gönderi") ``` ->>> post = Post.objects.get(baslik="Harika bir gönderi") -``` -Ardından `yayinla` methodu ile gönderiyi yayınlayalım! +Ardından `publish` (yayinla) methodu ile gönderiyi yayınlayalım: + +{% filename %}komut-satırı{% endfilename %} +```python +>>> post.publish() ``` ->>> post.yayinla() -``` -Şimdi yayınlanmış gönderileri tekrar almaya çalışalım (3 kez yukarı yön ve ardından `enter` tuşuna basın): +Şimdi yayınlanmış gönderileri tekrar almaya çalışalım (3 kez yukarı ok tuşuna ve ardından `enter` tuşuna basın): -``` ->>> Post.objects.filter(yayinlanma_tarihi__lte=timezone.now()) +{% filename %}komut-satırı{% endfilename %} + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) [] -``` +``` ### Nesneleri Sıralama -QuerySets ayrıca nesne listesini sıralamanızı da sağlar. Nesneleri `yaratilma_tarihi` özelliğine göre sıralamayı deneyelim: +QuerySets ayrıca nesne listesini sıralamanızı da sağlar. Nesneleri `created_date` (yaratilma_tarihi) özelliğine göre sıralamayı deneyelim: -``` ->>> Post.objects.order_by('yaratilma_tarihi') +{% filename %}komut-satırı{% endfilename %} + +```python +>>> Post.objects.order_by('created_date') [, , , ] -``` +``` Başına `-` ekleyerek sıralamayı tersine de çevirebiliriz: +{% filename %}komut-satırı{% endfilename %} + +```python +>>> Post.objects.order_by('-created_date') +[, , , ]> ``` ->>> Post.objects.order_by('-yaratilma_tarihi') -[, , , ] -``` -### Sorgu Setlerini Zincirlemek +### QuerySets (SorguSetlerini) Zincirlemek (Chaining) Sorgu setlerini **zincirleyerek** beraber kullanabilirsiniz: +```python +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> ``` ->>> Post.objects.filter(yayinlanma_tarihi__lte=timezone.now()).order_by('yayinlanma_tarihi') -``` Zincirleme gerçekten çok güçlüdür ve oldukça karmaşık sorgular yazmanıza imkan sağlar. -Güzel! Şimdi bir sonraki bölüm için hazırız. Kabuğu kapatmak için, şunu yazalım: +Güzel! Şimdi bir sonraki bölüm için hazırız. Komut satırını kapatmak için, şunu yazalım: -``` +{% filename %}komut-satırı{% endfilename %} + +```python >>> exit() $ -``` +``` \ No newline at end of file diff --git a/tr/django_start_project/README.md b/tr/django_start_project/README.md old mode 100755 new mode 100644 index 19febaad4f6..4b18e6ff559 --- a/tr/django_start_project/README.md +++ b/tr/django_start_project/README.md @@ -1,144 +1,203 @@ # İlk Django projen! -> Bu bölümün kaynağı Geek Girls Carrots (http://django.carrots.pl/) eğitim materyalidir. +> Bu bölümün bir kısmı Geek Girls Carrots tarafından hazırlanmış eğitimlere dayanılarak hazırlanmıştır (https://github.com/ggcarrots/django-carrots). > -> Bölümün parçaları Creative Commons Attribution-ShareAlike 4.0 International License ile lisanslı [django-marcador tutorial][1]'a dayanılarak hazırlanmıştır. Django-marcador tutorial'ının hakları Markus Zapke-Gründemann'e aittir. +> Bu bölümün [django-marcador tutorial](http://django-marcador.keimlink.de/)'a dayanan bazı kısımları Creative Commons Attribution-ShareAlike International License altında lisanslanmıştır. Django-marcador tutorial'ının hakları Markus Zapke-Gründemann'e aittir. - [1]: http://django-marcador.keimlink.de/ - -Basit bir blog oluşturacağız! +Küçük bir blog oluşturacağız! İlk adım yeni bir Django projesi başlatmaktır. Aslında, bizim için bir Django projesinin iskeletini yaratacak Django tarafından sağlanan bazı komut dosyaları çalıştıracağız. Bu sadece daha sonra kullanacağımız dosyalar ve dizinler grubudur. Bazı dosya ve dizinlerin isimleri Django için çok önemlidir. Oluşturmak üzere olduğumuz dosyaları yeniden adlandırmamalısınız. Onları başka bir yere taşımak da iyi bir fikir değil. Django'nun önemli şeyleri bulabilmesi için belirli yapısını koruması gerekir. -> virtualenv içindeki her şeyi çalıştırmayı unutmayın. Eğer konsolunuzda bir önek `(myvenv)` görmüyorsanız virtualenv'nizi çalışır hale getirmelisiniz. **Django yükleme** bölümünün **virtualenv ile Çalışma** kısmında nasıl yapılacağını açıkladık. Windows'da ` myvenv\Scripts\activate` ya da Mac OS / Linux'ta `source myvenv/bin/activate` yazmak sizin için bunu yapacaktır. +> virtualenv içindeki her şeyi çalıştırmayı unutmayın. Eğer konsolunuzda `(myenv)` öneki görmüyorsanız, virtualenv'inizi aktive etmeniz gerekir. **Django yükleme** bölümünün **Virtualenv ile çalışma** kısmında nasıl yapılacağını açıkladık. Windows'ta `myvenv\Scripts\activate` ya da, Mac OS ya da Linux'ta `source myvenv/bin/activate` yazmak bunu sizin için yapacaktır. -MacOS veya Linux konsolunuzda aşağıdaki komutu çalıştırmalısınız; **sonuna nokta `(.)` koymayı unutmayın**: + -``` -(myvenv) ~/djangogirls$ django-admin startproject mysite . -``` +MacOS veya Linux konsolunuzda aşağıdaki komutu çalıştırmalısınız; **sonuna nokta `(.)` koymayı unutmayın** -Windows'ta; ** sonunda nokta `(.)` koymayı unutmayın**: +{% filename %}komut-satırı{% endfilename %} -``` -(myvenv) C:\Users\Name\djangogirls > django-admin startproject mysite . -``` + (myvenv) ~/djangogirls$ django-admin startproject mysite . + + +> Nokta `.` bu durumda çok önemlidir çünkü; koda, Django'yu şu an bulunduğunuz dizine kurmasını söyler. (nokta `.` şu anki dizine bir kısayoldur). +> +> **Not** Yukarıdaki komutu yazarken, sadece `django-admin` ile başlayan kısmı yazmanız gerektiğini unutmayın. Burada gösterilen `(myvenv) ~/djangogirls$` kısmı, sadece komut satırında girdinizi davet eden komut istemi örneğidir. + + -> Nokta `.` bu durumda çok önemlidir çünkü; koda, Django'yu şu an bulunduğunuz dizine kurmasını söyler. (nokta `.` şu anki dizine bir kısayoldur) + + +Windows'ta aşağıdaki komutu çalıştırmalısınız. **(Sonuna nokta `.` koymayı unutmayın)**: + +{% filename %}komut-satırı{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite . + + +> Nokta `.` bu durumda çok önemlidir çünkü; koda, Django'yu şu an bulunduğunuz dizine kurmasını söyler. (nokta `.` şu anki dizine bir kısayoldur). > -> **Not** Yukarıdaki komutları yazarken sadece `django-admin` veya `django-admin.py` ile başlayan bölümü yazmayı unutmayın. Burada gösterilen `(myvenv) ~/djangogirls$` ve `(myvenv) C:\Users\Name\djangogirls>` kısımları, sadece, komut satırınızdaki girdilerinizi çağıracak olan komut isteği örnekleridir. +> **Not** Yukarıdaki komutu yazarken, sadece `django-admin.exe` ile başlayan bölümü yazmanız gerektiğini unutmayın. Burada gösterilmiş olan `(myvenv) C:\Users\Name\djangogirls>` kısmı komut satırına girdiğiniz davet edecek olan komut istemi örneğidir. + + `django-admin.py` sizin için dosya ve dizinler oluşturacak bir komut dosyasıdır. Şimdi aşağıdaki gibi görünen bir dizin yapınız olmalı: -``` -djangogirls -├───manage.py -└───mysite - settings.py - urls.py - wsgi.py - __init__.py -``` + djangogirls + ├───manage.py + ├───mysite + │ settings.py + │ urls.py + │ wsgi.py + │ __init__.py + └───requirements.txt + + +> **Not**: Dizin yapınızda, daha önceden oluşturduğumuz `myvenv` dizinini de göreceksiniz. `manage.py` site yönetimine yardımcı olan bir komut dosyasıdır. Bu dosya sayesinde, başka herhangi bir şey kurmadan bilgisayarımızda bir web sunucusunu başlatabileceğiz. `settings.py` dosyası, web sitesinizin ayarlarını içerir. -Bir mektubu nereye götüreceğini kontrol eden postacının hakkında konuştuğumuzu hatırlıyor musun? `urls.py` dosyası `urlresolver`(urlçözümleyici) tarafından kullanılan desenler listesi içerir. +Bir mektubu nereye götüreceğini kontrol eden postacının hakkında konuştuğumuzu hatırlıyor musun? `urls.py` dosyası `urlresolver`(urlçözümleyici) tarafından kullanılan kalıpların bir listesini içerir. Şu an için değişiklik yapmayacağımız diğer dosyaları yoksayalım. Unutmamanız gereken tek şey kazayla onları silmeyin! ## Ayarları değiştirme -Hadi `mysite/settings.py` dosyasında bazı değişiklikler yapalım. Daha önceden kurduğunuz kod düzenleyicinizi kullanarak dosyayı açın. +Hadi `mysite/settings.py` dosyasında bazı değişiklikler yapalım. Daha önceden kurduğunuz kod düzenleyicinizi (editör) kullanarak dosyayı açın. + +**Not**: `settings.py` dosyasının da diğerleri gibi normal bir dosya olduğunu aklınızda tutun. Bunu kod düzenleyicisi içerisinde "dosya -> aç" menü eylemini kullanarak açabilirsiniz. Bu, size `settings.py` dosyanıza gidebileceğiniz ve bu dosyayı seçebileceğiniz her zamanki klasik pencereyi açacaktır. Alternatif olarak, bu dosyayı masaüstünüzdeki djangogirls klasörüne gidip sağ tıklayarak açabilirsiniz. Sonra, listeden kod düzenleyicinizi seçin. Dosyayı açabilen ancak düzenlemenize izin vermeyecek diğer programların yüklü olması ihtimaline karşın kod düzenleyicinin seçilmesi önem arz etmektedir. -Web sitemizin doğru bir saate sahip olması güzel olurdu. [wikipedia timezones list][2] 'e gidin ve ilgili saat diliminizi (TZ -time zone-) kopyalayın. (örn. `Europe/Istanbul` ) +Web sitemizin doğru bir saate sahip olması güzel olurdu. [Wikipedia'nın zaman dilimleri listesine](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) gidin ve ilgili saat dilimini kopyalayın (ZD) (Ör. `Europe/Berlin`). - [2]: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones +`settings.py` dosyasında `TIME_ZONE` ifadesini içeren satırı bulun ve kendi seçtiğiniz zaman dilimine göre uyarlayın: -`settings.py` dosyasında <0>TIME_ZONE ifadesini içeren satırı bulun ve kendi seçtiğiniz zaman dilimine göre uyarlayın: +{% filename %}mysite/settings.py{% endfilename %} ```python TIME_ZONE = 'Europe/Istanbul' -``` +``` -"Europe/Istanbul" uygun şekilde değiştirildi +Bir dil kodu, dil (ör. İngilizce için `en` veya Almanca için `de`) ve ülke kodundan (ör. Almanya için `de` veya İsviçre için `ch`) oluşmaktadır. Eğer İngilizce ana diliniz değilse, varsayılan butonları ve Django uyarılarının dilini kendi dilinize değiştirmek için bunu ekleyebilirsiniz. Böylece "İptal" butonu burada tanımladığınız dile çevrilmiş olacaktır. [Django birçok çeviri ile birlikte gelmektedir](https://docs.djangoproject.com/en/2.0/ref/settings/#language-code). -Sabit dosyalar için de bir tane yol eklememiz gerekecek (Daha sonra eğitimde sabit dosyalar ve CSS hakkındaki her şeyi öğreneceğiz). Dosyanın *sonuna* en aşağıya `STATIC_URL` girdisinin altına gidin ve `STATIC_ROOT` adında yeni bir girdi ekleyin: +Farklı bir dil istiyorsanız, aşağıdaki satırı değiştirerek dil kodunu seçin: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +LANGUAGE_CODE = 'de-ch' +``` + +Ayrıca statik dosyalar için bir yol eklememiz gerekmektedir. (Eğitici ders içerisinde statik dosyalar ve CSS hakkında ayrıntılı bilgi bulabilirsiniz.) Dosyanın *son*'una gidin, hemen altında sadece `STATIC_URL` girişi yapın, `STATIC_ROOT` adında yeni birim ekleyin: + +{% filename %}mysite/settings.py{% endfilename %} ```python STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') -``` +STATIC_ROOT = BASE_DIR / 'static' +``` + +`DEBUG(Hata Ayıklama)` `True(Doğru)` ve `ALLOWED_HOSTS` boş olduğu zaman ana bilgisayar `['localhost', '127.0.0.1', '[::1]']`'a karşı doğrulanır. Bu, uygulamamızı dağıttıktan sonra, PythonAnywhere'deki anamakine adıyla eşleşmeyecek bu yüzden aşağıdaki ayarları değiştireceğiz: -## Veritabanı Kurulumu +{% filename %}mysite/settings.py{% endfilename %} + +```python +ALLOWED_HOSTS = ['127.0.0.1', '.pythonanywhere.com'] +``` + +> **Not**: Eğer Chromebook kullanıyorsanız bu satırı settings.py dosyanızın en altına ekleyiniz: `MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'` +> +> Ayrıca eğer cloud9 kullanıyorsanız `ALLOWED_HOSTS`'a `.c9users.io` 'i ekleyin + +## Bir veritabanı kur Web uygulamalarınız için farklı birçok veritabanı yazılımı vardır. Biz varsayılanı kullanacağız, `sqlite3`. Sqlite varsayılan olduğu için zaten `mysite/settings.py` dosyamızda kurulu: +{% 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', } } -``` - -Blogumuzun veritabanını oluşturmak için konsolda şu komutu çalıştırın:`python manage.py migrate` (`manage.py` dosyasını içeren `djangogirls` klasöründe olmalıyız). İşler iyi giderse şöyle bir şey görmelisiniz: - ``` -(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... - Running migrations: - Rendering model states... DONE - Applying contenttypes.0001_initial... OK - Applying auth.0001_initial... OK - Applying admin.0001_initial... 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 sessions.0001_initial... OK -``` + +Blogumuzun veritabanını oluşturmak için konsolda şu komutu çalıştırın: `python manage.py migrate` (`manage.py` dosyasını içeren `djangogirls` klasöründe olmalıyız). İşler iyi giderse şöyle bir şey görmelisiniz: + +{% filename %}komut-satırı{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py migrate + Operations to perform: + Apply all migrations: auth, admin, 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 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 sessions.0001_initial... OK + Hepsi bu kadar! Web sunucusunu (web server) çalıştırma ve websitemizin çalıştığını görme zamanı! +## Web sunucusunu başlatmak + `manage.py` dosyasının bulunduğu dizinde olmalıyız (`djangogirls` klasörü). Konsol üzerinden `python manage.py runserver` komutunu çalıştırarak web sunucusunu başlatabilirsiniz: -``` -(myvenv) ~/djangogirls$ python manage.py runserver -``` +{% filename %}komut-satırı{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver + + +Eğer Chromebook üzerindeyseniz, bunun yerine şu komutu kullanın: + +{% filename %}Cloud 9{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0.0.0.0:8080 + Eğer Windows'taysanız ve `UnicodeDecodeError` hatası varsa, bu komutu kullanın: -``` -(myvenv) ~/djangogirls$ python manage.py runserver 0:8000 -``` +{% filename %}komut-satırı{% endfilename %} -Şimdi tek yapmanız gereken, sitenizin çalışıp çalışmadığını kontrol etmek. Tarayıcınızı (Firefox, Chrome, Safari, Internet Explorer ya da ne kullanıyorsanız) açın ve şu adresi girin: + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + -``` -http://127.0.0.1:8000/ -``` +Şimdi tek yapmanız gereken sitenizin çalışıp çalışmadığına bakmak. Tarayıcınızı açın (Firefox, Chrome, Safari, Internet Explorer veya ne tercih ediyorsanız) ve bu adresi girin: + +{% filename %}tarayıcı{% endfilename %} -Web sunucusu, siz durdurana kadar komut sistemini tutacaktır yani başka komut yazamayacaksınız. Sunucu çalışıyorken daha fazla komut girebilmek için yeni bir terminal penceresi açın ve virtualenv'inizi aktive edin. Web sunucusunu durdurmak için çalıştığı pencereye tekrar gelin ve CTRL+C ye -Control ve C butonlarına birlikte - basın (Windows için Ctrl+Break'e basmanız gerekiyor olabilir). + http://127.0.0.1:8000/ + + +Eğer Chromebook kullanıyorsanız, her seferinde test sunucusunu ziyaret edeceksiniz ve erişeceksiniz: + +{% filename %}tarayıcı{% endfilename %} + + https://django-girls-.c9users.io + Tebrikler! ilk web siteni oluşturdun ve web sunucusu kullanarak çalıştırdın! Harika, değil mi? -![İşte çalışıyor!][3] +![Kurulum basarili!](images/install_worked.png) + +Web sunucusu çalışırken ek komutlar girmek için yeni bir komut satırı istemi göremezsiniz. Terminal yeni metin kabul edecek ama yeni komutları çalıştırmayacaktır. Bunun nedeni web sunucusunun duraklamadan gelen talepleri algılamasıdır. + +> Web sunucuları nasıl çalışır **How the Internet works (İnternet Nasıl Çalışır)** bölümünde görmüştük. - [3]: images/it_worked2.png +Web sunucusu açıkken yeni komut yazmak için, yeni bir terminal penceresi açıp virtualenv'inizi aktive etmeniz gerekmektedir. Web sunucusunu durdurmak için, çalıştığı pencereye geri dönün ve CTRL+C ye basın -Control ve C tuşlarına birlikte. (Windows'ta Ctrl+Break tuşları olabilir.). -Sonraki adım için hazır mısın? İçerikleri oluşturma zamanı! +Sonraki adım için hazır mısın? İçerikleri oluşturma zamanı! \ No newline at end of file diff --git a/tr/django_start_project/images/install_worked.png b/tr/django_start_project/images/install_worked.png new file mode 100644 index 00000000000..4354c634ddb Binary files /dev/null and b/tr/django_start_project/images/install_worked.png differ diff --git a/tr/django_start_project/images/it_worked2.png b/tr/django_start_project/images/it_worked2.png index 4412ecfc49e..4efa554e567 100644 Binary files a/tr/django_start_project/images/it_worked2.png and b/tr/django_start_project/images/it_worked2.png differ diff --git a/tr/django_templates/README.md b/tr/django_templates/README.md old mode 100755 new mode 100644 index b01e384561e..e3fbf54a30b --- a/tr/django_templates/README.md +++ b/tr/django_templates/README.md @@ -1,4 +1,4 @@ -# Django template +# Django templateleri Bazı verileri gösterme zamanı! Django bunun için bize faydalı bazı yerleşik **template etiketleri** sunuyor. @@ -8,101 +8,99 @@ Görüyoruz ki aslında, HTML'de Python kodu yazamayız, çünkü tarayıcılar **Django template etiketleri** Python benzeri yapıların HTML'ye aktarılmasını sağlar, böylece dinamik web sitelerini daha kolay ve hızlı oluşturabiliriz! -## Gönderi listesi template'ini göster +## Gönderi listesi template'ini gösterme Bir önceki bölümde, template'e `posts` değişkeni içinde gönderiler listesi verdik. Şimdi, bunu HTML'de göstereceğiz. -Django şablonunda bir değişken yazdırmak için, değişken adını çift kıvrımlı parantez içinde şu şekilde kullanırız: +Django şablonunda (template) bir değişken (variable) yazdırmak için, değişken adını çift kıvrımlı parantez içinde şu şekilde kullanırız: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {{ posts }} -``` - -Bunu `blog/templates/blog/post_list.html` şablonunda deneyelim. İkinci `
`'den üçüncü `
`'e kadar olan her şeyi `{{ posts }}` ile değiştirelim. Ne olduğunu görmek için dosyayı kaydedip sayfayı yenileyelim: +``` -![Şekil 13.1][1] +Bunu `blog/templates/blog/post_list.html` şablonunda deneyelim. Dosyayı kod editöründe açalım ve ikinci `
`'den üçüncü `
`'e kadar olan her şeyi `{{ posts }}` ile değiştirelim. Ne olduğunu görmek için dosyayı kaydedip sayfayı yenileyelim: - [1]: images/step1.png +![Şekil 13.1](images/step1.png) Gördüğümüz sadece bu: -``` -[, ] -``` +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +, ]> +``` Yani Django bunu bir nesneler listesi olarak algılıyor. **Python'a giriş**'ten listelerin nasıl gösterildiğini hatırlıyor musun? Evet, döngülerle! Bir Django template ile bunu şöyle yaparsın: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html {% for post in posts %} {{ post }} {% endfor %} -``` +``` Bunu kendi template'imizle deneyelim. -![Şekil 13.2][2] - - [2]: images/step2.png +![Şekil 13.2](images/step2.png) İşe yarıyor! Fakat bunların daha önce **HTML'ye giriş** bölümünde oluşturduğumuz statik gönderiler gibi görünmesini istiyoruz. HTML ve template etiketlerini karıştırabiliriz. `body` şöyle görünecektir: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html - + {% for post in posts %}
-

published: {{ post.yayinlanma_tarihi }}

-

{{ post.baslik }}

-

{{ post.yazi|linebreaks }}

+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

{% endfor %} -``` +``` {% raw %}`{% for %}` ve `{% endfor %}` arasına koyduğunuz her şey listedeki her nesne için tekrarlanır. Sayfanı yenile:{% endraw %} -![Şekil 13.3][3] +![Şekil 13.3](images/step3.png) - [3]: images/step3.png - -`{{ post.baslik }}` ya da `{{ post.yazi }}` için biraz farklı bir yazım kullandığımızı farkettin mi? Böylece `Post` modelinde tanımlanan alanlardaki verilere ulaşıyoruz. Ayrıca `|linebreaks` (satırsonu), gönderilerin metnini, satır sonlarını paragraflara çeviren bir filtreden geçiriyor. +Bu sefer biraz daha farklı bir notasyon kullandığımızın farkında mısınız (`{{ post.title }}` or `{{ post.text }})`)? Böylece `Post` modelinde tanımlanan alanlardaki verilere ulaşıyoruz. Ayrıca `|linebreaks` (satırsonu), gönderilerin metnini, satır sonlarını paragraflara çeviren bir filtreden geçiriyor. ## Bir şey daha -Web sitemizin İnternet'te hâlâ çalıştığını görmek iyi olacak, değil mi? PythonAnywhere yükleyelim yine. Adımları hatırlayalım... +Web sitemizin İnternet'te hâlâ çalıştığını görmek iyi olacak, değil mi? PythonAnywhere'e yükleyelim yine. Adımları hatırlayalım… -* İlk önce kodumuzu Github'a push komutu ile yükleyelim +* İlk önce kodumuzu Github'a push komutu ile yükleyelim -``` -$ git status -[...] -$ git add -A . -$ git status -[...] -$ git commit -m "Veritabanındaki postları görebilmek için template'i değiştirdim." -[...] -$ git push -``` +{% filename %}komut-satırı{% endfilename %} -* [PythonAnywhere][4]'e bağlanalım ve **Bash konsolu**'na gidelim (veya yeni bir konsol açalım) ve şunu çalıştıralım: + $ git status + [...] + $ git add --all . + $ git status + [...] + $ git commit -m "Veritabanından gönderileri göstermek için template'ler değiştirildi." + [...] + $ git push + - [4]: https://www.pythonanywhere.com/consoles/ +* [PythonAnywhere](https://www.pythonanywhere.com/consoles/)'e bağlanalım ve **Bash konsolu**'na gidelim (veya yeni bir konsol açalım) ve şunu çalıştıralım: -``` -$ cd ilk-blogum -$ git pull -[...] -``` +{% filename %}PythonAnywhere komut-satırı{% endfilename %} -* Ve son olarak da [Web tab][5] sekmesine gidip web uygulamamızdaki **Reload**'a basalım. Şimdi güncellememiz yayında olmalı! + $ cd $USER.pythonanywhere.com + $ git pull + [...] + - [5]: https://www.pythonanywhere.com/web_app_setup/ +* Son olarak, [Web sekmesi](https://www.pythonanywhere.com/web_app_setup/)ne gidip uygulamanızın **Yenile** butonuna basın. (Konsoldan diğer PythonAnywhere sayfalarına ulaşmak için, sağ üst köşedeki menü düğmesini kullanın.) Güncellemeniz https://isminiz.pythonanywhere.com adresinde yayınlanmalıdır - tarayıcıda kontrol edin! Eğer PythonAnywhere sitesindeki gönderilerin içeriği ile lokal sunucunuzda bulunan gönderilerin içeriği aynı değilse sorun değil. Lokal bilgisayarınızdaki veritabanı ile Python Anywhere'deki veritabanı, diğer dosyalarınız gibi eşitlenmiyor. -Tebrikler! Şimdi devam edelim ve Django admininde yeni bir gönderi eklemeyi deneyelim (yayinlanma_tarihi eklemeyi unutmayalım!), sonrasında gönderinin görünüp görünmediğini görmek için sayfayı yenileyelim. +Tebrikler! Şimdi Django admin üzerinden yeni bir gönderi eklemeyi deneyin (published_date eklemeyi unutmayın!) PythonAnywhere sitenizin Django admininde olduğunuzdan emin olun, https://yourname.pythonanywhere.com/admin. Arkasından gönderileri görebilmek için oradaki sayfanızı yenileyin. Şiir gibi çalışıyor, değil mi? Gurur duyabiliriz! Şimdi bilgisayar başından bir süre kalkalım, çünkü bir molayı hak ettik. :) -![Şekil 13.4][6] - - [6]: images/donut.png +![Şekil 13.4](images/donut.png) \ No newline at end of file diff --git a/tr/django_templates/images/donut.png b/tr/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/tr/django_templates/images/donut.png and b/tr/django_templates/images/donut.png differ diff --git a/tr/django_templates/images/step1.png b/tr/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/tr/django_templates/images/step1.png and b/tr/django_templates/images/step1.png differ diff --git a/tr/django_templates/images/step2.png b/tr/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/tr/django_templates/images/step2.png and b/tr/django_templates/images/step2.png differ diff --git a/tr/django_templates/images/step3.png b/tr/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/tr/django_templates/images/step3.png and b/tr/django_templates/images/step3.png differ diff --git a/tr/django_urls/README.md b/tr/django_urls/README.md old mode 100755 new mode 100644 index d048f5a6e7c..a1bde414a74 --- a/tr/django_urls/README.md +++ b/tr/django_urls/README.md @@ -1,129 +1,103 @@ -# Django url'leri +# Django URL'leri İlk web sayfamızı yapmak üzereyiz: blogunuzun anasayfası! Ama önce, biraz Django url'lerini öğrenmeye başlayalım. ## URL nedir? -URL basitçe bir web adresidir. Bir web sayfasını her ziyaret ettiğinizde tarayıcınızın adres barında bir URL görürsünüz (evet! `127.0.0.1:8000` bir URL'dir! Ve `https://djangogirls.com` da bir URL'dir): +URL basitçe bir web adresidir. Her defasında bir web sitesini ziyaret ettiğinde bir URL görürsün. Tarayıcının adres çubuğunda görünmektedir. (Evet! `127.0.0.1:8000` bir URL'dir! Ve `https://djangogirls.org` da bir URL'dir) -![Url][1] +![Url](images/url.png) - [1]: images/url.png - -Internetteki her sayfanın kendi URL'inin olması gerekir. Böylelikle bir URL açıldığında uygulama ne göstermesi gerektiğini bilir. Django'da `URLconf` (URL konfigürasyonu) denilen bir şey kullanıyoruz. URLconf, Django'ya gelen URL için doğru view'un bulunmasını sağlar. +İnternetteki her sayfanın kendi URL'si olması gerekir. Böylelikle bir URL açıldığında uygulama ne göstermesi gerektiğini bilir. Django'da `URLconf` (URL konfigürasyonu) denilen bir şey kullanıyoruz. URLconf Django'nun doğru viewı bulmak için istenen URL ile eşleştirmeyi deneyeceği desenler dizinidir. ## URL'ler Django'da nasıl çalışır? Kod editörümüzde `mysite/urls.py` dosyasını açalım ve neye benzediğine bakalım: +{% filename %}mysite/urls.py{% endfilename %} + ```python -from django.conf.urls import include, url +"""mysite URL Configuration + +[...] +""" +from django.urls import path, include from django.contrib import admin 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), ] ``` +Gördüğünüz gibi Django bu dosyaya bizim için bir şeyler koymuş bile. -Gördüğünüz gibi Django bizim için bir şeyler koymuş bile. +Üçlü tırnaklar (`'''` or `"""`) arasındaki satırlara docstrings denir - bunları bir dosyanın, sınıfın ya da metodun en üstüne ne yaptıklarını anlatmak için yazabilirsiniz. Python bunları çalıştırmaz. -`#` ile başlayan satırlar yorum satırlarıdır - bu satırlar Python tarafından çalıştırılmayacak manasına gelir. Çok pratik, değil mi? +Önceki bölümde gördüğümüz yönetici URL'si burada: -Geçen bölümde gittiğimiz admin URL şimdiden burda: +{% filename %}mysite/urls.py{% endfilename %} ```python - url(r'^admin/', include(admin.site.urls)), -``` - -`admin` ile başlayan her URL için Django ona denk gelen bir *view* bulur manasına gelir. Bu şekilde bir sürü admin URLlerini ekliyoruz böylece hepsi bu küçük dosyanın içinde sıkıştırılmış bir şekilde durmuyor -- bu hali daha okunabilir ve düzenli. - -## Regex (Kurallı İfade) - -Django'nun URL'leri view'larla nasıl eşleştirdiğini merak ediyor musunuz? Bu kısım biraz karışık. Django bunun için `regex` kullanıyor. Regex, "regular expressions"ın kısaltılmış hali ve düzenli ifadeler anlamına geliyor. Regex'in bir arama kalıbı oluşturmak için birçok (birçok!) kuralı var. Regexler ileri bir konu olduğu için nasıl çalıştığının detayına girmeyeceğiz. - -Gene de kalıpları nasıl oluşturduğumuzu anlamak isterseniz, aşağıdaki bir örnek var - aradığımız kalıbı oluşturmak için kuralların sadece bir kısmına ihtiyacımız olacak, şöyle: - + path('admin/', admin.site.urls), ``` -^ metnin başlangıcı için -$ metnin sonu için -\d rakamlar için -+ bir önceki karakterin en az bir kere bulunması gerektiğini belirtmek için -() kalıbın belli bir kısmını yakalamak için -``` - -Url tanımındaki diğer herşey birebir eşlenecek. -Şimdi `http://www.mysite.com/post/12345/` adresinde bir websitemiz olduğunu düşünelim. `12345` da gönderimizin numarası. +Bu satırın anlamı Django, `admin` ile başlayan her URL için ona uyan bir *view* bulur demektir. Bu durumda bir sürü yönetici URL'lerini ekliyoruz, böylece hepsi bu küçük dosyanın içinde sıkıştırılmış bir şekilde durmuyor -- bu hali daha okunabilir ve düzenli. -Her gönderi için ayrı bir view yazmak gerçekten can sıkıcı olurdu. Düzenli ifadelerle (regexlerle) url ile eşlecek bir kalıp oluşturup gönderi numarasını çıkartabiliriz: `^post/(\d+)/$`. Parçalara bölüp ne yaptığımıza bakalım: +## İlk Django URL'iniz! -* **^post/** Django'ya `post/` ile başlayan her şeyi almasını söylüyor ( `^`) -* **(\d+)** ise bir sayı (birden fazla rakam) olduğunu ve bu sayıyı yakalamak ve çıkarmak istediğimizi belirtiyor -* **/** ise Django'ya arkasından bir `/` karakteri gelmesi gerektiğini söylüyor -* **$** ise URL'nin sonuna işaret ediyor, yani sadece sonu `/` ile biten string'ler bu kalıpla eşleşecek +İlk URL'mizi oluşturma zamanı. 'http://127.0.0.1:8000/' adresinin bloğumuzun anasayfası olmasını ve gönderilerin bir listesini görüntülemesini istiyoruz. -## İlk Django url'niz! +Aynı zamanda `mysite/urls.py` dosyasını temiz tutmak istiyoruz, bu yüzden `blog` uygulamamızdan `mysite/urls.py` ana dosyamıza URL'leri aktarıyoruz (import). -İlk URL'imizi oluşturma zamanı! 'http://127.0.0.1:8000/'ın blogumuzun ana sayfası olmasını istiyoruz ve bize bir gönderi listesi göstermesini istiyoruz. +Devam edip, `blog.urls`'i import edecek bir satır ekleyelim. Ayrıca, ilk satırı değiştirmelisiniz çünkü burada `include` fonksiyonunu kullanıyoruz, bu yüzden bu içe aktarmayı (import) satırlara eklemeniz gerekecek. -Aynı zamanda `mysite/urls.py` dosyasını basit tutmak istiyoruz, bunun için ana `mysite/urls.py` dosyasına `blog` uygulamamızdan url'leri import edeceğiz (içeri alacağız). +`mysite/urls.py` dosyamız şöyle olmalı: -Yorum satırlarını silin (`#` ile başlayan satırları) ve ana url'ye `blog.urls` satırlarını import edecek (içeri alacak) bir satır ekleyin (`''`). - -`mysite/urls.py` dosyanız şöyle olmalıdır: +{% filename %}mysite/urls.py{% endfilename %} ```python -from django.conf.urls import include, url +from django.urls import path, include from django.contrib import admin urlpatterns = [ - url(r'^admin/', include(admin.site.urls)), - url(r'', include('blog.urls')), + path('admin/', admin.site.urls), + path('', include('blog.urls')), ] ``` - -Django artık 'http://127.0.0.1:8000/'ye gelen her şeyi `blog.urls`'ya yönlendirecek ve ordaki yönergelere bakacak. - -Python'da düzenli ifadeler her zaman string'in başına `r` ekleyerek yapılır. Bu Python için string'in özel karakterler içerdiğini, doğrudan Python için değil düzenli ifadeler için bir string olduğu konusunda ipucu verir. +Django artık 'http://127.0.0.1:8000/' adresine gelen her şeyi `blog.urls`'e yönlendirecek ve oradaki yönergelere bakacak. ## blog.urls -`blog/urls.py` adında yeni boş bir dosya oluşturun. Harika! Şu iki satırı ekleyin: +`blog` dizini içinde `urls.py` adında yeni bir boş dosya oluşturalım ve kod editöründe açalım. Tamam! Şu ilk iki satırı ekleyelim: + +{% filename %}blog/urls.py{% endfilename %} ```python -from django.conf.urls import url +from django.urls import path from . import views -``` +``` -Burada sadece Django'nun methodlarını ve `blog` uygulamasındaki tüm `view`leri içeri aktarıyoruz (uygulamamız henüz yok, ama birazdan o kısma da geçeceğiz!) +Burada `blog` uygulamasından Django'nun `path` fonksiyonunu ve bütün `views` fonksiyonlarını dahil ediyoruz (import). (Şu an hiç url'imiz yok ama birazdan olacak!) Bundan sonra ilk URL kalıbımızı ekleyebiliriz: +{% filename %}blog/urls.py{% endfilename %} + ```python urlpatterns = [ - url(r'^$', views.post_list, name='post_list'), + path('', views.post_list, name='post_list'), ] ``` +Gördüğünüz üzere, ana URL'e `post_list` adında bir `view` atıyoruz. Django URL resolver ful URL'in başındaki domain adını (yani, http://127.0.0.1:8000 /) göz ardı eder, böylece bu URL kalıbı (pattern) boş bir string ile eşleşecek. Bu kalıp, Django'ya eğer siteye biri 'http://127.0.0.1:8000/' adresinden gelirse gitmesi gereken yerin `views.post_list` olduğunu söylüyor. -Gördüğünüz üzere, `^$` URL'sine `post_list` adında bir `view` atıyoruz. Bu düzenli ifade `^` (başlangıç) ve `$` (bitiş)'e uyan stringlerle eşleşir - yani sadece boş string'lerle eşleşir. Bu doğru çünkü Django URL çözücülerinde 'http://127.0.0.1:8000/' URL'nin parçası değildir. Bu kalıp, Django'ya eğer siteye biri 'http://127.0.0.1:8000/' adresinden gelirse gitmesi gereken yerin `views.post_list` olduğunu söylüyor. - -Son kısım olan `name='post_list'` view'u tanımlamak için kullanılan URL'nin adı. Bu view'un adı ile aynı olabilir ama tamamen farklı bir şey de olabilir. Named URL'leri (isimlendirilmiş URL'leri) projenin ilerleyen kısımlarında kullanacağız, o yüzden uygulamadaki her URL'yi isimlendirmemiz önemli. Aynı zamanda URL isimlerini tekil ve kolay hatırlanabilir yapmamız gerekir. - -Her şey tamam mı? Tarayıcınızda http://127.0.0.1:8000/'ye gidin ve sonuçları görün. - -![Hata][2] +Son kısım `name='post_list'`, görünümü (view) tanımlamak için kullanılan URL'in adıdır. Bu view'un adı ile aynı olabilir ama tamamen farklı bir şey de olabilir. Bundan sonra projede isimlendirilmiş URL'leri kullanıyor olacağız, bu yüzden uygulamadaki her URL'i isimlendirmek önemli. Aynı zamanda URL isimlerini eşsiz ve kolay hatırlanabilir şekilde seçmeliyiz. - [2]: images/error1.png +Eğer şimdi http://127.0.0.1:8000/ adresine gitmeyi denerseniz, 'sayfanıza ulaşılamıyor' tarzında bir mesaj görürsünüz. Bunun nedeni sunucunun (`runserver` yazdığınızı hatırlıyor musunuz?) artık çalışmıyor olması. Sebebini bulmak için sunucunuzdaki komut penceresine bakın. -Artık "It works" demiyor, di mi? Meraklanmayın, sadece bir hata sayfası, korkacak birşey yok! Aslında çok kullanışlılar: +![Hata](images/error1.png) -Sayfada gördüğünüz şey: **no attribute 'post_list'**. *post_list* size bir şey hatırlatıyor mu? Bu view'un ismi! Bu her şey yerli yerinde sadece henüz *view* yok manasına geliyor. Hiç merak etmeyin, oraya geleceğiz. +Konsolunuz bir hata gösteriyor, ama endişelenmeyin -aslında bu oldukça kullanışlı: bize **'post_list' özelliği yok** diyor. Bu Django'nun bulup kullanmaya çalıştığı *view*'ın adı. Ama onu henüz oluşturmadık. Bu aşamada `/admin/` de çalışmayacaktır. Hiç merak etmeyin, oraya geleceğiz. Farklı bir hata görürseniz, web sunucunuzu yeniden başlatmayı deneyin. Komut satırına girin, konsol ekraninda Ctrl+C (Control ve C tuşlarına beraber) basarak sunucuyu durdurun ve `python manage.py runserver` komutunu çalıştırarak yeniden başlatın. -> Django URLconfs ile ilgili daha fazla bilgi edinmek istiyorsanız resmi dokümantasyona bakabilirsiniz: https://docs.djangoproject.com/en/1.10/topics/http/urls/ +> Django URLconfs ile ilgili daha fazla bilgi edinmek istiyorsanız resmi Django dokümantasyonuna bakabilirsiniz: https://docs.djangoproject.com/en/2.0/topics/http/urls/ \ No newline at end of file diff --git a/tr/django_urls/images/error1.png b/tr/django_urls/images/error1.png index 8bf6b9829a1..50618fca3fe 100644 Binary files a/tr/django_urls/images/error1.png and b/tr/django_urls/images/error1.png differ diff --git a/tr/django_urls/images/url.png b/tr/django_urls/images/url.png index 6cd1bd96291..c22441e930e 100644 Binary files a/tr/django_urls/images/url.png and b/tr/django_urls/images/url.png differ diff --git a/tr/django_views/README.md b/tr/django_views/README.md old mode 100755 new mode 100644 index 97a727c49d8..577d31af36b --- a/tr/django_views/README.md +++ b/tr/django_views/README.md @@ -1,38 +1,44 @@ # Django views - yaratma zamanı geldi! -Evvelki bölümde yaptığımız hatayı yok edelim :) +Bir önceki bölümde ortaya çıkan hatayı ortadan kaldırma vakti geldi! :) -*view*, "uygulama mantığının" ifade edildiği yerdir. Daha önce oluşturulan `model` den bilgi alıp `template`'e iletir. Gelecek bölümde bir template oluşturacağız. View'ler bildiğiniz Python methodlarıdır. Ancak, **Python'a Giriş** bölümünde yazdığımız methodlardan biraz daha karmaşıktır. +*view*, uygulamamızın "mantığının" ifade edildiği yerdir. Daha önce oluşturduğumuz `model` den bilgi alarak `template`'e iletir. "template"i ise gelecek bölümde oluşturacağız. View'ler bildiğiniz Python fonksiyonlarıdır. Ancak, **Python'a Giriş** bölümünde yazdığımız fonksiyonlardan biraz daha karmaşıktır. -View'ler `views.py` doyasına yazılır. Şimdi, `blog/views.py` dosyasına *view* ekleyelim. +View'ler `views.py` dosyasında yer alır. Şimdi, *view*'larımızı `blog/views.py` dosyasına ekleyelim. ## blog/views.py -Dosyayı açıp inceleyelim: +Tamam, şimdi bu dosyayı açalım ve içinde ne olduğuna bakalım: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render -# View'lar buraya yazılacak. -``` +# Create your views here. +``` + +Henüz fazla bir şey yok. + +`#` ile başlayan satırların yorumlar olduğunu unutmayın - bu # ile başlayan satırların Python tarafından çalıştırılmayacağı anlamına geliyor. -Henüz fazla bir şey görünmüyor. En basitinden *view* şöyle olabilir. +Hadi yorumun önerdiği gibi bir *view* oluşturalım. Bunun için alttaki viewı en alta ekleyin: + +{% filename %}blog/views.py{% endfilename %} ```python -def post_list(request): +def post_list(request): return render(request, 'blog/post_list.html', {}) -``` - -Burada, `request (istek)` i alıp template `blog/post_list.html` ile görüntüleyen `render` methodunu `döndüren` `post_list` isimli bir method yarattık. +``` -Dosyamızı kaydedelim ve http://127.0.0.1:8000/ e gidip bakalım. +Burada `post_list` isimli bir fonksiyon (`def`) yarattık, bu fonksiyon girdi olarak `request` (isteği) alıp, `blog/post_list.html` template'ini işleyecek olan `render` fonksiyonunu `döndürüyor`. -Yine hata! Okuyup anlamaya çalışalım: +Dosyamızı kaydedelim ve http://127.0.0.1:8000/ adresine gidip bakalım. -![Hata][1] +Bir başka hata! Okuyup neler olduğunu anlamaya çalışalım: - [1]: images/error.png +![Hata](images/error.png) -Bu hatayı düzeltmek kolay: *TemplateDoesNotExist* (Template bulunamadı). Bu hatayı template oluşturarak gelecek bölümde düzeltelim! +İyi tarafından bakarsak bu hata en azından sunucumuzun yeniden çalıştığını gösteriyor, ama hala bir şeyler yanlış, değil mi? Dert etmeyin, sadece bir hata sayfası, korkacak bir şey yok! Komut satırındaki hata mesajları gibi bunlar da aslında oldukça yararlılar. *TemplateDoesNotExist* hatası alıyoruz, yani Template bulunamadı. Gelecek bölümde bu hatayı template oluşturarak düzeltelim! -> Django view hakkında daha fazla bilgi edinmek için dokümantasyonları okuyun: https://docs.djangoproject.com/en/1.10/topics/http/views/ +> Django view'ları hakkında daha fazla bilgi edinmek için resmi dokümantasyonları okuyabilirsiniz: https://docs.djangoproject.com/en/2.0/topics/http/views/ \ No newline at end of file diff --git a/tr/django_views/images/error.png b/tr/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/tr/django_views/images/error.png and b/tr/django_views/images/error.png differ diff --git a/tr/domain/README.md b/tr/domain/README.md deleted file mode 100755 index aef4e74421b..00000000000 --- a/tr/domain/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# Domain (Alan Adı) - -Heroku size bir alan adı verdi, ama uzun, hatırlaması zor ve çirkin. Kısa ve kolay hatırlanabilir bir alan adı olsaydı harika olurdu, değil mi? - -Bu bölümde size yeni bir alan adı satın alıp Heroku'ya yönlendirmeyi öğreteceğiz! - -## Alan adını nerden alabiliriz? - -Bir alan adı ortalamada senelik $15 civarında oluyor. Alan adı sağlayıcısına göre daha ucuzları ve daha pahalıları var. Alan adı satın alabileceğiniz bir sürü şirket var: basit bir [google araması][1] size yüzlerce seçenek getirir. - - [1]: https://www.google.com/search?q=register%20domain - -Bizim favorimiz [I want my name][2]. Kendilerini "acısız alan adı yönetimi" diye nitelendiriyorlar ve gerçekten acısız. - - [2]: https://iwantmyname.com/ - -## IWantMyName ile alan adı nasıl satın alınır? - -[iwantmyname][3]'e gidin ve arama kutusuna istediğiniz alan adını girin. - - [3]: http://iwantmyname.com - -![][4] - - [4]: images/1.png - -Aradığınız ada sahip alan adlarının bir listesini görüyor olmanız lazım. Gülen surat, alan adını alabileceğinizi; üzülen surat ise alan adının halihazırda başkasında olduğunu gösteriyor. - -![][5] - - [5]: images/2.png - -`djangogirls.in` alan adını almaya karar verdik: - -![][6] - - [6]: images/3.png - -'Checkout'a gidin. Eğer hesabınız yoksa, kaydolmanız gerekir. Arkasından kredi kartı bilgilerinizi girin ve alan adını satın alın! - -Menüde '`Domains`'e (alan adları) tıklayın ve yeni satın alınmış alan adınızı seçin. Arkasından `managen DNS records` (DNS kayıtlarınızı yönetin) linkine tıklayın: - -![][7] - - [7]: images/4.png - -Arkasından bu formu bulmanız gerekiyor: - -![][8] - - [8]: images/5.png - -Ve aşağıdaki detayları girin: - Hostname: www - Type: CNAME - Value: Heroku'daki alan adınız (örneğin djangogirls.herokuapp.com) - TTL: 3600 - -![][9] - - [9]: images/6.png - -Önce 'Add' (ekle) butonuna tıklayın. Sonra da alttaki 'Save Changes'e (değişiklikleri kaydet) tıklayın. - -Alan adınızın çalışır hale gelmesi birkaç saati sürebilir, sabırlı olun! - -## Alan adını Heroku'da Ayarlayın - -Heroku'ya da kendi özel alan adınızı kullanmak istediğinizi belirtmeniz gerekiyor. - -[Heroku Dashboard][10]'una gidin, Heroku hesabınıza girin ve uygulamanızı seçin. 'Settings'e (ayarlar) girin ve `Domains` (alan adı) kısmına alan adınızı girin. Değişiklikleri kaydedin. - - [10]: https://dashboard.heroku.com/apps - -İşte bu kadar! diff --git a/tr/dynamic_data_in_templates/README.md b/tr/dynamic_data_in_templates/README.md old mode 100755 new mode 100644 index 95691590e84..c04a25414e4 --- a/tr/dynamic_data_in_templates/README.md +++ b/tr/dynamic_data_in_templates/README.md @@ -1,44 +1,50 @@ -# Template içerisinde dinamik veri +# Template içinde dinamik veri -Birkaç parçayı yerine oturttuk: `Post` (gönderi) modelini `models.py`'de tanımladık, `views.py`'de `post_list` (gönderi listesi) var ve template ekledik. Ama gönderilerimizi HTML'de görünür kıldık mı? Çünkü bu yapmak istediğimiz şey: içeriği (veritabanında kayıtlı modellerimiz) al ve güzelcene template içerisinde göster, değil mi? +Birkaç parçayı yerine oturttuk: `Post` (gönderi) modelini `models.py`'de tanımladık, `views.py`'de `post_list` (gönderi listesi) var ve template ekledik. Ama gönderilerimizi HTML'de görünür kıldık mı? Çünkü yapmak istediğimiz şey bu -bazı içerikleri (veritabanında kayıtlı modeller) al ve şablonumuzda göster, değil mi? -Bu tam olarak *view*'lerin yapmasını beklediğimiz şey: modelleri ve template'leri bağlamak. `post_list` *view*'de göstermek istediğimiz modelleri alıp template'e iletmemiz gerekecek. Yani temelde bir *view*de template içinde neyin (hangi modelin) gösterileceğine karar veriyoruz. +Bu tam olarak *view*'lerin yapmasını beklediğimiz şey: modelleri ve template'leri bağlamak. `post_list` *view* 'ımızda göstermek istediğimiz modelleri alıp template'e iletmemiz gerekecek. *view* ile template içinde neyin (hangi modelin) gösterileceğine karar veriyoruz. -Peki, bunu nasıl yapacağız? +Tamam, peki nasıl yapacağız? -`blog/views.py`'ı açacağız. Şu anda `post_list` *view*ü şöyle: +`blog/views.py`'ı açacağız. Şu anda `post_list` *view*'ı şöyle: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render def post_list(request): return render(request, 'blog/post_list.html', {}) -``` +``` + +Kodları farklı dosyalara eklemekten bahsettiğimizi hatırlıyor musunuz? Şu an `models.py` içinde yazdığımız modeli kullanma zamanı. `from .models import Post` şeklinde bir satır ekleyeceğiz: -Kodları farklı dosyalara eklemekten bahsettiğimizi hatırlıyor musunuz? Şimdi `models.py`'de yazdığımız modeli ekleme zamanı. `from .models import Post` satırını şu şekilde ekleyeceğiz: +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render from .models import Post -``` +``` -`from`'dan sonraki nokta, *mevcut dizin* veya *mevcut uygulama* anlamına geliyor. `views.py` ve `models.py` aynı dizinde oldukları için sadece `.` ve dosyanın adı (`.py` olmadan) kullanabiliyoruz. Arkasından modelin adını (`Post`)'u dahil ediyoruz). +`models`'dan önceki nokta, *mevcut dizin* veya *mevcut uygulama* anlamına geliyor. Hem `views.py` hem de `models.py` aynı dizindedir. Bu şu anlama geliyor: `.` ve dosya ismini (`.py` olmadan) kullanabiliriz. Arkasından modelin adını (`Post`)'u dahil ediyoruz (import ediyoruz). -Sırada ne var? `Post` modelinden gönderileri almamız için `QuerySet` dediğimiz bir şeye ihtiyacımız var. +Sırada ne var? `Post` modelinden gerçek blog gönderilerini almak için `QuerySet` denilen sorgu setine ihtiyacımız var. ## QuerySet (Sorgu Seti) -QuerySet'in nasıl çalıştığı konusunda bir fikriniz oluşmuştur. [Django ORM (QuerySets) bölümü][1]nde konuşmuştuk. +QuerySet'in nasıl çalıştığı konusunda bir fikriniz oluşmuştur. [Django ORM (QuerySets) bölümü](../django_orm/README.md)nde konuşmuştuk. - [1]: ../django_orm/README.md +Şimdi yayınlanmış ve `published_date`'e (yayınlanma tarihine) göre sıralanmış bir gönderi listesi istiyoruz, değil mi? Bunu QuerySets bölümünde yapmıştık zaten! -Şimdi yayınlanmış ve `yayinlanma_tarihi`'ne göre sıralanmış bir gönderi listesi istiyoruz, değil mi? Bunu QuerySets bölümünde yapmıştık zaten! +{% filename %}blog/views.py{% endfilename %} +```python +Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') ``` - Post.objects.filter(yayinlanma_tarihi__lte=timezone.now()).order_by('yayinlanma_tarihi') -``` -Şimdi bu kodu `blog/views.py` dosyasında `def post_list(request)` fonksiyonuna ekleyelim: +Şimdi `blog/views.py` dosyasına `def post_list(request)` fonksiyonunu ekleyin ama öncelikle `from django.utils import timezone` eklemeyi unutmayın: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -46,30 +52,30 @@ from django.utils import timezone from .models import Post def post_list(request): - posts = Post.objects.filter(yayinlanma_tarihi__lte=timezone.now()).order_by('yayinlanma_tarihi') + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') return render(request, 'blog/post_list.html', {}) -``` - -QuerySet'imiz için bir *değişken* yarattığımıza dikkat edin: `posts`. Bu QuerySet'in ismi. Bundan sonra ondan ismi ile bahsedebiliriz. +``` -Bu kod `timezone.now()` fonksiyonunu kullanıyor, dolayısıyla `timezone` için bir 'import' eklememiz gerekiyor. +Son eksik parça `posts` QuerySet'i şablon içeriğine iletiyor. Endişelenmeyin - daha sonraki bölümlerde nasıl görüntüleyebileceğimizi ele alacağız. -Son eksik kalan kısım `posts` QuerySet'ini template'e iletmek (nasıl göstereceğimizi bir sonraki bölümde işleyeceğiz). +QuerySet'imiz için bir *değişken* yarattığımıza dikkat edin: `posts`. Bu QuerySet'in ismi. Bundan sonra ondan ismi ile bahsedebiliriz. -`render` fonksiyonunda halihazırda `request` diye bir parametremiz var (dolayısıyla Internet üzerinden kullanıcı ile ilgili aldığımız her şey) ve bir de template dosyamız `'blog/post_list.html'` var. `{}` şeklindeki son parametremiz, template içinde kullanılmak üzere bir şeyler ekleyebileceğimiz bir değişken. Bunlara isimler vermemiz gerekiyor (`'posts'` ismini kullanmaya devam edeceğiz şimdilik :)). Şöyle olması lazım: `{'posts': posts}`. `:`'dan önceki kısmın bir string olduğuna dikkat edin; etrafına tek tırnak koymanız gerekiyor `''`. +`render` fonksiyonunda `request` (internet aracılığıyla kullanıcıdan aldığımız her şey) adında ve başka bir şablon dosyası (`'blog/post_list.html'`) veren parametremiz var. Son parametremiz `{}`, şablonu kullanmak için bir şeyler ekleyebileceğimiz bir yer. Bunlara isimler vermemiz gerekiyor (`'posts'` ismini kullanmaya devam edeceğiz şimdilik). :) Şöyle olması lazım: `{'posts': posts}`. `:` 'dan önceki kısım string bunu not edelim; çift tırnak: `"` içine almamız gerekiyor. Nihayetinde `blog/views.py` şu şekle gelmiş olmalı: +{% filename %}blog/views.py{% endfilename %} + ```python from django.shortcuts import render from django.utils import timezone from .models import Post def post_list(request): - posts = Post.objects.filter(yayinlanma_tarihi__lte=timezone.now()).order_by('yayinlanma_tarihi') - return render(request, 'blog/post_list.html', {'posts': posts}) -``` + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {'posts': posts}) +``` İşte bu kadar! Template'e geri gidip QuerySet'leri görünür hale getirme zamanı! -Django'da QuerySet'lerle ilgili daha fazla bilgi istiyorsanız şuraya bakabilirsiniz: https://docs.djangoproject.com/en/1.10/ref/models/querysets/ +Django'daki QuerySet'ler hakkında daha fazla bilgi sahibi olmak istiyor musunuz? Şuraya bakabilirsiniz: https://docs.djangoproject.com/en/2.0/ref/models/querysets/ \ No newline at end of file diff --git a/tr/extend_your_application/README.md b/tr/extend_your_application/README.md index 6dbe13abfdc..31179340232 100644 --- a/tr/extend_your_application/README.md +++ b/tr/extend_your_application/README.md @@ -1,3 +1,5 @@ +{% set warning_icon = '' %} + # Uygulamanı genişlet Websitemizi oluşturmak için gerekli adımların hepsini tamamladık: bir modelin, url'nin, view'ün ve template'in nasıl yazılacağını biliyoruz. Websitemizi nasıl güzelleştirebiliriz onu da biliyoruz. @@ -8,9 +10,9 @@ Blog'umuzda lazım olan ilk şey bir gönderiyi göstermek için bir sayfa, değ Halihazırda bir `Post` modelimiz var, dolayısıyla `models.py` dosyasına bir şey eklememize gerek yok. -## Bir gönderinin detayı için bir şablon linki oluşturun +## Bir gönderinin detayı için bir template(şablon) linki oluşturun -`blog/templates/blog/post_list.html` dosyasına bir link (bağlantı) ekleyerek başlayacağız. Şu ana kadar yaptıklarımızın şöyle gözüküyor olması lazım: +`blog/templates/blog/post_list.html` dosyasına bir link (bağlantı) ekleyerek başlayacağız. Bu dosyayı kod düzenleyicisinde açalım, şimdiye kadar yaptıklarımızın şöyle gözüküyor olması lazım: ```html {% extends 'blog/base.html' %} @@ -19,177 +21,194 @@ Halihazırda bir `Post` modelimiz var, dolayısıyla `models.py` dosyasına bir {% for post in posts %}
- {{ post.yayinlanma_tarihi }} + {{ post.published_date }}
-

{{ post.baslik }}

-

{{ post.yazi|linebreaks }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

{% endfor %} -{% endblock content %} -``` - +{% endblock %} +``` + +{% raw %}Gönderi listesindeki bir gönderinin başlığından bir gönderinin detay sayfasına bir link (bağlantı) olsun istiyoruz. `

{{ post.title }}

`'i gönderinin detay sayfasına link verecek şekilde değiştirelim:{% endraw %} -{% raw %}Gönderi listesindeki bir gönderinin başlığından bir gönderinin detay sayfasına bir link (bağlantı) olsun istiyoruz. `

{{ post.baslik }}

`'i gönderinin detay sayfasına link verecek şekilde değiştirelimi:{% endraw %} +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} ```html -

{{ post.baslik }}

-``` +

{{ post.title }}

+``` -{% raw %}Gizemli `{% url 'post_detail' pk=post.pk %}` satırını anlatma zamanı. Şüphelendiğiniz üzere, `{% %}` notasyonu, Django template tags (şablon etiketleri) kullandığımız manasına geliyor. Bu sefer bizim için URL oluşturacak bir template etiketi kullanacağız!{% endraw %} +{% raw %}Gizemli `{% url 'post_detail' pk=post.pk %}` satırını anlatma zamanı. Şüphelendiğiniz üzere, `{% %}` notasyonu, Django template tags (şablon etiketleri) kullandığımız manasına geliyor. Bu sefer bizim için URL oluşturacak bir şablon (template) etiketi kullanacağız!{% endraw %} -`blog.views.post_detail`, oluşturmak istediğimiz `post_detail` *view*'una bir yol. Lütfen dikkat: `blog` uygulamamızın adı (`blog` dizini); `views`, `views.py` dosyasının adından geliyor ve son kısım - `post_detail` - *view*'ün adından geliyor. +`post_detail` kısmı Django'nun `blog/urls.py/` dosyasının içinde post_detail adlı bir URL beklediği anlamına gelir. -Şimdi http://127.0.0.1:8000/'ye gittiğimizde bir hata alacağız (beklediğimiz bir şey, çünkü URL'miz veya `post_detail` için bir *view*'ümüz yok). Şöyle görünecektir: +Peki `pk=post.pk`? `pk` primary key (birincil anahtar) için kullanılan kısaltmadır, veritabanındaki her kayıt için verilen özgün (eşsiz) bir isimdir. `Post` modelimiz için bir primary key tanımlamamış olduğumuz için, Django onu bizim için otomatik olarak oluşturdu (genelde, her kayıt için bir artan numara ile, örnek 1, 2, 3) ve her post için `pk` adlı bir alan ekledi. Primary key'e erişmek için `post.pk` yazarız, tıpkı `Post` objesindeki diğer alanlara eriştiğimiz gibi (`title`, `author`, vb.)! -![NoReverseMatch error (Tersi yok hatası)][1] +Şimdi http://127.0.0.1:8000/ adresine gittiğimizde bir hata ile karşılaşacağız (`post_detail` için bir URL ya da *görüntü (view)* olmadığı için hatayı almamız normal). Hata böyle görünecektir: - [1]: images/no_reverse_match2.png +![NoReverseMatch error (Tersi yok hatası)](images/no_reverse_match2.png) ## Bir gönderinin detayı için URL oluşturun -`post_detail` *view*'ümüz için `urls.py`'un içinde bir URL oluşturalım! +`post_detail` *view*'ımız için `urls.py`'un içinde bir URL oluşturalım! İlk gönderimizin detayının şu **URL**'de gösterilmesini istiyoruz: http://127.0.0.1:8000/post/1/ -`blog/urls.py` dosyasında `post_detail` adında bir Django *view*'una işaret eden bir URL yapalım. Bu <1>view bir gönderinin tümünü gösterecek. `blog/urls.py` dosyasına `url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'),` satırını ekleyin. Dosyanın şu hale gelmiş olması gerekiyor: +`blog/urls.py` dosyasında `post_detail` adında bir Django *view*'ına işaret eden bir URL yapalım. Bu <1>view bir gönderinin tümünü gösterecek. Kod düzenleyicide `blog/urls.py` dosyasını açın ve `path('post/)/', views.post_detail, name='post_detail'),` satırını ekleyin, böylece dosya şöyle görünür: + +{% filename %}{{ warning_icon }} blog/urls.py{% endfilename %} ```python -from django.conf.urls import include, 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'), ] -``` - -Şu kısım `^post/(?P[0-9]+)/$` korkutucu gözüküyor, ama endişelenmeyin, açıklayacağız: -- Gene `^` ile başlıyor - "başlangıç'. -- `post/` sadece URL'nin başlangıçtan sonra __post__ ve __/.__ ifadelerinin geçmesi gerektiği anlamına geliyor. Şimdilik iyi gidiyor. -- `(?P[0-9]+)` - bu kısım biraz daha karışık. Buranın anlamı şu: Django bu alana yerleştirdiğimiz her şeyi alacak ve onu `pk` adında bir değişken olarak view'e aktaracak. `[0-9]` bize eşleşenlerin sadece rakam (yani harf olamaz) olabileceğini söylüyor (0 ile 9 arasındaki her şey). `+` en az bir veya daha fazla rakam olması gerektiğini ifade ediyor. Yani `http://127.0.0.1:8000/post//` eşleşmez ama `http://127.0.0.1:8000/post/1234567890/` eşleşir! -- `/` - gene bir __/__'e ihtiyacımız var -- `$` - "son"! - -Bu şu demek, eğer tarayıcınıza `http://127.0.0.1:8000/post/5/` yazarsanız, Django `post_detail` adında bir *view* aradığınızı anlar ve `pk` eşittir `5` bilgisini *view*'e aktarır. +``` -`pk`, `primary key`'in (tekil anahtarın) kısaltılmış hali. Bu isim sıklıkla Django projelerinde kullanılır. Değişkeninize istediğiniz ismi verebilirsiniz (hatırlayın: küçük harfler ve boşluk yerine `_`!). Örneğin `(?P[0-9]+)` yerine `post_id` değişkenini kullanabilirdik. O zaman şöyle olurdu: `(?P[0-9]+)`. +`post//` kısmı bir URL kalıbı belirtir - sizin için bunu açıklayalım: -Tamam, `blog/urls.py` dosyasına yeni bir URL kalıbı ekledik! Sayfayı tazeleyelim: http://127.0.0.1:8000/ Bam! Yeni bir hata daha! Beklenildiği üzere! +- `post/`, URL'nin **post** kelimesi ile başlayıp ardından ** / ** ile devam etmesi gerektiği anlamına gelir. +- `` - bu bölüm daha zorlayıcı. Django'nun bir tamsayı değeri beklediği ve onu `pk` adlı bir değişken olarak bir görünüme(view) aktaracağı anlamına gelir. +- `/` - URL'yi bitirmeden önce **/** 'e tekrar ihtiyacımız var. -![AttributeError (Özellik hatası)][2] +Bu şu demek, eğer tarayıcınıza `http://127.0.0.1:8000/post/5/` yazarsanız, Django `post_detail` adında bir *view* aradığınızı anlar ve `pk` eşittir `5` bilgisini *view*'e aktarır. -Bir sonraki adımın ne olduğunu hatırlıyor musunuz? Tabi ki: view'ü eklemek! +Tamamdır.`blog/urls.py`!'e yeni bir URL kalıbı ekledik! Http://127.0.0.1:8000/ sayfasını yenileyelim.Boom! Sunucu çalıştırmayı tekrar durdurdu. Konsola göz at, beklendiği gibi bir hata daha var! + +![AttributeError (Özellik hatası)](images/attribute_error2.png) + +Bir sonraki adımın ne olduğunu hatırlıyor musunuz? Tabi ki: view(görünüm)'ü eklemek! ## Gönderi detayı için bir view ekleyin -Bu sefer *view*'ümüze `pk` adında bir parametre ekleyeceğiz. *view*'ümüzün onu yakalaması gerekiyor, değil mi? Fonksiyonumuzu `def post_detail(request, pk):` olarak tanımlayacağız. Dikkat edin, url'lerde kullandığımız ismin birebir aynısını kullanmamız gerekiyor (`pk`). Bu değişkeni kullanmamak yanlıştır ve hataya sebep olacaktır! +Bu sefer *view*'ımıza `pk` adında bir parametre ekleyeceğiz. *view*'ümüzün onu yakalaması gerekiyor, değil mi? Fonksiyonumuzu `def post_detail(request, pk):` olarak tanımlayacağız. Dikkat edin, url'lerde kullandığımız ismin birebir aynısını kullanmamız gerekiyor (`pk`). Bu değişkeni kullanmamak yanlıştır ve hataya sebep olacaktır! -Şimdi sadece ve sadece bir blog gönderisini almak istiyoruz. Bunu yapmak için querysets'i şu şekilde kullanabiliriz: +Şimdi sadece ve sadece bir tane blog gönderisi almak istiyoruz. Bunu yapmak için şunun gibi sorgu setlerini/kümelerini kullanabiliriz: -``` +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} + +```python Post.objects.get(pk=pk) -``` +``` Ama bu kodun bir problemi var. Eğer gelen `primary key` (`pk` - tekil anahtar) ile bir `Post` (gönderi) yoksa, çok çirkin bir hatamız olacak! -![DoesNotExist error (Yok hatası)][3] +![DoesNotExist error (Yok hatası)](images/does_not_exist2.png) -Bunu istemiyoruz! Ama tabi Django'da bunu ele alan bir şey var: `get_object_or404`. Eğer verilen `pk` ile bir `Post` bulunamazsa, çok daha güzel bir sayfa gösterilecek (`Sayfa bulunamadı 404` sayfası). +Bunu istemiyoruz! Ama tabi Django'da bunu ele alan bir şey var: `get_object_or_404`. Eğer verilen `pk` ile bir `Post` bulunamazsa, çok daha güzel bir sayfa gösterilecek (`Sayfa bulunamadı 404` sayfası. -![Page not found (Sayfa bulunamadı)][4] +![Page not found (Sayfa bulunamadı)](images/404_2.png) İyi haber şu, kendi `Sayfa bulunamadı` sayfasını yapabilir ve istediğiniz kadar güzelleştirebilirsiniz. Ama şu anda çok önemli değil, o yüzden bu kısmı atlayacağız. -Evet, `views.py` dosyamıza bir *view* ekleme zamanı! +Tamam, `views.py` dosyamıza bir *view* ekleme zamanı! -`blog/views.py` dosyasını açıp aşağıdaki kodu ekleyelim: +`blog/urls.py` içinde `views.post_detail` denilen bir görünüm ifade eden `post_detail` adında bir URL kuralı oluşturduk. Bu, Django'nun ` blog/views.py içinde post_detail adlı bir görünüm fonksiyonu bekleyeceği anlamına gelir.

-``` -from django.shortcuts import render, get_object_or_404 -``` +

blog/views.py` 'i açmalıyız ve diğer `from` satırının yanına şu kodları eklemeliyiz: -Bunu diğer `from` satırlarının yakınına eklememiz gerekiyor. Dosyanın sonuna *view*'ümüzü ekleyeceğiz: +{% filename %}blog/views.py{% endfilename %} +```python +from django.shortcuts import render, get_object_or_404 ``` + +Ve dosyanın sonuna kendi *view*'ımızı ekleyeceğiz: + +{% filename %}blog/views.py{% endfilename %} + +```python def post_detail(request, pk): post = get_object_or_404(Post, pk=pk) return render(request, 'blog/post_detail.html', {'post': post}) -``` +``` Evet. http://127.0.0.1:8000/ sayfasını tazeleme zamanı -![Post list view (Gönderi listesi görünümü)][5] +![Post list view (Gönderi listesi görünümü)](images/post_list2.png) Çalıştı! Fakat blog gönderisi başlığındaki bir bağlantıya tıkladığınızda ne oluyor? -![TemplateDoesNotExist error (Template yok hatası)][6] +![TemplateDoesNotExist error (Template yok hatası)](images/template_does_not_exist2.png) Of hayır! Başka bir hata! Ama onu nasıl halledeceğimizi biliyoruz, di mi? Bir template eklememiz gerekiyor! -## Gönderi detayı için bir template oluşturun +## Post(gönderi) detayları için bir template(şablon) oluştur -`blog/templates/blog` dizininde `post_detail.html` adında bir dosya oluşturacağız. +`blog/templates/blog` dizininde `post_detail.html` adında bir dosya oluşturalım ve kod düzenleyicisinde açalım. Şöyle görünmeli: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} + ```html {% extends 'blog/base.html' %} - + {% block content %}

- {% if post.yayinlanma_tarihi %} + {% if post.published_date %}
- {{ post.yayinlanma_tarihi }} + {{ post.published_date }}
{% endif %} -

{{ post.baslik }}

-

{{ post.yazi|linebreaks }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

{% endblock %} -``` +``` -Bir kere daha `base.html` dosyasını genişleteceğiz. `content` bloğunda bir gönderinin varsa yayınlama tarihini , başlığını ve metnini göstermek istiyoruz. Ama daha önemli şeyleri konuşmalıyız, değil mi? +Bir kere daha `base.html` dosyasıa ekleme yapacağız. `content` blogunda bir gönderinin varsa published_date, title ve text'ini göstermek istiyoruz. Ama daha önemli şeyleri konuşmalıyız, değil mi? -{% raw %}`{% if ... %} ... {% endif %}` bir şeyi kontrol etmek istediğimizde kullanabileceğimiz bir template etiketidir ( **Python'a giriş** bölümünden <1>if ... else .. 'i hatırladınız mı?). Bu senaryoda gönderinin `yayinlanma_tarihi`'nin boş olup olmadığına bakmak istiyoruz.{% endraw %} +{% raw %}`{% if ... %} ... {% endif %}` bir şeyi kontrol etmek istediğimizde kullanabileceğimiz bir şablon etiketidir. ( `if ... else ..` ifadelerini **Python'a Giriş** bölümünden hatırladın mı?) Bu durumda eğer gönderinin `published_date` kısmı boş değilse kontrol etmek isteriz.{% endraw %} -Tamam, sayfamızı tazeleyip `Sayfa bulunamadı` hatasının gidip gitmediğine bakabiliriz. +Tamam, şimdi sayfamızı yenileyerek `TemplateDoesNotExist` hatası kaybolmuş mu görebiliriz. -![Post detail page (Gönderi detay sayfası)][7] +![Post detail page (Gönderi detay sayfası)](images/post_detail2.png) Heyo! Çalışıyor! -## Bir şey daha: deployment (yayına alma) zamanı! +# Yayına alma zamanı! Sitenizin hala PythonAnywhere'de çalışıp çalışmadığına bakmakta fayda var, değil mi? Yeniden taşımayı deneyelim. -``` -$ git status -$ git add -A . -$ git status -$ git commit -m "Detaylı blog gönderileri için CSS'e ilaveten view ve template eklendi." -$ git push -``` +{% filename %}komut satırı{% endfilename %} -* Sonra bir [PythonAnywhere Bash konsol][8] una gidip: + $ git status + $ git add --all . + $ git status + $ git commit -m "Site için CSS ve ayrıntılı blog gönderisi için görünüm ve şablon eklendi." + $ git push + -``` -$ cd ilk-blogum -$ source myvenv/bin/activate -(myvenv)$ git pull -[...] -(myvenv)$ python manage.py collectstatic -[...] -``` +Sonra bir [PythonAnywhere Bash konsol](https://www.pythonanywhere.com/consoles/) una gidip: + +{% filename %}komut satırı{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Açı parantezleri olmadan ``'i gerçek PythonAnywhere kullanıcı isminizle değiştirmeyi unutmayın). + +## Sunucudaki statik dosyaları güncelleyelim + +PythonAynwhere gibi sunucular "statik dosyalar"a (CSS dosyaları gibi) Python dosyalarından farklı davranır çünkü onları daha hızlı yüklenmesi için optimize edebilir. Sonuç olarak, CSS dosyalarında her değişiklik yaptığınızda, sunucuya onları güncellediğimizi söylemek için ilave bir komut çalıştırmalıyız. Bu komuta `collectstatic` adı verilir. + +Daha önceden çalıştırdığın virtualenv'in hala etkin değilse tekrar aktive ederek başlayın. (PythonAnywhere bunu yapmak için `workon` adlı bir komut kullanır. Kendi bilgisayarında kullandığın `source myenv/bin/activate` komutu gibi.): + +{% filename %}komut satırı{% endfilename %} + + $ workon .pythonanywhere.com + (kullaniciadiniz.pythonanywhere.com)$ python manage.py collectstatic + [...] + -* Nihayet, [Web tab][9] ına gidip **Reload** edelim. +`manage.py collectstatic` komutu biraz `manage.py migrate` komutu gibidir. Kodumuzda bazı değişiklikler yapıp Django'ya bu değişiklikleri sunucunun statik dosyalar yığınına ya da veritabanına uygulamasını söyledik. -O kadar! Tebrikler :) +Her durumda, artık ["Web" sayfasına](https://www.pythonanywhere.com/web_app_setup/) (konsolun sağ üstündeki menü düğmesinden) atlamaya ve **Yeniden Yükle** seçeneğine tıklamaya hazırız ve sonucu görmek için https://adınız.pythonanywhere.com sayfasına bakın. - [2]: images/attribute_error2.png - [3]: images/does_not_exist2.png - [4]: images/404_2.png - [5]: images/post_list2.png - [6]: images/template_does_not_exist2.png - [7]: images/post_detail2.png - [8]: https://www.pythonanywhere.com/consoles/ - [9]: https://www.pythonanywhere.com/web_app_setup/ +İşte bu kadar! Tebrikler :) \ No newline at end of file diff --git a/tr/extend_your_application/images/404_2.png b/tr/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/tr/extend_your_application/images/404_2.png and b/tr/extend_your_application/images/404_2.png differ diff --git a/tr/extend_your_application/images/attribute_error2.png b/tr/extend_your_application/images/attribute_error2.png index 05296adf4a5..4b8262476d9 100644 Binary files a/tr/extend_your_application/images/attribute_error2.png and b/tr/extend_your_application/images/attribute_error2.png differ diff --git a/tr/extend_your_application/images/does_not_exist2.png b/tr/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/tr/extend_your_application/images/does_not_exist2.png and b/tr/extend_your_application/images/does_not_exist2.png differ diff --git a/tr/extend_your_application/images/no_reverse_match2.png b/tr/extend_your_application/images/no_reverse_match2.png index 306926206f8..aba1c9c8980 100644 Binary files a/tr/extend_your_application/images/no_reverse_match2.png and b/tr/extend_your_application/images/no_reverse_match2.png differ diff --git a/tr/extend_your_application/images/post_detail2.png b/tr/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/tr/extend_your_application/images/post_detail2.png and b/tr/extend_your_application/images/post_detail2.png differ diff --git a/tr/extend_your_application/images/post_list2.png b/tr/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/tr/extend_your_application/images/post_list2.png and b/tr/extend_your_application/images/post_list2.png differ diff --git a/tr/extend_your_application/images/template_does_not_exist2.png b/tr/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/tr/extend_your_application/images/template_does_not_exist2.png and b/tr/extend_your_application/images/template_does_not_exist2.png differ diff --git a/tr/how_the_internet_works/README.md b/tr/how_the_internet_works/README.md index 86e97e28e04..919bafcc04f 100644 --- a/tr/how_the_internet_works/README.md +++ b/tr/how_the_internet_works/README.md @@ -1,53 +1,47 @@ -# İnternet nasıl çalışır +# İnternet Nasıl Çalışır -> Bu bölüm Jessica McKellar'ın "How the Internet works" yani "İnternet nasıl çalışır" adlı bir konuşmasından esinlenerek oluşturuldu. (http://web.mit.edu/jesstess/www/). +> Evdeki okuyucular için: bu bölüm [İnternet Nasıl Çalışır](https://www.youtube.com/watch?v=oM9yAA09wdc) videosunda anlatıldı. +> +> Bu bölüm Jessica McKellar'ın "İnternet Nasıl Çalışır" adlı konuşmasından esinlenilerek oluşturuldu. (http://web.mit.edu/jesstess/www/). -Bahse varız ki İnternet'i her gün kullanıyorsunuz. Fakat tarayıcınıza http://djangogirls.org gibi bir adres girip `enter` tuşuna bastığınızda neler olduğunu biliyor musunuz? +İddia ediyoruz ki her gün İnternet'i kullanıyorsunuz. Fakat tarayıcınıza https://djangogirls.org gibi bir adres girip `enter` tuşuna bastığınızda neler olduğunu biliyor musunuz? -Öncelikle bir web sitesinin bir sabit diske kaydedilmiş bir grup dosya olduğunu anlamanız gerekir. Tıpkı filmleriniz, müzikleriniz ya da resimleriniz gibi. Ancak, web sitelerine özel şöyle bir durum var: HTML adı verilen bir bilgisayar kodu içerirler. +Anlamanız gereken ilk şey; bir web sitesinin, sadece bir sabit diskte saklanan birtakım dosyalardan ibaret olduğudur. Tıpkı filmleriniz, müzikleriniz ya da resimleriniz gibi. Ancak, web sitelerine özel şöyle bir durum var: HTML adı verilen bir bilgisayar kodu içerirler. Eğer programlamaya aşina değilseniz HTML'yi kavramak başlangıçta zor olabilir, ama web tarayıcılarınız (Chrome, Safari, Firefox, vs.) ona bayılıyor. Web tarayıcılarınız bu kodu anlamak, komutlarını yerine getirmek ve size bu websitesini oluşturan dosyaları sunmak için tasarlanmıştır, tam da olmasını istediğiniz gibi. -Her dosya gibi, bu HTML dosyalarını da sabit diskte bir yerde saklamamız gerekir. Internet için, *sunucu* denilen özel ve güçlü bilgisayarlar kullanıyoruz. Bir ekranları, fareleri ya da klavyeleri yok çünkü esas amaçları veriyi saklamak ve sunmak. Bu yüzden onlara *sunucu* diyoruz -- çünkü size veri *sunuyorlar*. +Her dosya gibi, bu HTML dosyalarını da sabit diskte bir yerde saklamamız gerekir. Internet için, *sunucu (server)* denilen özel ve güçlü bilgisayarlar kullanıyoruz. Bir ekranları, fareleri ya da klavyeleri yok çünkü esas amaçları veriyi saklamak ve sunmak. Bu yüzden onlara *sunucular* diyoruz – çünkü size veri *sunuyorlar*. -Peki, fakat İnternet'in nasıl göründüğünü bilmek istiyorsunuz. Değil mi? +Tamam ama yinede Internetin nasıl gözüktüğünü görmek istersiniz değil mi? Size bir resmini çizdik, İnternet işte buna benzer: -![Şekil 1.1][1] +![Şekil 1.1](images/internet_1.png) - [1]: images/internet_1.png +Çok karışık, değil mi? Aslında birbirine bağlanmış bir makina ağıdır (yukarıda bahsedilen *servers*). Yüz binlerce makine! Dünyanın dört bir yanını saran yüz binlerce kilometrelik kablolar! İnternet'in ne kadar karışık olduğunu görmek için denizaltı kablo haritası web sitesine(http://submarinecablemap.com) göz atabilirsiniz. İşte web sitesinden bir ekran görüntüsü: -Çok karışık, değil mi? Aslında bu birbirine bağlı makinelerin(yukarıda bahsi geçen *sunucu*lar) birbirine bağlandığı bir ağ. Yüz binlerce makine! Dünyanın dört bir yanını saran yüz binlerce kilometrelik kablolar! İnternet'in ne kadar karışık olduğunu görmek için denizaltı kablo haritası web sitesine(http://submarinecablemap.com) göz atabilirsiniz. İşte web sitesinden bir ekran görüntüsü: +![Şekil 1.2](images/internet_3.png) -![Şekil 1.2][2] - - [2]: images/internet_3.png - -Büyüleyici, değil mi? Ama açıkça belli ki, İnternet'e bağlanan tüm makineler arasında kablolar olması mümkün değil. Yani, bir makineye ulaşmak için( örneğin http://djangogirls.org web sitesinin kayıtlı olduğu) bir çok farklı makineden istek geçmesi gerekli. +Büyüleyici, değil mi? Ama, İnternet'e bağlanan her makine arasında bir kablo olması mümkün değil. Yani, bir makineye erişmek için (örneğin, https://djangogirls.org sitesinin kayıtlı olduğu) birçok farklı makine üzerinden istek geçmesi gereklidir. Şöyle gözükmekte: -![Şekil 1.3][3] +![Şekil 1.3](images/internet_2.png) - [3]: images/internet_2.png - -Tarayıcınıza http://djangogirls.org yazdığınızda, "Sevgili Django Girls, ben djangogirls.org web sitesini görmek istiyorum. Lütfen bana gönderin!" diyen bir mektup gönderdiğinizi düşünün. +https://djangogirls.org yazdığınızda: "Sevgili Django Girls, djangogirls.org websitesini görmek istiyorum. Lütfen bana gönderin!" diyen bir mektup gönderdiğinizi düşünün. Mektubunuz size en yakın postaneye gider. Daha sonra sizden biraz daha uzak bir postaneye gider, daha sonra biraz daha uzaktakine, daha uzağa ve en son gitmesi gereken yere. Tek farklı olan, aynı yere bir çok mektup(*veri paketi*) gönderirseniz, tamamen farklı postanelerden(*yönlendirici*) geçebilir. Bu, her bir postanede nasıl dağıtım yapıldığına bağlıdır. -![Şekil 1.4][4] - - [4]: images/internet_4.png +![Şekil 1.4](images/internet_4.png) Evet, bu kadar basit. Bir mektup yollarsınız ve cevap beklersin. Tabii ki, kağıt kalem yerine bayt biriminde veri kullanırsınız, fakat fikir aynı! -Sokak adı, şehir, alan kodu ve ülke adı yerine, biz IP adreslerini kullanırız. Bilgisayarınız ilk olarak DNS'den (Domain Name System - Alan Adı Sistemi) djangogirls.org adresini bir IP adresine çevirmesini ister. Bu biraz ulaşmak istediğiniz kişinin adına bakarak telefon numarası ve adresini bulabildiğiniz eski telefon rehberleri gibi çalışır. +Sokak adı, şehir, alan kodu ve ülke adı yerine, biz IP adreslerini kullanırız. Bilgisayarınız ilk olarak DNS'den (Domain Name System - Alan Adı Sistemi) djangogirls.org adresini bir IP adresine çevirmesini ister. Bu bir nebze burada iletişim kurmak istediğiniz kişinin adına bakarak telefon numarası ve adresini bulabildiğiniz eski telefon rehberleri gibi çalışır. -Bir mektup gönderdiğinizde, bazı özelliklerin doğru teslim edilmesi gerekecektir: bir adres, pul vs. Ayrıca alıcının anlayacağı bir dil kullanıyorsunuz, değil mi? Aynısı bir web sitesini görmek için gönderdiğiniz *veri paketleri* için de geçerli. HTTP(Hypertext Transfer Protocol - HiperMetin transfer protokolü) adı verilen bir protokol kullanırız. +Bir mektup gönderdiğinizde, bazı özelliklerin doğru olarak teslim edilecek olması gerekir: bir adres, bir pul vs. Ayrıca alıcının anlayacağı bir dil kullanıyorsunuz, değil mi? Aynısı bir web sitesini görmek için gönderdiğiniz *veri paketleri* için de geçerli. HTTP(Hypertext Transfer Protocol - HiperMetin transfer protokolü) adı verilen bir protokol kullanırız. -Basit olarak, bir web siteniz olduğunuzda, içinde yaşayacağı bir *sunucu* makineniz olması gerekli. *Sunucu* (bir mektupla gelen) bir *istek* aldığında, (başka bir mektupla) size web sitenizi gönderir. +Basit olarak, bir web siteniz olduğunda, içinde yaşayacağı bir *sunucu* makineniz olması gerekli. *Sunucu* (bir mektupla gelen) bir *istek* aldığında, (başka bir mektupla) size web sitenizi gönderir. -Bu bir Django eğitimi olduğu için, Django'nun ne yaptığını soracaksınız. Bir yanıt gönderirken, herkese her zaman aynı şeyi göndermek istemezsiniz. Mektupları özellikle size yazan kişi için kişiselleştirmek çok daha iyi, değil mi? Django bu kişiselleştirilmiş, ilginç mektupları yazmanıza yardımcı olur :). +Bu bir Django eğitimi olduğundan, Django'nun ne yaptığını sorabilirsiniz. Bir yanıt gönderirken, herkese her zaman aynı şeyi göndermek istemezsiniz. Mektupları özellikle size yazan kişi için kişiselleştirmek çok daha iyi, değil mi? Django bu kişiselleştirilmiş, ilginç mektupları yazmanıza yardımcı olur. :) -Bu kadar konuşma yeter, bir şeyler yaratma vakti! +Yeterince konuştuk - Yaratma zamanı! \ No newline at end of file diff --git a/tr/how_the_internet_works/images/internet_1.png b/tr/how_the_internet_works/images/internet_1.png index 9c5bcf0b003..e289eac2b23 100644 Binary files a/tr/how_the_internet_works/images/internet_1.png and b/tr/how_the_internet_works/images/internet_1.png differ diff --git a/tr/how_the_internet_works/images/internet_2.png b/tr/how_the_internet_works/images/internet_2.png index dd5861f376f..e8cf8b77999 100644 Binary files a/tr/how_the_internet_works/images/internet_2.png and b/tr/how_the_internet_works/images/internet_2.png differ diff --git a/tr/how_the_internet_works/images/internet_3.png b/tr/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/tr/how_the_internet_works/images/internet_3.png and b/tr/how_the_internet_works/images/internet_3.png differ diff --git a/tr/how_the_internet_works/images/internet_4.png b/tr/how_the_internet_works/images/internet_4.png index 2661cec1b61..d4748ac48ef 100644 Binary files a/tr/how_the_internet_works/images/internet_4.png and b/tr/how_the_internet_works/images/internet_4.png differ diff --git a/tr/html/README.md b/tr/html/README.md old mode 100755 new mode 100644 index 6ee55824559..f59d27d5b6f --- a/tr/html/README.md +++ b/tr/html/README.md @@ -2,15 +2,15 @@ Template nedir diye sorabilirsiniz. -Template, farklı bilgileri hep aynı biçimde sunmak için tekrar tekrar kullanabileceğimiz bir dosyadır - örneğin, mektup yazmanıza yardımcı olan bir template kullanabilirsiniz çünkü yazacağınız tüm mektuplar farklı mesajlar içerse ve farklı kişilere gönderilse de aynı sayfa düzenine sahip olacaktır. +Template (şablon), farklı bilgileri hep aynı biçimde sunmak için tekrar tekrar kullanabileceğimiz bir dosyadır - örneğin, mektup yazmanıza yardımcı olan bir template kullanabilirsiniz çünkü yazacağınız tüm mektuplar farklı mesajlar içerse ve farklı kişilere gönderilse de aynı sayfa düzenine sahip olacaktır. -Bir Django template düzeni HTML adını verdiğimiz bir dilde tanımlanır (**İnternet nasıl çalışır** adlı ilk bölümde bahsettiğimiz HTML). +Bir Django template'inin formatı HTML adını verdiğimiz bir dilde tanımlanır (**İnternet nasıl çalışır** adlı ilk bölümde bahsettiğimiz HTML). ## HTML nedir? -HTML Chrome, Firefox veya Safari gibi web tarayıcılar tarafından bir web sayfasını kullanıcıya görüntülemek için yorumlanan basit bir koddur. +HTML kullanıcıya basit bir web sayfası görüntülemek için web tarayıcınız tarafından - Chrome, Firefox veya Safari gibi - yorumlanan basit bir koddur. -HTML "HyperText Markup Language" (HiperMetin İşaretleme Dili) anlamına gelir. **HyperText (HiperMetin)** sayfalar arası bağlantıları destekleyen türden bir metin demektir. **Markup (İşaretleme)**, bir belgeyi alıp onu kodlarla işaretleyerek, nasıl yorumlanacağını (tarayıcıya) söyledik demektir. HTML kodu **etiketler** ile oluşturulur, etiketlerin her biri `<` ile başlar ve `>` ile biter. Bu etiketler biçimlendirme **öğelerini** temsil eder. +HTML "HyperText Markup Language" (HiperMetin İşaretleme Dili) anlamına gelir. **HyperText** (HiperMetin) sayfalar arası bağlantıları destekleyen türden bir metin demektir. **Markup** (işaretleme), bir belgeyi alıp onu kodlarla işaretleyerek, nasıl yorumlanacağını (tarayıcıya) söylemek demektir. HTML kodu **etiketler** ile oluşturulur, etiketlerin her biri `<` ile başlar ve `>` ile biter. Bu etiketler biçimlendirme **öğelerini** temsil eder. ## İlk template'iniz! @@ -18,57 +18,58 @@ Bir template oluşturmak bir template dosyası oluşturmak demektir. Her şey bi Template'lar `blog/templates/blog` dizininde saklanır. Öyleyse blog klasörü altında `templates` adlı bir klasör oluşturalım. Sonra da templates klasörü altında yine `blog` adlı bir klasör oluşturalım: -``` -blog -└───templates - └───blog -``` + blog + └───templates + └───blog + -(Neden iki tane `blog` adlı klasöre gerek olduğunu merak etmiş olabilirsin. Daha sonra da anlaşılacağı gibi, sitemiz karmaşıklaştıkça bu şekilde isimlendirme tarzı işimizi oldukça kolaylaştırır.) +(`blog` diye adlandırılan iki dizine niye ihtiyacımız olduğunu merak edebilirsiniz - daha sonra anlayacağınız üzere, sitemiz karmaşıklaştıkça bu şekilde isimlendirme tarzı işimizi oldukça kolaylaştırır.) Şimdi de `blog/templates/blog` dizini içine `post_list.html` adlı bir dosya oluşturalım (şimdilik içini boş bırakalım). Web sitemizin nasıl göründüğüne bir bakalım: http://127.0.0.1:8000/ -> Eğer `TemplateDoesNotExists` hatası alırsanız sunucuyu yeniden başlatmayı deneyin. Komut satırına gidip, Ctrl+C (Control ve C tuşlarına eş zamanlı basarak) yaptıktan sonra sunucuyu tekrar başlatmak için `python manage.py runserver` komutunu çalıştırın. +> Eğer hala `TemplateDoesNotExist` hatası alıyorsanız, sunucunuzu yeniden başlatmayı deneyin. Komut satırına girin, Ctrl+C (Kontrol ve C tuşlarına beraber) basarak sunucuyu durdurun ve `python manage.py runserver` komutunu çalıştırarak yeniden başlatın. -![Şekil 11.1][1] - - [1]: images/step1.png +![Şekil 11.1](images/step1.png) Artık hata kalmadı! Tebrikler :) Ama, web sitemiz aslında boş bir sayfadan başka bir şey yayınlamıyor, çünkü template boş. Bunu düzeltelim. -Template dosyamıza şunları ekleyelim: +Yeni dosyayı kod düzenleyicisinde açıp şunları ekleyelim: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html +

Merhaba!

Çalışıyor!

+ -``` - -Web siteniz şimdi nasıl görünüyor? Öğrenmek için tıklayın: http://127.0.0.1:8000 / +``` -![Şekil 11.2][2] +Web siteniz şu anda nasıl görünüyor? Öğrenmek için bir bakalım: http://127.0.0.1:8000/ - [2]: images/step3.png +![Şekil 11.2](images/step3.png) Çalıştı! Tebrikler :) -* Tüm web sayfaları en temel etiket olan`` etiketi ile başlar ve her zaman `` ile biter. Gördüğünüz gibi, web sitesinin tüm içeriği `` başlangıç etiketi ve `` bitiş etiketinin arasında yer alır -* `

` paragraf öğelerini belirten etikettir; her paragrafın bitişinde de `

` olacaktır +* En temel etiket, ``, daima herhangi bir web sayfasının başlangıcıdır ve `` daima bitişidir. Gördüğünüz gibi, web sitesinin tüm içeriği `` başlangıç etiketi ve `` bitiş etiketinin arasında yer alır +* `

` paragraf öğelerini belirten etikettir; her paragrafın bitişinde de `

` olacaktır -## Head ve body (Başlık ve gövde) +## Kafa ve vücut Aynı zamanda tüm HTML sayfaları **head** ve **body** olmak üzere iki öğeye ayrılır. -* **head** belge hakkında ekranda görüntülenmeyen bilgiler içeren öğedir. +* **head** belge hakkında ekranda görüntülenmeyen bilgiler içeren öğedir. -* **body** ise ekranda gösterilen tüm öğeleri içeren öğedir. +* **body** ise ekranda gösterilen tüm öğeleri içeren öğedir. `` öğesini tarayıcıya sayfanın yapılandırmasını anlatmak için, `` öğesini ise sayfada aslında ne olduğunu anlatmak için kullanırız. -Örneğin, web sayfasının (title) başlık elemanını `` 'in içine böyle koyabilirsiniz: +Örnek olarak, bir web sayfası başlık ögesini `` içine koyabilirsiniz, bunun gibi: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html @@ -81,54 +82,54 @@ Aynı zamanda tüm HTML sayfaları **head** ve **body** olmak üzere iki öğeye ``` - Dosyayı kaydedin ve sayfanızı yenileyin. -![Şekil 11.3][3] - - [3]: images/step4.png +![Şekil 11.3](images/step4.png) Tarayıcınızın "Zeynep'in blogu" başlığını nasıl anladığını fark ettiniz mi? `Zeynep'in blogu` kısmını başlık olarak yorumlayarak yazıyı tarayıcının başlık kısmına yerleştirdi. (Bu yazı yer işaretleri gibi yerlerde de kullanılır). -Her açılan etiketin benzer bir *kapatan etiket*, `/` ile başlayan, ile kapatılmalıdır. Ayrıca bu etiketler *iç içe* yerleştirilebilir (bu da bir etiketi kapatabilmek için, içindeki tüm etiketlerin kapanmış olmasını gerektirir). +Her açılan etiketin `/` ile başlayan bir *kapatan etiket*'i ile kapatılması gerekmektir. Ayrıca bu etiketler *iç içe* yerleştirilebilir (bu da bir etiketi kapatabilmek için, içindeki tüm etiketlerin kapanmış olmasını gerektirir). Bir şeyleri kutulara yerleştirmek gibi. Büyük bir kutuda `` olsun; onun içinde `` kutusu olsun, onun da içinde daha küçük kutular olsun: `

`. -Etiketleri düzgün *kapatma* ve *iç içe * yerleştirme kurallarına uymak çok önemli. Aksi takdirde tarayıcı belgenizi doğru yorumlayamaz ve gösteremez. +Bu *kapatma* etiketleri ve *yuvalama* ögeleri kurallarını takip etmeye ihtiyacınız vardır - eğer yapmazsanız tarayıcı onları gerektiği gibi açıklayamayabilir ve sayfanız hatalı olarak görüntülenecektir. ## Template özelleştirme Şimdi artık biraz eğlenip template'inizi özelleştirmeyi deneyebilirsiniz! İşte bunun için faydalı birkaç etiket: -* `

Bir başlık

` - ana başlığınız için -* `

Bir alt başlık

` - bir sonraki seviyedeki bir başlık için -* `

Bir alt alt başlık

` ... ve böyle `
` ya kadar iner -* `metin` metni vurgular -* `metin` metni iyice vurgular -* `
` - alt satıra gider (br etiketi içine bir şey konulmaz) -* `bağlantı` bir bağlantı oluşturur -* `
  • ilk madde
  • ikinci madde
` - tıpkı bunun gibi bir liste yapar! -* `
` - sayfanın bir bölümünü tanımlar +* `

Bir başlık

` en önemli başlığınız (ana başlık) +* `

Bir alt başlık

` - bir sonraki seviyedeki bir başlık için +* `

Bir alt-alt başlık

`…ve böyle `
`'ya kadar gider +* `

Metin paragrafı

` +* `metin` metni vurgular +* `metin` metni iyice vurgular +* `
`alt satıra gider (br etiketi ve > işaretinin arasına bir şey konulmaz) +* `bağlantı` bağlantı oluşturur +* `
  • ilk madde
  • ikinci madde
` - tıpkı bunun gibi bir liste yapar! +* `
` - sayfanın bir bölümünü tanımlar + +İşte komple bir template örneği, kopyalayın ve `blog/templates/blog/post_list.html` içine yapıştırın: -Şimdi de tam bir template örneği: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html +html Django Girls blog -

published: 14.06.2014, 12:14

İlk Blogum

Çok heyecanlıyım! Bu benim ilk blogum. Ne kadar zevkli bir işmiş bilgisayarlarla uğraşmak. Artık bilgisayar başından kalkmam.

- +

published: 14.06.2014, 12:20

İkinci gönderim

@@ -136,24 +137,22 @@ Etiketleri düzgün *kapatma* ve *iç içe * yerleştirme kurallarına uymak ço
-``` +``` Burada üç tane `div` bölümü oluşturduk. -* İlk `div` öğesi blogumuzun başlığını içeriyor - bir başlık ve bir bağlantıdan oluşuyor -* Sonraki iki `div` öğesi blog gönderilerimizi içeriyor; bunlarda bir yayın tarihi, tıklanabilir bir `h2` başlığı ve biri tarih diğeri gönderi metnimiz için olmak üzere, iki tane `p` (paragraf) var. +* İlk `div` ögesi blogumuzun başlığını içerir - bu bir baş kısımdır ve bir bağlantıdır +* Sonraki iki `div` öğesi blog gönderilerimizi içeriyor; bunlarda bir yayın tarihi (published_date), tıklanabilir bir `h2` başlığı ve biri tarih diğeri gönderi metnimiz için olmak üzere, iki tane `p` (paragraf) var. Bize yaşattığı duygu: -![Şekil 11.4][4] - - [4]: images/step6.png +![Şekil 11.4](images/step6.png) -Yaşasın! Şimdiye dek, template tam olarak sadece **aynı bilgiyi ** görüntüledi - öncesinde ise template'in **farklı** bilgileri **aynı formatta** görüntülememize izin verdiğinden bahsetmiştik. +Yaşasın! Şimdiye dek, şablonumuz tam olarak sadece **aynı bilgiyi** görüntüler - öncesinde ise şablonlardan **aynı formatta** **farklı** bilgileri görüntülememizden bahsediyorduk. -Gerçekten yapmak istediğimiz ise Django adminde ekli gerçek gönderileri göstermek - ve bir sonraki adımımız da bu. +Aslında yapmak istediğimiz Django yöneticimize eklenen gerçek postaları açmak - bundan sonra oraya gidiyoruz. -## Birşey daha: dağıtım! +## Bir şey daha: deployment (yayına alma) zamanı! Bunları İnternet'te canlı olarak görmek çok güzel olur, değil mi: @@ -161,57 +160,58 @@ Bunları İnternet'te canlı olarak görmek çok güzel olur, değil mi: İlk önce son deployment dan sonra hangi dosyaların değiştiğine bakalım. Bu komutları lokal bilgisayarımızda çalıştıralım, PythonAnywhere'de değil: -``` -$ git status -``` +{% filename %}komut-satırı{% endfilename %} + + $ git status + `djangogirls` dizininde olduğumuzdan emin olalım ve `git` 'e bu dizinde yapılan tüm değişiklikleri dahil etmesini söyleyelim: -``` -$ git add -A . -``` +{% filename %}komut-satırı{% endfilename %} + + $ git add --all . + -> **Not:** `-A` (hepsi için bir kısaltma - İngilizce'de "all" hepsi demek) `git`'in silinmiş dosyaları tanır (normalde sadece yeni/güncellenmiş dosyaları tanır). Hatırlatma: `.` içinde olduğumuz klasör anlamına gelir (3. Bölüm). +> **Not** `--all` demek eğer `git`'in silinmiş dosyaları varsa onları tanımayı sağlar (varsayılan olarak sadece yeni/değiştirilmiş dosyaları tanır). Hatırlatma: `.` içinde olduğumuz klasör anlamına gelir (3. Bölüm). Dosyalarımızı yüklemeden önce `git`'in hangilerini yükleyeceğine (`git`'in yükleyeceği dosyalar yeşil gösterilir) bakalım: -``` -$ git status -``` +{% filename %}komut-satırı{% endfilename %} + + $ git status + Neredeyse bitirdik, şimdi bu değişikliği tarihçesine kaydetmesini söyleyelim. Commit için değişiklikleri açıklayan bir mesaj yazalım. Bu aşamada istediğimizi yazabiliriz, fakat tanımlayıcı yazılar gelecekte neler yapmış olduğumuzu hatırlatması açısından faydalı olacaktır. -``` -$ git commit -m "Site için HTML dosyasını değiştirdim." -``` +{% filename %}komut-satırı{% endfilename %} + + $ git commit -m "Site için HTML dosyasını değiştirdim." + > **Not** Tamamlama mesajını çift tırnak içerisinde kullandığımızdan emin olalım. -Bunu tamamladıktan sonra, değişiklikleri Github'a push komutunu kullanarak yükleyelim: +Bunu bir kez yapıp, değişikliklerimizi GitHub'a yükledik (ittik): -``` - $ git push -``` +{% filename %}komut-satırı{% endfilename %} + + $ git push + ### Pull ile yeni kodu PythonAnywhere e alıp web uygulamasını tekrar yükleyelim -* [PythonAnywhere consoles page][5]sayfasını ve **Bash console** u açalım (ya da yeni bir tane açalım). Sonra da çalıştıralım: +* [PythonAnywhere consoles page](https://www.pythonanywhere.com/consoles/)sayfasını ve **Bash console** u açalım (ya da yeni bir tane açalım). Sonra da çalıştıralım: - [5]: https://www.pythonanywhere.com/consoles/ +{% filename %}PythonAnywhere komut satırı{% endfilename %} -``` -$ cd ~/ilk-blogum -$ source myvenv/bin/activate -(myvenv)$ git pull -[...] -(myvenv)$ python manage.py collectstatic -[...] -``` + $ cd ~/.pythonanywhere.com + $ git pull + [...] + -Kodumuzun indirilmesini izleyelim. Kodun geldiğini kontrol etmek istersek **Files (dosyalar) sekme**sini açıp PythonAnywhere'de kodumuzu görebiliriz. +(Açı parantezleri olmadan ``'i gerçek PythonAnywhere kullanıcı isminizle değiştirmeyi unutmayın). -* Son olarak, [Web sekmesi][6]ne gidip uygulamanızın **Yenile** butonuna basın. +Ve kodunuzun indirilmesini izleyin. Kontrol etmek istersen, **Files** sekmesine gidip kodunu PythonAnywhere üzerinde görebilirsin (Konsol sayfasındaki menü butonundan diğer PythonAnywhere sayfalarına ulaşabilirsin). - [6]: https://www.pythonanywhere.com/web_app_setup/ +* Son olarak, [Web sekmesi](https://www.pythonanywhere.com/web_app_setup/)ne gidip uygulamanızın **Yenile** butonuna basın. -Güncelleme hazır olmalı! Devam edelim ve tarayıcıda web sitesini yenileyelim. Değişiklikler görünüyor olmalı :) +Güncelleme hazır olmalı! Devam edelim ve tarayıcıda web sitesini yenileyelim. Değişiklikler görünüyor olmalı. :) \ No newline at end of file diff --git a/tr/html/images/step1.png b/tr/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/tr/html/images/step1.png and b/tr/html/images/step1.png differ diff --git a/tr/html/images/step3.png b/tr/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/tr/html/images/step3.png and b/tr/html/images/step3.png differ diff --git a/tr/html/images/step4.png b/tr/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/tr/html/images/step4.png and b/tr/html/images/step4.png differ diff --git a/tr/html/images/step6.png b/tr/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/tr/html/images/step6.png and b/tr/html/images/step6.png differ diff --git a/tr/images/application.png b/tr/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/tr/images/application.png and b/tr/images/application.png differ diff --git a/tr/installation/README.md b/tr/installation/README.md old mode 100755 new mode 100644 index 08f9eac591d..bd12c1abe5d --- a/tr/installation/README.md +++ b/tr/installation/README.md @@ -1,10 +1,10 @@ # Eğer tutorial'ı evde yapıyorsanız -Eğer tutorial'ı [Django Girls etkinlikleri](http://djangogirls.org/events/)nin birinde değil de evde yapıyorsanız, bu bölümü atlayabilirsiniz ve doğrudan [İnternet nasıl çalışır?](../how_the_internet_works/README.md) bölümüne gidebilirsiniz. +Eğer tutorial'ı [Django Girls etkinliklerinden](https://djangogirls.org/events/) birinde değil de evde yapıyorsanız, bu bölümü şimdi tamamen atlayabilirsiniz ve direkt [İnternet nasıl çalışıyor](../how_the_internet_works/README.md) bölümüne geçebilirsiniz. -Çünkü burada anlatılanları tutorial boyunca zaten işliyoruz, bu kısım kurulum talimatlarının tek yerde toparlandığı ek bir sayfa sadece. Django Girls etkinlikleri, tutorial sırasında uğraşmamak için herşeyi kurduğumuz bir "kurulum akşamı"nı içeriyor. Bu sayfayı onun için kullanıyoruz. +Çünkü burada anlatılanları tutorial boyunca zaten işliyoruz, bu kısım kurulum talimatlarının tek yerde toparlandığı ek bir sayfa sadece. Django Girls etkinliği, çalıştay boyunca tekrar kurulumla uğraşmamak adına her şeyi yüklediğimiz bir "Kurulum akşamı" içeriyor. -Eğer yararlı olduğunu düşünüyorsanız, bu bölümü okuyabilirsiniz. Ama bilgisayarınıza bir şeyler kurmadan önce bir kaç şey öğrenmeye başlamak istiyorsanız, bu bölümü atlayın. Size kurulum işlerini sonra anlatacağız. +Eğer bunu yararlı bulduysanız, bu bölümü de takip edebilirsiniz. Ama bilgisayarınıza birkaç şey yüklemeden önce bir şeyler öğrenmeye başlamak istiyorsanız, bu bölümü atlayın. Daha sonra kurulum kısmını size açıklayacağız. İyi şanslar! @@ -12,25 +12,30 @@ Eğer yararlı olduğunu düşünüyorsanız, bu bölümü okuyabilirsiniz. Ama Atölyede bir blog geliştireceksiniz, eğitim günü kodlamaya hazır olmanız için önceden ayarlamakta fayda olan birkaç kurulum var. -# Python Yükleyin + {% include "/chromebook_setup/instructions.md" %} -{% include "/python_installation/instructions.md" %} + -# Bir "virtualenv" kurun ve Django'yu yükleyin +# Python Yükleyin -{% include "/django_installation/instructions.md" %} +{% include "/python_installation/instructions.md" %} # Bir kod düzenleyicisi yükleyin {% include "/code_editor/instructions.md" %} +# Bir "virtualenv" kurun ve Django'yu yükleyin + +{% include "/django_installation/instructions.md" %} + # Git yükleyin {% include "/deploy/install_git.md" %} # GitHub hesabı oluşturun -[GitHub.com](http://www.github.com)'a gidin ve ücretsiz yeni bir kullanıcı hesabı oluşturun. +[GitHub.com](https://www.github.com)'a gidin ve ücretsiz yeni bir kullanıcı hesabı oluşturun. # PythonAnywhere hesabı oluşturun @@ -40,10 +45,14 @@ Atölyede bir blog geliştireceksiniz, eğitim günü kodlamaya hazır olmanız Tebrikler, ayarlarınız tamam ve hazırsınız! Eğer atölyeden önce hala vaktiniz var ise, başlangıç bölümlerinden bazılarını okumanız yararlı olacaktır: - * [İnternet nasıl çalışır](../how_the_internet_works/README.md) +* [İnternet nasıl çalışır](../how_the_internet_works/README.md) + +* [Komut satırına giriş](../intro_to_command_line/README.md) + +* [Python'a giriş](../python_introduction/README.md) - * [Komut satırına giriş](../intro_to_command_line/README.md) +* [Django nedir?](../django/README.md) - * [Python'a giriş](../intro_to_command_line/README.md) +# Çalışmanın tadına varın! - * [Django nedir?](../django/README.md) +İşe başladığınızda doğrudan [Your first Django project!](../django_start_project/README.md) gidebilirsiniz çünkü çoktan önceki bölümlerde bu konuları çözdük. \ No newline at end of file diff --git a/tr/intro_to_command_line/README.md b/tr/intro_to_command_line/README.md index 6b13c10398e..ed6f9091a28 100644 --- a/tr/intro_to_command_line/README.md +++ b/tr/intro_to_command_line/README.md @@ -1,76 +1,109 @@ # Komut satırı arayüzüne giriş -Ha, heyecan verici, değil mi?! İlk kodunuzu birkaç dakika içinde yazacaksınız :) +> Evden okuyanlar için: Bu bölüm [ Yeni arkadaşınız: Command Line](https://www.youtube.com/watch?v=jvZLWhkzX-8) videosu içinde anlatıldı. + +Heyecanlı değil mi?! Birkaç dakika içinde ilk kod satırınızı yazacaksın! :) **Sizi yeni arkadaşınızla tanıştıralım: komut satırı!** Gelecek aşamalar size tüm "hacker"ların kullandığı siyah pencerenin nasıl kullanıldığını gösterecek. Başta biraz korkutucu görünebilir fakat bu sadece sizden komut bekleyen bir pencere. -> **Not** Lütfen bu kitap boyunca 'dizin' veya 'klasör' terimlerini birbirinin yerine kullandığımızı ve aynı anlama geldiklerini unutmayınız. +> **Not** Lütfen kitap boyunca 'dizin' ve 'klasör' terimlerini birbirinin yerine kullandığımızı ve aynı anlama geldiklerini not unutmayın. ## Komut satırı nedir? -Genellikle **komut satırı** veya **komut satırı arabirimi** adı verilen pencere, bilgisayarınızdaki dosyaları görmek, düzenlemek ve yönetmek için kullanılan metin tabanlı bir uygulamadır. Tıpkı Windows Gezgini veya Mac'deki Finder gibi, fakat grafik arayüzü olmadan. Komut satırının diğer adları: *cmd*, *CLI*, *komut istemcisi*, *konsol* veya *terminal (uçbirim)*dir. +Genellikle **komut satırı** veya **komut satırı arabirimi** adı verilen pencere, bilgisayarınızdaki dosyaları görmek, düzenlemek ve yönetmek için kullanılan metin tabanlı bir uygulamadır. Bu tıpkı windows gezgini yada mac'teki finder gibi fakat grafiksel arayüzü olmadan. Komut satırının diğer adları: *cmd*, *CLI*, *komut istemcisi*, *konsol* veya *terminal (uçbirim)*dir. ## Komut satırı arabirimini açın Birkaç deneme yapmak için önce komut satırı arabirimini açmamız gerekir. -### Windows + + +Başlat'a gidin → Windows sistemi → Komut istemcisi. + +> Daha eski bir windows sistemi için, Başlat menüsü →Tüm programlar → Aksesuarlar → Komut istemcisi. -Başlat menüsü → Tüm Programlar → Donatılar → Komut Satırı. + -### Mac OS X + -Uygulamalar → Araçlar → Terminal. +Uygulamalar → Araçlar →Terminal. -### GNU/Linux + -Muhtemelen Uygulamalar → Donatılar → Terminal altında olmalı, fakat sistemler arası farklılık gösterebilir. Eğer orada değilse İnternet'te arayın :) + + +Muhtemelen Uygulamalar → Donatılar → Terminal altında olmalı, fakat sistemler arası farklılık gösterebilir. Eğer orada değilse İnternet'te arayın. :) + + ## İstemci Şu anda yüksek ihtimalle sizden komut bekleyen siyah ya da beyaz bir ekran görüyor olmalısınız. + + Eğer Mac veya GNU/Linux kullanıyorsanız, yüksek ihtimalle `$` işareti göreceksiniz, tıpkı bunun gibi: -``` -$ -``` +{% filename %}komut-satırı{% endfilename %} + + $ + + + + + Windows'da ise `>` işareti göreceksiniz, bunun gibi: -``` -> -``` +{% filename %}komut-satırı{% endfilename %} + + > + + + -Tüm komutlar bu işaret ve bir boşluktan sonra gelir fakat bunu yazmak zorunda değilsiniz. Bilgisayarınız bunu sizin için yapacaktır :) +Tüm komutlar bu işaret ve bir boşluktan sonra gelir fakat bunu yazmak zorunda değilsiniz. Bilgisayarınız bunu sizin için yapacaktır. :) -> Ufak bir not: sizin durumunuzda bu `C:\Users\ola>` veya `Olas-MacBook-Air:~ ola$` ve benzeri bir şekilde olabilir ve bu kesinlikle doğru. Bu eğitimde bunu sade ve basit bir şekilde anlatacağız. +> Küçük bir not: sizin durumunuzda `C:\Users\ola>` veya `Olas-MacBook-Air:~ ola$` benzeri bir durumda olabilir ve kesinlikle sorun yok. + +Başında `$` veya `>` içeren kısımlar *komut satırı istemi* veya kısaca *komut istemi*'dir. Buraya bir şeyler girilir. + +Bu kılavuzda bir komut girmeniz istendiğinde, biz `$` veya `>` ekleyeceğiz, genellikle sola doğru. Sol tarafı göz ardı edebilir ve işlemi başlatan komutu girebilirsiniz. ## İlk komutunuz (Yaşasın!) -Basit bir şeyle başlayalım. Aşağıdaki komutu yazın: +Aşağıdaki komutu yazarak başlayalım: + + + +{% filename %}komut-satırı{% endfilename %} + + $ whoami + -``` -$ whoami -``` + -ya da + -``` -> whoami -``` +{% filename %}komut-satırı{% endfilename %} + + > whoami + + + Ve ardından `enter` tuşuna basın. Sonucumuz bu: -``` -$ whoami zeynep -``` +{% filename %}komut-satırı{% endfilename %} + + $ whoami zeynep + -Gördüğünüz gibi, bilgisayar az önce kullanıcı adınızı yazdı. Harika, değil mi? :) +Gördüğünüz gibi bilgisayar kullanıcı adınızı yazdı. Şahane, değil mi ? :) -> Her komutu yazmaya çalışın, kopyala-yapıştır yapmayın. Bu şekilde daha akılda kalıcı olur! +> Her komutu yazmaya çalışın; kopyala - yapıştır yapmayın. Böylece daha akılda kalıcı olur! ## Temeller @@ -80,47 +113,65 @@ Tüm işletim sistemleri komut satırı için birbirinden biraz farklı komutlar Nerede olduğumuzu bilmek güzel olurdu, değil mi? Bakalım. Bu komutu yazın ve `enter` tuşuna basın: -``` -$ pwd -/Users/zeynep -``` + -Windows'ta iseniz: +{% filename %}komut-satırı{% endfilename %} -``` -> cd -C:\Users\zeynep -``` - -Muhtemelen makinenizde benzeri bir yazı göreceksiniz. Komut satırını açtığınızda genellikle kullanıcınızın ev dizininde başlarsınız. + $ pwd + /Users/zeynep + > Not: 'pwd'nin anlamı "print working directory" yani "çalışma dizinini yazdır"dır. ---- + + + + +{% filename %}komut-satırı{% endfilename %} + + > cd + C:\Users\zeynep + + +> Not: 'cd' komutu 'dizin değiştir' anlamındadır. Powershell ile Linux veya macOS'teki gibi pwd komutunu kullanabilirsiniz. + + + +Muhtemelen makinenizde benzeri bir yazı göreceksiniz. Komut satırını açtığınızda genellikle kullanıcınızın ev dizininde başlarsınız. + +* * * ### Dosya ve dizinleri listele Yani içeride ne var? Bilmek harika olurdu. Haydi bakalım: -``` -$ ls -Uygulamalar -Masaüstü -İndirilenler -Müzik -... -``` - -Windows: - -``` -> dir Directory of C:\Users\zeynep -05/08/2014 07:28 PM Uygulamalar -05/08/2014 07:28 PM Masaüstü -05/08/2014 07:28 PM İndirilenler -05/08/2014 07:28 PM Müzik -... -``` + + +{% filename %}komut-satırı{% endfilename %} + + $ ls + Uygulamalar + Masaüstü + İndirilenler + Müzik + ... + + + + + + +{% filename %}komut-satırı{% endfilename %} + + > dir Directory of C:\Users\zeynep + 05/08/2014 07:28 PM Uygulamalar + 05/08/2014 07:28 PM Masaüstü + 05/08/2014 07:28 PM İndirilenler + 05/08/2014 07:28 PM Müzik + ... + + +> Not: Ayrıca PowerShell kullanırken Linux ve macOS'teki gibi 'ls' komutunu kullanabilirsiniz. * * * @@ -128,32 +179,49 @@ Windows: Şimdi, haydi Masaüstü dizinimize gidelim: -``` -$ cd Masaüstü -``` + + +{% filename %}komut-satırı{% endfilename %} + + $ cd Masaüstü + + + + + + +{% filename %}komut-satırı{% endfilename %} -Windows: + > cd Masaüstü + -``` -> cd Masaüstü -``` + Gerçekten değişmiş mi bir bakalım: -``` -$ pwd -C:\Users\zeynep\Masaüstü -``` + -Windows: -``` -> cd -C:\Users\zeynep\Masaüstü -``` +{% filename %}komut-satırı{% endfilename %} + + $ pwd + C:\Users\zeynep\Masaüstü + + + + + + +{% filename %}komut-satırı{% endfilename %} + + > cd + C:\Users\zeynep\Masaüstü + + + İşte oldu! -> Profesyonel ipucu: eğer `cd D` yazarsanız ve `tab` tuşuna basarsanız, komut satırı ismin kalanını otomatik tamamlar ve gitmek istediğiniz yere daha hızlı gidersiniz. Eğer "D" ile başlayan birden çok klasör var ise, seçeneklerin listesi için `tab` tuşuna iki kez basın. +> Profesyonel İpucu: Eğer `cd D` yazarsanız ve klavyenizden `tab`'a basarsanız, komut satırı ismin geri kalanını tamamlar ve daha hızlı gezersiniz. Eğer "D" ile başlayan birden fazla klasör varsa, diğer seçenekleri görmek için `tab` tuşuna iki kez basın. * * * @@ -161,17 +229,25 @@ C:\Users\zeynep\Masaüstü Uygulamalı yapmak için masaüstünüzde bir dizin oluşturmaya ne dersiniz? Bu şekilde yapabilirsiniz: -``` -$ mkdir uygulama -``` + + +{% filename %}komut-satırı{% endfilename %} + + $ mkdir uygulama + + + + + + +{% filename %}komut-satırı{% endfilename %} -Windows: + > mkdir uygulama + -``` -> mkdir uygulama -``` + -Bu küçük komut masaüstünüzde `uygulama` isimli bir klasör oluşturacaktır. Orada olup olmadığını kontrol etmek için `ls` veya `dir` komutlarını kullanabilirsiniz! Deneyin :) +Bu küçük komut masaüstünüzde `uygulama` isimli bir klasör oluşturacaktır. Orada olup olmadığını kontrol etmek için `ls` veya `dir` komutlarını kullanabilirsiniz! Deneyin. :) > Profesyonel ipucu: Eğer aynı komutları tekrar tekrar yazmak istemiyorsanız, `yukarı ok` ve `aşağı ok` tuşlarına basarak yazdığınız komutlar arasında geçiş yapabilirsiniz. @@ -179,25 +255,33 @@ Bu küçük komut masaüstünüzde `uygulama` isimli bir klasör oluşturacaktı ### Alıştırma! -Sizin için ufak bir alıştırma: yeni oluşturduğunuz `uygulama` dizininde `test` adında bir dizin oluşturun.`cd` ve `mkdir` komutlarını kullanın. +Sizin için ufak bir alıştırma: yeni oluşturduğunuz `alıştırma` dizininde `test` adında bir dizin oluşturun. (`cd` ve `mkdir` komutlarını kullanın.) #### Çözüm: -``` -$ cd uygulama -$ mkdir test -$ ls -test -``` + -Windows: +{% filename %}komut-satırı{% endfilename %} -``` -> cd uygulama -> mkdir test -> dir -05/08/2014 07:28 PM test -``` + $ cd uygulama + $ mkdir test + $ ls + test + + + + + + +{% filename %}komut satırı{% endfilename %} + + > cd uygulama + > mkdir test + > dir + 05/08/2014 07:28 PM test + + + Tebrikler! :) @@ -209,95 +293,135 @@ Ortalığı dağınık bırakmak istemeyiz, haydi yaptığımız her şeyi silel İlk önce masaüstüne geri dönmemiz gerek: -``` -$ cd .. -``` + + +{% filename %}komut satırı{% endfilename %} + + $ cd .. + + + + + + +{% filename %}komut satırı{% endfilename %} -Windows: + > cd .. + -``` -> cd .. -``` + -`cd` komutu ile `..` kullanmak sizi bir üst dizine götürür (Bu sizin şuanki dizininizi tutan ana dizindir). +`cd` komutu ile `..` kullanmak sizi geçerli dizinin bir üst dizinine götürür (bu şu anki dizinin ana dizinidir). Nerede olduğunuzu kontrol edin: -``` -$ pwd -C:\Users\zeynep\Masaüstü -``` + -Windows: +{% filename %}komut satırı{% endfilename %} -``` -> cd -C:\Users\zeynep\Masaüstü -``` + $ pwd + C:\Users\zeynep\Masaüstü + + + + + + +{% filename %}komut satırı{% endfilename %} + + > cd + C:\Users\zeynep\Masaüstü + + + Şimdi `uygulama` dizinini silme vakti: -> **Dikkat**: Dosyaları `del`,`rmdir` veya `rm` ile silme işlemi geri alınamaz, bu *silinen dosyalar sonsuza dek yok olur* anlamına gelir! Yani, bu komutları kullanırken çok dikkatli olun. +> **Dikkat**: `del`, `rmdir` veya `rm` komutları kullanılarak yapılan silme işlemleri geri alınamaz, bunun anlamı: *silinen dosyalar sonsuza dek yok olur*! Yani bu komutları kullanırken çok dikkatli olun. + + -``` -$ rm -r uygulama -``` +{% filename %}komut satırı{% endfilename %} -Windows: + $ rm -r uygulama + -``` -> rmdir /S uygulama -uygulama, Emin misiniz ? E -``` + + + + +{% filename %}komut satırı{% endfilename %} + + > rmdir /S uygulama + uygulama, Emin misiniz ? E + + + Bitti! Gerçekten silindiğinden emin olalım: -``` -$ ls -``` + + +{% filename %}komut satırı{% endfilename %} -Windows: + $ ls + -``` -> dir -``` + + + + +{% filename %}komut satırı{% endfilename %} + + > dir + + + ### Çıkış -Şimdilik bu kadar! Şimdi komut satırını güvenle kapatabilirsiniz. Bunu "hacker" tarzında yapalım, tamam mı?:) +Şimdilik bu kadar! Şimdi komut satırını güvenle kapatabilirsiniz. Bunu "hacker" tarzında yapalım, tamam mı? :) + + -``` -$ exit -``` +{% filename %}komut satırı{% endfilename %} -Windows: + $ exit + -``` -> exit -``` + -Harika, değil mi?:) + + +{% filename %}komut satırı{% endfilename %} + + > exit + + + + +Harika, değil mi? :) ## Özet İşte bazı yararlı komutların özeti: -| Komut (Windows) | Komut (Mac OS - GNU/Linux) | Açıklama | Örnek | -| --------------- | -------------------------- | ----------------------- | ------------------------------------------------- | -| exit | exit | pencereyi kapatır | **exit** | -| cd | cd | dizin değiştir | **cd test** | -| dir | ls | dizin/dosyaları listele | **dir** | -| copy | cp | dosya kopyala | **copy c:\test\test.txt c:\windows\test.txt** | -| move | mv | dosya taşı | **move c:\test\test.txt c:\windows\test.txt** | -| mkdir | mkdir | yeni bir dizin oluştur | **mkdir testdizini** | -| del | rm | bir dosya/dizin sil | **del c:\test\test.txt** | +| Komut (Windows) | Komut (Mac OS - GNU/Linux) | Açıklama | Örnek | +| ---------------- | -------------------------- | ----------------------- | ------------------------------------------------- | +| exit | exit | pencereyi kapatır | **exit** | +| cd | cd | dizin değiştir | **cd test** | +| cd | pwd | geçerli dizini göster | **cd** (Windows) veya **pwd** (Mac OS / Linux) | +| dir | ls | dizin/dosyaları listele | **dir** | +| copy | cp | dosya kopyala | **copy c:\test\test.txt c:\windows\test.txt** | +| move | mv | dosya taşı | **move c:\test\test.txt c:\windows\test.txt** | +| mkdir | mkdir | yeni bir dizin oluştur | **mkdir testdizini** | +| rmdir (veya del) | rm | dosyayı silin | **del c:\test\test.txt** | +| rmdir /S | rm -r | klasörü siliniz | **rm - r testdizini** | Bu kullanabileceğiniz komutlardan sadece birkaçı, fakat bugün bundan daha fazlasını kullanmayacaksınız. -Eğer merak ediyorsanız, [ss64.com][1] adresinden tüm işletim sistemleri için tüm komutların kullanımına ulaşabilirsiniz. - - [1]: http://ss64.com +Eğer merak ediyorsanız, [ss64.com](http://ss64.com) adresinden tüm işletim sistemleri için tüm komutların kullanımına ulaşabilirsiniz. ## Hazır mısınız? -Haydi Python'a giriş yapalım! +Haydi Python'a giriş yapalım! \ No newline at end of file diff --git a/tr/python_installation/README.md b/tr/python_installation/README.md old mode 100755 new mode 100644 index 506b8fb871d..e8fee28d9cd --- a/tr/python_installation/README.md +++ b/tr/python_installation/README.md @@ -4,10 +4,12 @@ Nihayet buradayız! Fakat önce, size Python'un ne olduğunu açıklayalım. Python web siteleri, oyunlar, bilimsel yazılımlar, grafikler ve çok daha fazlasını oluşturmak için kullanılan bir programlama dilidir. -Python'un kökleri 1980'li yılların sonlarına dayanmaktadır ve ana hedefi sadece makineler değil insanlar tarafından da okunabilir olmaktır. Bu yüzden diğer programlama dillerine oranla çok daha basit görünmektedir. Öğrenmesi kolaydır ama merak etmeyin, Python gerçekten güçlüdür! +Python'un kökleri 1980'li yılların sonlarına dayanmaktadır ve ana hedefi sadece makineler değil insanlar tarafından da okunabilir olmaktır. Bu nedenle öbür programlama dillerinden daha basit görünür, ama merak etmeyin - Python da hakikaten güçlü! # Python kurulumu -> **Not** Eğer kurulum aşamalarını zaten tamamladıysanız, tekrar yapmanıza gerek yok - direkt olarak diğer aşamaya geçebilirsiniz! +> **Not** Eğer Chromebook kullanıyorsanız bu bölümü geçin ve [Chromebook Kurulumu](../chromebook_setup/README.md)'daki talimatları takip edin. +> +> **Not** Eğer kurulum adımlarını zaten bitirdiyseniz tekrar yapmanıza gerek yok - doğrudan sonraki bölüme geçebilirsiniz! -{% include "/python_installation/instructions.md" %} +{% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/tr/python_installation/images/add_python_to_windows_path.png b/tr/python_installation/images/add_python_to_windows_path.png index 9510d6f2176..3266efb6177 100644 Binary files a/tr/python_installation/images/add_python_to_windows_path.png and b/tr/python_installation/images/add_python_to_windows_path.png differ diff --git a/tr/python_installation/images/python-installation-options.png b/tr/python_installation/images/python-installation-options.png index 4cb886349a1..a0a6c65d81d 100644 Binary files a/tr/python_installation/images/python-installation-options.png and b/tr/python_installation/images/python-installation-options.png differ diff --git a/tr/python_installation/images/windows-plus-r.png b/tr/python_installation/images/windows-plus-r.png index d99a4d1ac20..4f8f7433381 100644 Binary files a/tr/python_installation/images/windows-plus-r.png and b/tr/python_installation/images/windows-plus-r.png differ diff --git a/tr/python_installation/instructions.md b/tr/python_installation/instructions.md old mode 100755 new mode 100644 index acb23c1b56c..3d1546f682e --- a/tr/python_installation/instructions.md +++ b/tr/python_installation/instructions.md @@ -1,64 +1,106 @@ -> Bu bölüm Geek Girls Carrots tarafından yapılan bir eğitime dayanılarak hazırlanmıştır. (http://django.carrots.pl/) +> Evdeki okuyucular için: bu bölüm [Installing Python & Code Editor](https://www.youtube.com/watch?v=pVTaqzKZCdA) isimli videoda anlatılmıştır. +> +> Bu bölüm Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) tarafından hazırlanmış bir öğreticiye dayanmaktadır -Django, Python ile yazılmıştır. Django ile bir şey yapmak için Python diline ihtiyacımız var. Hadi Python kurmaya başlayalım! Biz Python 3.4 kurmak istiyoruz, eğer daha düşük bir sürüme sahipseniz, güncellemelisiniz. +Django, Python dilinde yazılmıştır. Django'da herhangi bir şey yapmak için Python'a ihtiyaç duyarız. Python'ın kurulumunu yaparak başlayalım! Sizden Python 3.6'nın kurulumunu yapmanızı istiyoruz. Yani, eğer daha önceki bir versiyonuna sahipseniz, güncellemeniz gerekecek. -### Windows + -Windows için Python indirmek için resmi siteyi ziyaret edebilirsiniz: https://www.python.org/downloads/release/python-343/. ***.msi** dosyasını indirdikten sonra, dosyayı çalıştırın (çift tıklayın) ve yönergeleri izleyin. Python kurulumunu yaptığınız dizinin yolunu (dizini) unutmamanız önemli. Daha sonra lazım olacak! +Öncelikle Windows + Pause/Break tuş kombinasyonlarına basarak bilgisayarınızın Windows'un 32-bit versyionunu mu 64-bit versiyonu mu çalıştırdığını kontrol edin. Bu size Sistem bilgisini açacak. Açılan bu pencerede "Sistem tipi" satırına bakın. Windows için Python'ı indirmek için resmi siteyi ziyaret edebilirsiniz: https://www.python.org/downloads/windows/. "Son Python 3 Sürümü - Python x.x.x" bağlantısına tıklayın. Eğer bilgisayarınız **64-bit** versiyon Windows çalıştırıyorsa, **Windows x86-64 çalıştırılabilir yükleyici**'yi indirin. Değilse, **Windows x86 çalıştırılabilir yükleyici**'yi indirin. Yükleyiciyi indirdikten sonra, çalıştırmalısınız (üzerine çift tıklayarak) ve oradaki talimatları takip etmelisiniz. -Dikkat: Özelleştir (Customize) olarak seçilmiş kurulum sihirbazının ikinci ekranında seçenekleri aşağıya kaydırın ve "Add python.exe to the Path" (python.exe yolunu ekle) seçeneğinin üzerine gelip "Will be installed on local hard drive" (Lokal hard diske kurulacak) seçeneğini seçin: +Dikkat edilmesi gereken bir şey: Yükleme esnasında "Setup" ("Kur") işaretli bir pencere farkedeceksiniz. "Add Python 3.6 to PATH" ("PATH'e Python 3.6'yı ekle) kutucuğunun işaretli olduğundan emin olun ve aşağıda gösterildiği gibi "Install Now" ("Şimdi Yükle") 'a tıklayın: -![Python'u arama yoluna eklemeyi unutmayın](../python_installation/images/add_python_to_windows_path.png) +![Python'u arama yoluna eklemeyi unutmayın](../python_installation/images/python-installation-options.png) -### Linux +Önümüzdeki adımlarda, Windows Komut Satırını kullanıyor olacaksınız (ki ayrıca bahsedeceğiz). Şimdilik, bazı komutlar girmeniz gerekirse, Başlat menüsüne gidin ve arama alanına "Komut istemi" yazıp enter'a basın. (Windows'un eski sürümlerinde, komut satırını Başlat menüsü → Windows sistemi → Komut istemi ile başlatabilirsin.) Ayrıca "Çalıştır" penceresi açılana kadar Windows tuşunu basılı tutup "R"-tuşuna basabilirsin. Komut Satırı'nı açmak için, "cmd" yazın ve "Çalıştır" penceresinde enter'a basın. + +!["Çalıştır" penceresine "cmd" yazın](../python_installation/images/windows-plus-r.png) + +Not: eğer Windows'un eski bir versiyonunu (7, Vista ya da herhangi bir eski versiyon) kullanıyorsanız ve Python 3.6.x yükleyicisi hata veriyorsa, aşağıdakilerden birini deneyebilirsiniz: + +1. bütün Windows Güncellemeleri'ni yükleyin ve Python 3.6'yı tekrar yüklemeyi deneyin; ya da +2. [eski bir Python versiyonu](https://www.python.org/downloads/windows/), örneğin [3.4.6](https://www.python.org/downloads/release/python-346/) yükleyin. + +Eğer Python'ın eski bir versiyonunu yüklerseniz, yükleme ekranı yukarıda gösterilenden biraz farklı görünebilir. "python.exe'yi Path'e ekle" görene dek aşağı kaydırdığınızdan emin olun, daha sonra soldaki butona tıklayın ve "Yerel sabit sürücüye yüklenecek"'i seçin: + +![Eski Python sürümlerini Path'e ekleyin](../python_installation/images/add_python_to_windows_path.png) + + + + + +> **Not** Python'ı macOS'te yüklemeden önce, Mac ayarlarınızın App Store'dan olmayan paketleri yüklemeye izin verdiğinden emin olmalısınız. Sistem Tercihleri'ne (Uygulamalar klasöründe) gidin, önce "Güvenlik & Gizlilik"'e ve daha sonra da "Genel" sekmesine tıklayın. Eğer sizin "Şuradan yüklenen uygulamalara izin ver:" ayarınız "Mac App Store"'a ayarlıysa, onu "Mac App Store and kimliği bilinen geliştirici."lere çevirin + +Python kurulum dosyasını indirmek için resmi siteye gitmelisiniz: https://www.python.org/downloads/release/python-361/ + +* *macOS 64-bit/32-bit yükleyici* dosyasını indirin, +* *python-3.6.1-macosx10.6.pkg* 'a çift tıklayarak yükleyiciyi çalıştırın. + + + + Muhtemelen sisteminizde Python zaten yüklüdür. Yüklü olup olmadığını (ya da hangi versiyon olduğunu) kontrol etmek için komut satırını açın ve aşağıdaki komutları girin: -``` -$ python3 --version -Python 3.4.3 -``` +{% filename %}komut satırı{% endfilename %} + + $ python3 --version + Python 3.6.1 + -Python yüklü değilse ya da farklı bir versiyon edinmek istiyorsanız aşağıdaki adımları takip edin: +Eğer farklı bir 'mikro sürüm' Python yüklüyse, örn: 3.6.0, o zaman yükseltme yapmak zorunda değilsiniz. Python yüklü değilse ya da farklı bir versiyon edinmek istiyorsanız aşağıdaki adımları takip edin: -#### Debian veya Ubuntu + + + Terminale bu komutu girin: -``` -$ sudo apt-get install python3.4 -``` +{% filename %}komut satırı{% endfilename %} + + $ sudo apt install python3.6 + -#### Fedora (21'e kadar) + + + Terminalde kullanmanız gereken komut: -``` -$ sudo yum install python3.4 -``` +{% filename %}komut satırı{% endfilename %} + + $ sudo dnf install python3 + + +Eğer eski bir Fedora sürümünüz varsa `dnf` komutu bulunamadı hatasını alabilirsiniz. Bu durumda, `yum` kullanmanız gerekir. -#### Fedora (22+) + + + Terminalde kullanmanız gereken komut: -``` -$ sudo dnf install python3.4 -``` +{% filename %}komut satırı{% endfilename %} + + $ sudo zypper install python3 + -### OS X + -Python kurulum dosyasını indirmek için resmi siteye gitmelisiniz: https://www.python.org/downloads/release/python-342/: +Komut istemini açıp `python3` komutunu çalıştırarak yüklemenin başarılı olup olmadığını doğrulayabilirsiniz: - * *Mac OS X 64-bit/32-bit yükleyici* dosyasını indirin, - * *python-3.4.3-macosx10.6.pkg* dosyasına çift tıklayarak yükleyiciyi çalıştırın. +{% filename %}komut satırı{% endfilename %} -Kurulumun başarılı olup olmadığını kontrol etmek için *Terminal* uygulamasını açın ve aşağıdaki `python3` komutunu çalıştırın: + $ python3 --version + Python 3.6.1 + -``` -$ python3 --version -Python 3.4.3 -``` +**Not:** Eğer Windows kullanıyorsanız ve `python3` bulunamadı hatasını alıyorsanız, `python` (`3` olmadan) komutunu deneyin ve Python 3.6 sürümlerinin olup olmadığını kontrol edin. * * * -Herhangi bir şüpheniz varsa, kurulumda bir şeyler ters gittiyse ya da sonrasında ne yapacağınızı bilmiyorsanız eğitmene sorabilirsiniz! Bazen işler düzgün gitmiyor, bu durumda daha fazla deneyime sahip birinden yardım istemelisiniz. +Eğer herhangi bir şüpheniz varsa veya kurulumda bir şeyler ters gittiyse ve sonrasında ne yapılacağını bilmiyorsanız, eğitmeninize sorabilirsiniz! Bazen işler düzgün gitmiyor, bu durumda daha fazla deneyime sahip birinden yardım istemelisiniz. \ No newline at end of file diff --git a/tr/python_introduction/README.md b/tr/python_introduction/README.md index dd0c0812758..f64ef088ba0 100644 --- a/tr/python_introduction/README.md +++ b/tr/python_introduction/README.md @@ -1,101 +1,131 @@ -# Python'a Giriş +{% set warning_icon = '' %} -> Bu bölümün bazı kısımları Geek Girls Carrots (http://django.carrots.pl/) öğreticisinden alınmıştır. +# Python'a giriş + +> Bu bölümün bir kısmı Geek Girls Carrots tarafından hazırlanmış eğitimlere dayanılarak hazırlanmıştır (https://github.com/ggcarrots/django-carrots). Biraz kod yazalım! ## Python komut istemi (prompt) -Python'la oynamaya başlamadan önce bilgisayarımızda bir *komut satırı* açmamız gerekiyor. Bunu nasıl yapacağınızı artık biliyorsunuz, [Komut satırına giriş][1] bölümünde öğrenmiştiniz. +> Evdeki okuyucular için: Bu kısım [Python Temelleri: Tamsayılar, Dizeler, Listeler, Değişkenler ve Hatalar](https://www.youtube.com/watch?v=MO63L4s-20U) videosunda bulunabilir. - [1]: ../intro_to_command_line/README.md +Python'la oynamaya başlamadan önce bilgisayarımızda bir *komut satırı* açmamız gerekiyor. Bunu zaten nasıl yapacağınızı artık biliyorsunuz, [Komut satırına giriş](../intro_to_command_line/README.md) bölümünde öğrenmiştiniz. Hazır olduğunuzda, aşağıdaki talimatları takip edin. Bir Python konsolu açmak istiyoruz; öyleyse Windows'ta `python`, Mac OS/Linux'ta `python3` yazıp, `enter`'a basın. -``` -$ python3 -Python 3.4.3 (...) -Type "help", "copyright", "credits" or "license" for more information. ->>> -``` +{% filename %}komut satırı{% endfilename %} + + $ python3 + Python 3.6.1 (...) + Type "help", "copyright", "credits" or "license" for more information. + >>> + ## İlk Python komutunuz! -Python komutunu çalıştırdıktan sonra, komut istemi `>>>` şeklinde değişti. Bizim için bu, şimdi yalnızca Python dilinde komutlar kullanabileceğimiz anlamına geliyor. `>>>` yazmanıza gerek yok, Python sizin için bunu yapıyor. +Python komutunu çalıştırdıktan sonra, komut istemi `>>>` şeklinde değişti. Bizim için bu, şimdi yalnızca Python dilinde komutlar kullanabileceğimiz anlamına geliyor. `>>>` yazmanıza gerek yok - Python bunu sizin için yapacak. Eğer herhangi bir zamanda Python komut satırından çıkmak isterseniz, yalnızca `exit()` yazmanız ya da Windows için `Ctrl + Z`, Mac/Linux için `Ctrl + D` kısa yolunu kullanmanız yeterli. Bunu yaptığınız taktirde artık `>>>` yazısını görmeyeceksiniz. -Şu an için Python komut satırından çıkmak istemiyoruz. Bu konuda daha fazlasını öğrenmek istiyoruz. Gerçekten basit bir şeyle başlayalım. Örneğin, biraz matematik yapmayı deneyip `2 + 3` gibi bir şey yazın ve `enter`'a basın. +Şimdilik, Python konsolundan çıkmak istemiyoruz. Bu konuda daha fazla bilgi edinmek istiyoruz. Biraz matematik yazarak başlayalım (` 2 + 3 ` gibi) ve `enter` 'a basalım. -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> 2 + 3 5 -``` +``` + +Güzel! Cevap nasıl da çıktı görüyor musun? Python matematik biliyor! Sen de diğer komutları şöyle deneyebilirsin: + +- `4 * 5` +- `5 - 1` +- `40 / 2` -Harika! Cevabın komut satırına geldiğini gördün değil mi? Python matematik biliyor! Şu gibi komutları da deneyebilirsiniz: - `4 * 5` - `5 - 1` - `40 / 2` +Üstel hesaplama yapmak için 2 üzeri 3 deyin, şöyle yazalım: {% filename %}komut-satırı{% endfilename %} -Bunları biraz kurcalayıp eğlen, sonra tekrar burada buluşalım :). +```python +>>> 2 ** 3 +8 +``` + +Bunları biraz kurcalayıp eğlen, sonra tekrar burada buluşalım. :) -Gördüğün üzere Python çok iyi bir hesap makinesi. Eğer başka neler yapabileceğini merak ediyorsan... +Gördüğün gibi Python çok iyi bir hesap makinesi. Eğer başka neler yapabileceğini merak ediyorsan... ## String'ler (dizeler) Mesela ismin? İsmini tırnak işaretleri içerisinde şu şekilde yaz: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> "Zeynep" 'Zeynep' -``` +``` -İlk string'ini oluşturdun! String (katar), bilgisayar tarafından işlenebilen ve karakterlerden oluşan dizilerin genel adıdır. Bir string her zaman aynı özel karakterle başlamalı ve aynı özel karakterle bitmelidir. Tek tırnak (`'`) veya çift tırnak (`"`) olabilir (aralarında herhangi bir fark yok!). Tırnak işaretleri Python'da içlerinde olan şeyin bir string olduğunu ifade eder. +İlk string'ini oluşturdun! String (dize), bilgisayar tarafından işlenebilen ve karakterlerden oluşan dizilerin genel adıdır. Bir string her zaman aynı özel karakterle başlamalı ve aynı özel karakterle bitmelidir. Tek tırnak (`'`) veya çift tırnak (`"`) olabilir (aralarında herhangi bir fark yok!). Tırnak işaretleri Python'da içlerinde olan şeyin bir string olduğunu ifade eder. Stringler birbirlerine eklenebilir. Şunu dene: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> "Merhaba " + "Zeynep" 'Merhaba Zeynep' -``` +``` Ayrıca stringleri bir sayı ile çarpabilirsin: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> "Zeynep" * 3 'ZeynepZeynepZeynep' -``` +``` Eğer stringinin içerisine bir tırnak işareti koymak istiyorsan, bunun için iki seçeneğin var. Çift tırnak kullanarak: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> "Turgut Uyar'ın dizeleriyiz" "Turgut Uyar'ın dizeleriyiz" -``` +``` -veya sola eğik çizgi (` \ `) kullanarak: +veya backslash (` \ `) kullanarak: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> 'Turgut Uyar\'ın dizeleriyiz' "Turgut Uyar'ın dizeleriyiz" -``` +``` Hoş değil mi? İsminin tamamını büyük harf yapmak için, sadece şunu yazman yeterli: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> "Zeynep".upper() 'ZEYNEP' -``` +``` -Stringin üzerinde `upper` **fonksiyon**unu kullandın! Bir fonksiyon (`upper()` gibi) , çağırıldığında(calling) Python'un bir obje (`"Zeynep"`) üzerinde gerçekleştirmesi gereken bir dizi işleme denilir. +String'in üzerinde `upper` **fonksiyon**unu kullandın! Bir fonksiyon (`upper()` gibi), çağırıldığında (calling) Python'un girdi olarak verilen bir obje (`"Zeynep"`) üzerinde gerçekleştirmesi gereken bir dizi işleme denilir. -Eğer ismindeki harflerin sayısını öğrenmek istiyorsan bunun için de bir fonksiyon var! +Eğer ismindeki harflerin sayısını öğrenmek istiyorsan bunun için de bir **fonksiyon** var! -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> len("Zeynep") 6 -``` +``` Fonksiyonları neden bazen stringin sonunda bir `.` ile (`"Zeynep".upper()` gibi) ve bazen de önce fonksiyonu çağırıp sonra parantez içerisine stringi yazarak kullandığımızı merak ediyor musun? Pekala, bazı durumlarda, fonksiyonlar bir takım nesnelere aittirler, mesela `upper()`, yalnızca stringler üzerinde kullanılabilir. Böyle durumlarda, bu tarz fonksiyonlara biz **method** ismini veriyoruz. Diğer durumlarda, bir fonksiyon özel olarak bir nesneye ait olmayıp, farklı çeşitlerde nesneler üzerinde de kullanılabilir, aynı `len()` gibi. İşte bu nedenle `"Zeynep"` stringini `len` fonksiyonuna bir parametre olarak veriyoruz. @@ -103,92 +133,110 @@ Fonksiyonları neden bazen stringin sonunda bir `.` ile (`"Zeynep".upper()` gibi Tamam, stringlerden yeterince bahsettik. Şu ana kadar şu konuları öğrendin: -* **konsol-komut istemcisi** - Python komut satırına komut(kod) yazdığında Python cevap veriyor -* **sayılar ve strings(karakter dizinleri)** - Python'da sayılar matematik ve stringler metin nesneleri için kullanılıyor -* **operators(işleçler)** + ve * gibi, değerleri birleştirerek yeni bir değer oluştuyor -* **fonksiyonlar-işlevler** - upper() ve len() gibi, nesneler üzerinde eylemler gerçekleştiriyor. +- **komut istemi** – komutları (kod) Python'un komut istemine yazdığınızda Python'da sonuçlandırarak yanıtlar üretir +- **sayılar ve dizeler** – Python'da sayılar matematik için dizeler ise metin nesneleri için kullanılmaktadır +- **operatörler** `+` ve `*` gibi, değerleri birleştirerek yeni bir değer üretmek için kullanılmaktadır +- **fonksiyonlar** `upper()` ve `len()` gibi, nesneler üzerinde eylemler gerçekleştirmektedirler. Bunlar öğreneceğiniz her programlama dilinin temelleri. Biraz daha zor bir şey için hazır mısın? İddiaya gireriz öylesin! ## Hatalar -Şimdi yeni bir şey deneyelim. Bir sayının uzunluğunu, bir string'in uzunluğunu bulduğumuz gibi bulabilir miyiz? Bunu görmek için `len(304023)` yazıp `enter`a basalım: +Şimdi yeni bir şey deneyelim. Bir sayının uzunluğunu, bir string'in uzunluğunu bulduğumuz gibi bulabilir miyiz? Bunu görmek için `len(304023)` yazıp `enter` a basalım: -``` +{% filename %}{{ warning_icon }} komut satırı{% endfilename %} + +```python >>> len(304023) Traceback (most recent call last): File "", line 1, in TypeError: object of type 'int' has no len() -``` +``` -İlk hatamızı aldık! Nesne türü "int" (tam sayılar, tüm sayılar) in uzunluğu olmadığını söylüyor. Şimdi ne yapabiliriz? Belki de rakamı bir string olarak yazabiliriz? Stringlerin bir uzunluğu var, değil mi? +İlk hatamızı aldık! {{ warning_icon }} ikonu çalıştırmak üzere olduğunuz programın beklediğiniz gibi çalışmayacağı konusunda sizi ikaz eder. Hatalar yapmak (kasıtlı olanlar bile) öğrenmenin önemli bir kısmı! -``` +Nesne türü "int" (tam sayılar, tüm sayılar) in uzunluğu olmadığını söylüyor. Şimdi ne yapabiliriz? Belki de rakamı bir string olarak yazabiliriz? Stringlerin bir uzunluğu var, değil mi? + +{% filename %}komut satırı{% endfilename %} + +```python >>> len(str(304023)) 6 -``` +``` İşe yaradı! `str` fonksiyonunu `len` fonksiyonunun içinde kullandık. `str` her şeyi string'e çeviriyor. -* `str` fonksiyonu, değişkenleri **stringe** çeviriyor -* `int` fonksiyonu değişkenleri **integera** çeviriyor +- `str` fonksiyonu, değişkenleri **stringe** çeviriyor +- `int` fonksiyonu değişkenleri **integera** çeviriyor -> Önemli: Tamsayıları yazıya çevirebiliriz, fakat yazıları(text) sayılara çeviremeyiz - `int('selamlar')` bir anlam ifade etmiyor. +> Önemli: Sayıları metin durumuna getirebiliriz ama metni sayılar durumuna tam olarak getiremeyebiliriz - yine de `int('hello')` olsa ne olurdu? ## Değişkenler -Programlamada en önemli konulardan biri değişkenlerdir. Değişken, daha sonra kullanmak istediğiniz bir yapıya verdiğiniz isimdir. Programcılar değişkenleri verileri tutmak ya da kodlarını daha okunabilir ve anlaşılabilir kılmak için kullanırlar ve böylece her şeyi sürekli akıllarında tutmaya gerek kalmaz. +Programlamada en önemli konulardan biri değişkenlerdir. Değişken (variable), daha sonra kullanmak istediğiniz bir yapıya verdiğiniz isimdir. Programcılar değişkenleri verileri tutmak ya da kodlarını daha okunabilir ve anlaşılabilir kılmak için kullanırlar ve böylece her şeyi sürekli akıllarında tutmaya gerek kalmaz. `name` adında bir değişken yaratmak istediğimizi varsayalım: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> name = "Ayşe" -``` +``` -Gördünüz mü? Ne kadar kolay: name değişkeni "Ayşe" oldu. +name (isim) eşittir "Ayşe" yazalım. Farkettiğiniz gibi, program daha öncekilerinin aksine bu kez hiçbir cevap vermedi. O zaman böyle bir değişkenin gerçekten tanımlı olduğunu nasıl bilebiliriz? Basitçe, `name` yazıp `enter` tuşuna basalım: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> name 'Ayşe' -``` +``` -İşte bu sizin ilk değişkeniniz! name değişkeninin işaret ettiği şeyi her zaman değiştirebilirsiniz: +Yaşasın! İşte bu senin ilk değişkenin! :) Bu değişkenin işaret ettiği şeyi her zaman değiştirebilirsin: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> name = "Suzan" >>> name 'Suzan' -``` +``` + +Bu değişkeni fonksiyonlar içinde de kullanabilirsin: -Bu değişkeni fonksiyonlar içinde de kullanabilirsiniz: +{% filename %}komut satırı{% endfilename %} -``` +```python >>> len(name) 5 -``` +``` -Harika değil mi? Tabii ki değişkenler, sayılar da dahil herhangi bir şey olabilir. Şunu deneyin: +Harika değil mi? Tabii ki değişkenler, sayılar da dahil herhangi bir şey olabilir. Şunu deneyin: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> a = 4 >>> b = 6 >>> a * b 24 -``` +``` -Peki ya değişkenin adını yanlış kullanırsak? Ne olacağını tahmin ediyor musunuz? Deneyelim! +Peki ya değişkenin adını yanlış kullanırsak? Ne olacağını tahmin ediyor musun? Deneyelim! -``` +{% filename %}{{ warning_icon }} komut satırı{% endfilename %} + +```python >>> city = "Tokyo" >>> ctiy Traceback (most recent call last): - File "", line 1, in + File "", line 1, in NameError: name 'ctiy' is not defined -``` +``` -Bir hata! Gördüğünüz gibi, Python bir çok çeşit hata çeşidine sahip ve bu hatanın adı **NameError**, yani İsimlendirme Hatası. Tanımlamadığınız bir değişkenin adını kullanmaya çalışırsanız, Python size bu hatayı verir. Eğer bu hata ile daha sonra karşılaşırsanız, kodunuzdaki değişkenlerin adını doğru yazıp yazmadığınızı kontrol edin. +Bir hata! Gördüğünüz gibi, Python birçok hata çeşidine sahip ve bu hatanın adı **NameError**, yani İsimlendirme Hatası. Tanımlamadığınız bir değişkenin adını kullanmaya çalışırsanız, Python size bu hatayı verir. Eğer bu hata ile daha sonra karşılaşırsanız, kodunuzdaki değişkenlerin adını doğru yazıp yazmadığınızı kontrol edin. Bununla biraz oynayıp, neler yapabildiğinizi görün! @@ -196,7 +244,9 @@ Bununla biraz oynayıp, neler yapabildiğinizi görün! Şunu deneyin: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> name = 'Merve' >>> name 'Merve' @@ -210,81 +260,100 @@ Daha ileride göreceğimiz gibi `print()`, işlevlerin içindeyken bir şey yazd ## Listeler -Python, string ve integerın yanı sıra, çok değişik türlerde nesnelere sahiptir. Şimdi, **liste** türünü tanıtacağız. Listeler tam da düşündüğünüz gibidir: diğer nesnelerin listesi olan nesne :) +Python, string (dize) ve integerın (tam sayı) yanı sıra, çok değişik türlerde nesnelere sahiptir. Şimdi, **liste** türünü tanıtacağız. Listeler tam da düşündüğünüz gibidir: diğer nesnelerin listesi olan nesne. :) Yeni bir liste yaratmakla devam edelim: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> [] [] -``` +``` Evet, liste boş. Çok kullanışlı sayılmaz, değil mi? Hadi loto numaralarıyla liste oluşturalım. Sürekli kendimizi tekrar etmek istemeyiz, o yüzden listeyi değişkene atayalım: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> lottery = [3, 42, 12, 19, 30, 59] -``` +``` Pekala, listeyi oluşturduk! Onunla ne yapabiliriz? Hadi listede kaç tane loto numarası olduğunu görelim. Hangi fonksiyonu kullanman gerektiği hakkında bir fikrin var mı? Zaten bildiğin bir fonksiyon! -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> len(lottery) 6 ``` Evet! `len()` listedeki nesne sayısını verir. Kullanışlı, değil mi? Belki de şu an listeyi sıralarız: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> lottery.sort() -``` +``` Bu hiçbir cevap vermez, sadece listedeki numaraların sırasını değiştirir. Şimdi listeyi yazdıralım ve ne olduğunu görelim: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> print(lottery) [3, 12, 19, 30, 42, 59] -``` +``` Gördüğünüz gibi, listedeki sayılar artık küçükten büyüğe sıralı. Tebrikler! Belki de sıralamayı ters çevirmek isteriz? Hadi yapalım! -``` +{% filename %}komut-satırı{% endfilename %} + +```python >>> lottery.reverse() >>> print(lottery) [59, 42, 30, 19, 12, 3] -``` +``` -Kolay, değil mi? Listeye yeni bir eleman eklemek isterseniz, bu komutu yazarak yapabilirsiniz: +Kolay, değil mi? Listeye yeni bir eleman eklemek isterseniz, şu komutu yazarak yapabilirsiniz: -``` +{% filename %}komut-satırı{% endfilename %} + +```python >>> lottery.append(199) >>> print(lottery) [59, 42, 30, 19, 12, 3, 199] -``` +``` Sadece listedeki ilk elemanı göstermek isterseniz, **indexes** (indeksler) ile yapabilirsiniz. İndeks elemanın listede nerede olduğunu belirten numaradır. Programcılar sıfırdan başlamayı tercih ederler, bu yüzden listedeki ilk eleman listenin 0. indeksindedir, sonraki 1. indeksindedir ve böyle devam eder. Şunu deneyin: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> print(lottery[0]) 59 >>> print(lottery[1]) 42 -``` +``` -Gördüğünüz gibi, Listedeki nesnelere listenin ismi ve köşeli parantez içindeki nesnenin indeksini kullanarak ulaşabilirsin. +Gördüğünüz gibi, listedeki nesnelere listenin ismi ve köşeli parantez içindeki nesnenin indeksini kullanarak ulaşabilirsin. -Listeden eleman silmek için yukarıda öğrendiğimiz gibi **indeksleri** ve **del** komutunu kullanman gerekir (del silmenin(delete) kısaltmasıdır). Bir örnekle öğrendiklerimizi pekiştirelim; listeden ilk numarayı sileceğiz. +Listenizden bir şeyler silmek için, yukarıda öğrendiğimiz gibi **indeksleri** ve `pop()` metodunu kullanmamız gerekecektir. Bir örnekle öğrendiklerimizi pekiştirelim; listeden ilk numarayı sileceğiz. -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> print(lottery) [59, 42, 30, 19, 12, 3, 199] >>> print(lottery[0]) 59 ->>> del lottery[0] +>>> lottery.pop(0) +59 >>> print(lottery) [42, 30, 19, 12, 3, 199] -``` +``` Kusursuz çalıştı! @@ -294,85 +363,102 @@ Bütün liste fonksiyonlarını Python dökümantasyonunun bu bölümünde bulab ## Sözlükler (Dictionaries) +> Evdeki okuyucular için: Bu kısım [Python Temelleri: Sözlükler](https://www.youtube.com/watch?v=ZX1CVvZLE6c) videosunda işlenmiştir. + Sözlük listeye benzerdir ancak sözlük değerlerine indeks yerine anahtar ile ulaşılır. Anahtar metin veya numara olabilir. Boş bir sözlük oluşturmak için kullanılan söz dizimi şudur: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> {} {} -``` +``` Bu boş bir sözlük oluşturduğunuzu gösterir. Yaşasın! -Şimdi, bu komutu yazmayı deneyin (kendi bilgilerinle değiştir): +Şimdi, bu komutu yazmayı deneyin (kendi bilgilerinizle değiştirmeyi deneyin): -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> participant = {'name': 'Ayşe', 'country': 'Türkiye', 'favorite_numbers': [7, 42, 92]} -``` +``` -Bu komut ile üç anahtar-değer çiftine sahip `participant` isminde bir değişken oluşturdun: +Bu komutla, üç anahtar-değer çifti ile `participant` (katılımcı) isminde bir değişken oluşturdunuz: -* Anahtar `name` `'Ayşe'` (`string` nesnesi) değerine işaret eder, -* `country` `Türkiye` (bir diğer `string`) değerine,), -* ve `favorite_numbers` `[7, 42, 92]` (3 numaralı bir `list`) değerine işaret eder. +- Anahtar `name` `'Ayşe'` (`string` nesnesi) değerine işaret eder, +- `country` `Türkiye` (bir diğer `string`) değerine), +- ve `favorite_numbers` `[7, 42, 92]` (3 numaralı bir `list`) değerine işaret eder. Bu söz dizimi ile tek bir anahtarın içeriğini kontrol edebilirsin: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> print(participant['name']) Ayşe -``` +``` -Gördün mü, listeye benzer. Ancak indeksini hatırlamana gerek yok - sadece ismi. +Gördünüz mü, bu listeye benzer. Fakat indeksi hatırlamanıza gerek yok - sadece ismini hatırlayın. Python'a olmayan bir anahtarın değerini sorarsak ne olur? Tahmin edebiliyor musun? Hadi deneyip görelim! -``` +{% filename %}{{ warning_icon }} komut satırı{% endfilename %} + +```python >>> participant['age'] Traceback (most recent call last): File "", line 1, in KeyError: 'age' -``` +``` Bir başka hata! **KeyError** hatası. Python yardımseverdir ve sana `'age'` anahtarının sözlükte bulunmadığını söyler. -Ne zaman sözlük veya liste kullanmalısın? Düşünmek için güzel bir nokta. Sonraki satırdaki cevaba bakmadan önce kafanızda bir çözüm oluşturun. +Ne zaman sözlük veya liste kullanmalısın? Düşünmek için güzel bir nokta. Sonraki satıra bakmadan önce cevap üzerinde bir düşünün. -* Sıralı elemanlara mı ihtiyacın var? Liste ile devam et. -* İleride hızlıca (anahtarlar ile) değerlere ulaşmak istediğin için anahtarlar ile ilişkilendirilmiş değerlere mi ihtiyacın var? Sözlük kullan. +- Sıralı elemanlara mı ihtiyacın var? Liste ile devam et. +- İleride hızlıca (anahtarlar ile) değerlere ulaşmak istediğin için anahtarlar ile ilişkilendirilmiş değerlere mi ihtiyacın var? Sözlük kullan. Sözlükler de listeler gibi değişebilirdir (*mutable*), yani oluşturulduktan sonra değiştirilebilirler. Oluşturulduktan sonra sözlüklere anahtar/değer çifti ekleyebilirsiniz, aşağıdaki gibi: -``` +{% filename %}komut-satırı{% endfilename %} + +```python >>> participant['favorite_language'] = 'Python' -``` +``` Listeler gibi, `len()` metodu sözlükteki anahtar-değer çiftlerinin sayısını bize verir. Devam edip şu komutu yazın: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> len(participant) 4 ``` - Umarım şu ana kadar mantıklı gelmiştir :) Sözlüklerle biraz daha eğlenceye hazır mısın? İlginç şeyler için sonraki satıra atla. -`del` komutunu sözlükten eleman silmek için kullanabilirsin. Mesela, `'favorite_numbers'` anahtarına karşılık gelen elemanı silmek istersen, sadece şu komutu yaz: +Sözlükten bir maddeyi silmek için `pop()` metodunu kullanabilirsin. Mesela, `'favorite_numbers'` anahtarına karşılık gelen elemanı silmek istersen, şu komutu yaz: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> del participant['favorite_numbers'] >>> participant {'country': 'Türkiye', 'favorite_language': 'Python', 'name': 'Ayşe'} -``` +``` Çıktıdan görebildiğin gibi, 'favorite_numbers' anahtarına karşılık gelen anahtar-değer çifti silindi. Bunun yanı sıra, sözlükteki daha önce oluşturulmuş anahtarın değerini değiştirebilirsiniz. Şunu yazın: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> participant['country'] = 'Almanya' >>> participant {'country': 'Almanya', 'favorite_language': 'Python', 'name': 'Ayşe'} -``` +``` Gördüğün gibi, `'country'` anahtarının değeri `'Türkiye'`den `'Almanya`'ya çevrildi. :) Heyecan verici değil mi? Yaşasın! Bir başka harika şey öğrendin. @@ -380,18 +466,22 @@ Gördüğün gibi, `'country'` anahtarının değeri `'Türkiye'`den `'Almanya`' Harika! Şu an programlama hakkında birçok şey biliyorsun. Bu kısımda, şunları öğrendin: -* **hatalar** - eğer Python yazdığın komutu anlamazsa çıkan hataları nasıl okuyacağını ve anlayacağını artık biliyorsun -* **değişkenler** - daha kolay kod yazmanı sağlayan ve kodunu daha okunabilir yapan nesnelerin isimleri -* **listeler** - belirli bir sırada tutulan nesnelerin listesi -* **sözlükler** - anahtar-değer çifti olarak tutulan nesneler +- **errors** - eğer Python yazdığın komutu anlamazsa çıkan hataları nasıl okuyacağını ve anlayacağını artık biliyorsun +- **değişkenler** - daha kolay kod yazmanı sağlayan ve kodunu daha okunabilir yapan nesnelerin isimleri +- **listeler** - belirli bir sırada tutulan nesnelerin listesi +- **sözlükler** - anahtar-değer çifti olarak tutulan nesneler -Bir sonraki part için heyecanlı mısınız? :) +Bir sonraki bölüm için heyecanlı mısınız? :) ## Karşılaştırma -Programlamanın önemli bir bölümü bir şeyleri karşılaştırmayı içerir. Karşılaştırılabilecek en kolay şey nedir? Tabii ki sayılar. Nasıl çalıştığını görelim (True = "Doğru", False= "Yanlış" demek). +> Evden okuyanlar için: Bu kısım [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4) videosunda anlatılıyor. -``` +Programlamanın büyük kısmı karşılaştırma içerir. Karşılaştırması en kolay olan şey nedir? Tabi ki sayılar. Bakalım nasıl çalışıyor: + +{% filename %}komut satırı{% endfilename %} + +```python >>> 5 > 2 True >>> 3 < 1 @@ -406,62 +496,73 @@ True Python'a birkaç sayı karşılaştırmasını söyledik. Gördüğünüz gibi, sadece sayıları karşılaştırmakla kalmadı, aynı zamanda metodların sonuçlarını da karşılaştırdı. Güzel değil mi? -İki sayının eşit olup olmadığını öğrenmek için neden iki tane eşittir işraretini `==` yan yana koyduk? Değişkenlere içerik verirken, tek `=` işaretini kullanıyoruz. İki sayının birbirine eşit olup olmadığını görmek için **her zaman** `==` işaretini kullanmak gerekiyor. Sayıların birbirine eşit olmaması durumunu da kontrol edebiliriz. Bunun için, yukarıdaki örnekteki gibi `!=` sembolünü kullanıyoruz. +İki sayının eşit olup olmadığını öğrenmek için neden iki tane eşittir işraretini `==` yan yana koyduk? Değişkenlere içerik verirken, tek `=` işaretini kullanıyoruz. Her zaman ama **her zaman** ikisini birden koyman gerekir – `==` – eğer birbirlerine eşit olup olmadıklarını kontrol etmek isterseniz. Sayıların birbirine eşit olmaması durumunu da kontrol edebiliriz. Bunun için, yukarıdaki örnekteki gibi `!=` sembolünü kullanıyoruz. Python' a iki görev daha verin: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> 6 >= 12 / 2 True >>> 3 <= 2 False -``` +``` -`>` ve `<` işaretleri kolay, fakat `>=` ve `<=` ne anlama geliyor? +`>`‘ı ve `<`‘ı gördük, ama `>=` ve `<=` ne anlama geliyor? Onları böyle okuyabilirsin: -* x `>` y : x büyüktür y -* x `<` y : x küçüktür y -* x `<=` y : x küçük eşittir y -* x `>=` y : x büyük eşittir y +- x `>` y : x büyüktür y +- x `<` y : x küçüktür y +- x `<=` y : x küçük eşittir y +- x `>=` y : x büyük eşittir y -Harika! Biraz daha ister misiniz? Şunu deneyin: +Harika! Birkaç denemeye daha ne dersiniz? Şunu deneyin: -``` +{% filename %}komut satırı{% endfilename %} + +```python >>> 6 > 2 and 2 < 3 True >>> 3 > 2 and 2 < 1 False >>> 3 > 2 or 2 < 1 True -``` +``` Python'a istediğiniz kadar sayıyı karşılaştırmak için verebilirsiniz, ve size hepsinin cevabını verecek. Çok akıllı değil mi? -* **and** - Mantıkta kullandığımız "ve" anlamına geliyor, yani iki taraf da True, yani doğruysa, cevap da True olacak -* **or** - Bu da "veya" anlamına geliyor, karşılaştırılan iki taraftan tek bir tanesi bile True ise bize True cevabını verecek +- **and** - Mantıkta kullandığımız "ve" anlamına geliyor, yani iki taraf da True, yani doğruysa, cevap da True olacak +- **or** - Bu da "veya" anlamına geliyor, karşılaştırılan iki taraftan tek bir tanesi bile True ise bize True cevabını verecek Portakallarla elmaları karşılaştılaştırabilir miyiz? Bunun Python'daki eşdeğerini deneyelim: -``` +{% filename %}{{ warning_icon }} komut satırı{% endfilename %} + +```python >>> 1 > 'django' -Traceback (most recent call last): - File "", line 1, in -TypeError: unorderable types: int() > str() -``` +Geri görüş (en son çağrı): + Dosya "", satır 1, ‘in içinde +HataTürü: ‘>’ 'int' ve 'str' örnekleri arasında desteklenmiyor +``` -Gördüğünüz gibi Python tam sayılar(`int`) ve kelimeleri(yani stringleri, `str`) karşılaştıramıyor. Onun yerine, **TypeError** göstererek iki farklı tipteki değişkenin karşılaştırılamayacağını söylüyor. +Gördüğünüz gibi Python tam sayılar(`int`) ve kelimeleri(yani stringleri, `str`) karşılaştıramıyor. Onun yerine, **TypeError** göstererek iki farklı tipteki değişkenin karşılaştırılamayacağını söylüyor. ## Boolean (Mantıksal) -Laf arasında, yeni bir Python nesne tipi öğrendiniz. Adı **boolean** olan bu tip çok kolay. +Bu arada, python'da yeni bir nesne türü öğrendin. Buna **Boolean** denir. -Sadece iki tane boolean nesnesi var: - True (Doğru) - False (Yanlış) +Yalnızca iki Boolean nesnesi vardır: -Python'un bunu anlaması için her zaman "True" (ilk harf büyük, geri kalanları küçük) yazmanız gerekiyor. **true, TRUE, tRUE işe yaramaz -- sadece True doğru.** (Aynısı "False" için de geçerli.) +- True +- False -Boolean'lar değişken de olabiliyor! Bakınız: +Python'un bunu anlaması için her zaman "True" (ilk harf büyük, geri kalanları küçük) yazmanız gerekiyor. **true, TRUE, tRUE işe yaramaz -- sadece True doğru.** (Aynısı "False" için de geçerli.) -``` +Boolean'lar değişken de olabiliyor! Bakınız: + +{% filename %}komut-satırı{% endfilename %} + +```python >>> a = True >>> a True @@ -469,140 +570,198 @@ True Ayrıca bu şekilde de yapabilirsiniz: -``` +{% filename %}komut-satırı{% endfilename %} + +```python >>> a = 2 > 5 >>> a False -``` +``` Boolean'lar ile aşağıdaki komutları deneyerek biraz oynayın: -* `True and True` -* `False and True` -* `True or 1 == 1` -* `1 != 2` +- `True and True` +- `False and True` +- `True or 1 == 1` +- `1 != 2` -Tebrikler! Boolean'lar programlamadaki en havalı özelliklerden, ve az önce onları nasıl kullanmanız gerektiğini öğrendiniz! +Tebrikler! Boolean'lar programlamadaki en havalı özelliklerden, ve az önce onları nasıl kullanmanız gerektiğini öğrendiniz! # Kaydet! +> Evdeki okuyucular için: Bu kısım [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk) videosunda işlenmiştir. + Şimdiye kadar kodumuzu bizi sadece tek satır yazmaya limitleyen yorumlayıcı üzerinde yazdık. Normal programlar dosyalar içine kaydedilir ve programlama dilimizin **yorumlayıcısıyla** veya **derleyicisiyle** çalıştırılır. Şimdiye kadar programlarımızı Python **yorumlayıcısında** teker satır teker satır çalıştırdık. Bundan sonraki görevlerde, birden fazla satıra ihtiyacımız olacak, bu yüzden şunlara ihtiyacımız olacak: -* Python yorumlayıcısından çıkın -* Seçtiğiniz kod düzenleyicisini açın -* Yeni Python dosyasına kod kaydedin -* Çalıştırın! +- Python yorumlayıcısından çıkın +- Seçtiğiniz kod düzenleyicisini açın +- Yeni Python dosyasına kod kaydedin +- Çalıştırın! -Kullandığımız Python yorumlayıcısından çıkmak için sadece ~~~ exit() ~~~ fonksiyonunu yazmanız yeterlidir: +Kullandığımız Python yorumlayıcısından çıkmak için ` +exit() ` fonksiyonunu yazın -```" +{% filename %}komut satırı{% endfilename %} + +```python >>> exit() $ -``` +``` Bu sizi komut satırına geri yönlendirecektir. -Biraz önce [kod editörü][2] bölümünden bir kod editörü seçmiştik. Şimdi o editörü açmalı ve yeni bir dosya içine kod yazmalıyız: +Biraz önce [kod editörü](../code_editor/README.md) bölümünden bir kod editörü seçmiştik. Şimdi o editörü açmalı ve yeni bir dosya içine kod yazmalıyız: - [2]: ../code_editor/README.md +{% filename %}editör{% endfilename %} ```python print('Merhaba, Django girls!') -``` - -> **Not** Kod editörlerinin en havalı özelliğini fark etmiş olmalısınız: renkler! Python konsolunda her şey aynı renkteydi, şimdi `print` fonksiyonunun stringden farklı bir renkte olduğunu görüyorsunuz. Bunun ismi "söz dizimi vurgulama" ve kod yazarken gerçekten yararlı bir özellik. Koddaki renkler sana ipucu verecektir, örneğin metin kullanım hatasında veya dildeki anahtar kelimenin yanlış yazımında (mesela fonksiyondaki `def`, aşağıda göreceğiz). Bu kod düzenleyicisi kullanma nedenlerimizden biri :) +``` Açıkça, artık oldukça deneyimli Python programcısısın, bu yüzden bugün öğrendiğin kodları yazmaktan çekinme. Şimdi dosyayı tanımlayıcı bir isimle kaydetmemiz gerekir. Dosyanın ismine **python_intro.py** diyelim ve masaüstüne kaydedelim. Dosyaya istediğimiz ismi verebiliriz, burada önemli olan kısım dosyanın **.py** uzantısı ile bitmesidir. **.py** uzantısı işletim sistemimize bu dosyanın bir **python çalıştırılabilir dosyası** olduğunu ve Python'un bu dosyayı çalıştırabileceğini belirtiyor. -Dosyayı kaydettiğimize göre artık çalıştırabiliriz! Konsoldan **Klasör değiştirme** yaparak masaüstüne ulaşın, komut satırı bölümünde öğrendiklerinizi hatırlayın. +> **Not** Kod editörleriyle ilgili en harika şeylerden birine dikkat etmelisiniz: renkler! Python konsolunda herşey aynı renkteydi; şimdi bakın `print` fonksiyonu dizeden farklı renkte. Bunun ismi "söz dizimi vurgulama" ve kod yazarken gerçekten yararlı bir özellik. Koddaki renkler ipucu verir, kapanmamış dizeler gibi ya da aşağıda göreceğimiz (`def` fonksiyonu gibi imla hatası içeren anahtar kelimeler olabilir). Bu kod düzenleyicisi kullanma nedenlerimizden biri. :) + +Dosyayı kaydettiğimize göre artık çalıştırabiliriz! Konsoldan **klasör değiştirme ** yaparak masaüstüne ulaşın, komut satırı bölümünde öğrendiklerinizi hatırlayın. + + Mac'de bu komut şunun gibi görünecektir: -``` -$ cd /Users//Desktop -``` +{% filename %}komut-satırı{% endfilename %} + + $ cd ~/Desktop + + + + + Linux'ta ise bu şekilde ("Desktop" kelimesi "Masaüstü" olarak da görünebilir): -``` -$ cd /home//Desktop -``` +{% filename %}komut-satırı{% endfilename %} -Ve Windows'ta, bu şekilde olacak: + $ cd ~/Desktop + -``` -> cd C:\Users\\Desktop -``` + -Bir problem olursa yardım istemekten çekinmeyin. + + +Windows Komut İstemi’nde, bunun gibi olacak: + +{% filename %}komut-satırı{% endfilename %} + + > cd %HomePath%\Desktop + + + + + + +Ve Windows Powershell’de, bunun gibi olacak: + +{% filename %}komut satırı{% endfilename %} + + > cd $Home\Desktop + + + + +Takılırsanız, yardım isteyin. Eğitmenler bunun için var! Şimdi dosyadaki komutları çalıştırmak için Python'u kulllanın: +{% filename %}komut-satırı{% endfilename %} + + $ python3 python_intro.py + Merhaba, Django girls! + + +Not: Windows'ta 'python3' bir komut olarak geçmez. Onun yerine, dosyayı çalıştırmak için 'python'ı kullanın: + +{% filename %}komut satırı{% endfilename %} + +```python +> python python_intro.py ``` -$ python3 python_intro.py -Merhaba, Django girls! -``` Tamam! Bir dosyaya kaydedilen ilk Python programınızı çalıştırdınız. Harika hissediyor musunuz? Şimdi programlamanın olmazsa olmaz bir aracını öğrenme zamanı: -## If...elif...else (Koşullu Akış) +## If … elif … else Kodunuzdaki bir çok şeyi sadece belirli bir durum sağlanıyorsa çalıştırmayı isteyeceksiniz. İşte tam da bu yüzden Python'da **if deyimi** isminde bir yapı bulunuyor. **python_intro.py** dosyasındaki kodunuzu şununla değiştirin: +{% filename %}python_intro.py{% endfilename %} + ```python if 3 > 2: -``` +``` -Eğer bunu kaydedip çalıştırsaydık şu hatayla karşılaşacaktık: +Eğer bunu kaydetmiş ve çalıştırmış olsaydık, bunun gibi bir hata görecektik: -``` -$ python3 python_intro.py -File "python_intro.py", line 2 - ^ -SyntaxError: unexpected EOF while parsing -``` +{% filename %}{{ warning_icon }} komut satırı{% endfilename %} + + $ python3 python_intro.py + File "python_intro.py", line 2 + ^ + SyntaxError: unexpected EOF while parsing + Python bizden kendisine `3 > 2` durumu (veya `True`) sağlandığında neyi çalıştıracağını söylememizi bekliyor. Python'a "Çalışıyor!" yazmasını söyleyelim. **python_intro.py** dosyanızdaki kodu şununla değiştirin: +{% filename %}python_intro.py{% endfilename %} + ```python if 3 > 2: print('Çalışıyor!') -``` +``` -4 tane boşluk karakteri bıraktığımıza dikkat ettiniz mi? Bunu yaparak if cümlesine yazdığım durum doğru olduğunda neyi çalıştırması gerektiğini Python'a söylemiş oluyoruz. Aslında tek bir boşlukla da yapabilirsiniz, ama hemen hemen bütün Python programcıları kodlarının temiz görünmesi için 4 boşluk bırakıyor. Tek `tab` karakteri de 4 boşluk yerine geçecektir. +4 tane boşluk karakteri bıraktığımıza dikkat ettiniz mi? Bunu yaparak if ifadesine yazılan durum doğru olduğunda neyi çalıştırması gerektiğini Python'a söylemiş oluyoruz. Aslında tek bir boşlukla da yapabilirsiniz, ama hemen hemen bütün Python programcıları kodlarının temiz görünmesi için 4 boşluk bırakıyor. Metin düzenleyiciniz ayarlıysa bir tab karakteri de 4 boşluk karakteri olarak sayılacaktır. Seçiminizi yaptıktan sonra değiştirmeyin! Eğer girintilerde 4 boşluk kullandıysanız, gelecek girintilerde de 4 boşluk kullanmaya devam edin - aksi halde sorunlarla karşılaşabilirsiniz. Kaydedip çalıştırmayı deneyelim: -``` +{% filename %}komut satırı{% endfilename %} + +```python $ python3 python_intro.py Çalışıyor! -``` +``` + +Not: Windows'ta 'python3'ün komut olarak geçerli olmadığını unutmayın. Bundan böyle dosyayı çalıştırmak için 'python3'ü 'python'la değiştirin. ### Ya bir koşul True (Doğru) değilse? -Önceki örneklerde kod sadece koşullar sadece True olduğunda çalışıyordu. Ama Python ayrıca `elif` ve `else` ifadelerine de sahip: +Önceki örneklerde kod sadece koşullar sadece True (doğru) olduğunda çalışıyordu. Ama Python ayrıca `elif` ve `else` ifadelerine de sahip: + +{% filename %}python_intro.py{% endfilename %} ```python if 5 > 2: print("5 gerçekten de 2'den büyüktür") else: print("5 2'den büyük değildir") -``` +``` Bu kod çalıştığında aşağıdaki çıktıyı verecektir: -``` -$ python3 python_intro.py -5 gerçekten de 2'den büyüktür -``` +{% filename %}komut satırı{% endfilename %} + + $ python3 python_intro.py + 5 gerçekten de 2'den büyüktür + + +Eğer 2 5'ten büyük bir sayı olsaydı, ikinci komut çalıştırılmış olacaktı. Bakalım `elif` nasıl çalışıyor: -Eğer 2 5'ten büyük bir sayı olsaydı ikinci komut çalışacaktı. Kolay, değil mi? Şimdi `elif`'in nasıl çalıştığına bakalım: +{% filename %}python_intro.py{% endfilename %} ```python name = 'Zeynep' @@ -612,18 +771,21 @@ elif name == 'Zeynep': print('Selam Zeynep!') else: print('Selam yabancı!') -``` +``` ve çalıştırılınca: -``` -$ python3 python_intro.py -Selam Zeynep! -``` +{% filename %}komut-satırı{% endfilename %} + + $ python3 python_intro.py + Selam Zeynep! + -Gördünüz mü? Eğer önceki if cümleleriniz doğru olmazsa kontrol edilmek üzere `elif` cümleleri ekleyebilirsiniz. +Gördünüz mü? Eğer önceki if ifadeleriniz doğru olmazsa kontrol edilmek üzere `elif` ifadeleri ekleyebilirsiniz. -`if` cümlenizden sonra istediğiniz kadar `elif` cümlesi ekleyebilirsiniz. Mesela: +`if` ifadesinden sonra istediğiniz kadar `elif` ifadesi ekleyebilirsiniz. Mesela: + +{% filename %}python_intro.py{% endfilename %} ```python volume = 57 @@ -639,39 +801,63 @@ elif 80 <= volume < 100: print("Biraz gürültülü!") else: print("Kulaklarım ağrıyor! :(") -``` +``` Python sırayla her sorguyu çalıştırır ve sonucu ona göre yazar: +{% filename %}komut satırı{% endfilename %} + + $ python3 python_intro.py + Harika, her notayı duyabiliyorum + + +## Yorumlar + +Yorumlar `#` ile başlayan satırlardır. İstediğiniz her neyse `#` den sonra yazabilirsiniz ve Python onu gözardı eder. Yorumlar kodunuzu diğer insanların anlamasını daha kolaylaştırabilir. + +Bakalım nasıl gözüküyor: + +{% filename %}python_intro.py{% endfilename %} + +```python +# Çok yüksek ya da çok düşük olduğunda ses seviyesini değiştirme +if volume < 20 or volume > 80: + volume = 50 + print("That's better!") ``` -$ python3 python_intro.py -Harika, her notayı duyabiliyorum -``` + +Kodun her satırı için bir açıklama yazmaya ihtiyacınız yoktur, ama kodunuzun niçin birşey yaptığını açıklamak ya da kompleks bir şey yaptığında bir özet sunmak için faydalıdırlar. ### Özet -Son üç alıştırmada öğrendikleriniz: +En son yaptığınız alıştırmalarda öğrendikleriniz: -* **kıyaslama yapmak** - Python'da `>`, `>=`, `==`, `<=`, `<`, `and`, `or` operatörlerini kullanarak kıyaslama yapabiliriz -* **Boolean** - İki farklı değer alabilen bir nesne tipidir: Ya `True` (doğru) olur ya da `False` (yanlış) -* **Dosya kaydetmek** - kodlarımızı dosyalara kaydederek daha büyük programları çalıştırabiliriz. -* **if...elif...else** - cümlelerini sadece belirli durumlar sağlandığında çalıştırmak istediğimiz komutlar için kullanabiliriz. +- **kıyaslama yapmak** - Python'da `>`, `>=`, `==`, `<=`, `<` ve `ve`, `veya` operatörlerini kullanarak kıyaslama yapabilirsiniz +- **Boolean** - İki farklı değer alabilen bir nesne tipidir: Ya `True` (doğru) olur ya da `False` (yanlış) +- **Dosya kaydetmek** – kodlarımızı dosyalara kaydederek daha büyük programları çalıştırabiliriz. +- **if ... elif ... else** - ifadelerini sadece belirli durumlar sağlandığında çalıştırmak istediğimiz komutlar için kullanabiliriz. +- **yorumlar** - kodunuzu belgelemenize izin verecek şekilde Python’un çalışmayacağı satırlar Bu bölümün son kısmının zamanı geldi! ## Kendi fonksiyonlarınız! -Python'daki `len()` gibi fonksiyonları hatırlıyor musunuz? Haberler iyi - artık kendi fonksiyonlarınızı da yazabileceksiniz! +> Evdeki okuyucular için: Bu kısım [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0) videosunda işlenmiştir. + +Python'da çalıştırabileceğin `len()` gibi fonksiyonları hatırlıyor musun? Güzel, iyi haber - Şimdi kendi fonksiyonlarını nasıl yazacağını öğreneceksin! + +Fonksiyon Python tarafından işlenmesi gereken yönergeler dizisidir. Python'da her fonksiyon `def` anahtar kelimesi ile başlar, bir isim verilir ve bazı parameterleri olabilir. Hadi başlayalım. **python_intro.py** içindeki kodu aşağıdaki ile değiştirelim: -Fonksiyon Python tarafından işlenmesi gereken yönergeler dizisidir. Python'da her fonksiyon `def` anahtar kelimesi ile başlar, bir isim verilir ve bazı parameterleri olabilir. Kolay bir tane ile başlayalım. **python_intro.py** içindeki kodu aşağıdaki ile değiştirelim: +{% filename %}python_intro.py{% endfilename %} ```python +python def hi(): print('Merhaba!') print('Nasılsın?') - + hi() -``` +``` Tamam, ilk fonksiyonumuz hazır! @@ -679,171 +865,205 @@ Fonksiyon adını neden dosyanın en altına yazdığımızı merak edebilirsini Haydi şimdi bunu çalıştıralım ve neler olacağını görelim: -``` -$ python3 python_intro.py -Merhaba! -Nasılsın? -``` +{% filename %}komut satırı{% endfilename %} + + $ python3 python_intro.py + Merhaba! + Nasılsın? + + +Not: Eğer çalışmadıysa panik yapmayın! Çıktı neden olduğu hakkında bir fikir verir: + +- Eğer bir `NameError` alırsanız, muhtemelen yanlış bir şey yazdığınız anlamına gelir, bu nedenle `def hi():` lı fonksiyonu oluştururken ve `hi()` lıyı çağırırken aynı adı kullanıp kullanmadığınızı kontrol etmelisiniz. +- Eğer bir `IndentationError` alırsanız,`print` dizelerinin her ikisinin de satır başında aynı boşluğa sahip olduğunu kontrol et: python fonksiyonun içindeki tüm kodların düzenli bir şekilde hizalanmasını ister. +- Eğer tamamında da çıktı yoksa, son `hi()` *isn't* girintiliğini kontrol et - eğer öyleyse, bu dize fonksiyonunda bir parçası haline gelecek ve hiçbir zaman çalışmayacak. -Bu epey kolaydı! Şimdi parametreli bir fonksiyon yazalım. Bir önceki örneği kullanabiliriz - fonksiyonumuz yine 'merhaba' desin - ama bu sefer ismini de söylesin: +İlk fonksiyonumuzu parametrelerle birlikte oluşturalım. Önceki örneği - çalışmaktaki kişiye merhaba diyen bi fonksiyon - ismiyle kullanacağız: + +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): -``` +``` Gördüğünüz gibi, fonksiyonumuza `name` (isim) adında bir parametre ekledik: +{% filename %}python_intro.py{% endfilename %} + ```python def hi(name): if name == 'Ayşe': - print('Selam Ayşe!') + print("Merhaba Ayşe!') elif name == 'Zeynep': - print('Selam Zeynep!') + print('Merhaba Zeynep!') else: - print('Selam yabancı!') - + print('Merhaba yabancı!') + hi() -``` +``` Unutmayın: `if` içerisindeki `print` fonksiyonundan önce dört tane boşluk var. Bunun sebebi sadece durum sağlandığında çalışmasını istememiz. Bakalım nasıl çalışıyor: -``` -$ 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' -``` +{% filename %}{{ warning_icon }} komut satırı{% 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' + Üzgünüz, bir hata. Neyse ki, Python bize oldukça yararlı bir hata mesajı veriyor. `hi()` fonksiyonun (yukarıda tanımladığımız) bir değişken kullanımını gerektirdiğini (`name` isimli) ve bizim o değişkeni fonksiyonu çağırırken iletmeyi unuttuğumuzu söylüyor. Dosyanın alt kısmında hatayı düzeltelim: +{% filename %}python_intro.py{% endfilename %} + ```python hi("Ayşe") -``` +``` Ve tekrar çalıştıralım: -``` -$ python3 python_intro.py +{% filename %}komut satırı{% endfilename %} + + $ python3 python_intro.py Selam Ayşe! -``` + -Ve eğer ismi değiştirirsek ne olur? +Eğer ismi değiştirirsek ne olur? + +{% filename %}python_intro.py{% endfilename %} ```python hi("Zeynep") -``` +``` Ve çalıştırın: -``` -$ python3 python_intro.py -Selam Zeynep! -``` +{% filename %}komut-satırı{% endfilename %} + + $ python3 python_intro.py + Selam Zeynep! + Peki Ayşe veya Zeynep dışında başka bir isim yazdığımızda ne olacağını tahmin edebiliyor musunuz? Deneyin ve tahmininizin doğru olup olmadığını görün. Şunun gibi bir şey yazmalı: -``` -Selam yabancı! -``` +{% filename %}komut satırı{% endfilename %} + + Selam yabancı! + Süper değil mi? Böylece fonksiyona göndereceğiniz isim değiştiğinde aynı kodu tekrar tekrar yazmanıza gerek kalmayacak. İşte fonksiyonlara tam da bu yüzden ihtiyacımız var - aynı kodu tekrar yazmaya gerek yok! -Hadi daha akıllıca bir şeyler yapalım -- tabii ki ikiden fazla isim var ve her isim için bir kontrol yazmak zor olurdu, değil mi? +Hadi daha zekice bir şey yapalım - İkiden fazla isim var ve her biri için bir şart yazmak zor olur değil mi? + +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): - print('Selam ' + name + '!') - + print('Merhaba ' + name + '!') + hi("Seda") -``` +``` Şimdi kodu çağıralım: -``` -$ python3 python_intro.py -Selam Seda! -``` +{% filename %}komut satırı{% endfilename %} + + $ python3 python_intro.py + Merhaba Seda! + Tebrikler! Az önce fonksiyonları nasıl yazacağınızı öğrendiniz! :) ## Döngüler +> Evdeki okuyucular için: Bu kısım [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0) videosunda işlenmiştir. + Bu da zaten son parça. Hızlı oldu, değil mi? :) -Programcılar kendilerini tekrar etmeyi sevmezler. Programlama tamamen işleri otomatize etmedir, bu yüzden her insanı ismiyle selam istemeyiz, değil mi? İşte burası döngülerin devreye girdiği yerdir. +Programcılar kendilerini tekrar etmeyi sevmezler. Programlama tamamen işleri otomatize etmedir, bu yüzden her insanı ismiyle selamlamak istemeyiz, değil mi? İşte burası döngülerin devreye girdiği yerdir. Hala listeleri hatırlıyoruz değil mi? Haydi bir kızlar listesi yapalım: +{% filename %}python_intro.py{% endfilename %} + ```python -girls = ['Seda', 'Gül', 'Pınar', 'Ayşe', 'Sen'] -``` +kızlar = ['Seda', 'Gül', 'Pınar', 'Ayşe', 'Sen'] +``` Diyelim ki hepsine merhaba demek istiyoruz. Az önce yazdığımız `hi` fonksiyonunu döngü içinde kullanabiliriz: +{% filename %}python_intro.py{% endfilename %} + ```python for name in girls: -``` +``` -~~~ for~~~ cümlesi ~~~ if~~~ cümlesine benzer davranır; ikisi için de dört boşluk karakterine ihtiyacımız car. +`for` un davranışı `if` e benziyor; aşağıdaki kodda her iki satır girintili olmalı (dört boşluk ile). Dosyada yer alacak tam kod aşağıdadır: +{% filename %}python_intro.py{% endfilename %} + ```python def hi(name): - print('Selam ' + name + '!') - + print('Merhaba ' + name + '!') + girls = ['Seda', 'Gül', 'Pınar', 'Ayşe', 'Sen'] for name in girls: hi(name) - print('Sıradaki') -``` + print('Sıradaki kız') +``` Ve onu çalıştırdığımız zaman: -``` -$ python3 python_intro.py -Selam Seda! -Sıradaki -Selam Gül! -Sıradaki -Selam Pınar! -Sıradaki -Selam Ayşe! -Sıradaki -Selam Sen! -Sıradaki -``` +{% filename %}komut satırı{% endfilename %} + + $ python3 python_intro.py + Selam Seda! + Sıradaki kız + Selam Gül! + Sıradaki kız + Selam Pınar! + Sıradaki kız + Selam Ayşe! + Sıradaki kız + Selam Sen! + Sıradaki kız + Gördüğünüz gibi, `for` cümlesinin içine boşluk karakteri ile koyduğunuz her şey `girls` listesi için tekrarlanıyor. Ayrıca `for`'u `range` fonksiyonuyla beraber sayılar üzerinde de kullanabilirsiniz: -``` +{% filename %}python_intro.py{% endfilename %} + +```python for i in range(1, 6): print(i) -``` +``` Çalıştırırsak: -``` -1 -2 -3 -4 -5 -``` +{% filename %}komut satırı{% endfilename %} + + 1 + 2 + 3 + 4 + 5 + `range` fonksiyonu birbirini takip eden sayılardan bir liste oluşturur (bu sayıları da siz parametre olarak yazarsınız). -Sizin verdiğiniz ikinci parametrenin listede olmadığına dikkat edin. Yani `range(1, 6)` 1'den 5'e kadar sayıyor, 6 dahil edilmiyor. Çünkü "range" yarı-açık bir aralık ifade ediyor, yani ilk sayı dahil ediliyor ama sondaki sayı dahil edilmiyor. +Sizin verdiğiniz ikinci parametrenin listede olmadığına dikkat edin. Yani `range(1, 6)` 1'den 5'e kadar sayıyor, 6 dahil edilmiyor. Çünkü “aralık” yarı açıktır, ve yani ilk değeri içerir, ama son değeri içermez. ## Özet İşte bu. **Harikasın, süpersin!** Bu bölüm biraz zordu, kendinle gurur duymalısın. Biz buraya kadar geldiğin için seninle gurur duyuyoruz! -Bir sonraki bölüme geçmeden önce kısa bir süreliğine başka birşey yapmak isteyebilirsiniz - esneyin, biraz etrafı dolaşın, gözlerinizi dinlendirin :) +Resmi ve tam python tutorialı için https://docs.python.org/3/tutorial/ adresini ziyaret edin. Bu size dil hakkında daha kapsamlı ve eksiksiz bir çalışma sunacaktır. Teşekkürler :) -![Kek][3] +Sonraki bölüme geçmeden başka bir şey yapmak isteyebilirsin. -gerin, biraz etrafta gezin, gözlerini dinlendir- :) - [3]: images/cupcake.png +![Cupcake](images/cupcake.png) \ No newline at end of file diff --git a/tr/python_introduction/images/cupcake.png b/tr/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/tr/python_introduction/images/cupcake.png and b/tr/python_introduction/images/cupcake.png differ diff --git a/tr/template_extending/README.md b/tr/template_extending/README.md old mode 100755 new mode 100644 index a07c9cb8ac8..9c839d0da15 --- a/tr/template_extending/README.md +++ b/tr/template_extending/README.md @@ -2,26 +2,27 @@ Django'nun size sunduğu başka bir güzellik de **template genişletmek**tir. O da ne demek? Şu demek, HTML dosyanızın bazı bölümlerini birden fazla sayfanızda kullanabilirsiniz. -Böylece aynı bilgi/yerleştirmeyi kullanmak istediğinizde her dosyada kendinizi tekrar etmenize gerek kalmaz. Ve bir değişiklik yapmak istediğinizde bunu bütün template dosyalarında yapmanıza gerek kalmaz, bir kere değiştirmek yeterlidir! +Templatelar aynı bilgiyi ya da yerleştirmeyi (layout) birden fazla yerde kullanmak istediğinizde yardım ederler. Yaptığınızı her dosya için tekrar etmek zorunda kalmazsınız. Ve bir şey değiştirmek isterseniz, tüm templatelarda değil sadece bir tanesinde değiştirirsiniz! -## Temel template oluşturun +## Bir Temel Template Oluştur Temel template web sitenizin bütün sayfalarında genişletebileceğiniz en temel template'inizdir. Şimdi `blog/templates/blog/` klasörü içinde `base.html` adlı bir dosya oluşturalım: -``` -blog -└───templates - └───blog - base.html - post_list.html -``` + blog + └───templates + └───blog + base.html + post_list.html + -Sonra bunu açalım ve `post_list.html` dosyasındaki her şeyi aşağıdaki gibi bu `base.html`'ye kopyalayalım: +Sonra bunu açalım ve `post_list.html` dosyasındaki her şeyi aşağıdaki gibi `base.html`'ye kopyalayalım: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html -{% load staticfiles %} +{% load static %} Django Girls blog @@ -34,28 +35,30 @@ Sonra bunu açalım ve `post_list.html` dosyasındaki her şeyi aşağıdaki gib - +
{% for post in posts %}
- {{ post.yayinlanma_tarihi }} + {{ post.published_date }}
-

{{ post.baslik }}

-

{{ post.yazi|linebreaks }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

{% endfor %}
- -``` + +``` Sonra, `base.html` dosyasındaki ``'nizi (`` ve `` arasında kalan her şeyi) şununla değiştirin: +{% filename %}blog/templates/blog/base.html{% endfilename %} + ```html
-``` +``` + +{% raw %}Her şeyin bununla değiştirildiğini fark edebilirsiniz`{% for post in posts %}`dan`{% endfor %}`bununla:{% endraw %} -Aslında sadece `{% for post in posts %}{% endfor %}` arasındaki her şeyi şununla değiştirmiş olduk: +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% block content %} {% endblock %} -``` +``` + +Ama neden? Bir `blok` oluşturdunuz! `{% block %}` içinde HTML ekleyecek alan yapmak için şablon etiketi kullandınız. HTML başka bir şablondan gelecek (`base.html`) bu şablonu genişletir. Bunun nasıl yapıldığını da hemen göstereceğiz. -Peki bu ne anlama geliyor? Az önce bir template etiketi olan `block`'u kullanarak bir blok oluşturdunuz. Diğer template'leri bu bloğun içine HTML ekleyerek `base.html`'yi genişletebilirsiniz. Bunun nasıl yapıldığını da hemen göstereceğiz. +Şimdi `base.html`'i kaydedelim ve `blog/templates/blog/post_list.html` dosyamızı tekrar açalım. {% raw %} `{% for post in posts %}`'ın üzerindeki ve `{% endfor %}`'ın altındaki her şeyi kaldıracaksınız. İşiniz bittiğinde dosya şu şekilde görünecektir:{% endraw %} -Şimdi bunu kaydedin ve tekrar `blog/templates/blog/post_list.html` dosyanızı açın. Body içinde kalanlar hariç her şeyi silin. Ve ayrıca `` bölümünü de silin. Dosyanız şöyle görünecektir: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %}
- {{ post.yayinlanma_tarihi }} + {{ post.published_date }}
-

{{ post.baslik }}

-

{{ post.yazi|linebreaks }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

{% endfor %} -``` +``` -Ve şimdi şu satırı sayfanın başına ekleyin: +Bunu, bütün içerik blokları için şablonumuzun bir parçası olarak kullanmak istiyoruz. Şimdi bu dosyaya blok etiketleri ekleme zamanı! -``` -{% extends 'blog/base.html' %} -``` +{% raw %}Blok etiketinizin `base.html` dosyanızdaki etikete uymasını istiyorsunuz. Ayrıca içerik bloklarınına ait bütün kodu da dahil etmek istiyorsun. Bunu yapmak için, her şeyi `{% block content %}`ve`{% endblock %}`'un arasına yerleştir. Şunun gibi:{% endraw %} -{% raw %}Bu şu anlama geliyor: `post_list.html` dosyasında `base.html` template'i genişletiyoruz. Sadece bir şey kaldı: Her şeyi (en son eklediğimiz satır hariç) `{% block content %}` ve `{% endblock content %}` arasına koyun. Şunun gibi:{% endraw %} +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + +```html +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

+
+ {% endfor %} +{% endblock %} +``` + +Geriye tek bir şey kaldı. Bu iki şablonu birbirine bağlamamız gerekiyor. Genişleyen şablonlar tam da bununla ilgili! Bunu dosyanın başlangıcına genişleyebilir etiketler ekleyerek yapacağız. Bunun gibi: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% extends 'blog/base.html' %} - + {% block content %} {% for post in posts %}
- {{ post.yayinlanma_tarihi }} + {{ post.published_date }}
-

{{ post.baslik }}

-

{{ post.yazi|linebreaks }}

+

{{ post.title }}

+

{{ post.text|linebreaksbr }}

{% endfor %} -{% endblock content %} -``` +{% endblock %} +``` -İşte bu! Sitenizin hala düzgün çalışıp çalışmadığını kontrol edin :) +İşte bu! Dosyayı kaydedip sitenizin hala düzgün çalışıp çalışmadığını kontrol edin. :) -> `blog/base.html` dosyası olmadığını söyleyen bir `TemplateDoesNotExists` hatası alıyorsanız, ve `runserver` konsolda çalışmaya devam ediyorsa Ctrl ve C butonlarına aynı anda basarak durdurmaya çalışın. Ve `python manage.py runserver` komutu ile yeniden başlatmayı deneyin. +> Eğer `TemplateDoesNotExist` hatasını alıyorsanız, bunun anlamı `blog/base.html` dosyası yok ve konsolda `runserver`'ı çalıştırıyorsunuz demektir. Konsolda durdurmayı deneyin (Ctrl+C -Control ve C tuşlarına birlikte basarak) ve `python manage.py runserver` komutunu çalıştırarak yeniden başlatın. \ No newline at end of file diff --git a/tr/whats_next/README.md b/tr/whats_next/README.md old mode 100755 new mode 100644 index 94f2944dd97..aee9350a995 --- a/tr/whats_next/README.md +++ b/tr/whats_next/README.md @@ -6,35 +6,19 @@ Kendini tebrik et! **Kesinlikle harikasın**. Seninle gurur duyuyoruz! <3 Bir ara ver ve rahatla. Gerçekten çok büyük bir şey yaptın. -Bundan sonra şunları yaptığına emin ol: +Sonra, güncel kalmak için Django Girls'ü [Facebook](http://facebook.com/djangogirls) ya da [Twitter](https://twitter.com/djangogirls) da takip ettiğinizden emin olun. -* Güncel kalmak için Django Girls'ü [Facebook][1] ya da [Twitter][2] dan takip et +### Daha geniş kapsamlı kaynaklar önerebilir misiniz? - [1]: http://facebook.com/djangogirls - [2]: http://twitter.com/djangogirls +Evet! Öncelikle [Django Girls Tutorial: Eklentiler](https://tutorial-extensions.djangogirls.org/) isimli diğer kitabımızı dene. -### Daha geniş kapsamlı kaynaklar önerebilir misiniz? +Daha sonra, aşağıdaki listedeki kaynakları deneyebilirsin. Hepsi birden çok kez önerilir! -Evet! Öncelikle [Django Girls Tutorial: Extensions][3] isimli diğer kitabımızı dene. - - [3]: http://djangogirls.gitbooks.io/django-girls-tutorial-extensions/ - -Sonra ise aşağıda listelenen diğer kaynakları deneyebilirsin. Hepsini öneriyoruz! - -- [Django'nun resmi eğitimi][4] -- [Kodlamaya Yeni Başlayan (New Coder) eğitimi][5] -- [Code Academy Python kursu][6] -- [Code Academy HTML & CSS kursu][7] -- [Django Carrots eğitimi][8] -- [Learn Python The Hard Way kitabı][9] -- [Getting Started With Django görünütülü dersleri][10] -- [Two Scoops of Django: Best Practices for Django 1.8 kitabı][11] - - [4]: https://docs.djangoproject.com/en/1.10/intro/tutorial01/ - [5]: http://newcoder.io/tutorials/ - [6]: http://www.codecademy.com/en/tracks/python - [7]: http://www.codecademy.com/tracks/web - [8]: http://django.carrots.pl/en/ - [9]: http://learnpythonthehardway.org/book/ - [10]: http://gettingstartedwithdjango.com/ - [11]: http://twoscoopspress.com/products/two-scoops-of-django-1-8 +- [Resmi Django eğitimi](https://docs.djangoproject.com/en/2.0/intro/tutorial01/) +- [Yeni başlayan eğitimleri](http://newcoder.io/tutorials/) +- [Code Academy Python kursu](https://www.codecademy.com/en/tracks/python) +- [Code Academy HTML & CSS kursu](https://www.codecademy.com/tracks/web) +- [Django Carrots eğitimi](https://github.com/ggcarrots/django-carrots) +- [Django'yu Zor Yoldan Öğren kitabı](http://learnpythonthehardway.org/book/) +- [Django Video Dersleriyle Başlangıç](http://www.gettingstartedwithdjango.com/) +- [2 Kaşık Django 1.11: Django Web Framework'ün En İyi Uygulamaları Kitabı](https://www.twoscoopspress.com/products/two-scoops-of-django-1-11) diff --git a/uk/code_editor/instructions.md b/uk/code_editor/instructions.md index 4f6cce57793..b877de82df1 100644 --- a/uk/code_editor/instructions.md +++ b/uk/code_editor/instructions.md @@ -8,11 +8,11 @@ Gedit є відкритим, безкоштовним редактором, до [Завантажте його можна тут](https://wiki.gnome.org/Apps/Gedit#Download) -## Sublime Text 3 +## Sublime Text Sublime Text є дуже популярним редактором із безкоштовним пробним періодом. Він легко встановлюється та простий у використанні, а також доступний для усіх операційних систем. -[Завантажити його можна тут](https://www.sublimetext.com/3) +[Завантажити його можна тут](https://www.sublimetext.com/) ## Atom diff --git a/uk/css/README.md b/uk/css/README.md index f84307689ea..26c0c08e382 100755 --- a/uk/css/README.md +++ b/uk/css/README.md @@ -45,7 +45,8 @@ Bootstrap - один з найбільш популярних HTML і CSS фре djangogirls ├── blog │ ├── migrations - │ └── static + │ ├── static + │   └── templates └── mysite Django автоматично знайде всі "статичні" папки всередині будь-якої з папок з вашими додатками, і він буде мати можливість використовувати їх як статичні файли. @@ -91,7 +92,7 @@ Class і id - імена, які ви присвоюєте елементам в Далі, нам треба повідомити наш HTML-шаблон про те, що ми додали CSS. Відкрийте файл `blog/templates/blog/post_list.html` і додайте на початок цей рядок: ```html -{% load staticfiles %} +{% load static %} ``` Тут лише завантажуються статичні файли :) @@ -106,7 +107,7 @@ Class і id - імена, які ви присвоюєте елементам в Тепер ваш файл має виглядати наступним чином: ```html -{% load staticfiles %} +{% load static %} Django Girls blog diff --git a/uk/css/images/bootstrap1.png b/uk/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/uk/css/images/bootstrap1.png and b/uk/css/images/bootstrap1.png differ diff --git a/uk/css/images/color2.png b/uk/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/uk/css/images/color2.png and b/uk/css/images/color2.png differ diff --git a/uk/css/images/final.png b/uk/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/uk/css/images/final.png and b/uk/css/images/final.png differ diff --git a/uk/css/images/font.png b/uk/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/uk/css/images/font.png and b/uk/css/images/font.png differ diff --git a/uk/css/images/margin2.png b/uk/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/uk/css/images/margin2.png and b/uk/css/images/margin2.png differ diff --git a/uk/deploy/README.md b/uk/deploy/README.md index 99badc01230..8f35a4db6c9 100755 --- a/uk/deploy/README.md +++ b/uk/deploy/README.md @@ -4,7 +4,7 @@ До цього часу ваш веб-сайт був доступний лише локально на вашому комп'ютері, тепер ви дізнаєтесь, як його розгорнути! Розгортання - це процес публікації вашого додатку в Інтернеті таким чином, що люди можуть зайти і побачити його :). -Як ви вже знаєте, веб-сайт має бути розміщений на сервері. В Інтернеті є багато компаній які пропонують такі послуги. Ми будемо використовувати той, який має відносно простий розгортання процес: [PythonAnywhere](https://pythonanywhere.com/). PythonAnywhere безкоштовний для малих додатків, в яких не дуже багато користувачів, тож нам цього точно буде достатньо. +Як ви вже знаєте, веб-сайт має бути розміщений на сервері. В Інтернеті є багато компаній які пропонують такі послуги. Ми будемо використовувати той, який має відносно простий розгортання процес: [PythonAnywhere](https://www.pythonanywhere.com/). PythonAnywhere безкоштовний для малих додатків, в яких не дуже багато користувачів, тож нам цього точно буде достатньо. Інший зовнішній інструмент, який ми будемо використовувати - це [GitHub](https://www.github.com), платформа для розміщення коду. У нього є альтернативи, але майже кожен програміст зараз має GitHub профіль, і скоро ви будете серед них! @@ -55,7 +55,7 @@ db.sqlite3 $ git status On branch master - Initial commit + No commits yet Untracked files: (use "git add ..." to include in what will be committed) @@ -92,7 +92,7 @@ db.sqlite3 -Зараз нам потрібно під'єднати Git репозиторій на локальному комп'ютері до щойно створеного на GitHib. +Зараз нам потрібно під'єднати Git репозиторій на локальному комп'ютері до щойно створеного на GitHub. Введіть у вашій консолі (замінивши `<ваше-github-ім'я>` іменем користувача, вказаним під час створення облікового запису GitHub, але без кутових дужок): diff --git a/uk/deploy/images/github_get_repo_url_screenshot.png b/uk/deploy/images/github_get_repo_url_screenshot.png index 62a29f5f8d7..ee1560b1e85 100644 Binary files a/uk/deploy/images/github_get_repo_url_screenshot.png and b/uk/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/uk/deploy/images/new_github_repo.png b/uk/deploy/images/new_github_repo.png index 64011e59a52..d1f82e5d863 100644 Binary files a/uk/deploy/images/new_github_repo.png and b/uk/deploy/images/new_github_repo.png differ diff --git a/uk/deploy/images/pythonanywhere_web_tab_virtualenv.png b/uk/deploy/images/pythonanywhere_web_tab_virtualenv.png index 97e87e7b07b..6069f6da831 100644 Binary files a/uk/deploy/images/pythonanywhere_web_tab_virtualenv.png and b/uk/deploy/images/pythonanywhere_web_tab_virtualenv.png differ diff --git a/uk/deploy/install_git.md b/uk/deploy/install_git.md index 28dd2f7693a..cd11f616a69 100644 --- a/uk/deploy/install_git.md +++ b/uk/deploy/install_git.md @@ -15,15 +15,10 @@ Git можна завантажити з [git-scm.com](https://git-scm.com/). В #### Debian або Ubuntu - $ sudo apt-get install git + $ sudo apt install git -#### Fedora (до 21) - - $ sudo yum install git - - -#### Fedora (22+) +#### Fedora $ sudo dnf install git diff --git a/uk/django_admin/README.md b/uk/django_admin/README.md index dad7f9ef8e3..de2e6babcf2 100755 --- a/uk/django_admin/README.md +++ b/uk/django_admin/README.md @@ -36,6 +36,6 @@ admin.site.register(Post) ![Django адміністратор](images/edit_post3.png) -Якщо бажаєте дізнатися більше про Django admin, гляньте документацію Django: https://docs.djangoproject.com/en/1.10/ref/contrib/admin/ +Якщо бажаєте дізнатися більше про Django admin, гляньте документацію Django: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/ Це напевне гарний час щоб налити кави (чи чаю) чи з’їсти щось щоб перезарядитися. Ви створили свою першу модель Django і заслуговуєте на короткий тайм-аут! diff --git a/uk/django_admin/images/django_admin3.png b/uk/django_admin/images/django_admin3.png index a450b4f9630..ea01ab951bf 100644 Binary files a/uk/django_admin/images/django_admin3.png and b/uk/django_admin/images/django_admin3.png differ diff --git a/uk/django_admin/images/edit_post3.png b/uk/django_admin/images/edit_post3.png index c8572a73e7d..d577b111424 100644 Binary files a/uk/django_admin/images/edit_post3.png and b/uk/django_admin/images/edit_post3.png differ diff --git a/uk/django_admin/images/login_page2.png b/uk/django_admin/images/login_page2.png index 47153ef6960..6ae26e9959a 100644 Binary files a/uk/django_admin/images/login_page2.png and b/uk/django_admin/images/login_page2.png differ diff --git a/uk/django_forms/README.md b/uk/django_forms/README.md index 4164d1f98e9..e773c22d764 100755 --- a/uk/django_forms/README.md +++ b/uk/django_forms/README.md @@ -52,7 +52,7 @@ class PostForm(forms.ModelForm): Після додавання відповідного рядка, ваш html файл має виглядати наступним чином: ```html -{% load staticfiles %} +{% load static %} Django Girls blog @@ -210,7 +210,7 @@ from django.shortcuts import redirect return redirect('post_detail', pk=post.pk) ``` -`blog.views.post_detail` - ім'я виду, до якого ми хочемо перейти. Пам'ятаєте, що цей вид потребує змінної `pk`? Щоб здійснити передачу вище згаданої змінної, скористаємося `pk=post.pk`, де `post` є новим постом! +`post_detail` - ім'я виду, до якого ми хочемо перейти. Пам'ятаєте, що цей вид потребує змінної `pk`? Щоб здійснити передачу вище згаданої змінної, скористаємося `pk=post.pk`, де `post` є новим постом! Але, щось дуже багато балачок, напевно ми хотіли б побачити, як відображується даний вид наразі в цілому, правда ж? @@ -330,7 +330,7 @@ form = PostForm(instance=post) Вітаємо! Ваш додаток стає все більш і більш повним! -Якщо бажаєте дізнатись більше інформації про форми Django, ознайомтесь із документацією: https://docs.djangoproject.com/en/1.10/topics/forms/ +Якщо бажаєте дізнатись більше інформації про форми Django, ознайомтесь із документацією: https://docs.djangoproject.com/en/1.11/topics/forms/ ## Безпека diff --git a/uk/django_forms/images/csrf2.png b/uk/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/uk/django_forms/images/csrf2.png and b/uk/django_forms/images/csrf2.png differ diff --git a/uk/django_forms/images/drafts.png b/uk/django_forms/images/drafts.png index cd88e3c3d84..1d62f8866f4 100644 Binary files a/uk/django_forms/images/drafts.png and b/uk/django_forms/images/drafts.png differ diff --git a/uk/django_forms/images/edit_button2.png b/uk/django_forms/images/edit_button2.png index 099b66731c8..804674f0965 100644 Binary files a/uk/django_forms/images/edit_button2.png and b/uk/django_forms/images/edit_button2.png differ diff --git a/uk/django_forms/images/edit_form2.png b/uk/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/uk/django_forms/images/edit_form2.png and b/uk/django_forms/images/edit_form2.png differ diff --git a/uk/django_forms/images/form_validation2.png b/uk/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/uk/django_forms/images/form_validation2.png and b/uk/django_forms/images/form_validation2.png differ diff --git a/uk/django_forms/images/new_form2.png b/uk/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/uk/django_forms/images/new_form2.png and b/uk/django_forms/images/new_form2.png differ diff --git a/uk/django_forms/images/post_create_error.png b/uk/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/uk/django_forms/images/post_create_error.png and b/uk/django_forms/images/post_create_error.png differ diff --git a/uk/django_installation/instructions.md b/uk/django_installation/instructions.md index 1b9ca462112..3a8c043f616 100644 --- a/uk/django_installation/instructions.md +++ b/uk/django_installation/instructions.md @@ -31,9 +31,9 @@ де `C:\Python34\python` - це папка, в якій ви перед цим встановили Python, а `myvenv` - ім'я вашого віртуального середовища `virtualenv`. Ви можете використовувати будь-яке ім’я, але старайтесь обмежитись маленькими буквами і не використовуйте пробілів, наголосів або спеціальних символів. Тримати ім’я коротким - також гарна ідея, оскільки ви будете часто посилатися на нього! -### Linux та OS X +### Linux та macOS -Створення віртуального середовища `virtualenv` як на Linux так і на OS X просто відбувається запуском `python3 -m venv myvenv`. +Створення віртуального середовища `virtualenv` як на Linux так і на macOS просто відбувається запуском `python3 -m venv myvenv`. Виглядає це так: $ python3 -m venv myvenv @@ -46,7 +46,7 @@ > Щоб обійти цю проблему, використовуйте натомість команду `virtualenv`. -> $ sudo apt-get install python-virtualenv +> $ sudo apt install python-virtualenv > $ virtualenv --python=python3.4 myvenv @@ -60,7 +60,7 @@ C:\Users\Name\djangogirls> myvenv\Scripts\activate -#### Linux та OS X +#### Linux та macOS Запустіть своє віртуальне середовище виконавши: @@ -80,10 +80,10 @@ ## Встановлення Django -Наразі, коли ваш `virtualenv` активований, можна встановлювати Django використавши `pip`. В консолі, запустіть `pip install django==1.10` (зазначте, що тут ми користуємося подвійним знаком рівності: `==`). +Наразі, коли ваш `virtualenv` активований, можна встановлювати Django використавши `pip`. В консолі, запустіть `pip install django==1.11` (зазначте, що тут ми користуємося подвійним знаком рівності: `==`). - (myvenv) ~$ pip install django==1.10 - Downloading/unpacking django==1.10 + (myvenv) ~$ pip install django==1.11 + Downloading/unpacking django==1.11 Installing collected packages: django Successfully installed django Cleaning up... @@ -94,7 +94,7 @@ для Windows 8 чи Windows 10 > Ваш командний рядок може зависнути, після того як ви спробуєте встановити Django. Якщо це сталось, замість вище зазначеної команди використовуйте: -> C:\Users\Name\djangogirls> python -m pip install django==1.10 +> C:\Users\Name\djangogirls> python -m pip install django==1.11 для Linux > Якщо виникла помилка під час запуску pip на Ubuntu 12.04, будь ласка, запустіть `python -m pip install -U --force-reinstall pip` щоб коректно перевстановити pip у віртуальному середовищі. diff --git a/uk/django_models/README.md b/uk/django_models/README.md index 221ee2ce6d3..03d73aa8968 100755 --- a/uk/django_models/README.md +++ b/uk/django_models/README.md @@ -102,12 +102,13 @@ INSTALLED_APPS = ( Відкриємо `blog/models.py`, видалимо все звідси та запишемо наступний код: ```python +from django.conf import settings from django.db import models from django.utils import timezone class Post(models.Model): - author = models.ForeignKey('auth.User') + author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) title = models.CharField(max_length=200) text = models.TextField() created_date = models.DateTimeField( @@ -142,7 +143,7 @@ class Post(models.Model): - `models.DateTimeField` - дата та час. - `models.ForeignKey` - зв'язок із іншою моделлю. -Не будемо пояснювати кожне слово в коді, оскільки це може зайняти надто багато часу. Якщо хочете дізнатися більше про поля моделей, а також як визначати речі відмінні від вище описаних, то дивіться документацію Django (https://docs.djangoproject.com/en/1.10/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`. diff --git a/uk/django_orm/README.md b/uk/django_orm/README.md index 8c0bd3eccfa..611ca099a54 100755 --- a/uk/django_orm/README.md +++ b/uk/django_orm/README.md @@ -40,7 +40,7 @@ A QuerySet є, по суті, списком об'єктів заданої мо Усе просто: імпортуємо модель `Post` з `blog.models`. Спробуємо вивести усі пости знову: >>> Post.objects.all() - [, ] + , ]> Це список з дописів, з якими ми працювали раніше! Ми створили ці дописи через панель адміністратора Django. Проте, зараз ми хочемо створити нові дописи за допомогою Python, як ми цього доб'ємось? @@ -60,7 +60,7 @@ A QuerySet є, по суті, списком об'єктів заданої мо Які користувачі присутні в нашій базі даних? Спробуймо це: >>> User.objects.all() - [] + ]> Це суперкористувач, якого ми створили раніше! Нам потрібен його екземпляр: @@ -75,7 +75,7 @@ A QuerySet є, по суті, списком об'єктів заданої мо Ура! Бажаєте перевірити, чи це працює? >>> Post.objects.all() - [, , ] + , , ]> Є, ще один допис в списку! @@ -90,12 +90,12 @@ A QuerySet є, по суті, списком об'єктів заданої мо Великою частиною QuerySets є можливість фільтрувати запити до бази даних. Скажімо, ми хочемо відшукати усі пости, що мають автора ola. Будемо використовувати `filter` замість `all` в `Post.objects.all()`. В дужках ми вказуємо яким умовам повинен відповідати пост, щоб завершити наш запит до бази даних. У нашому випадку це автор `author`, що дорівнює `me`. В Django цю умову можна виразити як: `author=me`. Тепер наш шматок коду виглядає так: >>> Post.objects.filter(author=me) - [, , , ] + , , , ]> Чи, можливо, ми хочемо побачити усі пости, що містять слово 'title' в полі `title`? >>> Post.objects.filter(title__contains='title') - [, ] + , ]> > **Зауваження** Тут використано два знаки підкреслювання (`_`) між `title` і `contains`. Django ORM використовує цей синтаксис щоб відокремити імена полів ("title") і операції або фільтри ("contains"). Якщо ви раптом використаєте одне підкреслювання, то отримаєте помилку на кшталт "FieldError: Cannot resolve keyword title_contains". @@ -115,7 +115,7 @@ A QuerySet є, по суті, списком об'єктів заданої мо Тепер спробуйте отримати список опублікованих дописів знову (натисніть стрілку вгору 3 рази, а потім `enter`): >>> Post.objects.filter(published_date__lte=timezone.now()) - [] + ]> ### Впорядкування об'єктів @@ -123,12 +123,12 @@ A QuerySet є, по суті, списком об'єктів заданої мо QuerySets також дозволяє впорядковувати список об'єктів. Давайте спробуємо впорядкувати їх за параметром поля `created_date`: >>> Post.objects.order_by('created_date') - [, , , ] + , , , ]> Також можна здійснити впорядкування у зворотньому напрямку, додавши `-` на початку: >>> Post.objects.order_by('-created_date') - [, , , ] + , , , ]> ### З'єднання QuerySets diff --git a/uk/django_start_project/README.md b/uk/django_start_project/README.md index 8b121540a53..087b4cdf8a8 100755 --- a/uk/django_start_project/README.md +++ b/uk/django_start_project/README.md @@ -69,7 +69,7 @@ TIME_ZONE = 'Europe/Kiev' ```python STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') +STATIC_ROOT = BASE_DIR / 'static' ``` @@ -83,7 +83,7 @@ STATIC_ROOT = os.path.join(BASE_DIR, 'static') DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'NAME': BASE_DIR / 'db.sqlite3', } } ``` diff --git a/uk/django_start_project/images/it_worked2.png b/uk/django_start_project/images/it_worked2.png index 4412ecfc49e..4efa554e567 100644 Binary files a/uk/django_start_project/images/it_worked2.png and b/uk/django_start_project/images/it_worked2.png differ diff --git a/uk/django_templates/README.md b/uk/django_templates/README.md index 40bd9d9ab87..aaa7ba667e3 100755 --- a/uk/django_templates/README.md +++ b/uk/django_templates/README.md @@ -24,7 +24,7 @@ __Шаблонні теги Django__ дозволяють нам передав Як можна побачити, все що ми отримали, це: - [, ] + , ]> Означає, що Django розуміє це як список об'єктів. Пам'ятаєте із розділу __Вступ до Python__ як ми можемо виводити списки? Звичайно, за допомогою циклу __for__! У Django шаблонах ви можете створити їх наступним чином: @@ -65,7 +65,7 @@ __Шаблонні теги Django__ дозволяють нам передав Було б непогано побачити як ваш сайт буде працювати в інтернеті, так? Давайте спробуєм розгорнути його в PythonAnywhere знову. Ось наступні кроки... -* По-перше, залийте ваш код на Github +* По-перше, залийте ваш код на GitHub ``` $ git status diff --git a/uk/django_templates/images/donut.png b/uk/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/uk/django_templates/images/donut.png and b/uk/django_templates/images/donut.png differ diff --git a/uk/django_templates/images/step1.png b/uk/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/uk/django_templates/images/step1.png and b/uk/django_templates/images/step1.png differ diff --git a/uk/django_templates/images/step2.png b/uk/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/uk/django_templates/images/step2.png and b/uk/django_templates/images/step2.png differ diff --git a/uk/django_templates/images/step3.png b/uk/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/uk/django_templates/images/step3.png and b/uk/django_templates/images/step3.png differ diff --git a/uk/django_urls/README.md b/uk/django_urls/README.md index 0e77e103ef0..9054f9e351b 100755 --- a/uk/django_urls/README.md +++ b/uk/django_urls/README.md @@ -119,4 +119,4 @@ urlpatterns = [ Можете прочитати тут: __no attribute 'post_list'__. Чи *post_list* не нагадує вам про щось? Це назва нашого відображення! Це означає, що все знаходиться на місці, але ми просто ще не створили наше *відображення*. Не переймайтесь, ми його отримаємо. -> Якщо бажаєте дізнатися більше про Django URLconf, зверніться до офіційної документації: https://docs.djangoproject.com/en/1.10/topics/http/urls/ +> Якщо бажаєте дізнатися більше про Django URLconf, зверніться до офіційної документації: https://docs.djangoproject.com/en/1.11/topics/http/urls/ diff --git a/uk/django_urls/images/error1.png b/uk/django_urls/images/error1.png index cc17593d19d..250028e996b 100644 Binary files a/uk/django_urls/images/error1.png and b/uk/django_urls/images/error1.png differ diff --git a/uk/django_urls/images/url.png b/uk/django_urls/images/url.png index 6cd1bd96291..b59f9dce992 100644 Binary files a/uk/django_urls/images/url.png and b/uk/django_urls/images/url.png differ diff --git a/uk/django_views/README.md b/uk/django_views/README.md index 5fe41b75ea2..6659604e69b 100755 --- a/uk/django_views/README.md +++ b/uk/django_views/README.md @@ -34,4 +34,4 @@ def post_list(request): Цього разу усе просто: *TemplateDoesNotExist*.Виправимо це і створимо шаблон в наступному розділі! -> Дізнатися більше про Django відображення можна, звернувшись до офіційної документації: https://docs.djangoproject.com/en/1.10/topics/http/views/ +> Дізнатися більше про Django відображення можна, звернувшись до офіційної документації: https://docs.djangoproject.com/en/1.11/topics/http/views/ diff --git a/uk/django_views/images/error.png b/uk/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/uk/django_views/images/error.png and b/uk/django_views/images/error.png differ diff --git a/uk/dynamic_data_in_templates/README.md b/uk/dynamic_data_in_templates/README.md index 9c188d2d835..8f0daf06845 100755 --- a/uk/dynamic_data_in_templates/README.md +++ b/uk/dynamic_data_in_templates/README.md @@ -68,4 +68,4 @@ def post_list(request): Це все! Час повернутись назад до нашого шаблону і вивести QuerySet! -Якщо бажаєте дізнатись трохи більше про QuerySets в Django, зазирніть сюди: https://docs.djangoproject.com/en/1.10/ref/models/querysets/ +Якщо бажаєте дізнатись трохи більше про QuerySets в Django, зазирніть сюди: https://docs.djangoproject.com/en/1.11/ref/models/querysets/ diff --git a/uk/extend_your_application/README.md b/uk/extend_your_application/README.md index a052ace1398..189c257df11 100755 --- a/uk/extend_your_application/README.md +++ b/uk/extend_your_application/README.md @@ -24,7 +24,7 @@

{{ post.text|linebreaksbr }}

{% endfor %} -{% endblock content %} +{% endblock %} ``` diff --git a/uk/extend_your_application/images/404_2.png b/uk/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/uk/extend_your_application/images/404_2.png and b/uk/extend_your_application/images/404_2.png differ diff --git a/uk/extend_your_application/images/attribute_error2.png b/uk/extend_your_application/images/attribute_error2.png index 6edcd9933c3..33a3b36b1d3 100644 Binary files a/uk/extend_your_application/images/attribute_error2.png and b/uk/extend_your_application/images/attribute_error2.png differ diff --git a/uk/extend_your_application/images/does_not_exist2.png b/uk/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/uk/extend_your_application/images/does_not_exist2.png and b/uk/extend_your_application/images/does_not_exist2.png differ diff --git a/uk/extend_your_application/images/no_reverse_match2.png b/uk/extend_your_application/images/no_reverse_match2.png index 306926206f8..aba1c9c8980 100644 Binary files a/uk/extend_your_application/images/no_reverse_match2.png and b/uk/extend_your_application/images/no_reverse_match2.png differ diff --git a/uk/extend_your_application/images/post_detail2.png b/uk/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/uk/extend_your_application/images/post_detail2.png and b/uk/extend_your_application/images/post_detail2.png differ diff --git a/uk/extend_your_application/images/post_list2.png b/uk/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/uk/extend_your_application/images/post_list2.png and b/uk/extend_your_application/images/post_list2.png differ diff --git a/uk/extend_your_application/images/template_does_not_exist2.png b/uk/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/uk/extend_your_application/images/template_does_not_exist2.png and b/uk/extend_your_application/images/template_does_not_exist2.png differ diff --git a/uk/how_the_internet_works/images/internet_1.png b/uk/how_the_internet_works/images/internet_1.png index 9c5bcf0b003..e289eac2b23 100644 Binary files a/uk/how_the_internet_works/images/internet_1.png and b/uk/how_the_internet_works/images/internet_1.png differ diff --git a/uk/how_the_internet_works/images/internet_2.png b/uk/how_the_internet_works/images/internet_2.png index dd5861f376f..e8cf8b77999 100644 Binary files a/uk/how_the_internet_works/images/internet_2.png and b/uk/how_the_internet_works/images/internet_2.png differ diff --git a/uk/how_the_internet_works/images/internet_3.png b/uk/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/uk/how_the_internet_works/images/internet_3.png and b/uk/how_the_internet_works/images/internet_3.png differ diff --git a/uk/how_the_internet_works/images/internet_4.png b/uk/how_the_internet_works/images/internet_4.png index 2661cec1b61..d4748ac48ef 100644 Binary files a/uk/how_the_internet_works/images/internet_4.png and b/uk/how_the_internet_works/images/internet_4.png differ diff --git a/uk/html/images/step1.png b/uk/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/uk/html/images/step1.png and b/uk/html/images/step1.png differ diff --git a/uk/html/images/step3.png b/uk/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/uk/html/images/step3.png and b/uk/html/images/step3.png differ diff --git a/uk/html/images/step4.png b/uk/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/uk/html/images/step4.png and b/uk/html/images/step4.png differ diff --git a/uk/html/images/step6.png b/uk/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/uk/html/images/step6.png and b/uk/html/images/step6.png differ diff --git a/uk/images/application.png b/uk/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/uk/images/application.png and b/uk/images/application.png differ diff --git a/uk/installation/README.md b/uk/installation/README.md index ae2cd0a743a..bff76bf0fef 100644 --- a/uk/installation/README.md +++ b/uk/installation/README.md @@ -1,6 +1,6 @@ # Якщо ви проходите цей підручник вдома -Якщо ви проходите цей посібник вдома, а не на одному з [майстер-класів 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 включає в себе "Вечір налаштувань", коли ми встановлюємо все потрібне, щоб не витрачати на це час під час воркшопу, це дуже зручно для нас. diff --git a/uk/intro_to_command_line/README.md b/uk/intro_to_command_line/README.md index 01859a6c4e5..70e30017ef8 100644 --- a/uk/intro_to_command_line/README.md +++ b/uk/intro_to_command_line/README.md @@ -20,7 +20,7 @@ __Дозвольте нам представити вас вашому ново Перейдіть до меню Пуск → Усі програми → Стандартні → Командний рядок. -### Mac OS X +### macOS Додатки → Утиліти → Термінал. diff --git a/uk/python_installation/images/add_python_to_windows_path.png b/uk/python_installation/images/add_python_to_windows_path.png index 9510d6f2176..3266efb6177 100644 Binary files a/uk/python_installation/images/add_python_to_windows_path.png and b/uk/python_installation/images/add_python_to_windows_path.png differ diff --git a/uk/python_installation/instructions.md b/uk/python_installation/instructions.md index 861c3e7d614..13e70bf9d7f 100644 --- a/uk/python_installation/instructions.md +++ b/uk/python_installation/instructions.md @@ -26,17 +26,10 @@ Python для Windows можна завантажити з сайту https://ww Наберіть наступну команду в консолі: - $ sudo apt-get install python3.4 + $ sudo apt install python3.4 -#### Fedora (до версії 21) - -Скористайтеся наступною командою в консолі: - - $ sudo yum install python3.4 - - -#### Fedora (22+) +#### Fedora Скористайтеся наступною командою в консолі: @@ -50,11 +43,11 @@ Python для Windows можна завантажити з сайту https://ww $ sudo zypper install python3 -### OS X +### macOS Вам необхідно перейти на веб сайт https://www.python.org/downloads/release/python-343/ і завантажити Python інсталятор: -* завантажте файл *Mac OS X 64-bit/32-bit installer*, +* завантажте файл *macOS 64-bit/32-bit installer*, * Двічі клацніть на *python 3.4.3 macosx10.6.pkg*, щоб запустити інсталятор. Підтвердіть, що інсталяція пройшла успішно відкривши програму *Terminal* і запустивши команду `python3`: diff --git a/uk/python_introduction/README.md b/uk/python_introduction/README.md index c9c23457c1a..a1609ae2b95 100644 --- a/uk/python_introduction/README.md +++ b/uk/python_introduction/README.md @@ -373,7 +373,7 @@ >>> 1 > 'django' Traceback (most recent call last): File "", line 1, in - TypeError: unorderable types: int() > str() + TypeError: '>' not supported between instances of 'int' and 'str' Бачимо тут, що як і у виразі, Python не в змозі порівняти число (`int`) та рядок (`str`). Натомість, виводиться **TypeError** і повідомляє нас про те, що ці два типи не можна порівнювати між собою. diff --git a/uk/python_introduction/images/cupcake.png b/uk/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/uk/python_introduction/images/cupcake.png and b/uk/python_introduction/images/cupcake.png differ diff --git a/uk/template_extending/README.md b/uk/template_extending/README.md index 81769f1efd0..8d35894913f 100755 --- a/uk/template_extending/README.md +++ b/uk/template_extending/README.md @@ -19,7 +19,7 @@ Відкрийте його і скопіюйте усе з `post_list.html` до файлу `base.html`, як тут: ```html -{% load staticfiles %} +{% load static %} Django Girls blog @@ -96,7 +96,7 @@ Ми хочемо використати це як частина нашого шаблону для всіх блоків контенту. Час додати теги блоків до цього файлу! -{% raw %}Ви хочете, щоб ваший тег блоку підходив до тегу у файлі `base.html`. Ви такоже хочете, щоб він включав в себе весь код, що належить вашим блокам з контентом. Щоб зробити це, розмістіть все між `{% block content %}` і `{% endblock content %}`. Як тут: {% endraw %} +{% raw %}Ви хочете, щоб ваший тег блоку підходив до тегу у файлі `base.html`. Ви такоже хочете, щоб він включав в себе весь код, що належить вашим блокам з контентом. Щоб зробити це, розмістіть все між `{% block content %}` і `{% endblock %}`. Як тут: {% endraw %} ```html diff --git a/uk/whats_next/README.md b/uk/whats_next/README.md index cc03b625155..349f6dc0008 100755 --- a/uk/whats_next/README.md +++ b/uk/whats_next/README.md @@ -12,7 +12,7 @@ ### Чи можете ви порекомендувати інші джерела? -Так! Спершу, спробуйте нашу іншу книгу [Django Girls Tutorial: Extensions](http://djangogirls.gitbooks.io/django-girls-tutorial-extensions/). +Так! Спершу, спробуйте нашу іншу книгу [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org). Пізніше, ви можете спробувати джерела, перелічені нижче. Дуже рекомендуємо! - [Django's official tutorial](https://docs.djangoproject.com/en/1.8/intro/tutorial01/) @@ -21,6 +21,6 @@ - [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://gettingstartedwithdjango.com/) +- [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/) diff --git a/zh/code_editor/instructions.md b/zh/code_editor/instructions.md index 25efbabebf6..da424920c91 100755 --- a/zh/code_editor/instructions.md +++ b/zh/code_editor/instructions.md @@ -8,11 +8,11 @@ Gedit 是开源、免费的编辑器,支持所有操作系统。 [在这里下载](https://wiki.gnome.org/Apps/Gedit#Download) -## Sublime Text 3编辑器 +## Sublime Text编辑器 Sublime Text 是一个很受欢迎的、免费试用的编辑器。它很容易安装和使用,并且支持所有操作系统。 -[在这里下载](https://www.sublimetext.com/3) +[在这里下载](https://www.sublimetext.com/) ## Atom编辑器 @@ -28,4 +28,4 @@ Atom 是 [GitHub](https://github.com/) 最新发布的代码编辑器。它开 第二个原因是代码编辑器专长于编辑代码,因此它们可以提供一些有用的功能,比如代码高亮,比如自动闭合引用号。 -以上这些我们将在实践中具体体会。很快你将会觉得,似乎过时的老文本编辑器正是最得心应手的工具!:) \ No newline at end of file +以上这些我们将在实践中具体体会。很快你将会觉得,似乎过时的老文本编辑器正是最得心应手的工具!:) diff --git a/zh/css/README.md b/zh/css/README.md index 24f4b2e9e73..9012f5ea7b6 100644 --- a/zh/css/README.md +++ b/zh/css/README.md @@ -6,7 +6,7 @@ 层叠样式表(Cascading Style Sheets)是一种语言,用来描述使用标记语言(如HTML)写成的网站的外观和格式。把它当做我们网站的化妆 ;)。 -但我们不想总是从零开始,对吧? 我们将会再一次采用程序们编写并发布到互联网上的免费玩意。 重新发明轮子十分无趣,你懂的。 +但我们不想总是从零开始,对吧? 我们将会再一次采用程序员们编写并发布到互联网上的免费玩意。 重新发明轮子十分无趣,你懂的。 ## 让我们用 Bootstrap 吧! @@ -47,7 +47,8 @@ Django已经知道到何处找到内建“admin”应用的静态文件。现在 djangogirls ├── blog │ ├── migrations - │ └── static + │ ├── static + │   └── templates └── mysite ``` @@ -169,7 +170,7 @@ Django会自动找到你应用文件夹目录下所有名字叫“static”的 ``` -这行将从谷歌的字体 (https://www.google.com/fonts) 中导入称为 *龙虾*的字体 。 +这行将从谷歌的字体 ( https://www.google.com/fonts ) 中导入称为 *龙虾*的字体 。 现在添加一行 `font-family: 'Lobster';` 到CSS文件 `blog/static/css/blog.css` 的 `h1 a` 声明块中(花括弧 `{` 与 `}` 之间的代码),然后刷新页面: diff --git a/zh/css/images/bootstrap1.png b/zh/css/images/bootstrap1.png index f7e1f57536c..bd81cd14373 100644 Binary files a/zh/css/images/bootstrap1.png and b/zh/css/images/bootstrap1.png differ diff --git a/zh/css/images/color2.png b/zh/css/images/color2.png index c191d399356..3f82e7d3922 100644 Binary files a/zh/css/images/color2.png and b/zh/css/images/color2.png differ diff --git a/zh/css/images/final.png b/zh/css/images/final.png index f90070b1aa5..067c83d36cc 100644 Binary files a/zh/css/images/final.png and b/zh/css/images/final.png differ diff --git a/zh/css/images/font.png b/zh/css/images/font.png index 8561bb1cb03..310f9e85f18 100644 Binary files a/zh/css/images/font.png and b/zh/css/images/font.png differ diff --git a/zh/css/images/margin2.png b/zh/css/images/margin2.png index 5ecba91ae54..895828b688d 100644 Binary files a/zh/css/images/margin2.png and b/zh/css/images/margin2.png differ diff --git a/zh/deploy/README.md b/zh/deploy/README.md index d20d8e4e930..0aa570e2fdd 100755 --- a/zh/deploy/README.md +++ b/zh/deploy/README.md @@ -6,7 +6,7 @@ 正如你所学习的,一个网站必须要放到一个服务器上。 在互联网上你可以找到很多的服务器供应商。 我们将使用一个相对简单的部署过程: [PythonAnywhere][1]。 PythonAnywhere 对于一些没有太多访问者的小应用是免费的,所以它对你来说绝对是足够使用的。 - [1]: https://pythonanywhere.com/ + [1]: https://www.pythonanywhere.com/ 其它我们将使用到的外部服务是[GitHub][2],它是一个代码托管服务。 还有其它的一些服务,但当今几乎所有的程序员都有 GitHub 帐户,并且现在你也会有的! @@ -56,7 +56,7 @@ Git会追踪这个目录下所有文件和文件夹的更改,但是有一些 $ git status On branch master - Initial commit + No commits yet Untracked files: (use "git add ..." to include in what will be committed) @@ -80,7 +80,7 @@ Git会追踪这个目录下所有文件和文件夹的更改,但是有一些 create mode 100644 mysite/wsgi.py -## 推送我们的代码到Github上 +## 推送我们的代码到 GitHub 上 跳转到[GitHub.com][2]网站,注册一个新的免费账号。(如果你在看线下活动之前就已经有账号的话,那就太好了!) @@ -98,7 +98,7 @@ Git会追踪这个目录下所有文件和文件夹的更改,但是有一些 [4]: images/github_get_repo_url_screenshot.png -现在我们需要把你电脑上的Git仓库和Github上的挂接。 +现在我们需要把你电脑上的Git仓库和GitHub上的挂接。 在控制台输入以下内容(替换 `` 为你的 github 用户名 ,不包含尖括号): @@ -106,7 +106,7 @@ Git会追踪这个目录下所有文件和文件夹的更改,但是有一些 $ git push -u origin master -输入你的Github账号名和密码,然后你会看到这样: +输入你的GitHub账号名和密码,然后你会看到这样: Username for 'https://github.com': hjwp Password for 'https://hjwp@github.com': @@ -120,7 +120,7 @@ Git会追踪这个目录下所有文件和文件夹的更改,但是有一些 -你的代码已经在Github上了。 快去确认一下吧! 你会发现这些好家伙们 — [Django][5], [Django Girls Tutorial][6],还有很多其它优秀的开放源代码软件项目同样也在Github上 :) +你的代码已经在GitHub上了。 快去确认一下吧! 你会发现这些好家伙们 — [Django][5], [Django Girls Tutorial][6],还有很多其它优秀的开放源代码软件项目同样也在GitHub上 :) [5]: https://github.com/django/django [6]: https://github.com/DjangoGirls/tutorial @@ -137,7 +137,7 @@ Git会追踪这个目录下所有文件和文件夹的更改,但是有一些 > **注意** PythonAnywhere 基于 Linux,因此如果你使用 Windows,控制台将会和你本地电脑上的略有不同。 -让我们通过创建一个我们仓库的 “Clone” 以便从 Github 拉取代码到 PythonAnywhere。 在 PythonAnywhere 控制台输入以下 (不要忘记使用 Github 用户名替换 ``): +让我们通过创建一个我们仓库的 “Clone” 以便从 GitHub 拉取代码到 PythonAnywhere。 在 PythonAnywhere 控制台输入以下 (不要忘记使用 GitHub 用户名替换 ``): $ git clone https://github.com//my-first-blog.git diff --git a/zh/deploy/images/github_get_repo_url_screenshot.png b/zh/deploy/images/github_get_repo_url_screenshot.png index 62a29f5f8d7..ee1560b1e85 100644 Binary files a/zh/deploy/images/github_get_repo_url_screenshot.png and b/zh/deploy/images/github_get_repo_url_screenshot.png differ diff --git a/zh/deploy/images/new_github_repo.png b/zh/deploy/images/new_github_repo.png index 64011e59a52..d1f82e5d863 100644 Binary files a/zh/deploy/images/new_github_repo.png and b/zh/deploy/images/new_github_repo.png differ diff --git a/zh/deploy/images/pythonanywhere_web_tab_virtualenv.png b/zh/deploy/images/pythonanywhere_web_tab_virtualenv.png index 97e87e7b07b..6069f6da831 100644 Binary files a/zh/deploy/images/pythonanywhere_web_tab_virtualenv.png and b/zh/deploy/images/pythonanywhere_web_tab_virtualenv.png differ diff --git a/zh/deploy/install_git.md b/zh/deploy/install_git.md index 5751a997d5f..4b0841daa08 100755 --- a/zh/deploy/install_git.md +++ b/zh/deploy/install_git.md @@ -10,7 +10,7 @@ 如果git还没有被安装的话,你可以从你的软件包管理器中下载git, 请试试下面命令: - sudo apt-get install git + sudo apt install git # or sudo yum install git # or diff --git a/zh/django_admin/README.md b/zh/django_admin/README.md index ed5e27ba0f9..88a5cd8ed52 100755 --- a/zh/django_admin/README.md +++ b/zh/django_admin/README.md @@ -13,13 +13,13 @@ admin.site.register(Post) 如你所见,我们导入(包括)了前一章定义的Post模型。 为了让我们的模型在admin页面上可见,我们需要使用`admin.site.register(Post)`来注册模型. -OK, 现在来看看我们的 Post 模型。 记得先在控制台输入`python manage.py runserver`启动服务器。 然后打开浏览器,输入地址http://127.0.0.1:8000/admin/你会看到登录界面像这样: +OK, 现在来看看我们的 Post 模型。 记得先在控制台输入`python manage.py runserver`启动服务器。 然后打开浏览器,输入地址 http://127.0.0.1:8000/admin/ 你会看到登录界面像这样: ![登录页面][1] [1]: images/login_page2.png -为了登录, 你需要创建一个掌控整个网站所有东西的*超级用户*。 回到刚才的命令行,输入`python manage.py createsuperuser`,按下Enter。 然后输入你的用户名(英文小写,不保护空格), 邮箱和密码。 你输密码的时候看不见输入?别担心,它就是这样的。 你就输入要输得到然后按`Enter`继续就好了。 输出应该长得像这样(用户名和邮箱应该是你自己的): +为了登录, 你需要创建一个掌控整个网站所有东西的*超级用户*。 回到刚才的命令行,输入`python manage.py createsuperuser`,按下Enter。 然后输入你的用户名(英文小写,不包括空格), 邮箱和密码。 你输密码的时候看不见输入?别担心,它就是这样的。 你就输入要输得到然后按`Enter`继续就好了。 输出应该长得像这样(用户名和邮箱应该是你自己的): (myvenv) ~/djangogirls$ python manage.py createsuperuser Username: admin diff --git a/zh/django_admin/images/django_admin3.png b/zh/django_admin/images/django_admin3.png index a450b4f9630..ea01ab951bf 100644 Binary files a/zh/django_admin/images/django_admin3.png and b/zh/django_admin/images/django_admin3.png differ diff --git a/zh/django_admin/images/edit_post3.png b/zh/django_admin/images/edit_post3.png index c8572a73e7d..d577b111424 100644 Binary files a/zh/django_admin/images/edit_post3.png and b/zh/django_admin/images/edit_post3.png differ diff --git a/zh/django_admin/images/login_page2.png b/zh/django_admin/images/login_page2.png index 47153ef6960..6ae26e9959a 100644 Binary files a/zh/django_admin/images/login_page2.png and b/zh/django_admin/images/login_page2.png differ diff --git a/zh/django_forms/README.md b/zh/django_forms/README.md index 36bf57356ae..7af33e31d12 100755 --- a/zh/django_forms/README.md +++ b/zh/django_forms/README.md @@ -84,7 +84,7 @@ class PostForm(forms.ModelForm): ``` -然后保存,刷新http://127.0.0.1:8000页面,你可以明显地看到一个熟悉的`NoReverseMatch`错误信息,是吧? +然后保存,刷新 http://127.0.0.1:8000 页面,你可以明显地看到一个熟悉的`NoReverseMatch`错误信息,是吧? ## URL @@ -226,11 +226,11 @@ def post_new(request): 把它添加到你文件的最开始处。现在我们可以说:创建完新帖子我们就转去`post_detail`页面。 ```python - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) ``` -`blog.views.post_detail` 是我们想去的视图的名字。 还记得这个*视图* 需得具有一个 `pk` 变量吗? 为了把它传递给视图我们使用`pk=post.pk`, 其中 `post` 就是我们刚刚创立的博客帖子! +`post_detail` 是我们想去的视图的名字。 还记得这个*视图* 需得具有一个 `pk` 变量吗? 为了把它传递给视图我们使用`pk=post.pk`, 其中 `post` 就是我们刚刚创立的博客帖子! 好吧,我们已经说了很多了,但可能我们想看到整个*视图*现在看起来什么样,对吗? @@ -243,14 +243,14 @@ def post_new(request): post.author = request.user post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm() 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 教程:扩展**中介绍 *publish button* 。. @@ -268,7 +268,7 @@ def post_new(request): Django会处理验证我们表单里的所有字段都是正确的。这不是很棒? -> 因为我们最近使用过Django管理界面,系统目前认为我们已经登录了。 有几种情况可能导致我们被登出(关闭浏览器,重新启动数据库等等)。 如果你发现当你创建一个文章时得到了一个指向未登录用户错误的时候,前往管理页面`http://127.0.0.1:8000/admin`,再登录。 这会暂时解决问题。 有一个一劳永逸的方法在等着你,可以看看只要教程后的**Homework: add security to your website!** 章节。 +> 因为我们最近使用过Django管理界面,系统目前认为我们已经登录了。 有几种情况可能导致我们被登出(关闭浏览器,重新启动数据库等等)。 如果你发现当你创建一个文章时得到了一个指向未登录用户错误的时候,前往管理页面 `http://127.0.0.1:8000/admin` ,再登录。 这会暂时解决问题。 有一个一劳永逸的方法在等着你,可以看看只要教程后的**Homework: add security to your website!** 章节。 ![记录错误][4] @@ -326,7 +326,7 @@ def post_edit(request, pk): post.author = request.user post.published_date = timezone.now() post.save() - return redirect('blog.views.post_detail', pk=post.pk) + return redirect('post_detail', pk=post.pk) else: form = PostForm(instance=post) return render(request, 'blog/post_edit.html', {'form': form}) @@ -393,7 +393,7 @@ def post_edit(request, pk): 我们来看看这一切能否运行在 PythonAnywhere 上。另一次部署的时间到了! -* 首先,提交你的新代码,然后将它推送到 Github 上 +* 首先,提交你的新代码,然后将它推送到 GitHub 上 ``` diff --git a/zh/django_forms/images/csrf2.png b/zh/django_forms/images/csrf2.png index 9dd1a9a4baa..ee946324f92 100644 Binary files a/zh/django_forms/images/csrf2.png and b/zh/django_forms/images/csrf2.png differ diff --git a/zh/django_forms/images/drafts.png b/zh/django_forms/images/drafts.png index f984ec2a4ae..1d62f8866f4 100644 Binary files a/zh/django_forms/images/drafts.png and b/zh/django_forms/images/drafts.png differ diff --git a/zh/django_forms/images/edit_button2.png b/zh/django_forms/images/edit_button2.png index f402eadd00b..804674f0965 100644 Binary files a/zh/django_forms/images/edit_button2.png and b/zh/django_forms/images/edit_button2.png differ diff --git a/zh/django_forms/images/edit_form2.png b/zh/django_forms/images/edit_form2.png index 329674ee5ad..3d4e525d5d0 100644 Binary files a/zh/django_forms/images/edit_form2.png and b/zh/django_forms/images/edit_form2.png differ diff --git a/zh/django_forms/images/form_validation2.png b/zh/django_forms/images/form_validation2.png index 0e81288c33e..6e333af3077 100644 Binary files a/zh/django_forms/images/form_validation2.png and b/zh/django_forms/images/form_validation2.png differ diff --git a/zh/django_forms/images/new_form2.png b/zh/django_forms/images/new_form2.png index 8180ce66a06..8f2a1088070 100644 Binary files a/zh/django_forms/images/new_form2.png and b/zh/django_forms/images/new_form2.png differ diff --git a/zh/django_forms/images/post_create_error.png b/zh/django_forms/images/post_create_error.png index ae4650a575a..d140e8e2419 100644 Binary files a/zh/django_forms/images/post_create_error.png and b/zh/django_forms/images/post_create_error.png differ diff --git a/zh/django_installation/instructions.md b/zh/django_installation/instructions.md index 611e7a79b88..c62dd5047f9 100755 --- a/zh/django_installation/instructions.md +++ b/zh/django_installation/instructions.md @@ -28,11 +28,11 @@ C:\Users\Name\djangogirls> C:\Python34\python -m venv myvenv -`C:\Python34\python` 是您之前安装Python的目录, `myvenv` 是您`虚拟环境` 的名字。 你可以使用其他任何名字,但请坚持使用小写,并不要使用空格、重音符号或特殊字符。 始终保持名称短小是个好主意 — — 你会大量引用它 ! +`C:\Python34` 是您之前安装Python的目录, `myvenv` 是您`虚拟环境` 的名字。 你可以使用其他任何名字,但请坚持使用小写,并不要使用空格、重音符号或特殊字符。 始终保持名称短小是个好主意 — — 你会大量引用它 ! -### Linux 和 OS X +### Linux 和 macOS -在 Linux 和 OS X 上创建的 `虚拟环境` 就和运行 `python3 -m venv myvenv` 一样简单。看起来像这样: +在 Linux 和 macOS 上创建的 `虚拟环境` 就和运行 `python3 -m venv myvenv` 一样简单。看起来像这样: ~/djangogirls$ python3 -m venv myvenv @@ -46,7 +46,7 @@ > > 为了解决这个问题,请使用 `virtualenv` 命令。 > -> ~/djangogirls$ sudo apt-get install python-virtualenv +> ~/djangogirls$ sudo apt install python-virtualenv > ~/djangogirls$ virtualenv --python=python3.4 myvenv > @@ -61,7 +61,7 @@ C:\Users\Name\djangogirls> myvenv\Scripts\activate -#### Linux 和 OS X +#### Linux 和 macOS 运行如下命令进入你的虚拟环境: @@ -102,7 +102,7 @@ Cleaning up... -在 Windows上 +在 Windows 上 > 如果你在 Windows 平台上调用 pip 时得到一个错误,请检查是否您项目的路径名是否包含空格、 重音符号或特殊字符 (如:`C:\Users\User Name\djangogirls`)。 若的确如此,请尝试移动它到另外一个没有空格、重音符号或特殊字符的目录,(例如:`C:\djangogirls`)。 在移动之后,请重试上面的命令。 diff --git a/zh/django_models/README.md b/zh/django_models/README.md index fcbd9a95bea..690d74c283f 100755 --- a/zh/django_models/README.md +++ b/zh/django_models/README.md @@ -104,12 +104,13 @@ Django 里的模型是一种特殊的对象 — — 它保存在 `数据库` 中 让我们打开 `blog/models.py`,从中删除一切并编写这样的代码: + from django.conf import settings from django.db import models from django.utils import timezone class Post(models.Model): - author = models.ForeignKey('auth.User') + author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) title = models.CharField(max_length=200) text = models.TextField() created_date = models.DateTimeField( @@ -134,7 +135,7 @@ Django 里的模型是一种特殊的对象 — — 它保存在 `数据库` 中 `class Post(models.Model):` - 这行是用来定义我们的模型 (这是一个 `对象`). * `class` 是一个特殊的关键字,表明我们在定义一个对象。 -* `Post`是我们模型的一个名字。我们可以给它取另外一个不同的名字(但是我们必须避免使用特殊字符或者空格符)。总是以首字面大写来作为类名。 +*   `Post`是我们模型的一个名字。我们可以给它取另外一个不同的名字(但是我们必须避免使用特殊字符或者空格符)。总是以首字母大写来作为类名。 * `models.Model` 表明Post是一个Django模型,所以Django知道它应该被保存在数据库中。 现在我们定义了我们曾经提及到的那些属性:`title`, `text`, `created_date`, `published_date`和`author`。 为了做到那样我们需要为我们每个字段定义一个类型(它是文本吗? 是数字? 是日期? 到另一个对象的关联,比如用户吗?)。 diff --git a/zh/django_orm/README.md b/zh/django_orm/README.md index 72376c3aba1..4a14a32ca53 100755 --- a/zh/django_orm/README.md +++ b/zh/django_orm/README.md @@ -41,7 +41,7 @@ 这很简单: 我们从 `blog.models` 导入 `Post` 的模型。让我们试着再一次显示所有的帖子: >>> Post.objects.all() - [, ] + , ]> 这是我们之前创建的文章的 list 列表!我们通过使用Django admin界面创建了这些文章。但是我们现在想通过Python来创建新的文章,那么我们应该如何做呢? @@ -63,7 +63,7 @@ 我们在数据库中有哪些用户?试试这个: >>> User.objects.all() - [] + ]> 这是一个我们之前创建的超级用户!让我们现在获取一个用户实例: @@ -81,7 +81,7 @@ 哈哈!要检查是否有效吗? >>> Post.objects.all() - [, , ] + , , ]> 就是这样,又一个文章在列表里面! @@ -95,13 +95,13 @@ QuerySets的很大一部分功能是对它们进行筛选。 譬如,我们想要发现所有都由用户ola编写的文章。 我们将使用 `filter`,而不是 `all` 在 `Post.objects.all()`。 我们需要在括号中申明哪些条件,以在我们的 queryset 结果集中包含一篇博客文章。 在我们的情况是 `author`,它等于 `me`。 把它写在 Django 的方式是: `author = me`。 现在我们的代码段如下所示: >>> Post.objects.filter(author=me) - [, , , ] + , , , ]> 或者,也许我们想看到包含在 `title` 字段标题的所有帖子吗? >>> Post.objects.filter(title__contains='title') - [, ] + , ]> > **注**在`title` 与 `contains` 之间有两个下划线字符 (`_`)。 Django 的 ORM 使用此语法来分隔字段名称 ("title") 和操作或筛选器 ("contains")。 如果您只使用一个下划线,您将收到类似"FieldError: 无法解析关键字 title_contains"的错误。 @@ -123,7 +123,7 @@ QuerySets的很大一部分功能是对它们进行筛选。 譬如,我们想 现在再一次尝试获取已发布的文章(按向上箭头按钮三次,然后按回车): >>> Post.objects.filter(published_date__lte=timezone.now()) - [] + ]> ### 对象排序 @@ -131,13 +131,13 @@ QuerySets的很大一部分功能是对它们进行筛选。 譬如,我们想 Queryset 还允许您排序结果集对象的列表。让我们试着让它们按 `created_date` 字段排序: >>> Post.objects.order_by('created_date') - [, , , ] + , , , ]> 我们也可以在开头添加 `-` 来反向排序: >>> Post.objects.order_by('-created_date') - [, , , ] + , , , ]> ### 链式 QuerySets @@ -152,4 +152,4 @@ Queryset 还允许您排序结果集对象的列表。让我们试着让它们 酷 !现在,你准备下一个部分 !若要关闭shell程序,请键入这: >>> exit() - $ \ No newline at end of file + $ diff --git a/zh/django_start_project/README.md b/zh/django_start_project/README.md index a9bb208565d..3f6e74177ee 100755 --- a/zh/django_start_project/README.md +++ b/zh/django_start_project/README.md @@ -66,7 +66,7 @@ TIME_ZONE = 'Europe/Berlin' 我们还需要添加 (我们会找出在教程后面所提到的静态文件和 CSS文件) 静态文件的路径。 我们下拉到文件的*最底部*, 就是在`STATIC_URL` 条目的下面。添加新的一行内容为 `STATIC_ROOT`: STATIC_URL = '/static/' - STATIC_ROOT = os.path.join(BASE_DIR, 'static') + STATIC_ROOT = BASE_DIR / 'static' ## 设置数据库 @@ -78,7 +78,7 @@ TIME_ZONE = 'Europe/Berlin' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'NAME': BASE_DIR / 'db.sqlite3', } } diff --git a/zh/django_start_project/images/it_worked2.png b/zh/django_start_project/images/it_worked2.png index 4412ecfc49e..4efa554e567 100644 Binary files a/zh/django_start_project/images/it_worked2.png and b/zh/django_start_project/images/it_worked2.png differ diff --git a/zh/django_templates/README.md b/zh/django_templates/README.md index 6d291d9b891..3a4af4cccf5 100755 --- a/zh/django_templates/README.md +++ b/zh/django_templates/README.md @@ -4,7 +4,7 @@ ## 什么是模板标签呢? -正如你在前面章节中所了解的那样, 我们并不能将python代码嵌入到HTML中。 因为浏览器不能识别python代码, 它只能解析HTML。 我们知道,HTML是静态页面,而python则显得更加动态。 +正如你在前面章节中所了解的那样, 我们并不能将 Python 代码嵌入到HTML中。 因为浏览器不能识别 Python 代码, 它只能解析HTML。 我们知道,HTML是静态页面,而 Python 则显得更加动态。 **Django模板标签**允许我们将Python之类的内容翻译成HTML,所以你可以更快更简单的建立动态网站。哈哈! @@ -28,7 +28,7 @@ 如你所见,我们得到如下: ``` - [, ] + , ]> ``` @@ -76,7 +76,7 @@ 如果我们将我们的网站放在互联网上运行,那将是一件很不错的事情,难道不是吗? 让我们试着再次部署到 PythonAnywhere。简单部署步骤如下... ... -* 首先,我们将我们的代码放到Github +* 首先,我们将我们的代码放到GitHub ``` $ git status diff --git a/zh/django_templates/images/donut.png b/zh/django_templates/images/donut.png index 64d38b4e889..f31cebdc8a3 100644 Binary files a/zh/django_templates/images/donut.png and b/zh/django_templates/images/donut.png differ diff --git a/zh/django_templates/images/step1.png b/zh/django_templates/images/step1.png index 113e145c943..cbf6420360a 100644 Binary files a/zh/django_templates/images/step1.png and b/zh/django_templates/images/step1.png differ diff --git a/zh/django_templates/images/step2.png b/zh/django_templates/images/step2.png index 464a7645731..fd6269c837c 100644 Binary files a/zh/django_templates/images/step2.png and b/zh/django_templates/images/step2.png differ diff --git a/zh/django_templates/images/step3.png b/zh/django_templates/images/step3.png index b56b64f142e..b471fdd4d7b 100644 Binary files a/zh/django_templates/images/step3.png and b/zh/django_templates/images/step3.png differ diff --git a/zh/django_urls/images/error1.png b/zh/django_urls/images/error1.png index cc17593d19d..250028e996b 100644 Binary files a/zh/django_urls/images/error1.png and b/zh/django_urls/images/error1.png differ diff --git a/zh/django_urls/images/url.png b/zh/django_urls/images/url.png index 6cd1bd96291..b59f9dce992 100644 Binary files a/zh/django_urls/images/url.png and b/zh/django_urls/images/url.png differ diff --git a/zh/django_views/README.md b/zh/django_views/README.md index 53b1cfd7b62..4b09e115d95 100755 --- a/zh/django_views/README.md +++ b/zh/django_views/README.md @@ -1,8 +1,8 @@ # Django视图 - 是时候去创建! -是是候去解决我们在上一章所制造的Bug了:) +是时候去解决我们在上一章所制造的Bug了:) -*view*是存放应用逻辑的地方。 它将从你之前创建的 `模型`中获取数据,并将它传递给 `模板`。 我们将在下一章创建 tempalte 模板。 视图就是Python方法,只不过比我们在**Python简介**章节中所做的事情稍复杂。 +*view*是存放应用逻辑的地方。 它将从你之前创建的 `模型`中获取数据,并将它传递给 `模板`。 我们将在下一章创建 template 模板。 视图就是Python方法,只不过比我们在**Python简介**章节中所做的事情稍复杂。 视图都被置放在`views.py`文件中。我们将加入我们自己的*views*到`blog/views.py`文件。 diff --git a/zh/django_views/images/error.png b/zh/django_views/images/error.png index 391c9e61e16..1530c879cb5 100644 Binary files a/zh/django_views/images/error.png and b/zh/django_views/images/error.png differ diff --git a/zh/extend_your_application/README.md b/zh/extend_your_application/README.md index 23d4675e148..d8269d1b166 100755 --- a/zh/extend_your_application/README.md +++ b/zh/extend_your_application/README.md @@ -25,7 +25,7 @@

{{ post.text|linebreaksbr }}

{% endfor %} - {% endblock content %} + {% endblock %} ``` diff --git a/zh/extend_your_application/images/404_2.png b/zh/extend_your_application/images/404_2.png index a8cb53172af..0a6fdf3234e 100644 Binary files a/zh/extend_your_application/images/404_2.png and b/zh/extend_your_application/images/404_2.png differ diff --git a/zh/extend_your_application/images/attribute_error2.png b/zh/extend_your_application/images/attribute_error2.png index 6edcd9933c3..33a3b36b1d3 100644 Binary files a/zh/extend_your_application/images/attribute_error2.png and b/zh/extend_your_application/images/attribute_error2.png differ diff --git a/zh/extend_your_application/images/does_not_exist2.png b/zh/extend_your_application/images/does_not_exist2.png index 023d8720081..e7015f2c80d 100644 Binary files a/zh/extend_your_application/images/does_not_exist2.png and b/zh/extend_your_application/images/does_not_exist2.png differ diff --git a/zh/extend_your_application/images/no_reverse_match2.png b/zh/extend_your_application/images/no_reverse_match2.png index 306926206f8..aba1c9c8980 100644 Binary files a/zh/extend_your_application/images/no_reverse_match2.png and b/zh/extend_your_application/images/no_reverse_match2.png differ diff --git a/zh/extend_your_application/images/post_detail2.png b/zh/extend_your_application/images/post_detail2.png index 240dc447b51..b40c92efb8c 100644 Binary files a/zh/extend_your_application/images/post_detail2.png and b/zh/extend_your_application/images/post_detail2.png differ diff --git a/zh/extend_your_application/images/post_list2.png b/zh/extend_your_application/images/post_list2.png index 8ae30c71311..dd0a0d67a6f 100644 Binary files a/zh/extend_your_application/images/post_list2.png and b/zh/extend_your_application/images/post_list2.png differ diff --git a/zh/extend_your_application/images/template_does_not_exist2.png b/zh/extend_your_application/images/template_does_not_exist2.png index 335ce2569ef..c856abeda31 100644 Binary files a/zh/extend_your_application/images/template_does_not_exist2.png and b/zh/extend_your_application/images/template_does_not_exist2.png differ diff --git a/zh/how_the_internet_works/README.md b/zh/how_the_internet_works/README.md index e8d4be41600..42d475b7c97 100644 --- a/zh/how_the_internet_works/README.md +++ b/zh/how_the_internet_works/README.md @@ -1,6 +1,6 @@ # 互联网是如何工作的? -> 本章内容衍生自Jessica McKellar的演讲“互联网是怎么工作的”(http://web.mit.edu/jesstess/www/)。 +> 本章内容衍生自Jessica McKellar的演讲“互联网是怎么工作的” (http://web.mit.edu/jesstess/www/) 。 我们猜你每天在使用互联网。但是当你在浏览器里输入一个像 https://djangogirls.org 的地址并按 `回车键`的时候,你真的知道背后发生了什么吗? @@ -18,7 +18,7 @@ [1]: images/internet_1.png -看起来很糟糕,对吗? 事实上,它是一个由互相连通的机器 (上面提到的*服务器*) 组成的网络。 数以十万计的机器! 很多,很多数以公里长的电缆分布在全世界! 你能访问一个海底电缆地图网站(http://submarinecablemap.com/)来看这个网络有多么复杂。 这是一个网站上的截屏: +看起来很糟糕,对吗? 事实上,它是一个由互相连通的机器 (上面提到的*服务器*) 组成的网络。 数以十万计的机器! 很多,很多数以公里长的电缆分布在全世界! 你能访问一个海底电缆地图网站( http://submarinecablemap.com/ )来看这个网络有多么复杂。 这是一个网站上的截屏: ![图1.2][2] @@ -32,7 +32,7 @@ [3]: images/internet_2.png -想象一下当你键入https://djangogirls.org,你会发送一封信说:“亲爱的Django Girls,我想看看djangogirls.org网站,请将它发送给我!” +想象一下当你键入 https://djangogirls.org ,你会发送一封信说:“亲爱的Django Girls,我想看看djangogirls.org网站,请将它发送给我!” 你的信件去了离你最近的邮局。 然后它去离你的收件人稍近一点的邮局,然后再去另一个,以此类推地到达它的目的地。 唯一的事情是,如果你将许多信件 (*数据包*) 发送到同一个地方,他们可以通过完全不同邮政局 (*路由器*)。 这取决于每个办公室的分布情况。 @@ -50,4 +50,4 @@ 既然这是Django教程,你会问Django做什么。 当你发送一个响应时,你通常不会发送同样的东西给每一个人。 如果你信件的内容是个性化的必然更好,尤其是对于那个刚刚给你写信的人,对吗? Django帮助你创建这些个性化,有趣的信件:)。 -废话少说,抓紧时间创造! \ No newline at end of file +废话少说,抓紧时间创造! diff --git a/zh/how_the_internet_works/images/internet_1.png b/zh/how_the_internet_works/images/internet_1.png index 9c5bcf0b003..e289eac2b23 100644 Binary files a/zh/how_the_internet_works/images/internet_1.png and b/zh/how_the_internet_works/images/internet_1.png differ diff --git a/zh/how_the_internet_works/images/internet_2.png b/zh/how_the_internet_works/images/internet_2.png index dd5861f376f..e8cf8b77999 100644 Binary files a/zh/how_the_internet_works/images/internet_2.png and b/zh/how_the_internet_works/images/internet_2.png differ diff --git a/zh/how_the_internet_works/images/internet_3.png b/zh/how_the_internet_works/images/internet_3.png index a23488e3f2f..6f5d95dec80 100644 Binary files a/zh/how_the_internet_works/images/internet_3.png and b/zh/how_the_internet_works/images/internet_3.png differ diff --git a/zh/how_the_internet_works/images/internet_4.png b/zh/how_the_internet_works/images/internet_4.png index 2661cec1b61..d4748ac48ef 100644 Binary files a/zh/how_the_internet_works/images/internet_4.png and b/zh/how_the_internet_works/images/internet_4.png differ diff --git a/zh/html/README.md b/zh/html/README.md index 5334811bc80..78aac23fad6 100755 --- a/zh/html/README.md +++ b/zh/html/README.md @@ -35,7 +35,7 @@ HTML代表“HyperText Markup Language(超文本标记语言)”。 **超文 [1]: images/step1.png -再也没有错误了 !祝贺:)然而,您的网站实际上并没有展现任何东西出了一个空白页,因为您的模板也是空。我们需要解决这个问题。 +再也没有错误了 !祝贺 :) 然而,您的网站实际上并没有展现任何东西除了一个空白页,因为您的模板也是空。我们需要解决这个问题。 在您的模板文件中添加以下内容: @@ -152,7 +152,7 @@ HTML代表“HyperText Markup Language(超文本标记语言)”。 **超文 我们把这些成果放到网上一定很棒,对吧?让我们再来一次 PythonAnywhere 部署: -### 提交并推送代码到Github +### 提交并推送代码到 GitHub 首先,让我们看看上次部署之后什么文件改变了(运行这些本地命令,不是在 PythonAnywhere 上): @@ -178,7 +178,7 @@ HTML代表“HyperText Markup Language(超文本标记语言)”。 **超文 > **注意** 请确保您使用双引号括提交消息。 -做完这些,我们上传(push)改动到 Github: +做完这些,我们上传(push)改动到 GitHub : git push diff --git a/zh/html/images/step1.png b/zh/html/images/step1.png index e9c2f1082d6..eb474aaeddd 100644 Binary files a/zh/html/images/step1.png and b/zh/html/images/step1.png differ diff --git a/zh/html/images/step3.png b/zh/html/images/step3.png index 811226fa3fc..47ede3f9993 100644 Binary files a/zh/html/images/step3.png and b/zh/html/images/step3.png differ diff --git a/zh/html/images/step4.png b/zh/html/images/step4.png index bd6c1a044e0..0e6b48ec4a5 100644 Binary files a/zh/html/images/step4.png and b/zh/html/images/step4.png differ diff --git a/zh/html/images/step6.png b/zh/html/images/step6.png index e42a2fe5388..f044389de53 100644 Binary files a/zh/html/images/step6.png and b/zh/html/images/step6.png differ diff --git a/zh/images/application.png b/zh/images/application.png index 6dcba6202c7..79071fe8d1b 100644 Binary files a/zh/images/application.png and b/zh/images/application.png differ diff --git a/zh/installation/README.md b/zh/installation/README.md index c697ade6ce2..afd992a2c49 100755 --- a/zh/installation/README.md +++ b/zh/installation/README.md @@ -28,7 +28,7 @@ {% include "/deploy/install_git.md" %} -# 创建一个 Github 账户 +# 创建一个 GitHub 账户 前往 [GitHub.com](https://www.github.com) 并注册一个新的账号。 @@ -44,6 +44,6 @@ * [命令行介绍](../intro_to_command_line/README.md) - * [Python 简介](../intro_to_command_line/README.md) + * [Python 简介](../python_introduction/README.md) * [Django 是什么?](../django/README.md) diff --git a/zh/intro_to_command_line/README.md b/zh/intro_to_command_line/README.md index 3fe4b30df4e..6dd9a4522e5 100755 --- a/zh/intro_to_command_line/README.md +++ b/zh/intro_to_command_line/README.md @@ -20,7 +20,7 @@ 转到开始菜单 → 所有程序 → 附件 → 命令提示符。 -### Mac OS X 系统 +### macOS 系统 应用程序 → 实用工具 → 终端。 diff --git a/zh/python_installation/images/add_python_to_windows_path.png b/zh/python_installation/images/add_python_to_windows_path.png index 9510d6f2176..3266efb6177 100644 Binary files a/zh/python_installation/images/add_python_to_windows_path.png and b/zh/python_installation/images/add_python_to_windows_path.png differ diff --git a/zh/python_installation/instructions.md b/zh/python_installation/instructions.md index bb56316be22..96ab8a115ed 100755 --- a/zh/python_installation/instructions.md +++ b/zh/python_installation/instructions.md @@ -1,4 +1,4 @@ -> 本节基于 Geek Girls Carrots (https://github.com/ggcarrots/django-carrots)的教程 +> 本节基于 Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) 的教程 Django 是用 Python 写的。 在 Django 中,我们需要使用 Python 语言去做所有的事情。 让我们从安装开始 ! 我们希望您能安装 Python 3.4,所以如果你有任何以前的版本,你将需要将其升级。 @@ -24,17 +24,10 @@ Django 是用 Python 写的。 在 Django 中,我们需要使用 Python 语言 在控制台中键入此命令: - $ sudo apt-get install python3.4 + $ sudo apt install python3.4 -#### Fedora (up to 21) - -在您的控制台中使用此命令: - - $ sudo yum install python3.4 - - -#### Fedora (22+) +#### Fedora 在您的控制台中使用此命令: @@ -48,11 +41,11 @@ Django 是用 Python 写的。 在 Django 中,我们需要使用 Python 语言 $ sudo zypper install python3 -### OS X +### macOS 你需要去到网站 https://www.python.org/downloads/release/python-343/ 然后下载 Python 安装程序: - * 下载 *Mac OS X 64-bit/32-bit installer* 文件, + * 下载 *macOS 64-bit/32-bit installer* 文件, * 双击 *python-3.4.3-macosx10.6.pkg* 以运行安装程序。 验证安装成功,请打开 *终端* 应用,运行 `python3` 命令: diff --git a/zh/python_introduction/README.md b/zh/python_introduction/README.md index 35bf29a05d9..6910bf5e168 100755 --- a/zh/python_introduction/README.md +++ b/zh/python_introduction/README.md @@ -322,7 +322,7 @@ 我希望你能觉得到目前为止这些都合情合理。:)准备享受更多字典的乐趣吗?跳到下一行去做一些更有趣的事情。 -你可以使用`del`命令去删除字典里的元素。 比如,如果你想删除键`'favorite_numbers'`所对应的项,只需要键入如下命令: +你可以使用`pop() `语句去删除字典里的元素。 比如,如果你想删除键`'favorite_numbers'`所对应的项,只需要键入如下命令: >>> participant.pop('favorite_numbers') >>> participant @@ -406,7 +406,7 @@ >>> 1 > 'django' Traceback (most recent call last): File "", line 1, in - TypeError: unorderable types: int() > str() + TypeError: '>' not supported between instances of 'int' and 'str' 在这里你看到就像在这表达式中,Python 是不能比较数字 (`int`) 和字符串 (`str`)。 相反,它显示一个 **TypeError**,并告诉我们两个类型不能相互比较。 diff --git a/zh/python_introduction/images/cupcake.png b/zh/python_introduction/images/cupcake.png index fa2f3baeae6..8c1820adee8 100644 Binary files a/zh/python_introduction/images/cupcake.png and b/zh/python_introduction/images/cupcake.png differ diff --git a/zh/template_extending/README.md b/zh/template_extending/README.md index 988d328e180..e5c9cf76df5 100755 --- a/zh/template_extending/README.md +++ b/zh/template_extending/README.md @@ -107,7 +107,7 @@ ``` -{% raw %}这意味着我们在 `post_list.html`模板文件中扩展了 `base.html` 模板的内容。 还有一件事:将所有(除了我们刚刚加入的那行) 内容置于`{% block content %}`和 `{% endblock content %}`之间。。 像这样:{% endraw %} +{% raw %}这意味着我们在 `post_list.html`模板文件中扩展了 `base.html` 模板的内容。 还有一件事:将所有(除了我们刚刚加入的那行) 内容置于`{% block content %}`和 `{% endblock %}`之间。。 像这样:{% endraw %} ```html {% extends 'blog/base.html' %} @@ -122,7 +122,7 @@

{{ post.text|linebreaksbr }}

{% endfor %} - {% endblock content %} + {% endblock %} ``` diff --git a/zh/whats_next/README.md b/zh/whats_next/README.md index f08ef2cf4f4..1fe9d3af464 100755 --- a/zh/whats_next/README.md +++ b/zh/whats_next/README.md @@ -17,7 +17,7 @@ 是啊!首先,继续尝试其他书籍,称作[Django Girls教程:扩展][3]. - [3]: http://djangogirls.gitbooks.io/django-girls-tutorial-extensions/ + [3]: https://tutorial-extensions.djangogirls.org 稍后,你可以试试利用以下的资源。 他们非常值得推荐啊! - [Django's official tutorial][4] @@ -35,6 +35,6 @@ [7]: https://www.codecademy.com/tracks/web [8]: https://github.com/ggcarrots/django-carrots/ [9]: http://learnpythonthehardway.org/book/ - [10]: http://gettingstartedwithdjango.com/ + [10]: http://www.gettingstartedwithdjango.com/ [11]: https://twoscoopspress.com/products/two-scoops-of-django-1-8