diff --git a/LANGS.md b/LANGS.md index 54002844570..84b4ed7b86d 100644 --- a/LANGS.md +++ b/LANGS.md @@ -1,9 +1,12 @@ * [English](en) * [Polski](pl) * [Українська](uk) +* [简体中文](zh) * [Español (beta)](es) -* [Français (beta)](fr) +* [Français](fr) * [Português-brasileiro (beta)](pt/) * [Русский (beta)](ru) * [한국어 (beta)](ko) -* [简体中文](zh) +* [Italian (beta)](it) +* [Magyar (beta)](hu) +* [Türkçe (beta)](tr) diff --git a/en/css/README.md b/en/css/README.md index b620eed31c5..e415744b2a2 100644 --- a/en/css/README.md +++ b/en/css/README.md @@ -100,7 +100,7 @@ Between the `` and ``, after the links to the Bootstrap CSS files a ```html ``` -The browser reads the files in the order they're given, so we need to be 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 override code in Bootstrap files. We just told our template where our CSS file is located. Your file should now look like this: diff --git a/en/deploy/README.md b/en/deploy/README.md index acf889f47df..fb16e72d98b 100644 --- a/en/deploy/README.md +++ b/en/deploy/README.md @@ -272,6 +272,7 @@ application = DjangoWhiteNoise(get_wsgi_application()) ``` > **Note** Don't forget to substitute in your own username where it says `` +> **Note** In line three, we make sure Pyhthon 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. It also sets up the "whitenoise" static files tool. diff --git a/en/django_forms/README.md b/en/django_forms/README.md index 4395a41752f..834a64f059c 100644 --- a/en/django_forms/README.md +++ b/en/django_forms/README.md @@ -47,7 +47,7 @@ It's time to open `blog/templates/blog/base.html`. We will add a link in `div` n ``` -Note that we want to call our new view `post_new`. +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. After adding the line, your html file should now look like this: @@ -198,7 +198,7 @@ if form.is_valid(): Basically, we have two things here: we save the form with `form.save` and we add an author (since there was no `author` field in the `PostForm` and this field is required!). `commit=False` means that we don't want to save `Post` model yet - we want to add author first. Most of the time you will use `form.save()`, without `commit=False`, but in this case, we need to do that. `post.save()` will preserve changes (adding author) and a new blog post is created! -Finally, it would be awesome if we can immediatelly go to `post_detail` page for newly created blog post, right? To do that we need one more import: +Finally, it would be awesome if we can immediately go to `post_detail` page for newly created blog post, right? To do that we need one more import: ```python from django.shortcuts import redirect @@ -207,10 +207,10 @@ from django.shortcuts import redirect Add it at the very beginning of your file. And now we can say: go to `post_detail` page for a newly created post. ```python -return redirect('blog.views.post_detail', pk=post.pk) +return redirect('post_detail', pk=post.pk) ``` -`blog.views.post_detail` is the name of the view we want to go to. Remember that this *view* requires a `pk` variable? To pass it to the views we use `pk=post.pk`, where `post` is the newly created blog post! +`post_detail` is the name of the view we want to go to. Remember that this *view* requires a `pk` variable? To pass it to the views we use `pk=post.pk`, where `post` is the newly created blog post! Ok, we talked a lot, but we probably want to see what the whole *view* looks like now, right? @@ -223,7 +223,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}) @@ -300,7 +300,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}) @@ -352,7 +352,23 @@ We're going to add another `{% if %}` tag to this which will make the link only This `{% if %}` will cause the link to only be sent to the browser if the user requesting the page is logged in. This doesn't protect the creation of new posts completely, but it's a good first step. We'll cover more security in the extension lessons. -Since you're likely logged in, if you refresh the page, you won't see anything different. Load the page in a new browser or an incognito window, though, and you'll see that the link doesn't show up! +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: + +```html + +``` + +Change it to: + +```html +{% if user.is_authenticated %} + +{% endif %} +``` + +Since you're likely logged in, if you refresh the page, you won't see anything different. Load the page in a new browser or an incognito window, though, and you'll see that the link doesn't show up, and the icon doesn't display either! ## One more thing: deploy time! diff --git a/en/django_installation/instructions.md b/en/django_installation/instructions.md index a37a8cb87f6..0cb2897d303 100644 --- a/en/django_installation/instructions.md +++ b/en/django_installation/instructions.md @@ -91,6 +91,11 @@ Now that you have your `virtualenv` started, you can install Django using `pip`. on Windows > 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 moving it to another place without spaces, accents or special characters (suggestion is: `C:\djangogirls`). After the move please try the above command again. +on Windows 8 and Windows 10 +> Your command line might freeze after when you try to install Django. If this happens, instead of the above command use: + +> C:\Users\Name\djangogirls> python -m pip install django==1.8 + on Linux > 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 7daa429869a..bb22a8eb04f 100644 --- a/en/django_models/README.md +++ b/en/django_models/README.md @@ -123,7 +123,7 @@ class Post(models.Model): return self.title ``` -> Double-check that you use two undescore characters (`_`) on each side of `str`. This convention is used frequently in Python and sometimes we also call them "dunder" (short for "double-underscore"). +> Double-check that you use two underscore characters (`_`) on each side of `str`. This convention is used frequently in Python and sometimes we also call them "dunder" (short for "double-underscore"). It looks scary, right? But no worries we will explain what these lines mean! @@ -152,7 +152,7 @@ If something is still not clear about models, feel free to ask your coach! We kn ### Create tables for models in your database -The last step here is to add our new model to our database. First we have to make Django know that we have some changes in our model (we have just created it!). Type `python manage.py makemigrations blog`. It will look like this: +The last step here is to add our new model to our database. First we have to make Django know that we have some changes in our model (we have just created it!). Go to your console window and type `python manage.py makemigrations blog`. It will look like this: (myvenv) ~/djangogirls$ python manage.py makemigrations blog Migrations for 'blog': diff --git a/en/django_templates/README.md b/en/django_templates/README.md index 4798b8beac4..e63fdd3ed9b 100644 --- a/en/django_templates/README.md +++ b/en/django_templates/README.md @@ -89,7 +89,7 @@ $ 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! -Congrats! Now go ahead and try adding a new post in your Django admin (remember to add published_date!), 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://www.yourname.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/installation/README.md b/en/installation/README.md index 9eb0a3460b7..533b95c53bc 100644 --- a/en/installation/README.md +++ b/en/installation/README.md @@ -32,13 +32,13 @@ Go to [GitHub.com](http://www.github.com) and sign up for a new, free user accou # Start reading -Congratulations, you are are all set up and ready to go! If you still have some time before the workshop, it would be useful to start reading a few of the beginning chapters: +Congratulations, you are all set up and ready to go! If you still have some time before the workshop, it would be useful to start reading a few of the beginning chapters: * [How the internet works](../how_the_internet_works/README.md) * [Introduction to the command line](../intro_to_command_line/README.md) -* [Introduction to Python](../intro_to_command_line/README.md) +* [Introduction to Python](../python_introduction/README.md) * [What is Django?](../django/README.md) diff --git a/en/intro_to_command_line/README.md b/en/intro_to_command_line/README.md index cffff760869..da6fa701572 100644 --- a/en/intro_to_command_line/README.md +++ b/en/intro_to_command_line/README.md @@ -42,7 +42,11 @@ On Windows, it's a `>` sign, like this: 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 that's 100% correct. In this tutorial we will just simplify it to the bare minimum. +> 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 that's 100% correct. + +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!) diff --git a/en/python_installation/instructions.md b/en/python_installation/instructions.md index a8de9e8423c..0b6dcebb59b 100644 --- a/en/python_installation/instructions.md +++ b/en/python_installation/instructions.md @@ -8,11 +8,10 @@ Django is written in Python. We need Python to do anything in Django. Let's star You can download Python for Windows from the website https://www.python.org/downloads/release/python-343/. After downloading the ***.msi** file, you should run it (double-click on it) and follow the instructions there. It is important to remember the path (the directory) where you installed Python. It will be needed later! -One thing to watch out for: on the second screen of the installation wizard, marked "Customize", make sure you scroll down and choose the "Add python.exe to the Path" option, as shown here: +One thing to watch out for: on the second screen of the installation wizard, marked "Customize", make sure you scroll down to the "Add python.exe to the Path" option and select "Will be installed on local hard drive", as shown here: ![Don't forget to add Python to the Path](../python_installation/images/add_python_to_windows_path.png) - ### Linux 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: diff --git a/en/python_introduction/README.md b/en/python_introduction/README.md index 0a9d0fc5455..266693a3a4e 100644 --- a/en/python_introduction/README.md +++ b/en/python_introduction/README.md @@ -431,13 +431,13 @@ Earlier, we picked out a code editor from the [code editor](../code_editor/READM print('Hello, Django girls!') ``` -> **Note** You should notice one of the coolest thing about code editors: colours! In the Python console, everything was the same colour, now you should see that the `print` function is a different colour from the string. This is called "syntax highlighting", and it's a really useful feature when coding. The colour of things will give you hints, such as unclosed strings or a typo in a keyword name (like the `def` in a function, which we'll see below). This is one of the reasons we use a code editor :) - - Obviously, you're a pretty seasoned Python developer now, so feel free to write some code that you've learned today. Now we need to save the file and give it a descriptive name. Let's call the file **python_intro.py** and save it to your desktop. We can name the file anything we want, but the important part here is to make sure the file ends in __.py__. The __.py__ extension tells our operating system that this is a **python executable file** and Python can run it. +> **Note** You should notice one of the coolest thing about code editors: colours! In the Python console, everything was the same colour, now you should see that the `print` function is a different colour from the string. This is called "syntax highlighting", and it's a really useful feature when coding. The colour of things will give you hints, such as unclosed strings or a typo in a keyword name (like the `def` in a function, which we'll see below). This is one of the reasons we use a code editor :) + + With the file saved, it's time to run it! Using the skills you've learned in the command line section, use the terminal to **change directories** to the desktop. On a Mac, the command will look something like this: diff --git a/en/whats_next/README.md b/en/whats_next/README.md index b8d920492eb..02e0544e418 100644 --- a/en/whats_next/README.md +++ b/en/whats_next/README.md @@ -19,7 +19,7 @@ Later on, you can try the resources listed below. They're all very recommended! - [New Coder tutorials](http://newcoder.io/tutorials/) - [Code Academy Python course](http://www.codecademy.com/en/tracks/python) - [Code Academy HTML & CSS course](http://www.codecademy.com/tracks/web) -- [Django Carrots tutorial](http://django.carrots.pl/en/) +- [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](http://twoscoopspress.com/products/two-scoops-of-django-1-8) diff --git a/es/deploy/README.md b/es/deploy/README.md index e0c6c53caec..962cc55452e 100755 --- a/es/deploy/README.md +++ b/es/deploy/README.md @@ -193,7 +193,7 @@ Tal y como hiciste en tu propio ordenador, puedes crear un virtualenv en PythonA 20:20 ~ $ source myvenv/bin/activate - (mvenv)20:20 ~ $ pip install django whitenoise + (mvenv)20:20 ~ $ pip install django==1.8 whitenoise Collecting django [...] Successfully installed django-1.8 whitenoise-1.0.6 diff --git a/es/django_forms/README.md b/es/django_forms/README.md index e98a03f592d..a446c4e0845 100755 --- a/es/django_forms/README.md +++ b/es/django_forms/README.md @@ -142,7 +142,7 @@ Bueno, vamos a ver cómo quedará el HTML en `post_edit.html`: {% block content %}

New post

-
{% raw %}{% csrf_token %}{% endraw %} + {% csrf_token %} {{ form.as_p }}
diff --git a/es/django_templates/README.md b/es/django_templates/README.md index 7ab58e6e4d3..9a74f088cf0 100755 --- a/es/django_templates/README.md +++ b/es/django_templates/README.md @@ -72,12 +72,25 @@ Todo lo que pones entre `{% for %}` y `{% endfor %}` se repetirá para cada obje 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... * Primero, sube tu código a GitHub - - $ git status [...] $ git add -A . $ git status [...] $ git commit -m "Added views to create/edit blog post inside the site." [...] $ git push + +``` +$ git status +[...] +$ git add -A . +$ git status +[...] +$ git commit -m "Modified templates to display posts from database." +[...] +$ git push +``` * Luego, identifícate en [PythonAnywhere][4] y ve a tu **consola Bash** (o empieza una nueva), y ejecuta: - - $ cd my-first-blog $ git pull [...] + +``` +$ cd my-first-blog +$ git pull +[...] +``` * Finalmente, ve a la [pestaña Web][5] y presiona **Reload** en tu aplicación web. ¡Tu actualización debería poder verse! diff --git a/es/html/README.md b/es/html/README.md index d3942297fdd..d8e8034595d 100755 --- a/es/html/README.md +++ b/es/html/README.md @@ -190,7 +190,14 @@ Una vez que hicimos esto, subimos (push) nuestros cambios a PythonAnywhere: * 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 $ git pull [...] +``` +$ cd ~/my-first-blog +$ source myvenv/bin/activate +(myvenv)$ git pull +[...] +(myvenv)$ python manage.py collectstatic +[...] +``` [5]: https://www.pythonanywhere.com/consoles/ diff --git a/es/intro_to_command_line/README.md b/es/intro_to_command_line/README.md index 1bb9b0237a7..2aa6b8a9f8e 100755 --- a/es/intro_to_command_line/README.md +++ b/es/intro_to_command_line/README.md @@ -8,7 +8,7 @@ Los siguientes pasos te mostrarán cómo usar aquella ventana negra que todos lo ## ¿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 la 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** 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*. ## Abrir la interfaz de línea de comandos @@ -217,7 +217,7 @@ Ahora es hora de eliminar el directorio `djangogirls`. > **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. - $ rm - r djangogirls + $ rm -r djangogirls Windows: @@ -272,4 +272,4 @@ Si tienes curiosidad, [ss64.com][1] contiene una referencia completa de comandos ## ¿Lista? -¡Vamos a sumergirnos en Python! \ No newline at end of file +¡Vamos a sumergirnos en Python! diff --git a/fr/CONTRIBUTING.md b/fr/CONTRIBUTING.md deleted file mode 100755 index 3ea54d5bc00..00000000000 --- a/fr/CONTRIBUTING.md +++ /dev/null @@ -1,109 +0,0 @@ -# How to contribute - -The Django Girls Tutorial is licensed under a *Creative Commons Attribution-ShareAlike 4.0* license. Everyone is free to add, edit and correct the tutorial. - -# Editing basics - -The source code of the tutorial is [hosted on Github](http://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.io/) service for publishing its documentation. [See more information about how Gitbook works](http://help.gitbook.io/). - -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). - -# Getting started and prerequisites - -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. - -## Fork the repository - -First fork the [DjangoGirls/tutorial](https://github.com/DjangoGirls/tutorial) repository to your personal Github account: - -![Fork button](contributing/images/fork.png) - -# Editing chapter content - -## Simple changes - -For simple changes like typo corrections you can use the Github online editor: - - * Open your local fork page on Github, - * go to *README.md* file in any chapter, - * press the *Edit* icon (pen) - -and you can edit the chapter directly on github.com. - -![Bouton d'édition](contributing/images/edit.png) - -Markdown syntax is used to edit the individual pages of the tutorial. - -![Github editor](contributing/images/github_editor.png) - -Save your changes and create a pull request as explained below. - -## 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: - - git clone git@github.com:yourgithubusername/tutorial.git - - -Download the [Gitbook Editor](http://help.gitbook.io/editor/README.html) app to your computer. - -Then you can open the tutorial in Gitbook Editor (*File* > *Open book*). - -![Gitbook](contributing/images/gitbook.png) - -Make any changes in the tutorial using the editor and then save changes (*Book* > *Save all*). - -Then commit the changes using `git` and push the changes to your remote Github repository. - -Example: - - $ git status - On branch contributing - Untracked files: - (use "git add ..." to include in what will be committed) - - contributing_and_editing_this_book/images/gitbook.png - - $ git add contributing_and_editing_this_book/images/gitbook.png - - $ git commit -m "Added gitbook editor screenshot" - [contributing fe36152] Added gitbook screenshot - 1 file changed, 0 insertions(+), 0 deletions(-) - create mode 100644 contributing_and_editing_this_book/images/gitbook.png - - $ git push - Counting objects: 11, done. - Delta compression using up to 8 threads. - Compressing objects: 100% (5/5), done. - Writing objects: 100% (5/5), 266.37 KiB | 0 bytes/s, done. - Total 5 (delta 1), reused 0 (delta 0) - To git@github.com:miohtama/tutorial.git - b37ca59..fe36152 contributing -> contributing - - -# Making a pull request - -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. - -In your own repository on Github press do *Compare & pull request* - -![Gitbook](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. - -# Further information and help - -For any questions please [contact DjangoGirls](http://djangogirls.org/). \ No newline at end of file diff --git a/fr/GLOSSARY.md b/fr/GLOSSARY.md new file mode 100644 index 00000000000..48cb7aaa0d3 --- /dev/null +++ b/fr/GLOSSARY.md @@ -0,0 +1,3 @@ +# Éditeur de texte + +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 9593a275d26..46c317557bb 100755 --- a/fr/README.md +++ b/fr/README.md @@ -1,4 +1,4 @@ -# Tutoriel Django Girls +# 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) @@ -6,21 +6,21 @@ ## Translation -This tutorial has been translated from English to French by a group of awesome volunteers. Special thanks for help go to Lucie Daeye and Georges Dubus. <3 <3 +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 ## 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 sort laissé·e à la traîne ? Avez vous déjà été curieux·se 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 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 ? -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 fun. +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 programmeur·se du jour au lendemain. Devenir vraiment bon·ne 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 notre mieux de vous expliquer différents morceaux de la technologie, pour la rendre moins intimidante. +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 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 ? +## 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, pour pouvoir montrer le résultat à d'autres personnes. +À 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 ! Ça devrait ressembler plus ou moins à ça : @@ -28,25 +28,25 @@ Nous espérons arriver à vous faire aimer la technologie autant que nous l'aimo [2]: images/application.png -> Si vous travaillez sur ce tutoriel dans votre coin et que vous n'avez pas de coach pour vous aider en cas de problème, 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). 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 d'y 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 ! -Okay, [commençons par le commencement...][3] +Alors, [commençons par le commencement...][3] - [3]: how_internet_works/README.md + [3]: how_the_internet_works/README.md -## À propos, et contributions +## À propos et contributions -Ce tutoriel est maintenu par [DjangoGirls][4]. Si vous trouvez des erreurs ou souhaitez mettre à jour le tutoriel veuillez [suivre les instructions de contribution][5]. +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]. [4]: http://djangogirls.org/ [5]: https://github.com/DjangoGirls/tutorial/blob/master/README.md -## Voulez vous nous aider à traduire le tutoriel dans d'autres langues ? +## Voulez-vous nous aider à traduire le tutoriel dans d'autres langues ? -Pour l'instant, les traductions sont maintenue sur crowdin.com. +Pour l'instant, les traductions sont stockées sur la plate-forme crowdin.com dans : 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 + [6]: https://github.com/DjangoGirls/tutorial/issues/new \ No newline at end of file diff --git a/fr/SUMMARY.md b/fr/SUMMARY.md index 530f0fdc542..4eabc020e6f 100755 --- a/fr/SUMMARY.md +++ b/fr/SUMMARY.md @@ -1,26 +1,26 @@ # Résumé * [Introduction](README.md) -* [Comment marche l'Internet?](how_internet_works/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) -* [Django](django/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) +* [Votre premier projet Django !](django_start_project/README.md) * [Les modèles dans Django](django_models/README.md) -* [Django ORM and QuerySets](django_orm/README.md) -* [L'interface d'administration de Django](django_admin/README.md) -* [Déployer!](deploy/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) -* [Nom de domaine](domain/README.md) -* [La suite?](whats_next/README.md) +* [La suite ?](whats_next/README.md) \ No newline at end of file diff --git a/fr/code_editor/README.md b/fr/code_editor/README.md index 08a0f46ac4d..b149081182d 100755 --- a/fr/code_editor/README.md +++ b/fr/code_editor/README.md @@ -1,33 +1,7 @@ # L'éditeur de texte -Vous allez bientôt écrire vos premières lignes de code : il vous faut tout d'abord télécharger un éditeur de texte ! +Vous allez bientôt écrire vos premières lignes de code : Il vous faut tout d'abord télécharger un éditeur de texte ! -Choisir un éditeur de texte parmi tous ceux disponibles est surtout une histoire de goûts personnels. La plupart des programmeurs Python utilisent des IDE (Environnement de développement intégré) complexes mais très puissant, 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. +> **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 pouvez choisir l'un des éditeurs de la liste ci-dessous mais n'hésiter pas à demander à votre coach l'éditeur qu'il·elle préfère. - -## Gedit - -Gedit un éditeur libre et gratuit qui est disponible sur tous les systèmes d'exploitation. - -[Télécharger][1] - - [1]: https://wiki.gnome.org/Apps/Gedit#Download - -## Sublime Text 2 - -Sublime text est un éditeur très populaire : il est disponible gratuitement sous forme de version d'évaluation pour tous les systèmes d'exploitation. Il est facile à installer et à utiliser. - -[Télécharger][2] - - [2]: http://www.sublimetext.com/2 - -## Atom - -Atom est un éditeur très récent créé par [GitHub][3]. Disponible pour tous les systèmes d'exploitation, il est libre, gratuit et facile à installer et à utiliser. - - [3]: http://github.com/ - -[Télécharger][4] - - [4]: https://atom.io/ \ No newline at end of file +{% 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 new file mode 100644 index 00000000000..c681ba67889 --- /dev/null +++ b/fr/code_editor/instructions.md @@ -0,0 +1,31 @@ +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. + +## Gedit + +Gedit est un éditeur libre et gratuit disponible pour tout les systèmes d'exploitation. + +[Télécharger](https://wiki.gnome.org/Apps/Gedit#Download) + +## Sublime Text 2 + +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. + +[Télécharger](http://www.sublimetext.com/2) + +## Atom + +Atom est un éditeur très récent créé par [GitHub](http://github.com/). Disponible pour tout les systèmes d'exploitation, il est libre, gratuit, facile à installer et à utiliser. + +[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 ? + +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 [TRF (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. + +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 :) \ No newline at end of file diff --git a/fr/css/README.md b/fr/css/README.md index 178e6771adb..a1e68ab4fdd 100755 --- a/fr/css/README.md +++ b/fr/css/README.md @@ -1,122 +1,111 @@ -# CSS - Rendez votre site joli! +# CSS - Rendez votre site joli ! -Soyons honnête: notre blog est plutôt moche, non ? Un peu de CSS devrait nous permettre d'arranger ça! +Soyons honnêtes : notre blog est plutôt moche, non ? Un peu de CSS devrait nous permettre d'arranger ça ! -## Qu'est-ce que le CSS? +## Qu'est-ce que le CSS ? -Les feuilles de style en cascade, 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, 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 ;) -Je suppose que vous n'avez pas envie de partir de rien et de 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éveloppeur·se·s. Réinventer à chaque fois la roue n'est pas fun en plus d'être absolument inutile. +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. -## Utilisons Bootstrap! +## 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: http://getbootstrap.com/ +Bootsrap est l'un des frameworks HTML et CSS les plus populaires. Il est utilisé pour créer de très beaux sites web : http://getbootstrap.com/ -Il fut codé par d'anciens programmeurs 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 programmeurs·ses de chez Twitter et 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, vous avez besoin d'ajouter ceci dans le `` de votre fichier `.html` (`blog/templates/blog/post_list.html`) : -``` +```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à! +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] [1]: images/bootstrap1.png -C'est déjà un peu mieux, n'est-ce pas? +C'est déjà un peu mieux ! ## Les fichiers statiques dans Django -Les **fichiers statiques** (static files) font eux aussi partie des nouvelles choses que vous allez apprendre aujourd'hui. Votre CSS ainsi que vos images font partie des fichiers statiques. Ces fichiers ne sont pas dynamiques, ce qui signifie qu'ils ne dépendent pas du contexte de la requête et seront donc identiques pour chaque utilisateur. - -Comme la CSS est un fichier statique, nous devons tout d'abord configurer les fichiers statiques dans Django. Vous n'avez besoin de faire cette étape qu'une seule fois. Commençons: +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. -### Configurer les fichiers statiques dans Django +### Où ranger les fichiers statiques dans Django ? -Tout d'abord, nous devons créer un dossier pour y ranger nos fichiers statiques. Allez-y: créez un dossier appelé `static` à l'intérieur de votre dossier `djangogirls`. +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`. -``` -djangogirls -├─── static -└─── manage.py -``` - +Pour cela, nous allons créer un fichier appelé `static` à l'intérieur de notre blog app : -Ouvrez le fichier `mysite/settings.py` et allez à la fin de celui-ci pour ajouter les lignes suivantes: - -``` -STATICFILES_DIRS = ( - os.path.join(BASE_DIR, "static"), -) -``` + djangogirls + ├── blog + │ ├── migrations + │ └── static + └── mysite -Maintenant, Django sait où se trouvent vos 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 première 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êt·e·s? +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 ? -``` -static -└─── css - blog.css -``` + djangogirls + └─── blog + └─── static + └─── css + └─── blog.css -Maintenant, écrivons un peu de CSS: ouvrez le fichier `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. -Vous n'avez peut-être pas envie de passer le reste de la journée à personnaliser vos pages web et à apprendre le CSS. De toute manière, ce n'est pas l'objectif de cet atelier! Nous vous invitons donc, une fois rentré·e chez vous, à vous plonger dans d'autres tutoriels de CSS. Vous verrez, c'est assez simple à comprendre. Vous pouvez consulter le cours [Codeacademy HTML & CSS course][2] qui est une excellente ressource qui vous permettra d'en apprendre plus sur la personnalisation de site web à l'aide de CSS. +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. [2]: http://www.codecademy.com/tracks/web -Que pourrions-nous faire rapidement ? Je sais : 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 le `rouge` et le `vert`. +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 le `rouge` et le `vert`. [3]: http://www.w3schools.com/cssref/css_colornames.asp -Ajoutez ceci dans votre fichier `static/css/blog.css`: +Ajoutez le code suivant dans votre fichier `blog/static/css/blog.css` : - h1 a { - color: #FCA205; - } - +```css +h1 a { + color: #FCA205; +} +``` -`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 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 ! -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. 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` : ```html -``` +``` Nous vous conseillons d'en apprendre un peu plus sur les sélecteurs CSS sur [w3schools][4]. [4]: http://www.w3schools.com/cssref/css_selectors.asp -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: +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 : ```html {% load staticfiles %} ``` - -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: +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 : ```html -``` +``` Nous venons simplement de dire à notre template où nous avons rangé notre fichier CSS. -Maintenant, votre fichier doit ressembler à ceci: +Maintenant, votre fichier doit ressembler à ceci : ```html {% load staticfiles %} @@ -125,7 +114,6 @@ Maintenant, votre fichier doit ressembler à ceci: Django Girls blog - @@ -142,79 +130,74 @@ Maintenant, votre fichier doit ressembler à ceci: {% endfor %} -``` - +``` -Ok, on sauvegarde et on rafraîchit la page! +Ok, on sauvegarde et on rafraîchit la page ! ![Figure 14.2][5] [5]: images/color2.png -Bravo! Peut-être que nous pourrions un peu aérer 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 ! -``` +```css body { padding-left: 15px; } -``` - +``` -Ajoutez ceci à votre fichier CSS, sauvegardez-le et voyons le résultat! +Ajoutez ceci à votre fichier CSS, sauvegardez-le et voyons le résultat ! ![Figure 14.3][6] [6]: images/margin2.png -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`: +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` : +```html + ``` - -``` Cette ligne nous permet d'importer la police de caractères *Lobster* depuis Google Fonts (https://www.google.com/fonts). -Maintenant, ajouter la ligne `font-family: 'Lobster';` dans votre fichier CSS `static/css/blog.css`. Attention à bien la placer à l'intérieur du block déclaratif `h1 a` (c'est à dire entre les accolades `{` et `}`). Ensuite, rechargez la page. Votre code doit ressembler à ceci: +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 rafraîchir la page. -``` +```css h1 a { color: #FCA205; font-family: 'Lobster'; } ``` - ![Figure 14.3][7] [7]: images/font.png -Super! +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. -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: +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 : -``` +```html -``` - + ``` -Maintenant, ajouter la classe `post` à votre `div` contenant votre blog post. +Maintenant, ajoutez la classe `post` à votre `div` contenant votre blog post. -``` +```html

published: {{ post.published_date }}

{{ post.title }}

{{ post.text|linebreaks }}

``` - -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 maintenant rajouter à notre fichier. Comme nous n'avons malheureusement pas le temps d'entrer dans les détails, copiez le code suivant dans votre fichier `mysite/static/css/blog.css`: +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` : -``` +```css .page-header { background-color: #ff9400; margin-top: 0; @@ -262,9 +245,9 @@ h1, h2, h3, h4 { .post h1 a, .post h1 a:visited { color: #000000; } -``` +``` -Nous allons maintenant nous intéresser au code concernant les posts. Remplacer le code suivant: +Nous allons maintenant nous intéresser au code concernant les posts. Il va falloir remplacer le code le code suivant : ```html {% for post in posts %} @@ -274,9 +257,9 @@ Nous allons maintenant nous intéresser au code concernant les posts. Remplacer

{{ post.text|linebreaks }}

{% endfor %} -``` +``` -Ce code se trouve dans le fichier `blog/templates/blog/post_list.html` et doit être remplacé par celui-ci: +Ce code se trouve dans le fichier `blog/templates/blog/post_list.html`. Il doit être remplacé par le code suivant : ```html
@@ -295,7 +278,6 @@ Ce code se trouve dans le fichier `blog/templates/blog/post_list.html` et doit
``` - Sauvegardez les fichiers modifiés et rafraîchissez votre site web. @@ -303,10 +285,10 @@ Sauvegardez les fichiers modifiés et rafraîchissez votre site web. [8]: 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 comprendre l'essentiel rien qu'en le lisant (ce n'est pas grave si ce n'est pas le cas!). +Woohoo ! C'est pas mal, non ? Le code que nous avons collé n'est pas bien compliqué à comprendre et vous devriez pouvoir en comprendre l'essentiel rien qu'en le lisant (ce n'est pas grave si ce n'est pas le cas ! ). -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 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 ! -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 connaîtrez ainsi tout ce qu'il y a savoir pour rendre son site bien plus joli! +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 connaîtrez ainsi tout ce qu'il y a savoir pour rendre son site bien plus joli ! -Prêt⋅e pour le chapitre suivant? :) +Prête pour le chapitre suivant ? :) \ No newline at end of file diff --git a/fr/deploy/README.md b/fr/deploy/README.md index c6ff212f361..1392d89547a 100755 --- a/fr/deploy/README.md +++ b/fr/deploy/README.md @@ -1,237 +1,312 @@ -# Déployer! +# Déployer ! -> **Note** Le chapitre suivant peut-être parfois 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. Nous avons décidé de placer ce chapitre au milieu du tutoriel afin que votre coach puisse vous aider dans cette tâche compliquée qu'est la mise en ligne d'un site web. Ça signifie que vous serez capable de finir le tutoriel par vous-même plus tard si jamais vous êtes à court de temps à la fin de la journée. +> **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 Internet était seulement disponible 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'à 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 :). -Comme vous l'avez appris, un site web a besoin d'être installé sur un serveur. Il existe de nombreux fournisseurs. Nous allons utiliser celui qui possède le processus de déploiement le plus simple: [Heroku][1]. Heroku est gratuit pour les petits sites qui n'ont pas beaucoup de visiteurs, ce qui devrait vous convenir pour le moment. +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. - [1]: http://heroku.com/ + [1]: http://pythonanywhere.com/ -Nous allons suivre ce tutoriel: https://devcenter.heroku.com/articles/getting-started-with-django. Nous l'avons reproduit (et traduit!) ici pour que cela soit plus simple pour vous. +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 ! -## Le fichier `requirements.txt` + [2]: http://www.github.com -Le fichier `requirements.txt` permet de communiquer à Heroku la liste des paquets Python qui ont besoin d'être installés sur le serveur qui hébergera votre site. +Github va nous servir d'intermédiaire pour envoyer et récupérer notre code sur PythonAnywhere. -Mais avant de créer ce fichier, nous avons besoin d'installer quelques paquets sur Heroku. Reprenez votre console, vérifiez que `virtualenv` est bien activé, puis tapez ceci: +# Git - (myvenv) $ pip install dj-database-url waitress whitenoise +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. + +{% include "/deploy/install_git.md" %} + +## Démarrer un dépôt Git + +Git conserve toutes les modifications apportées à un ensemble de fichiers dans un "repository" (ou "dépôt"). Nous allons devoir en créer un pour notre projet. Ouvrez votre terminal et allez dans le répertoire `djangogirls`. Ensuite, tapez les commandes suivantes : + +> **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 -Une fois l'installation terminée, allez dans le dossier `djangogirls` et tapez cette commande: +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. + +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 : - (myvenv) $ pip freeze > requirements.txt + *.pyc + __pycache__ + myvenv + db.sqlite3 + .DS_Store -Cette commande va créer le fichier `requirements.txt` qui contiendra la liste de tous les paquets Python que vous avez installés, c'est-à-dire toutes les librairies Python que vous utilisez, comme Django par exemple :). +Enregistrez ce fichier `.gitignore` dans votre répertoire principal "djangogirls". -> **Note**: `pip freeze` va lister toutes les librairies Python installées dans votre virtualenv tandis que `>` va se charger de mettre cette liste dans un fichier. Essayez de lancer `pip freeze` sans `> requirements.txt` et regardez ce qui se passe! +> **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 ! -Ouvrez le fichier créé et ajoutez ceci à la fin: +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 fichiers. 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 : - psycopg2==2.5.3 + $ git status + On branch master + + Initial commit + Untracked files: + (use "git add ..." to include in what will be committed) + + .gitignore + blog/ + manage.py + mysite/ + + nothing added to commit but untracked files present (use "git add" to track) + + +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 : -Vous avez besoin de cette dernière ligne pour que votre site web fonctionne sur Heroku. + $ git add -A . + $ git commit -m "My Django Girls app, first commit" + [...] + 13 files changed, 200 insertions(+) + create mode 100644 .gitignore + [...] + create mode 100644 mysite/wsgi.py + -## Procfile +## Publier votre code sur GitHub -Nous avons aussi besoin de créer un Procfile. Cela va permettre à Heroku de savoir quelles commandes lancer pour démarrer votre site web. Ouvrez votre éditeur de texte, créez un fichier `Procfile` dans le dossier `djangogirls` et ajoutez y la ligne suivante: +Allez sur [GitHub.com][2] et inscrivez-vous gratuitement (si vous possédez déjà un compte, c'est très bien!) - web: waitress-serve --port=$PORT mysite.wsgi:application - +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. -Cela signifie que nous allons déployer une application `web` et que nous allons le faire en lançant la commande `waitress-serve --port=$PORT mysite.wsgi:application`. `waitress-serve` est un programme qui est une sorte de version plus puissante de la commande `runserver` de Django. +![][3] -N'oubliez pas de sauvegarder votre fichier. Et voilà, c'est fait! + [3]: images/new_github_repo.png -## Le fichier `runtime.txt` +> **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. -Nous avons besoin de préciser à Heroku la version de Python que nous souhaitons utiliser. Pour cela, nous avons à nouveau besoin de créer un fichier dans le dossier `djangogirls`. Prenez votre éditeur de texte et créez le fichier `runtime.txt` qui contiendra ce tout petit bout de texte: +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 : - python-3.4.2 - +![][4] -## mysite/local_settings.py + [4]: images/github_get_repo_url_screenshot.png -Il existe une différence entre la configuration que nous utilisons localement (sur notre ordinateur) et la configuration utilisée sur notre serveur. Heroku utilise une base de données qui est différente de celle de votre ordinateur. Nous allons devoir créer un fichier de configuration différent qui ne sera utilisé que dans notre environnement local. +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. -Créez le fichier `mysite/local_settings.py`. Il doit contenir la même chose que la configuration de la partie `DATABASE` de votre fichier `mysite/settings.py`. Ça doit ressembler à ceci: +Tapez les instructions suivantes dans votre console (remplacez `` avec le nom d'utilisateur de votre compte GitHub et sans les chevrons) : - import os - BASE_DIR = os.path.dirname(os.path.dirname(__file__)) - - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - } - } + $ git remote add origin https://github.com//my-first-blog.git + $ git push -u origin master - DEBUG = True + +Entrez votre nom d'utilisateur et mot de passe Github. Vous devriez voir quelque chose comme ceci : + + 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 + * [new branch] master -> master + Branch master set up to track remote branch master from origin. -N'oubliez pas de sauvegarder votre fichier! :) + -## mysite/settings.py +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 :) -il va aussi falloir modifier le fichier `settings.py` de notre site web. Pour cela, ouvrez `mysite/settings.py` dans votre éditeur de texte et ajoutez les lignes suivantes à la toute fin du fichier: + [5]: https://github.com/django/django + [6]: https://github.com/DjangoGirls/tutorial - import dj_database_url - DATABASES['default'] = dj_database_url.config() - - SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') - - ALLOWED_HOSTS = ['*'] - - STATIC_ROOT = 'staticfiles' - - DEBUG = False - +# Mettre votre blog en ligne avec PythonAnywhere -Toujours à la fin du fichier `mysite/settings.py`, copier-coller ceci: +> **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. - try: - from .local_settings import * - except ImportError: - pass - +{% 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. -Si le fichier existe, cela va vous permettre d'importer l'intégralité de votre configuration locale. +> **Note** : PythonAnywhere utilise Linux. Si vous êtes sous Windows, la console sera un peu différente de celle de votre ordinateur. -Sauvegardez le fichier. +Importons notre code depuis Github vers PythonAnywhere en créant un "clone" de notre déôpt. Tapez la commande suivante dans la console de PythonAnywhere (n'oubliez pas d'utiliser votre nom d'utilisateur Github à la place de ``): -## mysite/wsgi.py + $ git clone https://github.com//my-first-blog.git + + +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 : + + $ 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 + -Ouvrez le fichier `mysite/wsgi.py` et ajoutez les lignes suivantes à la toute fin: +### Créer un virtualenv sur PythonAnywhere - from whitenoise.django import DjangoWhiteNoise - application = DjangoWhiteNoise(application) +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 whitenoise + Collecting django + [...] + Successfully installed django-1.8.2 whitenoise-2.0 -Hop, on enchaine! +> **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. -## Se créer un compte sur Heroku + -Pour continuer, vous allez devoir installer la toolbelt Heroku qui se trouve ici: https://toolbelt.heroku.com/. Vous pouvez passer cette partie si vous l'avez déjà installé avec votre coach. +### Collecter les fichiers statiques. -> Lorsque vous lancez l'installation de la toolbelt d'Heroku sous Windows, n'oubliez pas de choisir "Custom Installation" (installation personnalisée) lorsque l'on vous demandera quels composants vous souhaitez installer. N'oubliez pas de cocher "Git and SSH" dans la liste des composants disponibles à l'installation. -> -> Sous Windows, vous avez aussi besoin de lancer la commande suivante afin que Git et SSH soient ajoutés au `PATH` de votre prompt: `setx PATH "%PATH%;C:\Program Files\Git\bin"`. Relancez votre console afin que les changements soient pris en compte. +Mais qu'est-ce que "whitenoise" ? C'est un outil qui permet de servir des "fichiers statiques". Les fichiers statiques sont des fichiers qui ne changement que très rarement ou qui n’exécutent pas de code de programmation. C'est le cas des fichiers HTML ou CSS. Les fichiers statiques ne se comportent pas de la même façon sur un serveur et sur votre ordinateur : nous avons besoin d'un outil comme "whitenoise" pour qu'ils soient servis. -Il vous sera nécessaire de vous créer un compte gratuit sur Heroku. Vous pouvez le faire à cette adresse: https://id.heroku.com/signup/www-home-top +Pour le moment, vous n'avez pas besoin d'en savoir plus ! Ne vous inquiétez pas : nous reviendrons plus tard sur les fichiers statiques (partie CSS). L'objectif de ce chapitre est de poser toutes les bases nécessaires au déploiement pour passer rapidement à la suite :) -Ensuite, authentifiez votre compte Heroku sur votre ordinateur en lançant la commande suivante: +Pour l'instant, il ne nous reste juste qu'à exécuter une dernière commande sur notre serveur : `collectstatic`. Cette instruction va permettre à Django de rassembler tous les fichiers statiques dont il va avoir besoin sur le serveur. Pour le moment, il s'agit surtout des fichiers qui servent à rendre l'interface d'administration plus jolie. - $ heroku login + (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 -Si vous n'avez pas encore de clef SSH, cette commande va vous permettre d'en créer une automatiquement. Les clefs SSH sont obligatoires afin de pusher du code sur Heroku. +Tapez "yes", et c'est parti ! Personnellement, j'adore accompagner l'affichage de ces longues listes de texte impénétrable par un bruit de vieille imprimante : brp, brp, brp... -## Git + 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'. + -Git est un logiciel de gestion de versions décentralisé utilisé par de nombreux·ses programmeurs⋅ses. C'est un logiciel qui permet de garder un historique des changements d'un ou plusieurs fichiers: cela permet d'aller rechercher une version antérieure plus tard. Heroku utilise un repository git pour gérer les fichiers de votre projet. Nous allons donc devoir nous aussi l'utiliser. +### Créer une base de données sur PythonAnywhere -Créez un fichier `.gitignore` dans votre dossier `djangogirls` et copiez y le contenu suivant: +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 et les mêmes posts sur votre ordinateur et sur PythonAnywhere. - myvenv - __pycache__ - staticfiles - local_settings.py - db.sqlite3 +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 -Sauvegardez ce fichier. Le point au début du nom de fichier est important! Comme vous pouvez le voir, nous disons à Heroku d'ignorer le fichier `local_settings.py` et de ne pas le télécharger. Il ne sera disponible que sur votre ordinateur (localement). +## Faire de votre blog une application web -Ensuite, nous allons créer un nouveau repository git et sauvegarder nos changements. Prenez votre console et lancez les commandes suivantes: +Maintenant, notre code est sur PythonAnywhere, notre virtualenv est prêt, les fichiers statiques sont recueillis et la base de données est initialisé. Nous sommes prêts à le publier comme une application web ! - $ git init - Initialized empty Git repository in ~/djangogirls/.git/ - $ git config user.name "Votre nom" - $ git config user.email you@example.com - +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**. -Initialiser le repository git est quelque chose qu'il est nécessaire de ne faire qu'une fois par projet. +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. -Enfin, sauvegardons nos changements. Une nouvelle fois, prenez votre console et lancez les commandes suivantes: +> **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 ;-) - $ git add -A . - $ git commit -m "My Django Girls app" - [master (root-commit) 2943412] My Django Girls - 7 files changed, 230 insertions(+) - create mode 100644 .gitignore - create mode 100644 Procfile - create mode 100644 mysite/__init__.py - create mode 100644 mysite/settings.py - create mode 100644 mysite/urls.py - create mode 100644 mysite/wsgi.py - create mode 100644 manage.py - create mode 100644 requirements.txt - create mode 100644 runtime.txt - +### Configurer le virtualenv -## Trouver un nom à son application +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. -Nous allons rendre votre blog accessible en ligne à l'adresse `[nom de votre blog].herokuapp.com`. Pour cela, il va être nécessaire de choisir un nom qui n'est pas encore pris. Ce nom n'a pas besoin d'être en lien avec l'application `blog` de Django, `mysite`, où n'importe quoi d'autre que nous avons pu créer jusqu'à présent. Vous pouvez choisir le nom que vous voulez, tant qu'il est conforme aux règles strictes définies par Heroku: pas de majuscules, pas d'accents, pas de nombres ni de tirets (`-`). +![][7] -Si vous ne savez pas quoi prendre, pourquoi ne pas chercher quelque chose en rapport avec votre nom ou votre surnom? Une fois que vous avez choisi, lancez cette commande en remplaçant `djangogirlsblog` par le nom de votre application: + [7]: images/pythonanywhere_web_tab_virtualenv.png - $ heroku create djangogirlsblog - +Dans la section "Virtualenv", cliquez sur le texte en rouge qui indique "Enter the path to a virtualenv" (ajouter le chemin d'accès de votre environnement virtuel), et ajouter ceci : */home/nomdutilisateur/my-first-blog/myvenv/*. Cliquez sur la boite bleue avec la case à cocher pour sauvegarder le chemin d’accès. -> **Note**: N'oubliez pas de remplacer `djangogirlsblog` avec le nom de votre application sur Heroku. +> **Note** : N'oubliez pas de mettre votre nom d'utilisateur. Ne vous inquiétez pas : si vous faites une erreur, PythonAnywhere vous le signalera. -Si jamais vous n'avez vraiment pas d'idées de nom, vous pouvez lancer cette commande: +### Configurer le fichier WSGI - $ heroku create - +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. -Heroku choisira alors un nom pour vous. Ce sera probablement quelque chose de l'ordre de `enigmatic-cove-2527`). +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. -Si jamais vous avez envie de changer le nom de votre application Heroku, vous pouvez le faire facilement et quand vous voulez en tapant cette commande (n'oubliez pas de remplacer `the-new-name` par le nouveau nom que vous avez choisi): +Supprimer le contenu du fichier et le remplacer par ce qui suit : - $ heroku apps:rename the-new-name - +```python +import os +import sys -> **Note**: N'oubliez pas que lorsque vous aurez changer le nom de votre application, elle ne sera plus disponible à l'ancienne adresse, mais à `[the new name].herokuapp.com`. +path = '/home//my-first-blog' # remplacer your-username par votre nom d’utilisateur +if path not in sys.path: + sys.path.append(path) -## Déployer sur Heroku! +os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' -Nous venons de consacrer énormément de temps à configurer et à installer des choses mais rassurez vous, vous n'avez besoin de faire tout cela qu'une seule fois! Maintenant, nous allons enfin pouvoir passer au déploiement! +from django.core.wsgi import get_wsgi_application +from whitenoise.django import DjangoWhiteNoise +application = DjangoWhiteNoise(get_wsgi_application()) +``` -Lorsque vous lancez `heroku create`, Heroku est alors ajouté à la liste des repository distants. Par conséquent, nous n'avons plus qu'à faire un simple git push pour déployer notre application: +> **Note** : N'oubliez pas de remplacer `` par votre nom d'utilisateur - $ git push heroku master - +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. Cela permet aussi de configurer l'outil "whitenoise" qui s'occupe des fichiers statiques. -> **Note**: il est probable que cela produise *énormément* d'output (sortie) la première fois que vous lancez cette commande car Heroku va installer et compiler psycopg. Pour savoir si ça a marché, vous allez voir apparaitre `https://yourapplicationname.herokuapp.com/ deployed to Heroku` vers la fin de l'output. +Cliquez sur **Save** puis, retournez dans l'onglet **Web**. -## Consulter son application +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. -Tout ce que vous venez de faire vous a permis de déployer votre code sur Heroku. Vous avez aussi spécifié le type de processus dans le fichier `Procfile`: rappelez vous, nous avons choisi le processus de type `web` tout à l'heure. Maintenant, nous pouvons dire à Heroku de lancer ce `processus web`. +## Conseils en cas de bug -Pour cela, tapez la commande suivante: +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: - $ heroku ps:scale web=1 - + [8]: https://www.pythonanywhere.com/web_app_setup/ -Cela dit à Heroku de lancer une seule instance de notre processus `web`. Comme l'application blog que nous avons créée est relativement simple, nous n'avons pas besoin d'énormément de ressources. Un seul processus devrait faire l'affaire. Il est possible de demander à Heroku de lancer plusieurs processus (appelés "Dynos" sur Heroku) mais cette option est payante. +* 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. -Maintenant, vous pouvez aller sur votre app dans votre navigateur à l'aide de la commande `heroku open`. +* 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. - $ heroku open - +* 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"? -> **Note**: vous allez rencontrer une page d'erreur! Pas de soucis, nous allons y venir dans un instant. +* Se tromper de version de Python : votre environnement virtuel et votre application web doivent toutes les deux être sous Python 3.4. -Cette commande va ouvrir une url du type [https://djangogirlsblog.herokuapp.com/]() dans votre navigateur qui affichera une page d'erreur. Nous n'avons, pour l'instant, que créé l'interface d'administration de notre site. Essayez d'ajouter `admin/` à la fin de l'url ([https://djangogirlsblog.herokuapp.com/admin/]()). Cette page doit normalement fonctionner :) +* Il y a quelques [astuces générales de débogage sur le wiki PythonAnywhere][9]. -L'erreur que vous venez de voir est liée au fait que lorsque nous avons déployé notre application sur Heroku, nous avons créé une base de données vide. Pour cela, nous avons besoin de lancer la commande ~~~ migrate~~~ comme lorsque nous avons démarré notre projet pour la première fois. Cela permettra de générer notre base de données correctement: + [9]: https://www.pythonanywhere.com/wiki/DebuggingImportError - $ heroku run python manage.py migrate - - $ heroku run python manage.py createsuperuser - +Et n'oubliez pas, votre coach est là pour vous aider ! + +# Votre site est en ligne ! + +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. -Normalement, votre site web devrait maintenant pouvoir se charger dans votre navigateur! Félicitations! :) +*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 \ 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 new file mode 100644 index 00000000000..44412f84823 Binary files /dev/null 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 new file mode 100644 index 00000000000..6e19174ec88 Binary files /dev/null and b/fr/deploy/images/new_github_repo.png differ diff --git a/fr/deploy/images/pythonanywhere_web_tab_virtualenv.png b/fr/deploy/images/pythonanywhere_web_tab_virtualenv.png new file mode 100644 index 00000000000..cafa22c2d97 Binary files /dev/null and b/fr/deploy/images/pythonanywhere_web_tab_virtualenv.png differ diff --git a/fr/deploy/install_git.md b/fr/deploy/install_git.md new file mode 100644 index 00000000000..c3dc9051474 --- /dev/null +++ b/fr/deploy/install_git.md @@ -0,0 +1,15 @@ +### Windows + +Vous pouvez télécharger Git sur [git-scm.com](http://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. + +### MacOS + +Vous pouvez télécharger Git sur [git-scm.com](http://git-scm.com/). Pour le reste de l'installation, suivez simplement les instructions de l'installateur. + +### Linux + +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 \ No newline at end of file diff --git a/fr/deploy/signup_pythonanywhere.md b/fr/deploy/signup_pythonanywhere.md new file mode 100644 index 00000000000..3b6e7b711a2 --- /dev/null +++ b/fr/deploy/signup_pythonanywhere.md @@ -0,0 +1,5 @@ +Si vous ne l'avez pas encore fait, n'oubliez pas de vous créer un compte "Beginner" sur PythonAnywhere. + + * [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +> **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 diff --git a/fr/django/README.md b/fr/django/README.md index da985f860f9..de6a356e717 100755 --- a/fr/django/README.md +++ b/fr/django/README.md @@ -1,27 +1,27 @@ -# Django? +# Qu'est-ce que Django? -Django (*/ˈdʒæŋɡoʊ/ jang-goh*) est un framework web gratuit et libre écrit en Python. C'est un framework web, c'est-à-dire 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 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. -Quand vous construisez un site web, vous avez toujours besoin des mêmes composants de base: quelque chose pour que les utilisateurs puissent se connecter (s'inscrire, se connecter, se déconnecter), une partie administration, des formulaires, un moyen d'uploader des fichiers, etc. +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 personnes se sont aussi rendues compte de ce problème. Elles se sont alliées avec des développeurs et ont créé différents frameworks, dont Django, pour fournir un set de composants de base qui fonctionnent et qui peuvent être utilisés lors de la création d'un site web. +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. -Les frameworks existent pour vous éviter de réinventer la roue à chaque fois. Ils vous aident aussi à mettre facilement en place tous les éléments dont vous pourriez avoir besoin avant de vous lancer dans la création de votre site. +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. -## Pourquoi est-ce que vous auriez besoin d'un framework? +## Pourquoi est-ce que vous auriez besoin d'un framework ? -Pour comprendre ce qu'est exactement Django, nous avons besoin de nous intéresser aux différents rôles des serveurs. 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 à 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. -Imaginez que vous ayez une boîte aux lettres (port) qui serait surveillée afin de recevoir des lettres (requêtes). C'est ce que fait un 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 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. -## Qu'est-ce qui se passe quand quelqu'un demande un site web sur votre serveur? +## 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)*). -Ce serait comme une postière qui descendrait la rue avec une lettre et qui vérifierait à chaque maison si le numéro de celle-ci correspond à celui inscrit sur l'enveloppe. Dès que c'est le cas, elle dépose l'enveloppe dans la boîte aux lettres correspondante. C'est de cette manière que fonctionne l'urlresolver! +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 ! -C'est dans la fonction *vue* que les choses intéressantes se passent: c'est à ce moment qu'on regarde dans la base de données à la recherche d'informations dont on a besoin. 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 *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. -Bien sûr, 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. +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. -Maintenant, nous aurions la possibilité de vous assommer de détails compliqués 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? +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 ? \ No newline at end of file diff --git a/fr/django_admin/README.md b/fr/django_admin/README.md index 4079c96116b..c4240600cbd 100755 --- a/fr/django_admin/README.md +++ b/fr/django_admin/README.md @@ -2,9 +2,9 @@ Pour ajouter, éditer et supprimer les posts que nous venons de modéliser, nous allons utiliser l'interface d'administration de Django. -Ouvrons le fichier `blog/admin.py` et remplaçons son contenu par ceci: +Ouvrons le fichier `blog/admin.py` et remplaçons son contenu par ceci : -``` +```python from django.contrib import admin from .models import Post @@ -13,28 +13,21 @@ 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)`. -Ok, allons voir notre modèle « Post ». N'oubliez pas de lancer le server web en tapant `python manage.py runserver` dans la console. À l'aide de votre navigateur, allez à l'adresse suivante: - -``` -http://127.0.0.1:8000/admin/ -``` - -Vous verrez une page de login qui ressemble à 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. Dans votre navigateur, entrez l'adresse <0>http://127.0.0.1:8000/admin/. Si tout va bien, vous verrez une page comme celle-ci: ![Page de login][1] [1]: images/login_page2.png -Afin de pouvoir vous connecter, vous avez besoin de créer un *superuser ou superutilisateur*. C'est un utilisateur qui peut contrôler l'intégralité du site. Reprenez votre ligne de commande et taper `python manage.py createsuperuser` et appuyez sur entrée. Tapez votre nom d'utilisateur (en minuscules, sans espace), votre email et votre mot de passe lorsqu'on vous le demande. Ce qui apparaît dans votre console doit ressembler à ceci, au détail près que « username » et « email » doivent être ceux que vous avez entrés: +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. -``` -(myvenv) ~/djangogirls$ python manage.py createsuperuser -Username: admin -Email address: admin@admin.com -Password: -Password (again): -Superuser created successfully. -``` + (myvenv) ~/djangogirls$ python manage.py createsuperuser + Username: admin + Email address: admin@admin.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. @@ -42,14 +35,14 @@ Retournez dans votre navigateur et connectez-vous en tant que superutilisateur g [2]: images/django_admin3.png -Allez dans la partie "Post" et bidouillez un peu. Ajoutez 5 à 6 posts par exemple. N'accordez pas d'importance à leur contenu: vous pouvez tout simplement copier-coller le texte de ce tutoriel dans vos posts pour gagner du temps :). +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 :). -Ajoutez une date de publication à au moins deux ou trois posts sur tous ceux que vous venez de créer: nous en aurons besoin pour la suite. +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. ![Django admin][3] [3]: images/edit_post3.png -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/1.7/ref/contrib/admin/ +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.8/ref/contrib/admin/ -C'est probablement le bon moment de faire une pause et d'aller vous chercher un café (ou un thé) et quelque chose à grignoter: vous venez de créer votre premier modèle Django! Vous méritez bien une petite récompense! +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 ! \ No newline at end of file diff --git a/fr/django_forms/README.md b/fr/django_forms/README.md index b736be5390a..a946a7c38ad 100755 --- a/fr/django_forms/README.md +++ b/fr/django_forms/README.md @@ -1,12 +1,12 @@ # Formulaires Django -La dernière chose que nous voulons faire sur notre site web, c'est de créer une manière sympathique d'ajouter ou é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` 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 ! 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. -C'est exactement ce que nous voulons faire: nous allons créer un formulaire pour notre modèle `Post`. +C'est la seconde solution que nous allons utiliser pour créer un formulaire pour notre modèle `Post`. -Comme toutes les choses qui sont importantes dans Django, les formulaires ont leur propre fichier: `forms.py`. +Comme toutes les choses importantes dans Django, les formulaires ont leur propre fichier : `forms.py`. Nous allons devoir créer un fichier avec ce nom dans notre dossier `blog`. @@ -14,43 +14,43 @@ Nous allons devoir créer un fichier avec ce nom dans notre dossier `blog`. └── forms.py -Ouvrons maintenant ce fichier et tapons le code suivant: +Ouvrez maintenant ce fichier et tapez le code suivant : - from django import forms - - from .models import Post - - class PostForm(forms.ModelForm): - - class Meta: - model = Post - fields = ('title', 'text',) - +```python +from django import forms + +from .models import Post -Nous avons besoin tout d'abord d'importer les formulaires Django (`from django import forms`), puis, évidemment, nous avons besoin de notre modèle `Post` (`from .models import Post`). +class PostForm(forms.ModelForm): -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`. Nous utilisons `forms.ModelForm` pour cela. + class Meta: + model = Post + 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`). + +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`. 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`). -Enfin, nous précisions quels sont le⋅s champ⋅s qui doivent figurer dans notre formulaire. Dans notre cas, nous souhaitons que seul `title` et `text` apparaissent dans notre formulaire, car nous obtiendrons les autres données différemment. En effet, nous nous attendons à ce qu'`author` soit le nom de la personne connectée (en l’occurrence, vous! ) et `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 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). -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. +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. -Nous allons donc une nouvelle fois suivre le processus suivant et créer: un lien vers la page, une URL, une vue et un template. +Nous allons donc une nouvelle fois suivre le processus suivant et créer : un lien vers la page, une URL, une vue et un template. ## 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`: +C'est le moment d'ouvrir le fichier `blog/templates/blog/base.html`. Nous allons ajouter un lien dans un `div` appelé `page-header` : ```html - -``` - + +``` Remarquez que notre nouvelle vue s'appelle `post_new`. -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 : ```html {% load staticfiles %} @@ -59,13 +59,12 @@ Après avoir ajouté cette ligne, votre fichier html devrait maintenant ressembl Django Girls blog -
@@ -80,59 +79,63 @@ Après avoir ajouté cette ligne, votre fichier html devrait maintenant ressembl ``` -Normalement, après avoir rechargé la page `http://127.0.0.1:8000`, vous devriez encore tomber sur l'erreur `NoReverseMatch`. +Sauvegardez votre fichier et rafraîchissez la page http://127.0.0.1:8000 : vous devez normalement tomber encore une fois sur l'erreur `NoReverseMatch` ! ## URL -Ouvrez le fichier `blog/urls.py` et ajoutez cette ligne: +Ouvrez le fichier `blog/urls.py` et ajoutez cette ligne : +```python url(r'^post/new/$', views.post_new, name='post_new'), - +``` -Votre fichier doit maintenant ressembler à ceci: +Votre fichier doit maintenant ressembler à ceci : - from django.conf.urls import patterns, include, url - from . import views - - urlpatterns = patterns('', - url(r'^$', views.post_list), - url(r'^post/(?P[0-9]+)/$', views.post_detail), - url(r'^post/new/$', views.post_new, name='post_new'), - ) - +```python +from django.conf.urls import include, 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'), +] +``` -Une fois la page rechargée, vous allez voir une `AttributeError`, ce qui est normal, car nous n'avons pas encore de vue `post_new` implémentée. 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ée la vue `post_new`. Allons nous occuper de ça maintenant. ## La vue post_new -Ouvrons maintenant le fichier `blog/views.py` et ajoutez les lignes suivantes sous celles existantes: +Ouvrez maintenant le fichier `blog/views.py` et ajoutez les lignes suivantes avec celles du `from` qui existent déjà : - from .forms import PostForm - +```python +from .forms import PostForm +``` -Puis ajoutez la *vue*: +Puis ajoutez la *vue* : - def post_new(request): - form = PostForm() - return render(request, 'blog/post_edit.html', {'form': form}) - +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` Afin de pouvoir créer un nouveau formulaire `Post`, nous avons besoin d'appeler la fonction `PostForm()` et de la passer au template. Nous reviendrons modifier cette *vue* plus tard, mais pour l'instant, créons rapidement un template pour ce formulaire. ## Template -Nous avons pour cela 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: +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 besoin d'afficher le formulaire. Pour cela, nous n'avons qu'à utiliser `{{ form.as_p }}`. -* 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 avons besoin d'ajouter `{% raw %}{% csrf_token %}{% endraw %}` juste après la balise `
`. C'est très important: c'est ce qui va permettre de sécuriser votre formulaire! De toute manière, si vous avez oublié ce petit morceau, Django va se plaindre lors de la sauvegarde du formulaire: +* 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 : ![CSFR Forbidden page][1] [1]: images/csrf2.png -Ok, voyons maintenant à quoi devrait ressembler le fichier `post_edit.html`: +Ok, voyons maintenant à quoi devrait ressembler le fichier `post_edit.html` : ```html {% extends 'blog/base.html' %} @@ -145,102 +148,110 @@ Ok, voyons maintenant à quoi devrait ressembler le fichier `post_edit.html`:
{% endblock %} ``` - -Rafraîchissons la page! Et voilà: le formulaire s'affiche! +Rafraîchissons la page ! Et voilà : le formulaire s'affiche ! ![Nouveau formulaire][2] [2]: images/new_form2.png -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? +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éé. Est-ce que nous venons de rencontrer un bug? +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é ? -Heureusement non! Nous avons juste encore un peu de travail à accomplir. Retournons à notre *vue*. +La réponse est : rien ! Nous avons juste encore un peu de travail à accomplir. Retournons à notre *vue*. ## Sauvegarder le contenu du formulaire -Ouvrez à nouveau le fichier `blog/views.py`. Pour le moment, le contenu de notre vue `post_new` se limite à ceci: +Ouvrez à nouveau `blog/views.py`. Actuellement, `post_new` n'est composé que des lignes de code suivantes : - def post_new(request): - form = PostForm() - return render(request, 'blog/post_edit.html', {'form': form}) - +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` -Ainsi, lorsque nous soumettons notre formulaire, nous revenons à la même vue, mais cette fois, nous avons un peu plus de données dans `request` ou, plus précisément, dans `request.POST`. Est-ce que vous vous souvenez avoir 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 avons plus 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. -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)`). +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). - if request.method == "POST": - [...] - else: - form = PostForm() - +```python +if request.method == "POST": + [...] +else: + form = PostForm() +``` -Attaquons nous à remplir ces `[...]`. Comme la `method` est `POST`, c'est que nous voulons construire notre `PostForm` avec les données de notre formulaire. Pour cela, nous devons ajouter: +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 : - form = PostForm(request.POST) - +```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 sont bien remplis et qu'aucune donnée incorrecte ne soient sauvegardée. Nous allons utiliser `form.is_valid()`. +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 soient sauvegardée. Pour cela, nous allons utiliser `form.is_valid()`. -Testons donc si notre formulaire est valide et, si c'est le cas, sauvegardons-le! +Testons donc si notre formulaire est valide et, si c'est le cas, sauvegardons-le ! - if form.is_valid(): - post = form.save(commit=False) - post.author = request.user - post.save() - +```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 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 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éé ! -Enfin, ce serait génial si nous pouvions tout de suite obtenir la page `post_detail` pour le blog post que nous venons de créer. Pour cela, nous avons besoin d'un dernier "import": +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 : - from django.shortcuts import redirect - +```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 page. Maintenant, nous allons ajouter la ligne qui signifie : "aller à la page `post_detail` pour le nouveau post qui vient d'être créé". - return redirect('blog.views.post_detail', pk=post.pk) - +```python +return redirect('blog.views.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éé! - -Et si au lieu de parler, nous vous montrons à quoi ressemble maintenant notre *vue*? - - 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.save() - return redirect('blog.views.post_detail', pk=post.pk) - else: - form = PostForm() - return render(request, 'blog/post_edit.html', {'form': form}) - +`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éé ! -Voyons si ça marche. Allez à la page `http://127.0.0.1:8000/post/new/`. Ajoutez un `title` et du `text` et sauvegardez votre formulaire ... Et voilà! Le nouveau post est bien créé et vous êtes redirigé vers la page `post_detail`! +Et si au lieu de parler, nous vous montrions à quoi ressemble maintenant notre *vue* ? -Vous avez peut-être remarqué que nous ne nous sommes pas du tout occupé de la date de publication de nos posts? Nous nous occuperons d'ajouter un *publish button (bouton de publication)* dans la partie **Tutoriel Django Girls: exercices supplémentaires**. +```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}) +``` + +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` ! -Est-ce que ce n'est pas déjà génial tout ce que nous avons accompli ensemble aujourd'hui? +Vous avez peut-être remarqué que nous avons choisit 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). + +Encore bravo ! ## Validation de formulaire -Maintenant, nous allons vous montrer à quel point les formulaires Django sont cools! Un blog post a besoin de champs `title (titre)` et `text (texte)`. Comme nous n'avons pas signalé dans notre modèle `Post` que ces deux champs n'étaient pas obligatoire (à l'inverse du cas de `published_date`) Django s'attend à ce qu'ils soient remplis à chaque fois. +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! +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 -Django va s'occuper de la validation: il va regarder si tous les champs de notre formulaire sont en adéquation avec le modèle. C'est cool, non? +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 avez une erreur lors de la création de post qui fait référence au fait que vous ne pouvez pas faire cette action car vous n'êtes pas connecté, allez faire un tour dans l'interface d'administration `http://127.0.0.1:8000/admin`. Cela vous obligera forcément à vous connecter. Cependant, vous devinez bien que cette solution n'est pas bonne sur le 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. +> 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] @@ -248,97 +259,138 @@ Django va s'occuper de la validation: il va regarder si tous les champs de notre ## Éditer un formulaire -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. +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 le fichier `blog/templates/blog/post_detail.html` et ajoutez la ligne suivante: +Ouvrez le fichier `blog/templates/blog/post_detail.html` et ajoutez la ligne suivante : -```html +```python ``` -Votre template doit ressembler à ceci: +Votre template doit ressembler à ceci : ```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|linebreaks }}

-

{{ post.title }}

-

{{ post.text|linebreaks }}

{% endblock %} ``` - -Maintenant, dans `blog/urls.py`, ajoutez cette ligne: +Maintenant, dans `blog/urls.py`, ajoutez cette ligne : +```python url(r'^post/(?P[0-9]+)/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: - - 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}) - +Ouvrons `blog/views.py` et ajoutons à la toute fin du fichier : -Vous ne trouvez pas que ça ressemble presque à 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 faisons deux fois de ce post une `instance`. Tout d'abord lorsque nous sauvegardons le formulaire: +```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}) +``` - form = PostForm(request.POST, instance=post) - +Vous ne trouvez pas que ça ressemble presque à 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 faisons de ce post deux `instances`. Tout d'abord lorsque nous sauvegardons le formulaire : + +```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 : - form = PostForm(instance=post) - +```python +form = PostForm(instance=post) +``` -Alors, voyons si ça marche! Allons sur la page `post_detail`. Un bouton d'édition devrait apparaître dans le coin supérieur droit de la page: +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 : ![Bouton d'édition][5] [5]: images/edit_button2.png -Lorsque vous cliquez dessus, vous devez voir le formulaire du blog post apparaître: +Lorsque vous cliquez dessus, vous devez voir le formulaire du post de blog apparaitre : ![Éditer un formulaire][6] [6]: images/edit_form2.png -Essayez de manipuler un peu ce que vous venez de créer: ajoutez du texte, changez le titre puis sauvegardez ces changements! +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é ! + +Si jamais vous voulez en savoir plus sur les formulaire dans Django, n'hésitez pas à lire la documentation associée : https://docs.djangoproject.com/fr/1.8/topics/forms/ -Bravo! Votre application se complexifie et contient de plus en plus de fonctionnalité! +## Sécurité -Si vous souhaitez en apprendre plus sur les formulaires Django, n'hésitez pas à consulter la documentation associée: https://docs.djangoproject.com/en/1.7/topics/forms/ +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. -## Encore un petit effort: déployons! +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 : + +```html + +``` -Ce serait génial si nous pouvions aller sur notre site web hébergé sur Heroku et voir toutes ces nouvelles fonctionnalités! Remontons nos manches et déployons encore une fois. Si vous ne vous souvenez plus de ce que fait chaque commande, consultez la fin du chapitre 15: +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 : -```bash -$ git status -... -$ git add -A . -$ git status -... -$ git commit -m "Ajout des vues qui permettent d'ajouter et éditer des blog posts directement sur le site" -... -$ git push heroku master +```html +{% if user.is_authenticated %} + +{% 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. + +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 ! + +## Encore un petit effort : déployons ! + +Nos modifications fonctionnent-elles sur PythonAnywhere ? Pour le savoir, déployons à nouveau ! + +* Tout d'abord, commiter votre nouveau code et pusher le à nouveau sur Github + + $ git status + $ git add -A . + $ 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 -Normalement, ça devrait suffire! Encore bravo :) +* Puis, dans la console bash de [PythonAnywhere][7]: + + [7]: https://www.pythonanywhere.com/consoles/ + + $ cd my-first-blog + $ source myvenv/bin/activate + (myvenv)$ git pull + [...] + (myvenv)$ python manage.py collectstatic + [...] + + +* Enfin, cliquez sur l'onglet [Web][8] et cliquez sur **Reload**. + + [8]: https://www.pythonanywhere.com/web_app_setup/ + +Normalement, ça devrait suffire ! Encore bravo :) \ No newline at end of file diff --git a/fr/django_installation/README.md b/fr/django_installation/README.md index 677ab2293b8..c775ee7bbc4 100755 --- a/fr/django_installation/README.md +++ b/fr/django_installation/README.md @@ -1,113 +1,5 @@ # Installation de Django -> Note: ce chapitre est en partie inspiré d'un autre tutoriel réalisé par les Geek Girls Carrots (http://django.carrots.pl/). -> -> Ce chapitre est en partie inspiré du [tutoriel django-marcador][1] 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. +> **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 ! - [1]: http://django-marcador.keimlink.de/ - -## L'environnement virtuel - -Avant d'installer Django, nous allons vous faire installer un outil extrêmement utile qui vous aidera à maintenir votre environnement de développement propre. Vous pouvez sauter cette partie, mais nous vous le déconseillons: bien préparer votre ordinateur vous épargnera de nombreux problèmes par la suite! - -Donc, commençons par créer un **environnement de développement** (ou *virtualenv*). Cela va vous permettre, pour chaque projet, d'isoler votre installation Python/Django afin que les modifications que vous souhaitiez effectuer sur un site n'affectent pas les autres que vous seriez en train de développer à cô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:\Users\Name` (où `Name` est votre login). - -Dans ce tutoriel, nous allons utiliser le nouveau dossier `djangogirls` que vous allez créer dans votre dossier home: - - mkdir djangogirls - cd djangogirls - - -Nous allons créer un virtualenv appelé `myvenv`. Pour cela, nous taperons une commande qui ressemblera à: - - python -m venv myvenv - - -### Windows - -Afin de créer un nouveau `virtualenv`, vous avez besoin d'ouvrir votre console (on vous en a parlé précédemment, est-ce que vous vous en souvenez?) et tapez `C:\Python34\python -m venv myvenv`. Ça ressemblera à ça: - - C:\Users\Name\djangogirls> C:\Python34\python -m venv myvenv - - -`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 le nom que vous voulez, 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! - -### 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: - - ~/djangogirls$ python3 -m venv myvenv - - -`myvenv` est le nom de votre `virtualenv`. Vous pouvez choisir le nom que vous voulez, 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: -> -> 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 -> - -## 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. Tout ce que nous avons à faire maintenant, c'est de le lancer en tapant: - - C:\Users\Name\djangogirls> myvenv\Scripts\activate - - -sous Windows, ou: - - ~/djangogirls$ source myvenv/bin/activate - - -sous Linux et OS X. - -N'oubliez pas que si vous avez choisi un autre nom pour votre `virtualenv` à la place de `myvenv`, vous devez utiliser celui-là! - -> **NOTE:** il arrive parfois que `source` ne soit pas disponible. Dans ce cas, vous pouvez essayer ceci: -> -> ~/djangogirls$ . myvenv/bin/activate -> - -Vous saurez que votre `virtualenv` est lancé quand le prompt de votre console ressemblera à ceci: - - (myvenv) C:\Users\Name\djangogirls> - - -ou: - - (myvenv) ~/djangogirls$ - - -Remarquez le préfixe `(myvenv)` qui vient d'apparaître! - -Quand vous travaillez dans un environnement virtuel, la commande `python` fera automatiquement référence à la bonne version de Python que vous utilisez. Vous pouvez ainsi utiliser `python` à la place de la commande `python3`. - -Ok, nous avons installé toutes les dépendances dont nous avions besoin. Nous allons enfin pouvoir installer Django! - -## Installation de Django - -Maintenant que notre `virtualenv` est lancé, nous pouvons installer Django en utilisant `pip`. Dans la console, tapez `pip install django==1.7.1` (notez que nous utilisons un double signe égal): `==`). - - (myvenv) ~$ pip install django==1.7.1 - Downloading/unpacking django==1.7.1 - Installing collected packages: django - Successfully installed django - Cleaning up... - - -Sous Windows: - -> Si vous obtenez une erreur en utilisant pip sous Windows, vérifiez si le chemin d'accès de votre projet ne contient pas des espaces (par exemple: `C:\Users\User Name\djangogirls`). Si c'est le cas, il vaudrait peut-être mieux changer l'emplacement de votre projet afin de ne plus avoir de chemin d'accès avec des espaces (par exemple: `C:\djangogirls`). Après l'avoir déplacé, essayez de retaper la commande précédente. - -Sous Linux: - -> 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êt⋅e à créer votre première application en Django! Pour cela, vous allez avoir besoin d'un programme sympathique pour y écrire votre code... +{% 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 new file mode 100644 index 00000000000..7635ca180e9 --- /dev/null +++ b/fr/django_installation/instructions.md @@ -0,0 +1,113 @@ +> Note : ce chapitre est en partie inspiré d'un autre tutoriel réalisé par les Geek Girls Carrots (http://django.carrots.pl/). +> +> 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 + +Avant d'installer Django, nous allons vous faire installer un outil extrêmement utile qui vous aidera à maintenir votre environnement de développement propre. Nous vous recommandons fortement de ne pas sauter cette étape, même si elle n'est pas indispensable. En commençant avec la meilleure configuration possible vous éviterez beaucoup de problèmes par la suite ! + +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). + +Dans ce tutoriel, nous allons utiliser un nouveau dossier `djangogirls` que vous allez créer dans votre dossier home : + + mkdir djangogirls + cd djangogirls + + +Nous allons créer un virtualenv appelé `myvenv`. Pour cela, nous taperons une commande qui ressemblera à : + + python3 -m venv myvenv + + +### Windows + +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 : + + C:\Utilisateurs\Nom\djangogirls> C:\Python34\python -m venv myvenv + + +`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 : + + ~/djangogirls$ 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 : +> +> 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 +> + +## 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 : + + C:\Utilisateurs\Nom\djangogirls> myvenv\Scripts\activate + + +#### Linux et OS X + +Démarrez votre environnement virtuel en exécutant : + + ~/djangogirls$ 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 +> + +Vous saurez que votre `virtualenv` est lancé quand le prompt de votre console ressemblera à ceci : + + (myvenv) C:\Utilisateurs\Nom\djangogirls> + + +ou : + + (myvenv) ~/djangogirls$ + + +Vous remarquez que le préfixe `(myvenv)` est apparu ! + +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`. + +Ok, nous avons installé toutes les dépendances dont nous avions besoin. Nous allons enfin pouvoir installer Django ! + +## Installation de Django + +Maintenant que vous avez lancé votre `virtualenv`, vous pouvez installer Django à l'aide de `pip`. Dans votre console, tapez `pip install django==1.8`. Notez bien que nous utilisons un double signe égal : `==`). + + (myvenv) ~$ pip install django==1.8 + Downloading/unpacking django==1.8 + Installing collected packages: django + Successfully installed django + Cleaning up... + + +Sous Windows : + +> 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 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 ! \ No newline at end of file diff --git a/fr/django_models/README.md b/fr/django_models/README.md index 06ac6670b2b..578f15e7dc8 100755 --- a/fr/django_models/README.md +++ b/fr/django_models/README.md @@ -1,16 +1,16 @@ # Les modèles dans Django -Maintenant, ce qu'on veut, c'est un moyen de stocker les articles de notre blog. Mais, pour pouvoir faire ça, on doit tout d'abord 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 -Il y a un concept en programmation qu'on appelle la `programmation orientée objets`. L'idée, c'est de modéliser les choses et de définir comment elles interagissent entre elles plutôt que de tout voir comme une séquence d'instructions. +Il existe un concept en programmation qu'on appelle la `programmation orientée objets`. L'idée, c'est de modéliser les choses et de définir comment elles interagissent entre elles plutôt que de tout voir comme une séquence d'instructions. -Du coup, c'est quoi un objet? C'est une collection de propriétés et d'actions. Ça a l'air bizarre. Un exemple va nous permettre d'y voir plus clair. +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 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. -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 un objet `NourriturePourChat`, qui peut lui aussi avoir ses propres propriétés, comme le `goût`). Chat -------- @@ -30,11 +30,11 @@ Ensuite, nous pouvons donner des actions au `Chat`: `ronronner`, `gratter` ou `m 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! +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éponde à la question: qu'est-ce qu'un article de blog? Quelles propriétés a-t-il? +Pour ça, il faut réponde à la question : qu'est-ce qu'un article de blog ? Quelles propriétés devrait-il avoir ? -Déjà, notre blog post doit avoir du texte, comme du contenu et un titre par exemple, n'est-ce pas? Et puis, ce serait bien de savoir qui l'a écrit. On a donc besoin d'un auteur. Enfin, on aimerait aussi savoir quand l'article a été écrit et publié. +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é. Post -------- @@ -45,28 +45,28 @@ Déjà, notre blog post doit avoir du texte, comme du contenu et un titre par ex published_date -Quel genre d'actions peut-on faire sur un article de blog? Un bon début serait d'avoir une `méthode` qui permet de publier le post. +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. On va donc avoir besoin d'une méthode `publish`. -Voilà, nous savons ce que nous voulons: nous pouvons commencer à la modéliser dans Django! +Voilà, nous avons une idée de ce que nous avons besoin. Allons modéliser tout ça dans Django! ## Les modèles dans Django 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 `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. Pour vous aider à visualiser ce qu'est une base de données, pensez à un tableur avec des colonnes (champs) et des lignes (données). ### Créer une application -Pour ne pas nous laisser déborder par le désordre et garder une vision claire de ce que nous faisons, 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`): +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`) : (myvenv) ~/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. Vos dossiers et fichiers liés à votre projet doivent maintenant être organisés selon cette structure : djangogirls ├── mysite @@ -85,75 +85,78 @@ Vous pouvez voir qu'un nouveau dossier `blog` a été créé et qu'il contient d └── views.py -Après avoir créé une nouvelle application, vous devez dire à Django de l'utiliser. Pour faire ça, nous allons nous servir du fichier `mysite/settings.py`. Vous allez devoir trouver la section `INSTALLED_APPS` et ajouter à la fin de la liste la ligne `'blog',``)`. Après ajout, cette section doit ressembler à ceci: - - INSTALLED_APPS = ( - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'blog', - ) - +Après avoir créé une nouvelle application, vous devez dire à Django de l'utiliser. Pour cela, nous allons nous éditer le fichier `mysite/settings.py`. Trouvez la section `INSTALLED_APPS` et ajoutez `'blog',` juste avant `)`. La section doit maintenant ressembler à ceci : + +```python +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog', +) +``` ### 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. +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. -Ouvrez le fichier `blog/models.py`, 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 : - 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 - +```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 +``` -> Si jamais vous avez préféré le taper à la main, vérifiez que vous avez bien utilisé deux tirets bas (`_`) autour de `str`. Ils sont assez fréquemment utilisés en Python et portent parfois le doux nom de "dunder" ("double-underscore"). +> Vérifiez que vous avez bien utilisé deux tirets bas (`_`) autour de `str`. C'est une convention fréquemment utilisée en Python qui porte même un petit nom en anglais : "dunder", pour "double-underscore". -Ce gros morceau de code a l'air effrayant! Ne vous inquiétez pas, nous allons vous expliquer ce que signifie chacune de ces lignes! +Ce gros morceau de code a l'air effrayant mais, ne vous inquiétez pas : nous allons vous expliquer ce que signifie chacune de ces lignes! 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`). * 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 ainsi qu'y insérer des espaces. Le nom d'une classe commence toujours par une majuscule. +* `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 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 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, un utilisateur par exemple ?). * `models.CharField` - Cela nous permet de définir un champ texte avec un nombre limité de caractères. -* `models.TextField` - Ce type de champ est pour les longs textes car il ne possède pas de limite de taille. Ça ne vous paraît pas être pile ce que l'on cherche pour le contenu de nos blog posts? +* `models.TextField` - Cela nous permet de définir un champ text 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. -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/1.7/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 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.8/ref/models/fields/#field-types). -Et sinon, c'est quoi `def publish(self):`? Il s'agit de notre méthode `publish (publication)` dont nous parlions tout à l'heure. C'est le mot `def` qui permet de dire que c'est une fonction/méthode. `publish` est le nom de notre méthode. Vous pouvez le changer si vous le voulez. Mais, si vous le faîtes, veillez à respecter les règles suivantes: n'utilisez que des minuscules, pas de caractères spéciaux ou accentués, et remplacez les espaces par des tirets bas. Par exemple, si vous vouliez créer une méthode qui permet de calculer le prix moyen de quelque chose, vous pourriez l'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. 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`. -Les méthodes `retournent` très souvent quelque chose. C'est le cas de la méthode `__str__`. Dans notre tutoriel, lorsque nous appellerons `__str__()`, nous allons obtenir du texte (**string**) dans le titre du Post. +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. -Si quelque chose ne vous paraît pas clair au sujet des modèles, n'hésitez pas à demander à votre coach! Ça peut être très compliqué à comprendre la première fois, surtout lorsque l'on apprend les objets et les fonctions en même temps. Rassurez-vous! Avec le temps, tout cela vous paraitra de moins en moins magique et de plus en plus évident! +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 allons devoir signaler à Django que nous avons fait des modifications dans notre modèle (nous venons de le créer! ). Pour cela, tapez `python manage.py makemigrations blog`. Ça ressemblera à ç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. Tapez `python manage.py makemigrations blog` dans votre console. Le résultat devrait ressembler à ça : (myvenv) ~/djangogirls$ python manage.py makemigrations blog Migrations for 'blog': @@ -161,13 +164,14 @@ La dernière étape pour cette section est d'ajouter notre nouveau modèle à no - Create model Post -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 devez voir ceci s'afficher dans votre console : +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 : (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 1e6bec3f96e..ffea092799a 100755 --- a/fr/django_orm/README.md +++ b/fr/django_orm/README.md @@ -1,21 +1,21 @@ -# Django ORM and QuerySets +# L'ORM Django et les QuerySets -Dans ce chapitre, nous allons apprendre comment Django se connecte à la base de données et comment il y enregistre des choses. On respire un grand coup et on y va! +Dans ce chapitre, nous allons apprendre comment Django se connecte à la base de données et comment il y enregistre des choses. On respire un grand coup et on y va ! -## Qu'est-ce qu'un QuerySet? +## Qu'est-ce qu'un QuerySet ? Un QuerySet est, par essence, une liste d'objets d'un modèle donné. C'est ce qui vous permet de lire, trier et organiser, des données présentes dans une base de données. -Il est plus simple d'apprendre avec un exemple. Et si nous nous intéressions à celui-ci? +Il est plus simple d'apprendre avec un exemple. Et si nous nous intéressions à celui-ci ? ## Le shell Django -Ouvrez votre console et tapez cette commande: +Ouvrez la console de votre ordinateur (et non celle de PythonAnywhere) et tapez la commande suivante : (myvenv) ~/djangogirls$ python manage.py shell -Ceci devrait maintenant s'afficher dans votre console: +Ceci devrait maintenant s'afficher dans votre console : (InteractiveConsole) >>> @@ -25,134 +25,152 @@ Vous êtes maintenant dans la console interactive de Django. C'est comme celle d ### Lister tous les objets -Essayons tout d'abord d'afficher tous nos posts. Vous pouvez le faire à l'aide de cette commande: +Essayons tout d'abord d'afficher tous nos posts. Vous pouvez le faire à l'aide de cette commande : - >>> Post.objects.all() - Traceback (most recent call last): - File "", line 1, in - NameError: name 'Post' is not defined - +```python +>>> Post.objects.all() +Traceback (most recent call last): + File "", line 1, in +NameError: name 'Post' is not defined +``` -Ooops! Voilà que ça nous renvoie une erreur! Cela nous dit qu'il n'existe pas de Post. En effet, nous avons oublié de commencer par un "import"! +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" ! - >>> from blog.models import Post - +```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: +Rien de compliqué : nous importons le modèle `Post` depuis notre `blog.models`. Essayons à nouveau la commande précédente : - >>> Post.objects.all() - [] - +```python +>>> Post.objects.all() +[, ] +``` -Ce double crochet signifie que notre liste est vide. Ce qui est totalement correct: nous n'avons pas encore créé de post! Corrigeons ça de suite. +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 ? ### Créer des objets -Voilà comment créer un objet Post dans notre base de données: +Voici comment créer un nouveau objet Post dans la base de données : - >>> Post.objects.create(author=moi, title='Exemple de titre', text='Test') - +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') +``` -Cependant, il nous manque un petit quelque chose: `moi`. Nous avons besoin de lui passer une instance du modèle `User` en guise d'auteur (author). Comment faire? +Cependant, il nous manque un petit quelque chose : `moi`. Nous avons besoin de lui passer une instance du modèle `User` en guise d'auteur (author). Comment faire ? -Tout d'abord, il nous faut importer le modèle User: +Tout d'abord, il nous faut importer le modèle User : - >>> from django.contrib.auth.models import User - +```python +>>> from django.contrib.auth.models import User +``` -Avons-nous des utilisateurs dans notre base de données? Voyons voir: +Avons-nous des utilisateurs dans notre base de données ? Voyons voir : - >>> User.objects.all() - [] - +```python +>>> User.objects.all() +[] +``` -Nous n'avons pas d'utilisateur! Il nous faut donc nous en créer un: +C'est le superutilisateur que nous avions créé tout à l'heure ! Essayons maintenant d'obtenir une instance de l'utilisateur : - >>> User.objects.create(username='ola') - - +```python +me = User.objects.get(username='ola') +``` -Avons-nous bien créé un utilisateur dans notre base de données? Pour le savoir, tapons la commande suivante: +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. - >>> User.objects.all() - [] - - -Cool! L'utilisateur que nous avons créé dans cet exemple s'appelle Ola. Essayons maintenant d'obtenir l'instance de cet utilisateur: - - moi = 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. +Nous allons enfin pouvoir créer notre post : -Maintenant, nous pouvons enfin créer notre premier post: +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') +``` - >>> Post.objects.create(author = moi, title = 'Exemple de titre', text = 'Test') - +Youpi ! Et si on vérifiait quand même si ça a marché ? -Youpi! Et si on vérifiait quand même si ça a marché? +```python +>>> Post.objects.all() +[, , ] +``` - >>> Post.objects.all() - [] - +Et voilà : un post de plus dans la liste ! ### Ajouter plus de posts -Amusez-vous à ajouter plusieurs posts avec ce que nous venons de voir. Ajoutez en deux ou trois puis passez à la suite. +Amusez-vous à ajouter d'autres posts pour vous entrainer un peu. Essayez d'ajouter 2-3 posts en plus puis passez à la partie suivante. ### Filtrer les objets -L'intérêt des QuerySets, c'est qu'on peut les filtrer. Disons que nous voulons trouver les posts écrits par l'utilisateur Ola. Nous allons utiliser `filter` à la place de `all` dans `Post.objects.all()`. Les parenthèses vont nous servir à préciser le⋅s condition⋅s nécessaire⋅s aux différents posts pour qu'ils puissent se retrouver dans notre QuerySet. Dans notre exemple, `author` est égal à `moi`. La manière de le dire en Django c'est: `author=moi`. 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 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: - >>> Post.objects.filter(author=moi) - [, , , ] - +```python +>>> Post.objects.filter(author=me) +[, , , ] +``` Et si nous voulions chercher les posts qui contiennent uniquement le mot "titre" dans le champs `title`? - >>> Post.objects.filter(title__contains='title') - [, ] - +```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 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". -Vous pouvez aussi obtenir une liste de tous les posts publiés. Pour cela, nous allons seulement conserver les posts qui possèdent une date de publication (`published_date`): +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é : - >>> Post.objects.filter(published_date__isnull=False) - [] - +```python +>>> from django.utils import timezone Post.objects.filter(published_date__lte=timezone.now()) [] +``` -Malheureusement, aucun de nos posts n'a été publié pour l'instant. Changeons ça! Tout d'abord, obtenons une instance du post que nous souhaitons publier: +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 publié : - >>> post = Post.objects.get(id=1) - +```python +>>> post = Post.objects.get(title="Sample title") +``` Ensuite, publions-le grâce à notre méthode `publish`! - >>> post.publish() - +```python +>>> post.publish() +``` -Réessayons d'obtenir une liste des posts publiés (pour aller plus vite, appuyez trois fois sur la flèche du haut de votre clavier et appuyer sur entrer): +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` : - >>> Post.objects.filter(published_date__isnull=False) - [] - +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +[] +``` ### Classer les objets -Les QuerySets vous permettent aussi de classer des listes d'objets. Essayons de les classer par date de création (champ `created_date`): +Les QuerySets permettent aussi de trier la liste des objets. Essayons de les trier par le champs `created_date` : - >>> Post.objects.order_by('created_date') - [, , , ] - +```python +>>> Post.objects.order_by('created_date') +[, , , ] +``` -Nous pouvons inverser l'ordre en mettant un `-` au début du nom de notre champ: +On peut aussi inverser l'ordre de tri en ajouter `-` au début: - >>> Post.objects.order_by('-created_date') - [, , , ] - +```python +>>> Post.objects.order_by('-created_date') +[, , , ] +``` + +### Chainer les QuerySets + +Vous pouvez aussi combiner les QuerySets and les **chainant** les unes aux autres : + +```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. -Cool! Maintenant, vous êtes prêt⋅e à passer à la partie suivante! Pour fermer le shell, tapez ceci: +Génial ! Vous êtes maintenant prête à passer à l'étape suivante ! Pour fermer le shell, tapez ceci: - >>> exit() - $ +```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 8e9089613fd..633d7ddb16f 100755 --- a/fr/django_start_project/README.md +++ b/fr/django_start_project/README.md @@ -1,34 +1,34 @@ -# Votre premier projet Django! +# Votre premier projet Django ! -> Note: ce chapitre est en partie inspiré d'un autre tutoriel réalisé par les Geek Girls Carrots (http://django.carrots.pl/). +> Note : ce chapitre est en partie inspiré d'un autre tutoriel réalisé par les Geek Girls Carrots (http://django.carrots.pl/). > > 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/ -Nous allons créer un petit blog! +Nous allons créer un petit blog ! -La première étape consiste à démarrer un nouveau projet Django. En gros, ça veut dire que nous allons lancer quelques scripts fournis par Django qui vont nous créer un squelette de projet Django (une poignée de fichiers qui vont nous être utiles). +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 y a certains fichiers et dossiers dont les noms sur 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. -Dans une console, lancez ça (n'oubliez pas, pas besoin de taper `(myvenv) ~/djangogirls$`): +> 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. -> N'oubliez pas de tout lancer dans le 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**. +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** : -Lancer sous Windows: - - (myvenv) ~/djangogirls$ python myvenv\Scripts\django-admin.py startproject mysite . + (myvenv) ~/djangogirls$ django-admin startproject mysite . -ou sous Linux ou Mac OS: +Pour les utilisatrices de Windows, tapez la commande suivante. **N'oubliez pas le point `.` à la fin** : - (myvenv) ~/djangogirls$ django-admin startproject mysite . + (myvenv) C:\Users\Name\djangogirls> django-admin startproject mysite . -> **Remarque**: N'oubliez pas le point (`.`) à la fin de la commande. Il est super important. +> 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. -`django-admin` est un script qui créé les dossiers et fichiers nécessaires pour vous. Vous devriez maintenant avoir une structure de dossier qui ressemble à celle-ci: +`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 @@ -43,66 +43,95 @@ ou sous Linux ou Mac OS: Le fichier `settings.py` contient la configuration de votre site web. -Vous vous souvenez de l'histoire du postier qui livre des lettres? `urls.py` contient une liste de modèles d'urls utilisés par `urlresolver`. +Vous vous souvenez de l'histoire du postier qui livre des lettres ? `urls.py` contient une liste de patterns d'urls utilisés par `urlresolver`. -Ignorons les autres fichiers pour l'instant, nous n'allons pas avoir besoin d'y toucher. Le seul truc aucun il faut faire attention est de ne pas les supprimer par accident! +Ignorons les autres fichiers pour l'instant, nous n'allons pas avoir besoin d'y toucher. La seule chose à retenir est qu'il ne faut pas les supprimer par accident ! ## Changer la configuration Apportons quelques changements à `mysite/settings.py`. Ouvrez le fichier avec l'éditeur de code que vous avez installé tout à l'heure. -Ce serait sympa d'avoir les bonnes heures sur notre site web. Allez voir sur http://en.wikipedia.org/wiki/List_of_tz_database_time_zones et copiez le bon fuseau horaire (timezone, TZ). (par exemple, `Europe/Berlin`) +Ç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`) -Vous devriez trouver des lignes qui contiennent `USE_TZ` et `TIME_ZONE`. Modifiez-les pour qu'elles ressemblent à ça (en remplaçant `Europe/Berlin` par le bon fuseau horaire): + [2]: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones - USE_TZ = False - TIME_ZONE = 'Europe/Berlin' - +Dans settings.py, recherchez la ligne qui contient le `TIME_ZONE` et modifiez-la pour choisir votre propre fuseau horaire : + +```python +TIME_ZONE = 'Europe/Paris' +``` + +En remplaçant "Europe/Paris" par la valeur appropriée + +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` : + +```python +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'static') +``` ## Configuration de la base de données -Il existe tout un tas de systèmes de gestion de bases de données qu'on pourrait utiliser pour stocker les données de votre site. On va utiliser celui par défaut, `sqlite3`. +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 va utiliser celui par défaut : `sqlite3`. -Il est déjà configuré dans ce morceau de votre fichier `mysite/settings.py`: +Il est déjà configuré dans cette partie de votre fichier `mysite/settings.py`: - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - } +```python +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } - +} +``` -Pour créer la base de donnée de votre blog, il fait lancer la commande suivante dans la console: `python manage.py migrate` (on a 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: +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: (myvenv) ~/djangogirls$ python manage.py migrate Operations to perform: - Apply all migrations: admin, contenttypes, auth, sessions + 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 -Et voilà! Il ne plus qu'à lancer le server et voir si le site web marche! +Et voilà ! Il ne reste plus qu'à lancer le serveur et voir si notre site web fonctionne ! -Pour ça, vous avez besoin d'être dans le dossier qui contient le fichier `manage.py` (le dossier `djangogirls`). Dans la console, vous pouvez lancer le serveur en tapant `python manage.py runserver`: +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`: (myvenv) ~/djangogirls$ python manage.py runserver -Ensuite, il ne vous reste plus qu'à vérifier que le site tourne. Ouvrez votre navigateur (Firefox, Chrome, Safari, Internet Explorer, ou n'importe quel autre), et entre l'adresse: +Si vous utilisez Windows et que vous obtenez l'erreur `UnicodeDecodeError`, tapez plutôt cette commande : + + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + + +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 : http://127.0.0.1:8000/ -Le serveur web remplace la ligne de commande tant que vous ne l’arrêtez pas. Pour pouvoir taper de nouvelles commandes, vous devez soit lancer une nouvelle fenêtre de terminal (et n'oubliez pas d'y activer votre virtualenv), ou arrêter le serveur web en sélectionnant la fenêtre de terminal et où tourne le serveur et en appuyant sur CTRL+C (Contrôle et C en même temps). Sous Windows, ça sera Ctrl+Arrêt défil. +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. -Bravo! Vous venez de créer votre premier site web, et de le lancer avec un serveur web! C'est génial, non? +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é!][2] +![Ça a marché !][3] - [2]: images/it_worked2.png + [3]: images/it_worked2.png -Prête pour la suite? Il est temps de créer du contenu! +Prête pour la suite ? Il est temps de créer du contenu! \ No newline at end of file diff --git a/fr/django_templates/README.md b/fr/django_templates/README.md index 9dc4515aeca..dda057c6ef4 100755 --- a/fr/django_templates/README.md +++ b/fr/django_templates/README.md @@ -1,49 +1,50 @@ # Templates Django -Il est temps d'afficher des données! Pour nous aider, Django fournit des balises de gabarit (**template tags**) qui sont intégrées au framework. Pour le reste du tutoriel, nous utiliserons plutôt le mot template, bien plus répandu que sa traduction "gabarit". +Il est temps d'afficher des données ! Pour nous aider, Django fournit des balises de gabarit (**template tags**) qui sont intégrées au framework. Pour le reste du tutoriel, nous utiliserons plutôt le mot template, bien plus répandu que sa traduction "gabarit". -## Qu'est-ce que c'est que des balises de template? +## Qu'est-ce que c'est que des balises de template ? 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 transfert 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 et facilement. Cool, non ? ## Template d'affichage de la liste des posts Dans le chapitre précédent, nous avons donné à notre template une liste de posts à l'aide de la variable `posts`. Nous allons maintenant les afficher en HTML. -Afin d'afficher une variable dans un template Django, nous utilisons des doubles accolades avec le nom de la variable à l'intérieur. Ça ressemble à ceci: +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 : - {{ posts }} - +```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 `
` avec la ligne `{{ posts }}`. Sauvegardez votre fichier et rafraîchissez votre page pour voir le résultat: +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] [1]: images/step1.png -Comme vous pouvez le voir, tout ce que nous avons, c'est ceci: +Comme vous pouvez le voir, tout ce que nous avons, c'est ceci : - [, ] - +```python +[, ] +``` -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 to Python**. Vous avez trouvé? Avec des boucles! Dans un template Django, vous pouvez les écrire de cette façon: +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 : ```html {% for post in posts %} {{ post }} {% endfor %} ``` - -Essayez-la dans votre template. +Essayez ceci dans votre template. ![Figure 13.2][2] [2]: images/step2.png -Ç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 to 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 : ```html
@@ -52,42 +53,54 @@ Essayez-la dans votre template. {% for post in posts %}
-

published: {{ post.published_date }}

+

publié: {{ post.published_date }}

{{ post.title }}

{{ post.text|linebreaks }}

{% endfor %} ``` - -{% raw %}Tout ce qui se situe entre `{% for %}` et `{% endfor %}` va être répété pour chaque objet dans la liste. Rafraichissez votre page:{% endraw %} +{% 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] [3]: images/step3.png -{% raw %}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.{% endraw %} +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 ! -Ce serait génial si nous pouvions aller sur notre site web hébergé sur Heroku et voir toutes ces nouvelles fonctionnalités! Remontons nos manches et déployons encore une fois. Si vous ne vous souvenez plus de ce que fait chaque commande, consultez la fin du chapitre 15: +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... -```bash -$ git status -... -$ git add -A . -$ git status -... -$ git commit -m "Utilisation de template Django à la place de HTML statique" -... -$ git push heroku master -``` +* En premier lieu, envoyez votre code sur GitHub (push) + + $ git status + [...] + $ git add -A . + $ git status + [...] + $ git commit -m "Modified templates to display posts from database." + [...] + $ git push -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, rafraîchissez votre page et regardez si votre post apparaît. +* Ensuite, reconnectez-vous à [PythonAnywhere][4] 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 + $ 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/ + +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, rafraîchissez votre page et regardez si votre post apparaît. -Ça a marché? Super! Vous pouvez être fière de vous! Allez faire une pause et manger quelque chose qui vous fera plaisir: vous l'avez bien mérité! +Ç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. :) -![Figure 13.4][4] +![Figure 13.4][6] - [4]: images/donut.png + [6]: images/donut.png \ No newline at end of file diff --git a/fr/django_urls/README.md b/fr/django_urls/README.md index e879d78ec24..1b6aebf781c 100755 --- a/fr/django_urls/README.md +++ b/fr/django_urls/README.md @@ -1,100 +1,125 @@ # Les urls 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 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. -## Qu'est-ce qu'une URL? +## Qu'est-ce qu'une URL ? -Une URL n'est tout simplement qu'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! Tout comme http://djangogirls.com en est une aussi): +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.com` est aussi une URL) : ![Url][1] [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 quelque chose qui s'appelle `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. 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. -## Comment est-ce que les URLs fonctionnent dans Django? +## Comment les URLs fonctionnent-elles dans Django ? -Ouvrons le fichier `mysite/urls.py` et regardons à quoi il ressemble: +Ouvrons le fichier `mysite/urls.py` dans notre éditeur de code et regardons à quoi il ressemble : - from django.conf.urls import patterns, include, url - from django.contrib import admin - - urlpatterns = patterns('', - # Examples: - # url(r'^$', 'mysite.views.home', name='home'), - # url(r'^blog/', include('blog.urls')), - - url(r'^admin/', include(admin.site.urls)), - ) - +```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)), +] +``` Comme vous pouvez le voir, Django nous a déjà préparé une partie du travail. -Les lignes qui commencent par `#` permettent de commenter notre code: ces lignes ne seront donc pas exécutées par Python. Pratique, non? +Les lignes qui commencent par `#` permettent de commenter notre code : ces lignes ne seront donc pas exécutées par Python. Pratique, non ? -Comme vous pouvez le voir, l'adresse de l'interface d'administration est déjà en place: +Comme vous pouvez le voir, l'adresse de l'interface d'administration est déjà en place : +```python url(r'^admin/', include(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. +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`, des expressions régulières. Les regex ont beaucoup (vraiment beaucoup! ) de règles qui permettent de créer des patterns de recherche (ou des formules magiques obscures ;)). Ce n'est pas toujours évident à comprendre, donc ne vous en préoccupez pas trop aujourd'hui: vous aurez tout le temps de revenir dessus plus tard. Aujourd'hui, nous allons seulement utiliser les formules dont nous avons besoin. +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 chaine 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-là morceau par morceau pour comprendre ce que nous faisons : -Si vous êtes curieux⋅se, voici un petit exemple, histoire de ne pas vous laisser sur votre faim! Imaginez que vous avez un site qui possède une adresse comme celle-ci: `http://www.mysite.com/post/12345/`. `12345` serait le numéro du post à afficher. Ce serait vraiment pénible de devoir écrire une vue différente pour chaque post que nous voudrions rédiger. Du coup, Django rend les choses plus faciles et vous n'avez simplement qu'à écrire `http://www.mysite.com/post//`. Ne vous préoccupez pas du reste, Django se charge de tout! +* **^ 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 chaines de caractères se terminant par `/` correspondrons au pattern -## Votre première URL Django! +## Votre première URL Django ! -C'est le moment de créer votre toute première URL! Nous aimerions faire de http://127.0.0.1:8000/ la page d'accueil de notre site web où s'afficherait une liste de posts. +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. 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 `#`, et ajoutez une ligne qui va nous permettre d'importer `blog.urls` dans notre URL principale (`''`). +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 (`''`). -Votre fichier `mysite/urls.py` doit maintenant ressembler à ceci: +Votre fichier `mysite/urls.py` devrait maintenant ressembler à ceci: - from django.conf.urls import patterns, include, url - from django.contrib import admin - - urlpatterns = patterns('', - url(r'^admin/', include(admin.site.urls)), - url(r'', include('blog.urls')), - ) - +```python +from django.conf.urls import include, url +from django.contrib import admin -Django va maintenant rediriger tout ce qui arrive sur `http://127.0.0.1:8000/` vers `blog.urls`. À partir de là, il agira en fonction des instructions que nous lui aurons données. +urlpatterns = [ + url(r'^admin/', include(admin.site.urls)), + url(r'', 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 chaine de caractères. Cela permet d'indiquer à Python que ce qui va suivre inclus 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 fichier appelé `blog/urls.py`. Ajoutez ces deux lignes au début de votre nouveau fichier: +Créez un nouveau fichier vide `blog/urls.py`. OK ! Ajoutez maintenant ces deux premières lignes : - from django.conf.urls import patterns, include, url - from . import views - +```python +from django.conf.urls import url +from . import views +``` -Ici, nous ne faisons qu'importer les méthodes Django dont nous avons besoin ainsi que toutes les `vues` liées à notre application `blog`. Mais nous n'avons pas encore créé de vues! Pas de problème: nous y viendrons dans une minute! +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 -Ensuite, nous pouvons ajouter notre premier pattern d'URL: +Après ça, nous pouvons ajouter notre premier pattern d'URL: - urlpatterns = patterns('', - url(r'^$', views.post_list), - ) - +```python +urlpatterns = [ + url(r'^$', views.post_list, name='post_list'), +] +``` -Comme vous pouvez le voir, nous assignons une `vue` appelée `post_list` à l'URL `^$`. Mais qu'est-ce que `^$` signifie? C'est une formule regex magique :) Découpons-la en petits morceaux: - `^` signifie en regex "le début". C'est à partir de ce site que nous pouvons commencer à chercher les correspondances par rapport à notre pattern - `$` signifie "la fin". Ça signifie que nous arrêterons de cherchons notre pattern à cet endroit +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 chaine 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/". -Si nous mettons ces deux symboles ensemble, ça donne l'impression que nous sommes à la recherche d'une chaine de caractère (string) vide! C'est exactement ce que nous voulons! En effet, pour l'url resolver de Django, `http://127.0.0.1:8000/` ne fait pas partie de l'URL. Ce pattern va montrer à Django que la vue `views.post_list` doit être affichée lorsqu'un utilisateur de votre site web se rend à 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 nom d'URLs simple à retenir. -Est-ce que cela vous paraît clair? Ouvrons http://127.0.0.1:8000/ dans notre navigateur pour voir ce que ça donne. +Est-ce que tout fonctionne toujours ? Ouvrez votre navigateur à l'adresse http://127.0.0.1:8000/ pour vérifier. ![Erreur][2] [2]: images/error1.png -"It works" ne s'affiche plus, pourquoi donc? Ne vous inquiétez pas, c'est tout simplement une page d'erreur et elle ne va pas vous manger! Bien au contraire, il va nous falloir nous nourrir de ce qu'elle raconte: +"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 : -Vous pouvez lire le message **no attribute 'post_list'**. Est-ce que *post_list* vous rappelle quelque chose? C'est le nom de 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 :) +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 :). -> 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/1.7/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/fr/1.8/topics/http/urls/ \ No newline at end of file diff --git a/fr/django_views/README.md b/fr/django_views/README.md index 7c105ce44a4..03bb2b5bee5 100755 --- a/fr/django_views/README.md +++ b/fr/django_views/README.md @@ -2,36 +2,37 @@ 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` que nous allons créer dans la section suivante. Concrètement, les vues ne sont que des méthodes Python un peu plus élaborées que ce que nous avons manipulé 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 méthodes Python un peu plus élaborées que celles que nous avons manipulé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 pour voir ce qu'il contient : - from django.shortcuts import render - - # Create your views here. - +```python +from django.shortcuts import render -Il n'y pas encore grand chose dans ce fichier. La vue la plus simple que l'on peut créer ressemble à ceci: +# Create your views here. +``` - def post_list(request): - - return render(request, 'blog/post_list.html', {}) - +Il n'y pas encore grand chose dans ce fichier. La vue la plus simple que l'on peut créer ressemble à ceci : + +```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é `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`. 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: +Une autre erreur ! Voyons ce qu'elle nous dit : ![Erreur][1] [1]: images/error.png -Celle-là est plutôt simple: *TemplateDoesNotExist*. Corrigeons ça en créant un template dans la section suivante! +Celle-là est plutôt simple : *TemplateDoesNotExist*. Corrigeons ça en créant un template dans la section suivante ! -> Pour en apprendre un peu plus sur les vues dans Django, consultez la documentation officielle: https://docs.djangoproject.com/en/1.7/topics/http/views/ +> Pour en apprendre un peu plus sur les vues dans Django, consultez la documentation officielle : https://docs.djangoproject.com/fr/1.8/topics/http/views/ \ No newline at end of file diff --git a/fr/domain/README.md b/fr/domain/README.md index 5ec06376077..65b59077c5b 100755 --- a/fr/domain/README.md +++ b/fr/domain/README.md @@ -1,12 +1,12 @@ # Nom de domaine -Heroku vous a donné un nom de domaine, mais il est long, difficile à retenir, et franchement moche... Ce serait quand même mieux d'avoir un nom de domaine plus court et plus facile à retenir, n'est-ce pas? +Heroku vous a donné un nom de domaine, mais il est long, difficile à retenir, et franchement moche... Ce serait quand même mieux d'avoir un nom de domaine plus court et plus facile à retenir, n'est-ce pas ? -C'est ce que nous allons voir dans ce chapitre: comment acheter un nom de domaine et le faire pointer vers Heroku! +C'est ce que nous allons voir dans ce chapitre : comment acheter un nom de domaine et le faire pointer vers Heroku ! -## Où enregistrer son nom de domaine? +## Où enregistrer son nom de domaine ? -Un nom de domaine coûte environ 15$ par an. Vous pouvez en trouver des plus cher ou des moins cher, tout dépend de votre provider. Il existe de très nombreuses compagnies spécialisées dans l'enregistrement de nom de domaine: une simple recherche sur [Google][1] vous listera plusieurs centaines de possibilités. +Un nom de domaine coûte environ 15$ par an. Vous pouvez en trouver des plus ou moins cher : tout dépend de votre provider. Il existe de très nombreuses compagnies spécialisées dans l'enregistrement de nom de domaine : une simple recherche sur [Google][1] vous listera plusieurs centaines de possibilités. [1]: https://www.google.com/search?q=register%20domain @@ -14,7 +14,7 @@ Notre petit favori est [I want my name][2]. Ils revendiquent un "management de n [2]: https://iwantmyname.com/ -## Comment enregistrer mon nom de domaine sur IWantMyName? +## Comment enregistrer mon nom de domaine sur IWantMyName ? Allez sur [iwantmyname][3] et tapez le nom de domaine que vous souhaiteriez enregistrer dans le champ de recherche. @@ -30,27 +30,27 @@ Une liste des noms de domaines disponibles avec le nom que vous souhaiteriez va [5]: images/2.png -Nous avons décidé d'acheter `djangogirls.in`: +Nous avons décidé d'acheter `djangogirls.in` : ![][6] [6]: images/3.png -Allez dans votre panier et confirmez-le. Vous allez devoir vous créer un compte sur iwantmyname. Ensuite, vous allez pouvoir sortir votre carte bleue et acheter votre nom de domaine! +Allez dans votre panier et confirmez-le. Vous allez devoir vous créer un compte sur iwantmyname. Ensuite, vous allez pouvoir sortir votre carte bleue et acheter votre nom de domaine ! -Une fois ces étapes franchies, cliquez sur `Domains` dans le menu et sélectionnez votre tout nouveau nom de domaine. Ensuite, trouvez et cliquez sur le lien `manage DNS records`: +Une fois ces étapes franchies, cliquez sur `Domains` dans le menu et sélectionnez votre tout nouveau nom de domaine. Ensuite, trouvez et cliquez sur le lien `manage DNS records` : ![][7] [7]: images/4.png -Cherchez ce formulaire: +Cherchez ce formulaire : ![][8] [8]: images/5.png -Remplissez le avec les informations suivantes: - Hostname: www - Type: CNAME - Value: votre nom de domaine chez Heroku (par exemple djangogirls.herokuapp.com) - TTL: 3600 +Remplissez le avec les informations suivantes : - Hostname: www - Type: CNAME - Value: votre nom de domaine chez Heroku (par exemple djangogirls.herokuapp.com) - TTL: 3600 ![][9] @@ -58,7 +58,7 @@ Remplissez le avec les informations suivantes: - Hostname: www - Type: CNAME - V Cliquez sur le bouton "Add" puis le bouton "Save changes" en bas de la page. -Il va falloir attendre quelques heures avant que votre nom de domaine fonctionne, soyez patient⋅e! +Il va falloir attendre quelques heures avant que votre nom de domaine fonctionne, soyez patient⋅e ! ## Configurer un nom de domaine dans Heroku @@ -68,4 +68,4 @@ Pour cela, allez dans le [Dashboard d'Heroku][10], connectez-vous avec votre com [10]: https://dashboard.heroku.com/apps -Et voilà, c'est tout! +Et voilà, c'est tout ! \ No newline at end of file diff --git a/fr/domain/images/1.png b/fr/domain/images/1.png deleted file mode 100644 index 97a06e28f2a..00000000000 Binary files a/fr/domain/images/1.png and /dev/null differ diff --git a/fr/domain/images/2.png b/fr/domain/images/2.png deleted file mode 100644 index 604fd5b02c8..00000000000 Binary files a/fr/domain/images/2.png and /dev/null differ diff --git a/fr/domain/images/3.png b/fr/domain/images/3.png deleted file mode 100644 index c941c0d231d..00000000000 Binary files a/fr/domain/images/3.png and /dev/null differ diff --git a/fr/domain/images/4.png b/fr/domain/images/4.png deleted file mode 100644 index dcbe145b271..00000000000 Binary files a/fr/domain/images/4.png and /dev/null differ diff --git a/fr/domain/images/5.png b/fr/domain/images/5.png deleted file mode 100644 index 778765053e5..00000000000 Binary files a/fr/domain/images/5.png and /dev/null differ diff --git a/fr/domain/images/6.png b/fr/domain/images/6.png deleted file mode 100644 index 52a0bb87c4c..00000000000 Binary files a/fr/domain/images/6.png and /dev/null differ diff --git a/fr/domain/images/images/1.png b/fr/domain/images/images/1.png deleted file mode 100644 index 97a06e28f2a..00000000000 Binary files a/fr/domain/images/images/1.png and /dev/null differ diff --git a/fr/domain/images/images/2.png b/fr/domain/images/images/2.png deleted file mode 100644 index 604fd5b02c8..00000000000 Binary files a/fr/domain/images/images/2.png and /dev/null differ diff --git a/fr/domain/images/images/3.png b/fr/domain/images/images/3.png deleted file mode 100644 index c941c0d231d..00000000000 Binary files a/fr/domain/images/images/3.png and /dev/null differ diff --git a/fr/domain/images/images/4.png b/fr/domain/images/images/4.png deleted file mode 100644 index dcbe145b271..00000000000 Binary files a/fr/domain/images/images/4.png and /dev/null differ diff --git a/fr/domain/images/images/5.png b/fr/domain/images/images/5.png deleted file mode 100644 index 778765053e5..00000000000 Binary files a/fr/domain/images/images/5.png and /dev/null differ diff --git a/fr/domain/images/images/6.png b/fr/domain/images/images/6.png deleted file mode 100644 index 52a0bb87c4c..00000000000 Binary files a/fr/domain/images/images/6.png and /dev/null differ diff --git a/fr/dynamic_data_in_templates/README.md b/fr/dynamic_data_in_templates/README.md index 4bae5856423..191eb8189c4 100755 --- a/fr/dynamic_data_in_templates/README.md +++ b/fr/dynamic_data_in_templates/README.md @@ -1,66 +1,74 @@ -# Django Querysets +# Données dynamiques dans les templates -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. +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. Concrètement, c'est dans la *vue* que nous allons décider ce qui va s'afficher (modèle) dans un template. -Ok, et sinon, on fait comment? +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`. Pour l'instant, la *vue* `post_list` ressemble à ceci : - from django.shortcuts import render - - def post_list(request): - return render(request, 'blog/post_list.html', {}) - +```python +from django.shortcuts import render -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: +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` - from django.shortcuts import render - from .models import Post - +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 : + +```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`). -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`. +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)][1].

+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 ! + +```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)` : - [1]: /django_orm/README.html +```python +from django.shortcuts import render +from django.utils import timezone +from .models import Post -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! +def post_list(request): + posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + return render(request, 'blog/post_list.html', {}) +``` - Post.objects.filter(published_date__isnull=False).order_by('published_date') - +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. -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)`: +Notez aussi que notre code utilise la fonction `timezone.now()` que nous allons aussi devoir importer de `timezone`. - from django.shortcuts import render - from .models import Post - - def post_list(request): - posts = Post.objects.filter(published_date__isnull=False).order_by('published_date') - return render(request, 'blog/post_list.html', {}) - +Il nous manque encore un petit quelque chose : passer notre QuerySet `posts` à notre template. 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 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 chaine de caractères : vous devez donc l'entourer de guillemets `''`. -Il nous manque encore un petit quelque chose: passer notre QuerySet `posts` à notre template. Nous intéresserons plus particulièrement à celui-ci dans la section suivante. +Au final, notre fichier `blog/views.py` doit ressembler à ceci maintenant : -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 par exemple de lui donner des noms: nous allons rester sur `'posts'` pour le moment :). Ça va ressembler à ça: `{'posts': posts}`. Attention! La partie située avant les `:` est entourée de guillemets simples `''`. +```python +from django.shortcuts import render +from django.utils import timezone +from .models import Post -Au final, notre fichier `blog/views.py` doit ressembler à ceci maintenant: +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 .models import Post - - def post_list(request): - posts = Post.objects.filter(published_date__isnull=False).order_by('published_date') - return render(request, 'blog/post_list.html', {'posts': posts}) - +Et voilà, c'est bon ! Nous allons retourner du côté de notre template pour que notre QuerySet puisse s'afficher correctement ! -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.8/ref/models/querysets/ -Si vous voulez en savoir plus sur les QuerySets, n'hésitez pas à consulter la documentation officielle du framework: https://docs.djangoproject.com/en/1.7/ref/models/querysets/ + [1]: ../django_orm/README.md \ No newline at end of file diff --git a/fr/extend_your_application/README.md b/fr/extend_your_application/README.md index 98d0933cdd2..30e7e7de433 100755 --- a/fr/extend_your_application/README.md +++ b/fr/extend_your_application/README.md @@ -1,16 +1,16 @@ # 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 aujourd'hui ! -Tout d'abord, il faudrait que notre blog possède une page qui permet d'afficher un post, n'est-ce pas? +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`. ## 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`. Pour le moment, ce fichier doit ressembler à ceci : ```html {% extends 'blog/base.html' %} @@ -26,73 +26,65 @@ Nous allons tout d'abord ajouter un lien à l'intérieur du fichier `blog/templa
{% endfor %} {% endblock content %} -``` - +``` -{% raw %}Nous aimerions pouvoir cliquer sur le titre du post et arriver sur une page nous détaillant celui-ci. Pour cela, changeons `

{{ post.title }}

` et transformons-le en lien:{% 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 %} ```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 parfait moment pour expliquer le mystérieux `{% url 'blog.views.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 %} - -`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*. +`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*. -Maintenant, allons à l'adresse: - - http://127.0.0.1:8000/ - - -Nous allons rencontrer une erreur, ce qui est normal car nous n'avons ni URL ni *vue* pour `post_detail`. Ça doit ressembler à ceci: +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 : ![Erreur NoReverseMatch][1] [1]: 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`! -### URL: http://127.0.0.1:8000/post/1/ +Nous aimerions que le contenu de notre premier post s'affiche à cette **URL** : http://127.0.0.1:8000/post/1/ -Nous voulons crer une URL pour pointer Django vers une *vue* appelée `post_detail`, ce qui nous permettra d'afficher l'intégralité d'un blog post. Ajoutez la ligne `url(r'^post/(?P[0-9]+)/$', views.post_detail),` au fichier `blog/urls.py`. Ça devrait ressembler à ceci: +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 : - from django.conf.urls import patterns, include, url - from . import views - - urlpatterns = patterns('', - url(r'^$', views.post_list), - url(r'^post/(?P[0-9]+)/$', views.post_detail), - ) - +```python +from django.conf.urls import include, url +from . import views -Une nouvelle fois, ce bout de code a l'air effrayant! Ne vous inquiétez pas, nous allons le décortiquer 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*. +urlpatterns = [ + url(r'^$', views.post_list, name='post_list'), + url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'), +] +``` -`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/(?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"! -Ok! Rafraîchissons la page: +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*. - http://127.0.0.1:8000/ - +`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]+)`. -Boom! Encore une erreur! Mais on s'y attendait ;) +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 ;) ![AttributeError][2] [2]: images/attribute_error2.png -Est-ce que vous vous souvenez de ce que nous devons faire ensuite? Mais bien sûr! Il faut ajouter une vue! +Est-ce que vous vous souvenez de ce que nous devons faire ensuite ? Il falloir ajouter une vue ! -## La vue post_detail +## Ajouter une vue pour le contenu du post -Cette fois, nous allons donner un paramètre supplémentaire à notre *vue*: `pk`. Notre *vue* a besoin de le récupérer, n'est-ce pas? 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 incorrect et va générer une erreur! +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 incorrect et va générer une erreur ! Maintenant, nous aimerions obtenir qu'un seul blog post. Pour cela, nous allons utiliser des QuerySets qui ressemblent à ceux-ci: - Post.objects.get(pk=pk) - +```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èdent cette `primary key (clef primaire)` (`pk`), nous allons nous retrouver avec une super erreur bien cracra! @@ -100,67 +92,69 @@ Cependant, il y a un petit problème dans cette ligne de code. Si aucun de nos ` [3]: images/does_not_exist2.png -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`. +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 -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 ;). +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: - from django.shortcuts import render, get_object_or_404 - +```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: - def post_detail(request, pk): - post = get_object_or_404(Post, pk=pk) - return render(request, 'blog/post_detail.html', {'post': post}) - - -Yep, c'est l'heure de recharger notre page: +```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/ - +Hop, réactualisons la page http://127.0.0.1:8000/ ![Vue post_list][5] [5]: images/post_list2.png -Ok, ça a marché! Mais que ce 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 -Oh non! Encore une erreur! Mais cette fois, vous savez quoi faire: nous avons besoin d'un template! +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`. -Ça ressemblera à ça: +Ça ressemblera à ça : ```html {% extends 'blog/base.html' %} {% block content %} -
+
{% if post.published_date %} - {{ post.published_date }} +
+ {{ post.published_date }} +
{% endif %} +

{{ post.title }}

+

{{ post.text|linebreaks }}

-

{{ post.title }}

-

{{ post.text|linebreaks }}

{% 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 to Python**. Dans notre exemple, nous aimerions vérifier si un post possède une date de publication (`published_date`).{% endraw %} +{% 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 %} Ok, vous pouvez maintenant rafraîchir votre page et voir si la page `Page not found` a enfin disparu. @@ -168,22 +162,33 @@ Ok, vous pouvez maintenant rafraîchir votre page et voir si la page `Page not f [7]: images/post_detail2.png -Yay! Ça marche! +Yay ! Ça marche! -## Encore un petit effort: déployons! +## Encore un petit effort : déployons ! -Ce serait génial si nous pouvions aller sur notre site web hébergé sur Heroku et voir toutes ces nouvelles fonctionnalités! Remontons nos manches et déployons encore une fois. Si vous ne vous souvenez plus de ce que fait chaque commande, consultez la fin du chapitre 15: +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 :) -```bash -$ git status -... -$ git add -A . -$ git status -... -$ git commit -m "Ajout de vues supplémentaires pour le site." -... -$ git push heroku master -``` + $ git status + $ git add -A . + $ git status + $ git commit -m "Added view and template for detailed blog post as well as CSS for the site." + $ git push + + +* Puis, dans la console bash de [PythonAnywhere][8]: + + [8]: https://www.pythonanywhere.com/consoles/ + + $ cd my-first-blog + $ source myvenv/bin/activate + (myvenv)$ git pull + [...] + (myvenv)$ python manage.py collectstatic + [...] -Normalement, ça devrait suffire! Encore bravo:) +* Enfin, cliquez sur l'onglet [Web][9] et cliquez sur **Reload**. + + [9]: https://www.pythonanywhere.com/web_app_setup/ + +Normalement, ça devrait suffire ! Encore bravo :) \ No newline at end of file diff --git a/fr/extend_your_application/images/images/no_reverse_match2.png b/fr/extend_your_application/images/images/no_reverse_match2.png deleted file mode 100644 index db65a5dc70a..00000000000 Binary files a/fr/extend_your_application/images/images/no_reverse_match2.png and /dev/null differ diff --git a/fr/extend_your_application/images/no_reverse_match2.png b/fr/extend_your_application/images/no_reverse_match2.png index db65a5dc70a..306926206f8 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/how_internet_works/README.md b/fr/how_the_internet_works/README.md old mode 100755 new mode 100644 similarity index 50% rename from fr/how_internet_works/README.md rename to fr/how_the_internet_works/README.md index c0175ea8f01..70fa62d142e --- a/fr/how_internet_works/README.md +++ b/fr/how_the_internet_works/README.md @@ -1,40 +1,40 @@ -# Comment marche l'Internet +# Comment fonctionne l'Internet ? > Ce chapitre est inspiré par la présentation "How the Internet works" par Jessica McKellar (http://web.mit.edu/jesstess/www/). -Vous utilisez sûrement Internet tous les jours. Mais savez-vous ce que ce passe vraiment quand vous tapez une adresse comme http://djangogirls.org dans votre navigateur et appuyez sur 'Entrée'? +Vous utilisez sûrement Internet tous les jours. Mais savez-vous ce qu'il ce passe vraiment quand vous tapez une adresse comme http://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. +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. 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. -Bon, d'accord. Mais vous avez envie de savoir à quoi Internet ressemble, n'est-ce-pas? +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: +On va a fait un dessin ! Internet ressemble à ça : ![Figure 1.1][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: +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 -Fascinant, non? Mais, il n'est évidemment pas possible de tirer un câble de chaque machine connecté à Internet vers chaque autre. Du coup, pour atteindre une machine (par exemple, celle où http://djangogirls.org est sauvegardé), on doit faire passer une requête par plein d'autres machines. +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ù http://djangogirls.org est sauvegardé), on doit faire passer une requête par plein d'autres machines. -Ça ressemble ça: +Ça ressemble ça : ![Figure 1.3][3] [3]: images/internet_2.png -C'est un peu comme si, quand vous tapez http://djangogirls.org, vous envoyiez une lettre que dit "Chères Django Girls, je voudrais voir le site djangogirls.org. Pouvez-vous me l'envoyer?" +C'est un peu comme si, quand vous tapiez http://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 post le plus proche. Ensuite, il file vers un autre, qui est plus proche de votre destinataire. Puis un autre, et encore une autre, jusqu'à sa destination. Pour Internet, c'est pareil. La seule différence, c'est que si vous envoyez plusieurs lettres (*des paquets de données*) vers le même endroit, chaque lettre peut emprunter une route différente, et voir différents bureaux de post (*routeurs*), selon la manière dont chaque bureau de poste distribue chaque lettre. +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] @@ -42,12 +42,11 @@ Votre lettre part vers le bureau de post le plus proche. Ensuite, il file vers u 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. -À 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ù on peut chercher le nom d'une personne et trouver son numéro de téléphone et son adresse. +À 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, 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). -Donc, au final, pour avoir un site web il faut qu'il soit sur un *serveur* (c'est une machine). Le *serveur* attend qu'on lui envoie une *requête* (une lettre qui demande au serveur d'envoyer le site web) et renvoie le 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/0> (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 parler, il est temps de commencer à créer des trucs! +Assez parlé, il est temps de commencer à créer des trucs ! \ No newline at end of file diff --git a/fr/how_internet_works/images/internet_1.png b/fr/how_the_internet_works/images/internet_1.png similarity index 100% rename from fr/how_internet_works/images/internet_1.png rename to fr/how_the_internet_works/images/internet_1.png diff --git a/fr/how_internet_works/images/internet_2.png b/fr/how_the_internet_works/images/internet_2.png similarity index 100% rename from fr/how_internet_works/images/internet_2.png rename to fr/how_the_internet_works/images/internet_2.png diff --git a/fr/how_internet_works/images/internet_3.png b/fr/how_the_internet_works/images/internet_3.png similarity index 100% rename from fr/how_internet_works/images/internet_3.png rename to fr/how_the_internet_works/images/internet_3.png diff --git a/fr/how_internet_works/images/internet_4.png b/fr/how_the_internet_works/images/internet_4.png similarity index 100% rename from fr/how_internet_works/images/internet_4.png rename to fr/how_the_internet_works/images/internet_4.png diff --git a/fr/html/README.md b/fr/html/README.md index 41ae541a8c8..e6e6ff7b5c1 100755 --- a/fr/html/README.md +++ b/fr/html/README.md @@ -2,21 +2,21 @@ Vous vous demandez sûrement ce qu'est un template. -Un template est un fichier que vous pouvez réutiliser afin de présenter des informations différentes sous un seul et même format. Par exemple, vous pourriez avoir envie d'utiliser un template pour écrire une lettre: bien que son contenu varie ou qu'elle puisse être adressée à des personnes différentes, sa forme reste la même. +Un template est un fichier que vous pouvez réutiliser afin de présenter des informations différentes sous un seul et même format. Par exemple, vous pourriez avoir envie d'utiliser un template pour écrire une lettre : bien que son contenu varie ou qu'elle puisse être adressée à des personnes différentes, sa forme reste la même. -Le format d'un template Django est décrit grâce à un langage qui s'appelle HTML (c'est le même HTML que celui dont nous parlions dans le chapitre un, **Comment Internet marche**). +Le format d'un template Django est décrit grâce à un langage qui s'appelle HTML (c'est le même HTML que celui dont nous parlions dans le chapitre un, **Comment fonctionne l'Internet**). -## Qu'est-ce que le HTML? +## 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 l'abréviation de "HyperText Markup Language." **HyperText** signifie que s'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 permettent de structurer les **éléments**. +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. -## Votre premier template! +## Votre premier template ! -Créer un template signifie créer un fichier template. Et oui, encore des fichiers! Vous aviez déjà probablement remarqué que tout tourne autour des fichiers. +Créer un template signifie créer un fichier template. Et oui, encore des fichiers ! Vous aviez déjà probablement remarqué que tout tourne autour des fichiers. -Les templates sont sauvegardés dans le dossier `blog/templates/blog`. Tout d'abord, créons un dossier appelé `templates` à l'intérieur du dossier de notre blog. Ensuite, créez un autre dossier appelé `blog` à l'intérieur de votre dossier templates: +Les templates sont sauvegardés dans le dossier `blog/templates/blog`. Tout d'abord, créons un dossier appelé `templates` à l'intérieur du dossier de notre blog. Ensuite, créez un autre dossier appelé `blog` à l'intérieur de votre dossier templates : blog └───templates @@ -27,57 +27,59 @@ Vous pourriez vous demander pourquoi nous avons besoin de deux dossiers portant 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/ +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, arrêtez votre server en appuyant simultanément sur Ctrl+C (les touches Control et C de votre clavier) et relancer le en tapant la commande `python manage.py runserver`. +> Si vous avez une erreur `TemplateDoesNotExists`, essayez de redémarrer votre serveur. Prenez 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`. ![Figure 11.1][1] [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. +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: +Ajoutez ce qui suit à votre fichier template : - -

Hi there!

-

It works!

- - +```html + +

Hi there!

+

It works!

+ +``` -Alors, à quoi ressemble notre site web maintenant? Allons le découvrir: http://127.0.0.1:8000/ +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 -Ç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. ## Head & 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. 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 ``: - - - - Le blog d'Ola - - -

Salut!

-

Ça marche :)

- - - +Par exemple, vous pouvez donner un titre à votre site en utilisant l'élément titre dans le `` : + +```html + + + Ola's blog + + +

Hi there!

+

It works!

+ + +``` Sauvegardez votre fichier et actualisez la page. @@ -85,7 +87,7 @@ Sauvegardez votre fichier et actualisez la page. [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.). +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.). Vous avez aussi probablement remarqué que chaque balise ouvrante possède sa *balise fermante*, composée d'un `/`, est qu'elles *encadrent* les différents éléments. Cela signifie que vous ne pouvez pas fermer une balise si celles imbriquées à l'intérieur de celle-ci n'ont pas été fermées. @@ -95,90 +97,113 @@ Essayez de vous rappeler cet exemple lorsque vous utilisez les balises *fermante ## 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: +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'à `
` +* `

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! +* `
  • 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: - - - - Django Girls blog - - - - -
-

published: 14.06.2014, 12:14

-

Mon premier 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

-

Mon 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.

-
- - - +Voici un exemple de template utilisant plusieurs balises : + +```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

+

Mon 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.

+
+ + +``` Nous avons créé trois sections à l'aide de `div`. -* Le premier `div` contient le titre de notre blogpost - c'est un titre et un lien -* Les deux autres `div` contiennent nos blogposts avec leur date de publication, un titre de post `h2` qui est cliquable ainsi que deux `p`s (paragraphe) de texte: un pour la date et l'autre pour notre blogpost. +* Le premier `div` contient le titre de notre blogpost - c'est à la fois un titre et un lien +* Les deux autres `div` contiennent nos blogposts avec leur date de publication, un titre de post `h2` qui est cliquable ainsi que deux `p`s (paragraphe) de texte : un pour la date et l'autre pour notre blogpost. -Ce qui nous donne: +Ce qui nous donne : ![Figure 11.4][4] [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**. +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 maintenant, c'est afficher les posts que nous avons créés précédemment dans l'interface d'administration de Django. Et si nous nous penchions là dessus? +## Une dernière chose : déployer ! -## Encore une chose! +Ne serait-il pas génial de pouvoir voir tout ces changements en ligne ? Hop, déployons à nouveau ! -Ce serait bien de savoir si notre site web sera toujours capable de fonctionner correctement une fois sur Heroku. Essayons de le déployer à nouveau. +### Commiter et pusher votre code sur GitHub -Tout d'abord, regardons quels fichiers ont été modifiés depuis notre dernier déploiement: +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 -Maintenant, essayons de dire à `git` que nous voulons inclure les changements qui ont eu lieu dans le dossier courant: +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 : $ git add -A . -> **Note** `-A` (abréviation 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. +> **Note** `-A` (abréviation 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 apparaître en vert) : $ 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. +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" > **Note** N'oubliez pas d'utiliser de doubles guillemets autour de votre message de commit. -Une fois que vous avez terminé, vous pouvez enfin uploader (pusher) vos modifications sur Heroku: +Une fois que nous avons fait cela, nous pouvons mettre en ligne (pusher) nos modifications sur GitHub : + + git push + + +### Puller les modifications sur PythonAnywhere et recharger son appli web - git push heroku master +* Allez sur la page des [consoles de PythonAnywhere][5]. Retournez dans votre **console Bash** ou ouvrez-en une nouvelle puis tapez la commande suivante : + + [5]: https://www.pythonanywhere.com/consoles/ + + $ cd ~/my-first-blog + $ source myvenv/bin/activate + (myvenv)$ git pull + [...] + (myvenv)$ python manage.py collectstatic + [...] -Normalement, ça devrait marcher! Une fois qu'Heroku a terminé, vous pouvez utiliser votre navigateur pour aller sur la page de votre site et la rafraîchir. Normalement, vous devriez constater du changement! +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**. + + [6]: https://www.pythonanywhere.com/web_app_setup/ + +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/installation/README.md b/fr/installation/README.md new file mode 100644 index 00000000000..58e37fa1d04 --- /dev/null +++ b/fr/installation/README.md @@ -0,0 +1,49 @@ +# Si vous suivez ce tutoriel chez vous + +Si vous suivez ce tutoriel chez vous et non dans un [évènement Django Girls](http://djangogirls.org/events/), vous pouvez passer directement au chapitre [Comment fonctionne l'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 inclue 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. + +Bonne chance ! + +# 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. + +# Installer Python + +{% include "/python_installation/instructions.md" %} + +# Mettre en place virtualenv et installer Django + +{% include "/django_installation/instructions.md" %} + +# Installez un éditeur de code + +{% include "/code_editor/instructions.md" %} + +# Installer Git + +{% include "/deploy/install_git.md" %} + +# Créer un compte GitHub + +Allez sur [GitHub.com](http://www.github.com) et créez-vous un nouveau compte gratuitement. + +# Créer un compte PythonAnywhere + +{% include "/deploy/signup_pythonanywhere.md" %} + +# Commencer à lire + +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) + + * [Introduction à la ligne de commande](../intro_to_command_line/README.md) + + * [Introduction à Python](../intro_to_command_line/README.md) + + * [Qu'est-ce que Django?](../django/README.md) \ No newline at end of file diff --git a/fr/intro_to_command_line/README.md b/fr/intro_to_command_line/README.md index c753103f9c8..6714989c295 100755 --- a/fr/intro_to_command_line/README.md +++ b/fr/intro_to_command_line/README.md @@ -1,18 +1,20 @@ # 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 :) +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!** +**Commençons par vous présenter un nouvel ami : la ligne de commande !** -Les étapes suivantes vont vous montrer comment utiliser la fenêtre noire que tous les bidouilleurs·euses utilisent. Elle est un peu effrayante à première vue, mais en fait, c'est un programme qui attend qu'on lui donne des commandes. +Les étapes suivantes vont vous montrer comment utiliser la fenêtre noire que tous les bidouilleurs·euses utilisent. Elle est un peu effrayante à première vue, mais en fait, c'est un tout simplement un programme qui attend qu'on lui donne des commandes. -## Qu'est-ce qu'une ligne de commande? +> **Note :** Il existe deux mots pour parler de dossier : dossier ou répertoire. Il se peut que nous utilisions les deux dans le tutoriel mais, pas de panique : ils signifient la même chose. -Cette fenêtre, qu'on appelle aussi **ligne de commande** ou **interface en ligne de commande**, est une application textuelle qui permet de voir et de manipuler des fichiers sur votre ordinateur (comme l'explorateur Windows ou Finder sur Mac, mais sans interface graphique). On l'appelle parfois aussi: *cmd*, *CLI*, *prompt*, *console* ou *terminal*. +## Qu'est-ce qu'une ligne de commande ? + +Cette fenêtre, qu'on appelle aussi **ligne de commande** ou **interface en ligne de commande**, est une application textuelle qui permet de voir et de manipuler des fichiers sur votre ordinateur. C'est un peu la même chose que l'Explorateur Windows ou Finder dans Mac, mais sans interface graphique. On l'appelle parfois aussi : *cmd*, *CLI*, *prompt*, *console* ou *terminal*. ## Ouvrir l'interface en ligne de commande -Pour commencer à expérimenter, on a d'abord besoin d'ouvrir notre interface en ligne de commande. +Pour commencer à expérimenter, nous avons d'abord besoin d'ouvrir notre interface en ligne de commande. ### Windows @@ -30,69 +32,69 @@ Vous la trouverez probablement dans Applications → Accessoires → Terminal, m Vous devriez maintenant voir une fenêtre noire ou blanche qui attend vos commandes. -Si vous être sous Max ou Linux, vous verrez probablement un `$`, comme ça: +Si vous être sous Mac ou Linux, vous verrez probablement un `$`, comme ça : $ + - -Sur Windows, c'est un signe `>`, comme ça: +Sur Windows, c'est un signe `>`, comme ça : > - + Chaque commande commence par ce signe, puis un espace. Mais vous n'avez pas besoin de le taper, votre ordinateur le fait 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 et c'est parfaitement normal. C'est juste parce que dans ce tutoriel, on tente de simplifier les choses autant que possible. +> 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. -## Votre première commande (YAY!) +## Votre première commande (YAY !) -Commençons par quelque chose de simple. Tapez la commande suivante: +Commençons par quelque chose de simple. Tapez la commande suivante : $ whoami - + ou > whoami + - -Et puis appuyez sur Entrée. Chez nous, ça donne ça: +Puis, appuyez sur la touche `entrée`. Voilà ce qui s'affiche chez moi : $ whoami olasitarska + +Comme vous pouvez le voir, l'ordinateur vient d'afficher votre nom d'utilisateur. Sympa, non ? ;) -Vous pouvez constater que l'ordinateur vient juste de vous montrer votre nom d'utilisateur. Pas mal, hein? :) - -> Essayez de taper chaque commande sans copier-coller. Ça aide à retenir! +> 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. On est parti? +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 pas mal de savoir où on est, non? Voyons voir. Tapez cette commande 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` : $ pwd /Users/olasitarska + - -Si vous êtes sous Windows: +Si vous êtes sous Windows : > cd C:\Users\olasitarska - + 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". +> Remarque : "pwd" veut dire "print working directory" (afficher le dossier courant). * * * ### Lister les fichiers et les dossiers -Du coup, y'a quoi dans ce dossier personnel? Ce serait pas mal de le savoir. Essayons ça: +Du coup, que pouvons-nous trouver dans ce dossier personnel ? Pour le savoir, essayons ceci : $ ls Applications @@ -100,9 +102,9 @@ Du coup, y'a quoi dans ce dossier personnel? Ce serait pas mal de le savoir. Ess Musique Téléchargements ... + - -Windows: +Windows : > dir Directory of C:\Users\olasitarska @@ -111,79 +113,79 @@ Windows: 05/08/2014 07:28 PM Musique 05/08/2014 07:28 PM Téléchargements ... - + * * * ### Changer le dossier courant -Et si on allait voir dans notre dossier Bureau? +Maintenant, essayons d'aller sur notre bureau : $ cd Bureau + - -Windows: +Windows : > cd Bureau + - -Vérifions que ça a bien changé: +Vérifions que ça a bien changé : $ pwd /Users/olasitarska/Bureau + - -Windows: +Windows : > cd C:\Users\olasitarska\Bureau + +Et voilà ! -Et voilà! - -> Pro tip: si vous tapez `cd B` puis que vous appuyez sur la touche `tab`, la ligne de commande va automatiquement compléter le reste du nom, pour vous permettre d'aller plus vite. Si plusieurs dossiers commencent par un "B", appuyez sur `tab` 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 `tabulation` deux fois pour avoir une liste des options. * * * ### Créer un dossier -Et si on créait un dossier Django Girls sur votre bureau? Vous pouvez faire comme ça: +Que diriez-vous de créer un répertoire dédié aux exercices sur votre bureau ? Vous pouvez le faire de cette façon : - $ mkdir djangogirls + $ mkdir exercices + +Windows : -Windows: + > mkdir exercices + - > mkdir djangogirls +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é `djangogirls` 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, essayer 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é. * * * -### Un peu d'exercice! +### Un peu d'exercice ! -Petit défi pour vous: dans votre nouveau dossier `djangogirls`, créez un dossier appelé `test`. Pour ça, utilisez les commands `cd` et `mkdir`. +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: +#### Solutions : - $ cd djangogirls + $ cd exercices $ mkdir test $ ls test + +Windows : -Windows: - - > cd djangogirls + > cd exercices > mkdir test > dir 05/08/2014 07:28 PM test + - -Félicitation! :) +Félicitations ! :) * * * @@ -191,70 +193,70 @@ Félicitation! :) 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 : $ cd .. + - -Windows: +Windows : > 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). -Faire un `cd` vers `..` permet de changer le dossier courant vers le dossier parent (c'est à dire le dossier qui contient le dossier courant). - -Vérifiez où vous êtes: +Vérifiez où vous êtes : $ pwd /Users/olasitarska/Bureau + - -Windows: +Windows : > cd C:\Users\olasitarska\Bureau + +Maintenant, il est temps de supprimer notre dossier `exercices` : -Maintenant, supprimons le dossier `djangogirls`. +> **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. -> **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. + $ rm -r exercices + - $ rm -r djangogirls +Windows : + > rmdir /S exercices + exercices, Are you sure ? Y + -Windows: - - > rmdir /S djangogirls - djangogirls, Are you sure ? Y - - -Et voilà. Pour être sûrs que le dossier a bien été supprimé, vérifions: +Et voilà. Pour être sure que le dossier a bien été supprimé, vérifiez : $ ls + - -Windows: +Windows : > dir - + ### Sortir -C'est tout pour le moment! Vous pouvez fermer 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. :) $ exit + - -Windows: +Windows : > exit + - -Cool, non? :) +Cool, non ? :) ## Résumé -Voici un résumé de quelques commandes utiles: +Voici un résumé de quelques commandes utiles : | Commande (Windows) | Commande (Mac OS / Linux) | Description | Exemple | | ------------------ | ------------------------- | --------------------------- | ------------------------------------------------- | @@ -266,12 +268,12 @@ Voici un résumé de quelques commandes utiles: | mkdir | mkdir | crée un nouveau dossier | **mkdir testdirectory** | | del | rm | supprime un dossier/fichier | **del c:\test\test.txt** | -Ce ne sont que quelques-unes des commandes que vous pouvez utiliser en ligne de commande, mais on aura pas besoin de plus aujourd'hui. +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 curieux⋅se, [ss64.com][1] contient une référence complète de toutes les commandes pour tous les systèmes d'exploitation. +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 -## Vous êtes prêt·e·s? +## Vous êtes prête ? -Nous allons plonger dans Python! +Nous allons plonger dans Python ! \ No newline at end of file diff --git a/fr/python_installation/README.md b/fr/python_installation/README.md index fed92994d11..47e71cbd43a 100755 --- a/fr/python_installation/README.md +++ b/fr/python_installation/README.md @@ -1,69 +1,13 @@ # Commençons par Python -On est parti! +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. Le rendre lisible par des humains, et non seulement des machines, était l'objectif principal des créateurs du langage. Par conséquent, il a l'air beaucoup plus simple à lire que d'autres langages de programmation. 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. 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 ! # Installation de Python -> Note: ce sous-chapitre est largement inspiré d'un autre tutoriel réalisé par les Geek Girls Carrots (http://django.carrots.pl/) - -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. - - -### Windows - -Vous pouvez télécharger Python pour Windows à partir de ce site: https://www.python.org/downloads/release/python-342/. 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. - - -### Linux - -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 taper la commande suivante: - - $ python3 --version - Python 3.4.2 - -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 - -Tapez cette commande dans votre console: - - $ sudo apt-get install python3.4 - - -#### Fedora (<=21) - -Tapez cette commande dans votre console: - - $ sudo yum install python3.4 - - -#### Fedora (22+) - -Tapez cette commande dans votre console: - - $ sudo dnf install python3.4 - - -### OS X - -Vous devez aller sur le site https://www.python.org/downloads/release/python-342/ et télécharger l'installateur python: - -* Téléchargez le fichier *Mac OS X 64-bit/32-bit installer**DMG*, -* Double-cliquez pour l'ouvrir, -* Double-cliquez sur *Python.mpkg* 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`: - - $ python3 --version - Python 3.4.2 - - -* * * +> **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 ! -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 quelques fois 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. +{% 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 new file mode 100644 index 00000000000..7946019bc29 Binary files /dev/null and b/fr/python_installation/images/add_python_to_windows_path.png differ diff --git a/fr/python_installation/instructions.md b/fr/python_installation/instructions.md new file mode 100644 index 00000000000..2981f45ef6c --- /dev/null +++ b/fr/python_installation/instructions.md @@ -0,0 +1,59 @@ +> Note : ce sous-chapitre est en partie inspiré d'un autre tutoriel réalisé par les Geek Girls Carrots (http://django.carrots.pl/) + +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. + +### Windows + +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 : + +![N'oubliez pas d'ajouter Python à votre chemin (path)](../python_installation/images/add_python_to_windows_path.png) + +### Linux + +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 : + + $ python3 --version + Python 3.4.3 + + +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 + +Tapez cette commande dans votre terminal : + + $ sudo apt-get install python3.4 + + +#### Fedora (jusqu'à la version 21) + +Tapez cette commande dans votre terminal : + + $ sudo yum install python3.4 + + +#### Fedora (22+) + +Tapez cette commande dans votre terminal : + + $ sudo dnf install python3.4 + + +### OS X + +Vous devez aller sur le site https://www.python.org/downloads/release/python-343/ et télécharger l'installateur Python : + + * 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`: + + $ python3 --version + Python 3.4.3 + + +* * * + +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 cf278e43909..129c73bdf83 100755 --- a/fr/python_introduction/README.md +++ b/fr/python_introduction/README.md @@ -1,692 +1,791 @@ # Introduction à Python -> Note: ce chapitre est en partie inspiré d'un autre tutoriel réalisé par les Geek Girls Carrots (http://django.carrots.pl/). +> Note : ce chapitre est en partie inspiré d'un autre tutoriel réalisé par les Geek Girls Carrots (http://django.carrots.pl/). -Allons écrire du code! +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]. - [1]: /intro_to_command_line/README.html + [1]: ../intro_to_command_line/README.md -Dès que vous êtes prêt⋅e, suivez les instructions suivantes. +Dès que vous êtes prête, suivez les instructions suivantes. -Nous voulons ouvrir une console Python. Il faut donc taper `python3` et appuyer sur Entrée. +Afin d'ouvrir une console Python, tapez `python` sous Windows ou `python3` sous Mac OS/Linux et appuyez sur `entrée`. - $ python3 - Python 3.4.2 (...) - Type "copyright", "credits" or "license" for more information. - >>> - +```python +$ python3 +Python 3.4.3 (...) +Type "help", "copyright", "credits" or "license" for more information. +>>> +``` -## Votre première commande Python! +## Votre première commande Python ! -Après avoir lancé la commande Python, votre prompt 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) 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. Quand vous voudrez sortir de la console Python, tapez `exit()` ou utilisez le raccourcit `Ctrl + Z` pour Windows ou `Ctrl + D` pour Mac/Linux. Après ça, vous ne verrez plus le `>>>`. -Mais pour l'instant, nous ne voulons pas sortir de la console Python. Nous voulons en apprendre un peu plus à son sujet. Commençons par essayer quelque chose de simple. Par exemple, essayez de taper un peu de maths, comme `2 + 3` et appuyez sur 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`. - >>> 2 + 3 - 5 - +```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 ! 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` Amusez-vous un peu avec ça, et revenez ici après :). -Comme vous pouvez le constater, Python est une très bonne calculette. Si vous vous demandez ce qu'il peut faire d'autre... +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 ... -## Chaînes de caractères (Strings) +## Chaines de caractères (Strings) -On essaye votre nom? Tapez votre prénom entre guillemets comme ça: +Et si nous essayions avec votre nom ? Tapez votre prénom entre guillemets, comme cela : - >>> "Ola" - 'Ola' - +```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 chaine de caractères doit toujours commencer et terminer par le même caractère. Ça peut être une guillement simple (`'`) ou une guillemet double (`"`). Ces guillements permettent à Python de savoir que tout ce qu'il y a à l'intérieur d'une chaîne de caractères. +Vous venez de créer votre première chaine 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 chaine de caractères. -On peut assembler des chaînes de caractères comme ça: +Il est possible d'assembler des chaines de caractères comme ceci : - >>> "Salut " + "Ola" - 'Salut Ola' - +```python +>>> "Salut " + "Ola" +'Salut Ola' +``` -Vous pouvez aussi multiplier une chaîne de caractères par un nombre: +Vous pouvez aussi multiplier une chaîne de caractères par un nombre : - >>> "Ola" * 3 - 'OlaOlaOla' - +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` -Si vous avez besoin de mettre une apostrophe dans votre chaîne de caractères, vous avez deux manières. +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: +Vous pouvez utiliser des guillemets doubles : - >>> "J'aime la mousse au chocolat" - "J'aime la mousse au chocolat" - +```python +>>> "J'aime la mousse au chocolat" +"J'aime la mousse au chocolat" +``` -ou alors échapper l'apostrophe avec un antislash (``): +ou échapper l’apostrophe avec une barre oblique inversée (un backslash, ``) : - >>> 'J\'aime la mousse au chocolat' - "J'aime la mousse au chocolat" - +```python +>>> 'J\'aime la mousse au chocolat' +"J'aime la mousse au chocolat" +``` -Pas mal, non? Pour voir votre nom en majuscules, tapez juste: +Pas mal, non ? Pour voir votre nom en majuscules, tapez juste : - >>> "Ola".upper() - 'OLA' - +```python +>>> "Ola".upper() +'OLA' +``` -Vous venez d'utiliser la **fonction** `upper` sur votre string! Une fonction (comme `upper()`) est un ensemble d'instructions que Python va effectuer sur un objet donné (`"Ola"`) quand vous l'appelez. +Vous venez d'utiliser la **fonction** `upper` sur votre chaine 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. -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 ! - >>> len("Ola") - 3 - +```python +>>> len("Ola") +3 +``` -Vous vous demandez pourquoi des fois on appelle des fonctions avec un `.` après la chaîne de caractères (comme `"Ola".upper()`) et des fois on appelle d'abord la fonction et on met la chaîne de caractères après, entre parenthèses? Et bien, dans certains cas, les fonctions appartiennent aux objets, comme `upper()`, qui ne peut être effectué que sur 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 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 *, ils combinent des valeurs pour en obtenir de nouvelles -* **les fonctions** - comme upper() et len(), que effectuent des actions sur les objets. +* **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 * qui combinent des valeurs pour en obtenir de nouvelles +* **les fonctions** - comme upper() et len() qui effectuent des actions sur les objets. -Ce sont les bases de tous les langages de programmation que vous pouvez apprendre. Prêt⋅e pour quelque chose de plus compliqué? Allons-y! +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 ! ## Les erreurs -Essayons quelque chose de nouveau. Est-ce qu'on peut avoir la longueur d'un nombre de la même manière qu'on peut avoir la longueur de votre nom? Tapez `len(304023)` et appuyez sur Entrée: +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` : - >>> len(304023) - Traceback (most recent call last): - File "", line 1, in - TypeError: object of type 'int' has no len() - +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` -On vient d'avoir notre première erreur! Ça dit que les objets de type "int" (integers, ça veut dire nombre entier) n'ont pas de longueur. Qu'est-ce qu'ont peut faire, du coup? Peut-être qu'on peut écrire notre nombre comme une chaîne de caractères. Les chaînes de caractères ont une taille, non? +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 chaine de caractères ? Après tout, les chaînes de caractères ont bien une taille, non ? - >>> len(str(304023)) - 6 - +```python +>>> len(str(304023)) +6 +``` -Ça a marché! On a 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 `str` convertit des choses en **chaines de caractères** * La fonction `int` convertit des choses en **entiers** -> Important: on peut convertir des nombres en texte, mais on ne peut pas toujours convertir du texte en nombres. Parce que, bon, ça vaudrait quoi `int('salut')`? +> 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')` ? ## Variables -Il y a un concept super important en programmation: les variables. Une variable, ce n'est jamais rien qu'un nom pour quelque chose qu'on peut utiliser plus tard. Les programmeurs⋅euses utilisent des variables pour stocker des données, rendre leur code plus lisible, et pour ne pas avoir à se rappeler de ce que sont les choses. +Il y existe un concept super important en programmation : les variables. Une variable, c'est juste un nom pour quelque chose que l'on aimerait utiliser plus tard. Les programmeurs⋅euses utilisent des variables pour stocker des données, rendre leur code plus lisible, et pour ne pas avoir à se rappeler de ce que sont les choses. -Disons qu'on souhaite créer une variable appelée `name`: +Disons que nous aimerions créer une variable appelée `name` : - >>> name = "Ola" - +```python +>>> name = "Ola" +``` -Vous voyez? C'est tout bête! C'est simplement: name est égal à Ola. +Vous voyez ? C'est tout bête ! C'est simplement : name vaut 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 simplement `name` et appuyez sur `entrée` : - >>> name - 'Ola' - +```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 : - >>> name = "Sonja" - >>> name - 'Sonja' - +```python +>>> name = "Sonja" +>>> name +'Sonja' +``` -Vous pouvez aussi l'utiliser dans des fonctions: +Vous pouvez aussi l'utiliser dans des fonctions : - >>> len(name) - 5 - +```python +>>> len(name) +5 +``` -Génial, non? Et bien sûr, les variables peuvent être n'importe quoi, y compris des nombres! Essayez ça: +Génial, non ? Et bien sûr, les variables peuvent être n'importe quoi, y compris des nombres ! Essayez ça : - >>> a = 4 - >>> b = 6 - >>> a * b - 24 - +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` -Mais qu'est-ce qui se passe si on utilise le mauvais nombre? Vous sauriez deviner? Essayons! +Mais que ce passe-t-il si nous utilisons le mauvais nom ? Essayez de deviner ! C'est parti ! - >>> name = "Maria" - >>> names - Traceback (most recent call last): - File "", line 1, in - NameError: name 'names' is not defined - +```python +>>> city = "Tokyo" +>>> ctiy +Traceback (most recent call last): + File "", line 1, in +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érifier dans votre code que vous n'avez pas fait une faute de frappe dans une variable. +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 avez ça, et voyez ce que vous arrivez à faire! +Jouez un peu avec les variables et essayez de voir ce que vous pouvez faire ! ## La fonction print -Essayez ça: +Essayez ça : - >>> name = 'Maria' - >>> name - 'Maria' - >>> print(name) - Maria - +```python +>>> name = 'Maria' +>>> name +'Maria' +>>> print(name) +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 joli. +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 on le verra plus tard, `print()` est aussi utile quand on veut afficher des choses depuis l'intérieur de fonctions, ou quand on veut afficher des choses sur plusieurs lignes. +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 -À part les chaînes de caractères et les entiers, Python a tout un tas d'autres types d'objets. On va maintenant vous présenter un type appelé **listes**. Les listes sont exactement ce que vous pensez qu'elles sont: ce 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é **listes**. Les listes sont exactement ce que vous pensez qu’elles sont : des objets qui sont des listes d’autres objets :) -Allez-y, créez une liste: +Allez-y, créez une liste : - >>> [] - [] - +```python +>>> [] +[] +``` -Oui, cette liste est vide. Pas très utile, hey? Créons maintenant une liste de numéro de loterie. Nous ne voulons pas nous répéter tout le donc, donc mettons la dans une variable: +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 : - >>> lottery = [3, 42, 12, 19, 30, 59] - +```python +>>> lottery = [3, 42, 12, 19, 30, 59] +``` -Voilà, nous avons une liste! Qu'est ce qu'on peut faire avec? Voyons combien de numéros de loterie il y a dans cette liste. Une idée de la fonction pour faire ça? On la connait déjà! +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à ! - >>> len(lottery) - 6 - +```python +>>> len(lottery) +6 +``` -Hé oui! `len()` peut aussi vous donner le nombre d'objets dans une liste. Pratique, non? Peut-être qu'on peut aussi la trier: +Hé oui ! `len()` peut aussi vous donner le nombre d'objets dans une liste. Pratique, non ? Peut-être qu'on peut aussi la trier : - >>> lottery.sort() - +```python +>>> lottery.sort() +``` -Ça ne renvoie rien, ça a juste changé l'ordre dans lequel les nombres apparaissent dans la liste. Affichons-la encore pour voir ce qu'il s'est passé: +Ç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é : - >>> print(lottery) - [3, 12, 19, 30, 42, 59] - +```python +>>> print(lottery) +[3, 12, 19, 30, 42, 59] +``` -Comme vous pouvez le voir, les nombres de la liste sont maintenant triés sur plus petit au plus grand. Bravo! +Comme vous pouvez le voir, les nombres de la liste sont maintenant triés du plus petit au plus grand. Bravo ! -Est-ce qu'on peut inverser l'ordre? Faisons ça! +Pouvons-nous inverser cet ordre ? Essayons! - >>> lottery.reverse() - >>> print(lottery) - [59, 42, 30, 19, 12, 3] - +```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: +Facile, non ? Si vous voulez ajouter quelque chose à la liste, vous pouvez le faire en tapant cette commande : - >>> lottery.append(199) - >>> print(lottery) - [59, 42, 30, 19, 12, 3, 199] - +```python +>>> lottery.append(199) +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +``` -Si vous voulez ne montrer 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 ordinateurs comptent à partir de 0, donc le premier objet de la liste est à l'indice 0, le suivant à l'indice 1, et ainsi de suite. Essayez ça: +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 : - >>> print(lottery[0]) - 59 - >>> print(lottery[1]) - 42 - +```python +>>> print(lottery[0]) +59 +>>> print(lottery[1]) +42 +``` -Comme vous pouvez le voir, on peut accéder à différents objets dans la liste en utilisant le nom de la liste suivi de l'indice de l'objet entre crochets. +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 voir, essayez d'autres indices: 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 les résultats vous paraissent logiques? +Pour supprimer un objet de votre liste, vous aurez besoin de son **indice** ainsi que de la commande **del** (del est une abréviation de delete (supprimer)). Essayons l'exemple suivant : supprimez le premier numéro de votre liste. -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 +```python +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +>>> print(lottery[0]) +59 +>>> del lottery[0] +>>> 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 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, mais on accède aux valeurs en utilisant une clef plutôt qu'un indice. 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: +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 chaine de caractère ou n'importe quel nombre. La syntaxe pour définir un dictionnaire vide est la suivante : - >>> {} - {} - +```python +>>> {} +{} +``` -C'est comme ça que l'on crée un dictionnaire vide. Hourra! +C'est comme ça que l'on crée un dictionnaire vide. Hourra ! -Maintenant, essayer d'écrire la commande suivante (et mettez vos propres informations): +Maintenant, essayez d'écrire la commande suivante (et essayez aussi de changer le contenu) : - >>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} - +```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 object `chaîne de caractère`), -* `country` pointe vers `'Poland'` (une autre ` chaîne de caractères`), +* 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: +Vous pouvez vérifier le contenu de chaque clef avec cette syntaxe : - >>> print(participant['name']) - Ola - +```python +>>> print(participant['name']) +Ola +``` -Vous voyez, c'est un peu comme une liste. Sauf que l'on a pas besoin de se souvenir de l'indice, juste du nom. +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. -Qu'est ce que se passe quand on demande à 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 ! - >>> participant['age'] - Traceback (most recent call last): - File "", line 1, in - KeyError: 'age' - +```python +>>> participant['age'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'age' +``` -Oh, une autre erreur! Celle-ci est une **KeyError**. Python se rend utile et nous dit que la clef `'age'` n'existe pas dans le dictionnaire. +Oh, une autre erreur ! Celle-ci est une **KeyError**. Python nous donne un coup de main et nous dit que la clef `'age'` n'existe pas dans le dictionnaire. -Quand faut-il 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 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 : - >>> participant['favorite_language'] = 'Python' - +```python +>>> participant['favorite_language'] = 'Python' +``` -Comme pour les listes, la fonction `len()` permet d'obtenir le nombre de paires clef-valeur du dictionnaire. Essayez, tapez la commande suivante: +Comme pour les listes, la fonction `len()` permet d'obtenir le nombre de paires clef-valeur du dictionnaire. Essayez et tapez la commande suivante : - >>> len(participant) - 4 - +```python +>>> len(participant) +4 +``` -J'espère que c'est compréhensible pour l'instant :) Prêt⋅e pour s'amuser un peu plus avec les dictionnaires? Passez à la ligne suivante pour voir des trucs géniaux. +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 `del` 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 commande `del` 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 : - >>> del participant['favorite_numbers'] - >>> participant - {'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} - +```python +>>> del participant['favorite_numbers'] +>>> participant +{'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +``` -Comme vous pouvez le voir dans la sortie, 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. -En outre, vous pouvez changer la valeur associée à une clef déjà créée dans le dictionnaire. Tapez: +De même, vous pouvez changer la valeur associée à une clef déjà créée dans le dictionnaire. Tapez ceci : - >>> participant['country'] = 'Germany' - >>> participant - {'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} - +```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 trucs sur la programmation maintenant. Dans cette partie, vous avez appris: +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 une de vos commandes +* **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 -Embalé⋅e pour la partie suivant? :) +On continue ? :) ## Comparer des choses -Comparer des choses, c'est vachement important en programmation. Quelle est la chose la plus facile à comparer? Les nombres! Voyons voir comment ça marche: +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 : - >>> 5 > 2 - True - >>> 3 < 1 - False - >>> 5 > 2 * 2 - True - >>> 1 == 1 - True - +```python +>>> 5 > 2 +True +>>> 3 < 1 +False +>>> 5 > 2 * 2 +True +>>> 1 == 1 +True +>>> 5 != 2 +True +``` -On a donné à Python des nombres à comparer. Comme vous pouvez voir, Python peut comparer des nombres, mais aussi des résultats de méthodes. Pas mal, non? +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 ? -Vous vous demander pourquoi on a mis deux signes `==` côte à côte pour savoir si deux nombres sont é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. +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: +Donnons encore un peu de boulot à Python : - >>> 6 >= 12 / 2 - True - >>> 3 <= 2 - False - +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` -`>` et `<` sont faciles, mais qu'est ce que `>=` et `<=` veulent dire? Ils se lisent comment ça: +`>` et `<` sont faciles, mais qu'est ce que `>=` et `<=` veulent dire ? Ils se lisent comment ça : -* x `>` u veut dire: x est plus grand que y -* x `<` y veut dire: x est plus petit que y -* x `<=` y veut dire: x est plus petit ou égal à y -* x `>=` y veut dire: x est plus grand 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: +Super ! Un dernier ? Essayez ça : - >>> 6 > 2 and 2 < 3 - True - >>> 3 > 2 and 2 < 1 - False - >>> 3 > 2 or 2 < 1 - True - +```python +>>> 6 > 2 and 2 < 3 +True +>>> 3 > 2 and 2 < 1 +False +>>> 3 > 2 or 2 < 1 +True +``` -Vous pouvez donner à Python autant de nombres à comparer, et il vous donnera la réponse. Plutôt malin, non? +Vous pouvez donner à Python autant de nombres à comparer que vous le souhaitez et il vous donnera une réponse. Plutôt malin, non ? -* **et** - si vous utilisez l'opérateur `and`, les deux comparaisons doivent être True (vraies) pour que la commande tout entier soit True -* **ou** - si vous utilisez l'opérateur `or`, il suffit qu'une des deux comparaisons soit True (vraie) pour que la commande tout entier 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: +Vous connaissez l'expression "on ne compare pas les choux et les carottes" ? Essayons l'équivalent en Python : - >>> 1 > 'django' - Traceback (most recent call last): - File "", line 1, in - TypeError: unorderable types: int() > str() - +```python +>>> 1 > 'django' +Traceback (most recent call last): + File "", line 1, in +TypeError: unorderable types: int() > str() +``` -Voilà, 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**, et c'est probablement le type le plus simple que existe. +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. -Il n'y a que deux objets Booléens: True et False +Il n'y a que deux objets Booléens : - True (vrai) - False (faux) -Pour que Python le comprenne, 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! Voyez: +Les Booléens aussi peuvent être des variables ! regardez : - >>> a = True - >>> a - True - +```python +>>> a = True +>>> a +True +``` -Vous pouvez aussi faire ça: +Vous pouvez aussi faire ça : - >>> a = 2 > 5 - >>> a - False - +```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` +* `1 != 2` -Bravo! Les Booléens sont une des fonctionnalités les plus cools en programmation, et vous venez d'apprendre comment les utiliser! +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! +# Sauvegardez tout ça ! -Pour l'instant, on a é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**. On va avoir besoin de plus qu'une ligne de code pour la suite, alors on va avoir besoin de: +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 : * Quitter l'interpréteur Python * Ouvrir l'éditeur de code de notre choix -* Sauvegarder du code dans un nouveau fichier python -* Le lancer! +* 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()~~~ : - >>> exit() - $ - +```python +>>> exit() +$ +``` -Ça vous ramènera dans la ligne de commande du système d'exploitation. +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. Nous avons maintenant besoin de l'ouvrir et d'écrire du code dans un nouveau fichier: +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 : [2]: ../code_editor/README.md - print('Hello, Django girls!') - +```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 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 bas). C'est ce genre de fonctionnalités qui font que vous aimerez rapidement programmer avec un éditeur de code :) -Alors forcément, vous avez maintenant pas mal de connaissances en python, donc n'hésitez pas à écrire du code avec ce que vous avez appris aujourd'hui. +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. On peut lui n'importe quel nom, tant qu'on s'assure que le nom de fichier se termine par **.py**, ça permet à l'ordinateur de savoir que c'est un **fichier exécutable python** et que Python peut l'exécuter. +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. -Une fois que le fichier est sauvegardé, on peut 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. +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 à: +Sur Mac, ça ressemblera à : - cd /Users//Desktop + $ cd /Users//Desktop -Sous Linux, comme ça (il se peut que le mot Bureau soit dans une autre langue): +Sous Linux, comme ça (il se peut que le mot Bureau soit dans une autre langue) : - cd /home//Bureau + $ cd /home//Desktop -Et sous Windows, ce sera comme ça: +Et sous Windows, ce sera comme ça : - cd C:\Users\\Desktop + > cd C:\Users\\Desktop -Si vous êtes bloqué⋅e, n'hésitez pas à appeler à l'aide. +Si vous êtes bloquée, n'hésitez pas à appeler à l'aide. -Une fois que c'est bon, utilisez Python pour exécuter le fichier comme ça: +Maintenant, utilisez Python pour exécuter le code contenu dans votre fichier : $ python3 python_intro.py Hello, Django girls! -Okay! Vous venez de lancer votre premier programme python à partir d'un fichier. Vous vous sentez génial⋅e? +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: +Et maintenant, passons à un autre outil essentiel de la programmation : ## If...elif...else -Quand on code, il y a plein choses qui ne doivent être exécutées que dans certaines conditions. Pour ça, Python a quelque chose qui s'appelle le l'instruction **if**. +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). -Remplacer le code dans votre fichier **python_intro.py** par ça: +Remplacez le code dans votre fichier **python_intro.py** avec ceci : - if 3 > 2: - +```python +if 3 > 2: +``` -Si on sauvegardait ça et qu'on le lançait tel quel, on aurait l'erreur suivante: +Si nous sauvegardons ce fichier et que nous le lançons, nous obtiendrons l'erreur suivante : - $ python3 python_intro.py - File "python_intro.py", line 2 - ^ - SyntaxError: unexpected EOF while parsing - +```python +$ python3 python_intro.py +File "python_intro.py", line 2 + ^ +SyntaxError: unexpected EOF while parsing +``` -Python s'attend à se qu'on lui donne des instructions sur ce qu'il faut exécuter quand la condition `3 > 2` est vraie (ou plutôt, `True`). Faisons-lui afficher "Ça marche!". Remplacez le code dans **python_intro.py** par ça: +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 : - if 3 > 2: - print('Ça marche!') - +```python +if 3 > 2: + print('It works!') +``` -Vous remarquez comme on a décalé la seconde ligne de code de 4 espaces sur la gauche? On appelle ça indenter. On a besoin de le faire pour que Python sache quel code lancer si la condition est vraie. Un seul espace suffirait, mais à peu près tous⋅tes les programmeur⋅se⋅s Python pensent que 4, c'est plus clair. Une tabulation compte aussi 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. Une seule `tab` (tabulation) compte également comme 4 espaces. -Sauvegardez le fichier et relancez le: +Sauvegardez le fichier et relancez le : $ python3 python_intro.py - Ça marche! + Ça marche ! -### Et sinon? +### Et que se passe-t-il si une condition n’est pas vraie ? -Dans le dernier exemple, le code était exécuté quand la condition est vraie. Mais Python a aussi des instructions `elif` et `else`: +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) : - if 5 > 2: - print('5 est effectivement plus grand que 2') - else: - print("5 n'est pas plus grand que 2") - +```python +if 5 > 2: + print('5 est effectivement plus grand que 2') +else: + print("5 n'est pas plus grand que 2") +``` -Quand on lance ça, ça affiche: +Lorsque vous exécuterez le code, ceci s'affichera : $ 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. Facile, non? Voyons voir comment `elif` marche: +Et si 2 était plus grand que 5, la seconde commande serait exécutée. Facile, non ? Voyons comment `elif` fonctionne : - name = 'Sonja' - if name == 'Ola': - print('Hey Ola!') - elif name == 'Sonja': - print('Hey Sonja!') - else: - print('Hey anonymous!') - +```python +name = 'Sonja' +if name == 'Ola': + print('Hey Ola!') +elif name == 'Sonja': + print('Hey Sonja!') +else: + print('Hey anonymous!') +``` -On l'exécute: +Exécutons le code : $ python3 python_intro.py Hey Sonja! -Vous voyez ce qu'il s'est passé? +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 : + +```python +volume = 57 +if volume < 20: + print("C'est plutôt calme.") +elif 20 <= volume < 40: + print("Une jolie musique de fond.") +elif 40 <= volume < 60: + print("Parfait, je peux entendre tous les détails du morceau.") +elif 60 <= volume < 80: + print("Parfait pour faire la fête !") +elif 80 <= volume < 100: + print("Un peu trop fort !") +else: + print("Au secours ! Mes oreilles ! :(") +``` + +Python va tester les différentes conditions puis il affichera ceci : + + $ python3 python_intro.py + Parfait, je peux entendre tous les détails du morceau. + ### Résumé -Avec ces trois derniers exercices, vous avez appris: +Avec ces trois derniers exercices, vous avez appris : -* **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` -* **Sauvegarder des fichiers** - stocker votre code dans des fichiers pour pouvoir écrire des programmes plus longs. +* **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. -Il est temps d'attaquer la dernière partie de ce chapitre! +Il est temps d'attaquer la dernière partie de ce chapitre ! -## Vos propres fonctions! +## Vos propres fonctions ! -Vous vous souvenez des fonctions comme `len()` que vous pouvez exécuter en Python? Et bien, bonne nouvelle, vous allez apprendre comment écrire vos propres fonctions! +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. On va commencer par quelque chose de facile. Remplacer le code de **python_intro.py** avec ça: +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 : - def hi(): - print('Hi there!') - print('How are you?') - - hi() - +```python +def hi(): + print('Hi there!') + print('How are you?') + +hi() +``` -Voilà, notre première fonction est prête! +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 de haut en 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. 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. -Lançons le pour voir ce qui se passe: +Lançons notre code pour voir ce qui se passe : $ python3 python_intro.py Hi there! How are you? -C'était facile! Construisons maintenant notre première fonction avec des paramètres. Dans l'exemple précédent, on avait une fonction que dit "Salut" à la personne qui la lance. Faisons pareil, mais avec un nom: +C'était facile ! 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 : - def hi(name): - +```python +def hi(name): +``` -Comme vous le voyez, on a donné à notre fonction un paramètre appelé `name`: +Comme vous le voyez, nous avons donné à notre fonction un paramètre appelé `name` : - def hi(name): - if name == 'Ola': - print('Hi Ola!') - elif name == 'Sonja': - print('Hi Sonja!') - else: - print('Hi anonymous!') - - hi() - +```python +def hi(name): + if name == 'Ola': + print('Hi Ola!') + elif name == 'Sonja': + print('Hi Sonja!') + else: + print('Hi anonymous!') -Comme vous voyez, on a dur mettre deux indentations avant la fonction `print`, parce que le `if` a besoin de savoir ce qui doit se passer quand la condition est vraie. Voyons voir comment ça marche: +hi() +``` - $ 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' - +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 : -Oups, une erreur. Heureusement, Python nous donne un message d'erreur assez utile. Il nous dit que la fonction `hi()` (celle qu'on a définie) a besoin d'un argument (qu'on a appelé `name`) et que nous avons oublier de le passer quand nous avons appelé la fonction. Corrigeons la dernière ligne du fichier: +```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' +``` - hi("Ola") - +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 : -et relançons le: +```python +hi("Ola") +``` + +Et exécutez votre code à nouveau : $ python3 python_intro.py Hi Ola! -Ey si on change le nom? +Et que se passe-t-il quand on change de nom ? - hi("Sonja") - +```python +hi("Sonja") +``` -et qu'on le lance: +Exécutez votre code à nouveau : $ python3 python_intro.py Hi Sonja! -Et maintenant, qu'est-ce qui se passera si on met un autre nom (Ni Ola ni Sonja)? Essayez et voyez si vous arriver à deviner. Ça devrait afficher ça: +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 : Hi anonymous! -Super, non? Avec ça, vous n'avez pas besoin de vous repéter quand vous voulez changer le nom de la personne à saluer. Et c'est exactement pour ça qu'on a besoin de fonctions: parce qu'on ne veut jamais avoir à répéter du 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 maintenant quelque chose de plus malin -- il existe plus de deux noms, et ce serait un peu dur d'écrire une condition pour chacune, non? +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 ? - def hi(name): - print('Hi ' + name + '!') - - hi("Rachel") - +```python +def hi(name): + print('Hi ' + name + '!') + +hi("Rachel") +``` -Appelons le code: +Exécutons à nouveau notre code : $ python3 python_intro.py Hi Rachel! -Bravo! Vous venez d'apprendre à écrire des fonctions :)! +Félicitations ! Vous venez juste d’apprendre à écrire des fonctions ! :) ## Les boucles -Et voici la dernière partie. Ça a été vite, non? :) +C’est déjà la dernière partie. C’était rapide, non ? :) -On l'a déjà dit: les programmeur⋅euse⋅s sont fénéant⋅e⋅s, et n'aiment pas se répéter. Programmer, c'est automatiser des choses: on ne veut pas avoir à saluer chaque personne par son nom manuellement, non? C'est là que les boucles interviennent. +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. -Vous vous souvenez des listes? Faisons une liste de Django Girls: +Vous vous souvenez des listes ? Faisons une liste de Django Girls : - girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] - +```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 donc une boucle : - for name in girls: - +```python +for name in girls: +``` -L'instruction ~~~for~~~ se comporte un peu comme ~~~if~~~, le code qui suit doit être indenté de quatre espaces. +L'instruction ~~~for~~~ se comporte un peu comme ~~~if~~~. Le code qui suit doit donc être indenté de quatre espaces. -Voilà le code complet à mettre dans le fichier: +Voilà le code complet à mettre dans votre fichier : - def hi(name): - print('Hi ' + name + '!') - - girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] - for name in girls: - hi(name) - print('Next girl') - +```python +def hi(name): + print('Hi ' + name + '!') -Et quand on le lance: +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +for name in girls: + hi(name) + print('Next girl') +``` + +Exécutez votre code : $ python3 python_intro.py Hi Rachel! @@ -701,15 +800,16 @@ Et quand on le lance: Next girl -Comme vous le voyez, tout ce qu'on met dans un `for` avec une indentation est repété pour chaque élément de la liste `girls`. +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`. Vous pouvez aussi utiliser `for` sur des nombres grâce à la fonction `range`: - for i in range(1, 6): - print(i) - +```python +for i in range(1, 6): + print(i) +``` -Ce qui affiche: +Ce qui affiche : 1 2 @@ -718,16 +818,16 @@ Ce qui affiche: 5 -`range` est une fonction qui crée une liste de nombres qui se suivent (c'est vous qui donnez l'intervale via les paramètres). +`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). -Remarquez 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). +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). C'est lié au fait que "range" est à moitié ouvert. Cela signifie qu'il inclue la première valeur mais, pas la dernière. ## Résumé -Et voilà! **Vous roxez du poney!** Ça n'était pas si facile que ça, vous pouvez être fière de vous. En tout cas, nous, on est fiers de vous pour être arrivée jusque ici! +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ère de vous ! -Allez donc vous chercher un cupcake avant de passer au chapitre suivant :) +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 :) ![Cupcake][3] - [3]: images/cupcake.png + [3]: images/cupcake.png \ No newline at end of file diff --git a/fr/template_extending/README.md b/fr/template_extending/README.md index bec5be094a7..69fb14278ef 100755 --- a/fr/template_extending/README.md +++ b/fr/template_extending/README.md @@ -1,14 +1,14 @@ # Héritage de template -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. +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 de vous é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 que dans un seul template! +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! ## Créer un template de base Un template de base est le template le plus simple que vous pouvez faire hériter à chaque page de votre site web. -Créons le fichier `base.html` dans le dossier `blog/templates/blog/`: +Créons le fichier `base.html` dans le dossier `blog/templates/blog/` : blog └───templates @@ -17,7 +17,7 @@ Créons le fichier `base.html` dans le dossier `blog/templates/blog/`: post_list.html -Ensuite, ouvrez ce fichier `base.html` 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 : ```html {% load staticfiles %} @@ -26,7 +26,6 @@ Ensuite, ouvrez ce fichier `base.html` et collez-y tout ce qui se trouve dans le Django Girls blog - @@ -53,9 +52,8 @@ Ensuite, ouvrez ce fichier `base.html` et collez-y tout ce qui se trouve dans le ``` - -Puis, dans le fichier `base.html`, remplacer tout ce qui se trouve dans `` (de `` à ``) par ceci: +Puis, dans le fichier `base.html`, remplacez tout ce qui se trouve dans `` (de `` à ``) par ceci : ```html @@ -72,19 +70,17 @@ Puis, dans le fichier `base.html`, remplacer tout ce qui se trouve dans ``
``` - -{% raw %}Nous venons concrètement de remplacer tout ce qui se trouve entre `{% for post in posts %}{% endfor %}` par:{% endraw %} +Nous venons concrètement de remplacer tout ce qui se trouve entre `{% for post in posts %}{% endfor %}` par : ```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. -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. - -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: +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 : ```html {% for post in posts %} @@ -97,16 +93,14 @@ Maintenant, sauvegardez votre fichier puis ouvrez à nouveau `blog/templates/blo
{% endfor %} ``` - -Maintenant, ajoutez cette ligne au début du fichier: +Maintenant, ajoutez cette ligne au début du fichier : ```html {% extends 'blog/base.html' %} ``` - -Vous venez de permettre à `post_list.html` d'hériter du template de `base.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 vous venons juste d'insérer. Votre fichier doit maintenant ressembler à ceci: +{% 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 vous venons juste d'insérer. Comme ceci :{% endraw %} ```html {% extends 'blog/base.html' %} @@ -123,8 +117,7 @@ Vous venez de permettre à `post_list.html` d'hériter du template de `base.html {% endfor %} {% endblock content %} ``` - -Et voilà! Vérifiez que votre site fonctionne toujours correctement:) +Et voilà ! 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 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`. \ No newline at end of file diff --git a/fr/whats_next/README.md b/fr/whats_next/README.md index 3e8487456b3..e9176ae47be 100755 --- a/fr/whats_next/README.md +++ b/fr/whats_next/README.md @@ -1,26 +1,25 @@ # La suite? -Un immense bravo à vous! **Vous êtes totalement géniale**. Nous sommes fièr·e·s de vous! < 3 +Un immense bravo à vous ! **Vous êtes totalement géniale**. Nous sommes fière de vous ! < 3 -### Que faire maintenant? +### Que faire maintenant ? Faites une pause et détendez-vous. Vous venez d'accomplir quelque chose de vraiment énorme. Après ça, vous pouvez : -* Suivez Django Girls sur [Facebook][1] ou [Twitter][2] pour être tenu·e au courant +* Suivez Django Girls sur [Facebook][1] ou [Twitter][2] pour être tenue au courant [1]: http://facebook.com/djangogirls [2]: http://twitter.com/djangogirls -### À la recherche de ressources supplémentaires? +### À la recherche de ressources supplémentaires ? Jetez un coup d’œil à notre autre livre, [Django Girls Tutorial: Extensions][3] (en anglais). [3]: http://djangogirls.gitbooks.io/django-girls-tutorial-extensions/ -Vous pouvez aussi essayer les ressources suivantes. Elles sont toutes recommandables! - +Ensuite, vous pouvez essayer les ressources listée ci-dessous. Elles sont toutes recommandables ! - [Django's official tutorial][4] - [New Coder tutorials][5] - [Code Academy Python course][6] @@ -28,13 +27,13 @@ Vous pouvez aussi essayer les ressources suivantes. Elles sont toutes recommanda - [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] +- [Two Scoops of Django: Best Practices for Django 1.8 book][11] - [4]: https://docs.djangoproject.com/en/1.7/intro/tutorial01/ + [4]: https://docs.djangoproject.com/en/1.8/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.org/products/two-scoops-of-django-1-6 + [11]: http://twoscoopspress.com/products/two-scoops-of-django-1-8 \ No newline at end of file diff --git a/hu/GLOSSARY.md b/hu/GLOSSARY.md new file mode 100644 index 00000000000..0b906ac1f3c --- /dev/null +++ b/hu/GLOSSARY.md @@ -0,0 +1,3 @@ +# kódszerkesztő + +A kódszerkesztő egy alkalmazás, amely segítségével elmentheted a kódodat, így később vissza tudsz térni hozzá. A [Kódszerkesztő fejezetből](./code_editor/README.md) tudhatod meg, hogyan juthatsz hozzá \ No newline at end of file diff --git a/hu/README.md b/hu/README.md new file mode 100644 index 00000000000..803023efded --- /dev/null +++ b/hu/README.md @@ -0,0 +1,51 @@ +# Django Girls Tutorial + +[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/DjangoGirls/tutorial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +> Ez az anyag Creative Commons Attribution-ShareAlike 4.0 International License jogvédelme alatt áll. A licenc megtekintéséhez látogass el ide: http://creativecommons.org/licenses/by-sa/4.0/ + +## Fordítás +A tutorial magyar fordítását egy csapat lelkes önkéntes készítette el: Czapári Dóri, Hanna Kollo, Erő Julcsi, Bónis Balázs, Kádár Szilvi, Szelle Erika, Téglássy Anna, Szabó Adrienn, Nádudvari György. Köszönjük nekik! <3 + +## Bevezetés + +Érezted már úgy hogy a világ egyre inkább a technológiáról szól, és te valahogy kimaradsz belőle? Gondolkoztál már azon, hogyan kell egy weblapot létrehozni, de soha nem volt elég erőd elkezdeni? Érezted úgy, hogy a szoftveres világ túl bonyolult ahhoz, hogy egyáltalán megpróbálj valamit létrehozni benne magadtól? + +Nos, jó hírünk van számodra! A programozás egyáltalán nem olyan nehéz, mint amilyennek tűnik, és mi megmutatjuk, hogy mennyire jó móka tud lenni. + +Ez a tutorial nem fog téged egy csapásra programozóvá változtatni. Ha profi akarsz lenni benne, hónapokat vagy akár éveket kell eltöltened tanulással és gyakorlással. De meg szeretnénk mutatni, hogy a programozás, illetve a weblapkészítés nem annyira bonyolult, mint amilyennek tűnik. Megpróbáljuk minél jobban elmagyarázni a különböző részleteket, hogy ne tűnjön annyira ijesztőnek a technológia. + +Reméljük, veled is annyira megszerettetjük a számítógépek világát, mint amennyire mi szeretjük! + +## Mit fogsz a tutorial alatt megtanulni? + +A tutorial befejezésével lesz egy egyszerű, működő webes alkalmazásod: a saját blogod. Megmutatjuk, hogyan kell a netre feltölteni, hogy mások is lássák az eredményt! + +Körülbelül így fog kinézni: + +![Figure 0.1][2] + + [2]: images/application.png + +> Ha egyedül dolgozol a tutorialon és nincs melletted coach, aki segíthetne, ha bármi probléma felmerül, használd a chatet, amit neked tartunk fenn: [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/DjangoGirls/tutorial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge). Megkértük a segítőinket és korábbi résztvevőket, hogy legyenek fent, ahogy idejük engedi, és segítsenek másoknak a tutorialban. Kérdezz tőlük bátran! + +Oké, [kezdjük az elejénél...][3] + + [3]: ./how_the_internet_works/README.md + +## A tutorialról és a közreműködésről + +Ezt a tutorialt a [DjangoGirls][4] tartja fenn. Ha bármilyen hibát találsz benne, vagy frissíteni szeretnéd, kérlek kövesd a [közreműködési útmutatót][5]. + + [4]: http://djangogirls.org/ + [5]: https://github.com/DjangoGirls/tutorial/blob/master/README.md + +## Szeretnél segíteni lefordítani a tutorialt más nyelvekre? + +A fordításokat jelenleg a crowdin.com platformon végezzük: + +https://crowdin.com/project/django-girls-tutorial + +Ha a te nyelved nem szerepel a crowdin listán, kérlek [hozz létre egy új issue-t][6], amely megjelöli a nyelvet, hogy hozzáadhassuk. + + [6]: https://github.com/DjangoGirls/tutorial/issues/new \ No newline at end of file diff --git a/hu/SUMMARY.md b/hu/SUMMARY.md new file mode 100644 index 00000000000..32bf04596b8 --- /dev/null +++ b/hu/SUMMARY.md @@ -0,0 +1,26 @@ +# Összefoglaló + +* [Bevezetés](README.md) +* [Installáció](installation/README.md) +* [Hogy működik az Internet?](how_the_internet_works/README.md) +* [Bevezetés a parancssor használatába](intro_to_command_line/README.md) +* [A Python telepítése](python_installation/README.md) +* [Kódszerkesztő (editor)](code_editor/README.md) +* [Bevezetés a Pythonba](python_introduction/README.md) +* [Mi a Django?](django/README.md) +* [Django telepítés](django_installation/README.md) +* [Az első Django projekted!](django_start_project/README.md) +* [Django modellek](django_models/README.md) +* [Django admin](django_admin/README.md) +* [Deploy!](deploy/README.md) +* [Django url-ek](django_urls/README.md) +* [Django views - itt az ideje alkotni!](django_views/README.md) +* [Bevezetés a HTML-be](html/README.md) +* [Django ORM és QuerySet-ek](django_orm/README.md) +* [Dinamikus adatok a template-ben](dynamic_data_in_templates/README.md) +* [Django sablonok (template)](django_templates/README.md) +* [CSS - Tegyük széppé!](css/README.md) +* [Template-kiegészítés](template_extending/README.md) +* [Egészítsd ki az applikációdat](extend_your_application/README.md) +* [Django űrlapok](django_forms/README.md) +* [Következő lépések](whats_next/README.md) diff --git a/hu/code_editor/README.md b/hu/code_editor/README.md new file mode 100644 index 00000000000..dd6521f1a3b --- /dev/null +++ b/hu/code_editor/README.md @@ -0,0 +1,7 @@ +# Kódszerkesztő (editor) + +Nemsokára megírod a kód első sorát, itt az ideje letölteni egy kódszerkesztőt! + +> **Megjegyzés:** Lehet, hogy ezt már megtetted a Telepítés fejezet olvasása során - ha igen, ugorj előre a következő fejezetre! + +{% include "/code_editor/instructions.md" %} diff --git a/hu/code_editor/instructions.md b/hu/code_editor/instructions.md new file mode 100644 index 00000000000..9ca929c50a5 --- /dev/null +++ b/hu/code_editor/instructions.md @@ -0,0 +1,31 @@ +Sokféle kódszerkesztő program létezik, és valójában ízlés kérdése, hogy ki melyiket választja. A legtöbb Python programozó bonyolult fejlesztői környezetet (IDE - Integrated Development Environment) használ, mint például a PyCharm. Egy kezdőnek viszont nem ezek a legmegfelelőbbek. A programok, amiket mi ajánlunk, hasonlóan hatékonyak, de használatuk sokkal egyszerűbb. + +Mi az alábbiakat javasoljuk, de nyugodtan kérj segítséget a coach-odtól, ő is könnyen tud tanácsot adni ez ügyben. + +## Gedit + +A Gedit egy open-source (nyílt forráskódú), ingyenes kódszerkesztő, az összes jelenlegi operációs rendszeren elérhető. + +[Letöltés](https://wiki.gnome.org/Apps/Gedit#Download) + +## Sublime Text 2 + +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](http://www.sublimetext.com/2) + +## Atom + +Az Atom egy teljesen új kódszerkesztő, amelyet a [GitHub](http://github.com/) hozott létre. Ingyenes, nyílt forráskódú, könnyen telepíthető és könnyen használható. Elérhető Windows-on, OSX-en és Linuxon. + +[Letöltés](https://atom.io/) + +## Miért telepítünk kódszerkesztőt? + +Most talán azon gondolkozol, miért telepítünk speciális kódszerkesztőt, ahelyett, hogy a Word vagy a Notepad alkalmazást használnánk. + +Az első ok az, hogy a kódot **egyszerű szövegként** kell szerkeszteni. Az általános (nem programozóknak szánt) szövegszerkesztőkkel, mint a Word és a Textedit, az a probléma, hogy nem egyszerű szöveges fájlt állítanak elő, hanem formázott dokumentumot (például [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format) formátumban), amelyben számít például a betűtípus, formázás, stb. + +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 diff --git a/hu/css/README.md b/hu/css/README.md new file mode 100644 index 00000000000..7dddabaa815 --- /dev/null +++ b/hu/css/README.md @@ -0,0 +1,295 @@ +# CSS - csinosítsd ki! + +Egyelőre nem túl szép a blogunk, igaz? Itt az ideje, hogy kicsinosítsd! Erre a CSS-t fogjuk használni. + +## Mi a CSS? + +A CSS (Cascading Style Sheets) egy nyelv, amit a HTML-ben megírt weboldalak kinézetének leírására használunk. Vagyis mintha kisminkelnéd a weboldaladat ;). + +De nem akarjuk megint az alapoktól kezdeni, igaz? Itt is olyasmit fogunk felhasználni, amit más programozók már létrehoztak, és szabadon elérhetővé tettek az Interneten. Minek találnánk fel újra a spanyolviaszt? + +## Használjunk Bootstrapet! + +A Bootstrap az egyik legnépszerűbb HTML és CSS keretrendszer, amivel szép weboldalakat készíthetünk: http://getbootstrap.com/ + +Eredetileg a Twitternél dolgozó programozók készítették, de most önkéntesek fejlesztik szerte a világon. + +## Bootstrap telepítés + +Hogy telepítsd a Bootstrapet, add hozzá a következő a sorokat a `` részhez a `.html` fájlodban (`blog/templates/blog/post_list.html`): + +```html + + +``` + +Ezzel nem adsz hozzá új fájlokat a projektedhez, csak az Interneten létező fájlokra hivatkozol. Nyisd meg újra a weboldaladat, és frissítsd! Itt is van! + +![14.1 ábra][1] + + [1]: images/bootstrap1.png + +Már sokkal jobban néz ki! + +## Statikus fájlok a Django-ban + +Most nézzük meg kicsit közelebbről ezeket a "**statikus fájl**"-nak nevezett dolgokat. A CSS-ed és az összes képfájl statikus fájlnak számít -- ilyen minden, ami nem dinamikus, vagyis aminek a tartalma nem függ a kontextustól (magyarul a weboldal aktuális állapotától), és ezért minden felhasználó számára ugyanaz. + +### 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. + +Ehhez pedig létre kell hozunk egy "`static`" nevű könyvtárat a blog applikáción belül: + + djangogirls + ├── blog + │ ├── migrations + │ └── static + └── 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. + +## Az első CSS fájlod! + +Írjunk egy CSS fájlt, hogy hozzáadd a saját stílusodat a weboldaladhoz. Hozz létre egy `css` nevű könyvtárat a `static` könyvtárban! Majd hozz létre egy új fájlt `blog.css` néven a `css` könyvtárban. Kész vagy? + + djangogirls + └─── blog + └─── statikus + └─── 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]: http://www.codecademy.com/tracks/web + +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`. + + [3]: http://www.w3schools.com/cssref/css_colornames.asp + +A `blog/static/css/blog.css` fájlba írd bele a következő kódot: + +```css +h1 a { + color: #FCA205; +} +``` + +A `h1 a` egy CSS szelektor. Ez azt jelenti, hogy alkalmazzuk a stílusunkat minden olyan `a` elemre, ami egy `h1` elemen belül van (például, mikor valami ilyesmi van a kódban: `

link

`). Ebben az esetben azt mondjuk, hogy változtasd meg a kiválasztott elem színét `#FCA205`-re, ami narancssárgát jelent. Természetesen nyugodtan használd a saját színedet itt! + +A CSS fájlban mondjuk meg, hogy nézzenek ki a HTML fájl elemei. Az egyes elemek beazonosíthatók az elemek nevei alapján (pl. `a`, `h1`, `body`), és a `class` vagy az `id` attribútumaik alapján. A class és az id olyan nevek, amelyeket te adhatsz meg az elemeknek. A class attribútum elemek egy csoportjára vonatkozik, míg az id-val kifejezetetten egy elemet tudunk beazonosítani. A következő tag például beazonosítható akár az "`a`" tag névvel, az `external_link` class-szal vagy a `link_to_wiki_page` id-val: + +```html + +``` + +Olvass utána a [CSS szelektorokról a w3schools oldalán][4]. + + [4]: http://www.w3schools.com/cssref/css_selectors.asp + +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 %} +``` + +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: + +```html + +``` + +Most megmondtuk a template-ünknek, hol találja a CSS fájlokat. + +Így kellene kinéznie a fájlodnak: + +```html +{% load staticfiles %} + + + Django Girls blog + + + + + + + + {% for post in posts %} +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+ {% endfor %} + + +``` + + +Oké, mentsd el a fájlt és frissítsd be az oldalt! + +![14.2 ábra][5] + + [5]: images/color2.png + +Szép munka! Lehet, hogy jó lenne adni egy kis "teret" a weboldalunknak és növelni a bal oldali margót. Próbáljuk meg! + +```css +body { + padding-left: 15px; +} +``` + +Írd hozzá a CSS fájlodhoz, mentsd el és lássuk, működik-e! + +![14.3 ábra][6] + + [6]: images/margin2.png + +Lehet, hogy testre szabhatnánk a betű stílusát a header-ünkben. A következő sort másold bele a ``-be a `blog/templates/blog/post_list.html` fájlon belül: + +```html + +``` + +Ez a sor beimportál egy *Lobster* nevű betűtípust a Google Fonts-ból (https://www.google.com/fonts). + +Most add hozzá a `font-family: 'Lobster';` sort a `blog/static/css/blog.css` fájlodban, a `h1 a` stílusát meghatározó blokkhoz (ez a `{` kapcsos zárójel `}` közötti kód) és frissítsd az oldalt: + +```css +h1 a { + color: #FCA205; + font-family: 'Lobster'; +} +``` + +![14.3 ábra][7] + + [7]: images/font.png + +Szuper! + +Ahogy fentebb említettük, a CSS-ben van egy "class" nevű fogalom, ami alapvetően azt teszi lehetővé, hogy elnevezd a HTML kódod egy részét és alkalmazz rajta egy stílust, csak ezen a részen, ami így nem befolyásolja a többit. Nagyon hasznos tud lenni, például amikor van két dived, amelyek nagyon különböző dolgokat csinálnak (akár a header-ed vagy a post-od), tehát nem akarod, hogy ugyanúgy nézzenek ki. + +Menj végig és nevezd el egy részét a HTML kódodnak. Adj egy `page-header` nevű class-t a `div`-edhez, amelyik a header-t tartalmazza, akárcsak így: + +```html + +``` + +És most adj egy `post` class-t a `div`-hez, ami a blog postokat tartalmazza. + +```html +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+``` + +Most pedig adjunk stílusblokkokat a különböző szelektorokhoz. A `.` -tal kezdődő szelektorok classokra utalnak. Rengeteg szuper tutorial és magyarázat található a weben a CSS-ről, ami segít megérteni a következő kódot. Most csak másold ki és illeszd be a `blog/static/css/blog.css` fájlodba: + +```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; +} +``` + +Ezután jelöld ki a HTML kódot, ami a post-okat jeleníti meg egy class="post" attribútummal. Cseréld le ezt: + +```html +{% for post in posts %} +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% endfor %} +``` + +a `blog/templates/blog/post_list.html` fájlban ezzel: + +```html +
+
+
+ {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+ {% endfor %} +
+
+
+``` + +Mentsd el a fájlokat és frissítsd az oldalad. + +![14.4 ábra][8] + + [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. + +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 diff --git a/fr/css/images/images/bootstrap1.png b/hu/css/images/bootstrap1.png similarity index 100% rename from fr/css/images/images/bootstrap1.png rename to hu/css/images/bootstrap1.png diff --git a/fr/css/images/images/color2.png b/hu/css/images/color2.png similarity index 100% rename from fr/css/images/images/color2.png rename to hu/css/images/color2.png diff --git a/fr/css/images/images/final.png b/hu/css/images/final.png similarity index 100% rename from fr/css/images/images/final.png rename to hu/css/images/final.png diff --git a/fr/css/images/images/font.png b/hu/css/images/font.png similarity index 100% rename from fr/css/images/images/font.png rename to hu/css/images/font.png diff --git a/fr/css/images/images/margin2.png b/hu/css/images/margin2.png similarity index 100% rename from fr/css/images/images/margin2.png rename to hu/css/images/margin2.png diff --git a/hu/deploy/README.md b/hu/deploy/README.md new file mode 100644 index 00000000000..2e0488ac7a7 --- /dev/null +++ b/hu/deploy/README.md @@ -0,0 +1,314 @@ +# Deploy! + +> **Megjegyzés** A következő fejezet néhol kissé bonyolult lehet. Tarts ki és vedd át az egész fejezetet; ugyanis most a webfejlesztés egy nagyon fontos része következik - az ún. deployment. Ez a fejezet a tutorial közepén található, így majd a mentorod is tud segíteni a trükkösebb részeknél, miközben a honlapodat online is elérhetővé teszed. Magát a tutorialt később egyedül is befejezheted, ha esetleg kifutnál az időből. + +Ezidáig a honlapod csak a saját számítógépeden volt elérhető - most tanuljuk meg, hogyan tegyük mások számára is elérhetővé! Ez az ún. deploying - az a tevékenység, amely során az alkalmazásodat közzé teszed az interneten, hogy mások is láthassák és használhassák azt :). + +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]: http://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]: http://www.github.com + +A GitHubról fogjuk a forráskódunkat áthelyezni a PythonAnywhere-be, és fordítva. + +# 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 + +> **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! + +{% include "/deploy/install_git.md" %} + +## Készítsünk Git repository-t + +A Git nyomon követi a változásokat az adott fájlokban egy ún. csomagtárban (repository vagy röviden "repo"). Nyissunk egy új repo-t a projektünknek. Nyisd fel a konzolt és futtasd le a következő parancsokat, a `djangogirls` mappában: + +> **Megjegyzés** Az alábbi parancsokkal ellenőrizheted a munkamappát (working directory, az éppen megnyitott mappa): `pwd` (OSX/Linux) vagy `cd` (Windows) mielőtt létrehoznád a repositoryt. A `djangogirls` mappában kell lenned. + + $ git init + Initialized empty Git repository in ~/djangogirls/.git/ + $ git config --global user.name "Your Name" + $ git config --global user.email you@example.com + + +A git csomagtár inicializálása olyasvalami, amit minden projekt esetében csak egyszer kell véghezvinni (így majd nem kell újra és újra megadni a felhasználónevet ill. jelszót). + +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 + + +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. + +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 + + Untracked files: + (use "git add ..." to include in what will be committed) + + .gitignore + blog/ + manage.py + mysite/ + + nothing added to commit but untracked files present (use "git add" to track) + + +Végül mentsük le a változtatásokat. A konzolban futtasd le a következő parancsokat: + + $ git add -A . + $ git commit -m "My Django Girls app, first commit" + [...] + 13 files changed, 200 insertions(+) + create mode 100644 .gitignore + [...] + create mode 100644 mysite/wsgi.py + + +## Forráskód feltöltése a GitHubra + +A böngészőben keresd fel a [GitHub.com][2] honlapot és regisztrálj be egy új "free user" fiókba. (Ha már beregisztráltál, ezt a pontot kihagyhatod) + +Ezután hozz létre egy új csomagtárat ("repót"), amit nevezz "my-first-blog"-nak. Hagyd az "initialise with a README" mezőt jelöletlenül, a .gitignore lehetőséget hagyd üresen (ezt manuálisan tettük), a "License" résznél maradjon a "None" opció. + +![][3] + + [3]: images/new_github_repo.png + +> **Megjegyzés** A `my-first-blog` név fontos -- választhattál volna más nevet is, de gyakran előfordul majd a későbbiekben is a parancsokban. Valószínűleg egyszerűbb lesz számodra is, ha a `my-first-blog` nevet használod. + +A következő oldalon látni fogod a repód url-jét (repo's clone url). Válaszd a "HTTPS" verziót, másold ki - mindjárt bemásoljuk a terminálba: + +![][4] + + [4]: images/github_get_repo_url_screenshot.png + +Most összekötjük a Git csomagtárat a számítógépeden a másik csomagtárral a GitHubon. + +A konzolba írd be a következőt (helyettesítsd a `` a saját felhasználóneveddel, amivel a GitHubon regisztráltál, de a kacsacsőrök nélkül): + + $ git remote add origin https://github.com//my-first-blog.git + $ git push -u origin master + + +Add meg a GitHub felhasználónevedet és jelszódat, valami hasonlót kell hogy láss: + + 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. + + + + +A forráskódod most már fent van a GitHubon. Menj és nézd meg! Láthatod hogy jó társasága van - [Django][5], a [Django Girls Tutorial][6], és sok más szuper nyílt forráskódú szoftver forráskódja szintén a GitHubon található :) + + [5]: https://github.com/django/django + [6]: https://github.com/DjangoGirls/tutorial + +# Tegyük fel a blogot a PythonAnywhere-re + +> **Megjegyzés** Valószínűleg már létrehoztál egy PythonAnywhere fiókot korábban a telepítés során - ha így van, ezt nem kell újból megtenned. + +{% include "/deploy/signup_pythonanywhere.md" %} + +## Forráskód letöltése a PythonAnywhere-be + +Amikor bejelentkezel a PythonAnywhere-be, egyből a dashboard-on, vagy "Consoles" oldalon találod magad. Válaszd a "Bash" konzol indítása opciót -- ez a PythonAnywhere konzolja, ugyanolyan, mint a parancssor a gépeden. + +> **Megjegyzés** A PythonAnywhere Linux rendszeren alapszik, tehát ha Windows-ot használsz, a konzol egy kissé máshogy fog kinézni a te számítógépeden. + +Töltsük be a forráskódodat a GitHubról a PythonAnywhere-be egy "clone" létrehozásával. Írd be az alábbiakat a konzolba a PythonAnywhere-ben (ne felejtsd, hogy a `` helyébe a saját, GitHubon használt felhasználónevedet helyettesítsd be): + + $ git clone https://github.com//my-first-blog.git + + +Ez majd betölti a forráskódod másolatát a PythonAnywhere-be. Ellenőrizheted, ha beírod a konzolba, hogy `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 + + +### Virtuális környezet létrehozása a PythonAnywhere-en + +Ugyanúgy, ahogy a saját gépeden csináltad, a PythonAnywhere-en is létrehozhatsz virtualenvet. Írd be a Bash konzolba: + +``` +$ 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 +``` + + +> **Megjegyzés** A `pip install` lépés eltarthat pár percig. Légy türelmes! De ha több mint 5 percig tart, akkor valószínűleg valami nincs rendben. Kérdezd meg a coachodat! + + + +### 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. + +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. + + (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 + + +Í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... + + 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'. + + +### 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. + +A szerveren ugyanúgy tudod létrehozni az adatbázist, mint a saját gépeden, a `migrate` és `createsuperuser` parancsokkal: + + (mvenv) $ python manage.py migrate + Operations to perform: + [...] + Applying sessions.0001_initial... OK + + + (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. + +![][7] + + [7]: images/pythonanywhere_web_tab_virtualenv.png + +A "Virtualenv" részben kattints rá a piros szövegre: "Enter the path to a virtualenv", majd írd be: `/home//my-first-blog/myvenv/`. Kattints a kék dobozra a pipajellel, hogy elmentsd a path-t, mielőtt továbblépsz. + +> **Megjegyzés** Helyettesítsd be a saját felhasználóneved. Ha elrontasz valamit, a PythonAnywhere figyelmeztetni fog. + +### A WSGI fájl konfigurálása + +A Django a "WSGI protokollt" használja. Ez egy szabvány, ami a Python segítségével kiszolgált weboldalakra érvényes. A PythonAnywhere is támogatja ezt. Ahhoz, hogy a PythonAnywhere felismerje a Django blogunkat, egy WSGI konfigurációs fájlt kell szerkesztenünk. + +Kattints a "WSGI configuration file" linkre (a "Code" szekcióban az oldal tetejénél -- olyasmi neve lesz, hogy `/var/www/_pythonanywhere_com_wsgi.py`). Egy kódszerkesztőbe fogsz jutni. + +Törölj ki mindent, és cseréld ki valami ilyesmire: + +```python +import os +import sys + +path = '/home//my-first-blog' # itt a saját felhasználónevedet használd! +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()) +``` + +> **Megjegyzés** Ne felejtsd el a saját felhasználóneveddel helyettesíteni a ``-et! + +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. + +Nyomd meg a **Save** (Mentés) gombot, majd menj vissza a **Web** fülre. + +Kész is vagyunk! Nyomd meg a nagy zöld **Reload** gombot, és máris meg fogod tudni nézni az alkalmazásodat. Az oldal tetején fogsz találni hozzá egy linket. + +## Tippek debuggoláshoz + +Ha hibát látsz, amikor megpróbálod meglátogatni az oldaladat, az első hely, ahol információt kaphatsz a debuggoláshoz, az **error log**. Ehhez a PythonAnywhere [Web tab][8]-ján találod meg a linket. Nézd meg, hogy van-e benne bármilyen hibaüzenet; a legfrissebbek lesznek alul. Gyakran előforduló problémák: + + [8]: https://www.pythonanywhere.com/web_app_setup/ + +* Kihagytad valamelyik lépést a konzolban: a virtualenv létrehozását, aktiválását, a Django installálását a virtualenvben, a collectstatic lefuttatását, az adatbázis migrálását. + +* Valamit elrontottál a virtualenv path-ban a Web fülön -- általában egy piros hibaüzenet jelzi, ha valami gond van. + +* Valamit elrontottál a WSGI konfigurációs fájlban -- jól írtad be a my-first-blog könyvtárhoz vezető elérési útvonalat? + +* Ugyanazt a Python verziót választottad a virtualenved számára, mint az alkalmazásodhoz? Mindkettőnek a 3.4-esnek kell lennie. + +* A [PythonAnywhere wikiben is találsz néhány általános hibakeresési tippet][9]. + + [9]: https://www.pythonanywhere.com/wiki/DebuggingImportError + +És ne feledd, a coachod azért van, hogy segítsen! + +# Él a weboldalad! + +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. + +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 new file mode 100644 index 00000000000..44412f84823 Binary files /dev/null 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 new file mode 100644 index 00000000000..6e19174ec88 Binary files /dev/null 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 new file mode 100644 index 00000000000..cafa22c2d97 Binary files /dev/null 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 new file mode 100644 index 00000000000..c9d78838bf7 --- /dev/null +++ b/hu/deploy/install_git.md @@ -0,0 +1,15 @@ +### Windows + +A Gitet innen töltheted le: [git-scm.com](http://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](http://git-scm.com/), majd kövesd az utasításokat. + +### Linux + +Ha még nincs telepítve, elérhető a a package manager-en keresztül, szóval próbáld meg az alábbiakat: + + sudo apt-get install git + # vagy + sudo yum install git \ No newline at end of file diff --git a/hu/deploy/signup_pythonanywhere.md b/hu/deploy/signup_pythonanywhere.md new file mode 100644 index 00000000000..283a3a92986 --- /dev/null +++ b/hu/deploy/signup_pythonanywhere.md @@ -0,0 +1,5 @@ +Most itt az ideje, hogy létrehozz magadnak egy ingyenes, "Kezdő" ("Beginner") fiókot a PythonAnywhere oldalon. + + * [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +> **Megjegyzés:** A blogod címe, vagyis URL-je `felhasználónév.pythonanywhere.com` lesz, vagyis érdemes a regisztrációkor felhasználónévnek vagy a saját becenevedet választani, vagy a blogod témájához kapcsolódó nevet. \ No newline at end of file diff --git a/hu/django/README.md b/hu/django/README.md new file mode 100644 index 00000000000..4daf57a971a --- /dev/null +++ b/hu/django/README.md @@ -0,0 +1,27 @@ +# Mi a Django? + +A Django egy webes alkalmazások készítésére használható, Pythonban írt, ingyenes, nyílt forráskódú keretrendszer (framework). A webes keretrendszerek különböző építőelemek gyűjteményei, segítségükkel könnyebben és gyorsabban tudunk weboldalakat fejleszteni. + +Amikor weboldalt készítesz, mindig hasonló elemekre lesz szükséged: meg kell oldanod a felhasználók azonosítását (regisztráció, be- és kijelentkezés), kell egy felület a honlap kezeléséhez, formok (kérdőívek), kell valami megoldás a fájlok feltöltésére, stb. + +Szerencsére mások már régen észrevették, hogy a webfejlesztők mindig hasonló problémákkal szembesülnek egy új oldal készítésekor, ezért közösen kifejlesztettek különböző keretrendszereket (ezek egyike a Django). Ezek a frameworkok használatra kész komponenseket tartalmaznak. + +A keretrendszerek megakadályozzák, hogy újra és újra fel kelljen találnod a spanyolviaszt, és sok időt megspórolnak a weboldalkészítésben. + +## Miért van szükséged keretrendszerre? + +Hogy megértsd, pontosan mire jó a Django, fontos, hogy jobban megismerd a szervereket. Az első dolog, amit egy szervernek tudnia kell az az, hogyha szeretnéd, hogy kiszolgáljon neked egy weboldalt. + +Képzelj el egy postaládát (port), amit folyamatosan figyelnek, hogy vannak-e beérkezett levelek (requestek). Ezt csinálja egy webszerver. A webszerver elolvassa a levelet, és választ (response) küld, amiben egy weboldal van. Azonban amikor küldeni szeretnél valamit, szükséged van tartalomra. A Django ennek a tartalomnak a megalkotásában segít. + +## Mi történik, amikor valaki lekérdez egy honlapot a szerveredtől? + +Amikor beérkezik egy kérés (request) a szerverre, a Django kapja meg, ami megpróbálja kitalálni, hogy pontosan mire irányul a kérés. Először a weboldal címét nézi meg, és megpróbál rájönni, hogy mit kell tenni. Ezt a részt a Django **urlresolver** része végzi (emlékezz vissza, hogy a weboldalak címét URL-nek - Uniform Resource Locatornak - hívják, vagyis az *urlresolver* névnek - kb. url-fordító - van értelme). Ez a dolog nem túl okos - csak fog egy csomó mintát (pattern), és megpróbálja hozzájuk illeszteni az URL-t. A Django felülről lefelé vizsgálja meg a mintákat, és ha az URL valamelyikkel megegyezik, továbbadja a requestet a megfelelő function-nek (függvénynek), amit *view*-nak hívunk). + +Képzelj el egy postást egy levéllel. Ahogy halad az utcán, minden házszámot megnéz, és összehasonlítja a levélen lévővel. Ha megegyezik, bedobja a levelet a postaládába. Így működik az urlresolver! + +A *view*, vagyis "nézet" rész az, ahol az érdekes dolgok történnek: itt nézhetünk bele adatbázisokba, hogy megkeressünk valamilyen információt. Talán a felhasználó meg szeretne változtatni valamilyen adatot? Mint egy levél, ami azt írja: "Kérlek, változtasd meg a munkám leírását." A *view* megnézi, hogy jogosult vagy-e erre a módosításra, aztán megváltoztatja a munka leírását, és visszaküld egy üzenetet: "Kész!". Aztán a *view* létrehoz egy választ, amit a Django elküld a felhasználó böngészőjének. + +Természetesen ez a leírást egy kicsit leegyszerűsítettünk, de még nem kell, hogy minden technikai részletet tudj. Elég, ha van egy általános elképzelésed. + +Most ahelyett, hogy túlságosan belemennénk a részletekbe, egyszerűen csak elkezdünk létrehozni valamit a Djangóval, és menet közben fogjuk megtanulni a fontos részeket! \ No newline at end of file diff --git a/hu/django_admin/README.md b/hu/django_admin/README.md new file mode 100644 index 00000000000..41fcb46710d --- /dev/null +++ b/hu/django_admin/README.md @@ -0,0 +1,48 @@ +# Django admin + +Az előbb elkészítettük a bejegyzések modelljeit. Ahhoz, hogy létrehozhassuk, szerkeszthessük és törölhessük őket, a Django admint fogjuk használni. + +Nyisd meg a `blog/admin.py` fájlt, és cseréld ki a benne lévő kódot erre: + +```python +from django.contrib import admin +from .models import Post + +admin.site.register(Post) +``` + +Amint láthatod, importáljuk az előző fejezet végén definiált Post modellt, vagyis elérhetővé tesszük ebben a fájlban is. Hogy a modell látszódjon az admin oldalon, regisztrálnunk kell a `admin.site.register(Post)` sorral. + +Most nézzük meg, hogy néz ki a Post modell. Ne felejtsd el futtatni a `python manage.py runserver` parancsot a konzolban, hogy elindítsd a webszervert. Írd be a böngészőben a http://127.0.0.1:8000/admin/ címet. Egy ilyen login oldalt fogsz látni: + +![Login page][1] + + [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): + + (myvenv) ~/djangogirls$ python manage.py createsuperuser + Username: admin + Email address: admin@admin.com + Password: + Password (again): + Superuser created successfully. + + +Térj vissza a böngészőbe. Jelentkezz be a superuser adataival, amit az előbb adtál meg; ha minden jól megy, a Django admin dashboardra jutsz. + +![Django admin][2] + + [2]: images/django_admin3.png + +Nyisd meg a Posts részt, és kísérletezz vele egy kicsit. Hozz létre 5-6 blogposztot. Ne törődj a tartalommal - nyugodtan másolj be valami szöveget ebből a tutorialból, hogy időt spórolj :). + +Állíts be legalább két-három posztnak (de ne mindegyiknek!) egy publish date-et (megjelenési dátumot). Később jól fog jönni. + +![Django admin][3] + + [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/ + +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/fr/django_admin/images/images/django_admin3.png b/hu/django_admin/images/django_admin3.png similarity index 100% rename from fr/django_admin/images/images/django_admin3.png rename to hu/django_admin/images/django_admin3.png diff --git a/fr/django_admin/images/images/edit_post3.png b/hu/django_admin/images/edit_post3.png similarity index 100% rename from fr/django_admin/images/images/edit_post3.png rename to hu/django_admin/images/edit_post3.png diff --git a/fr/django_admin/images/images/login_page2.png b/hu/django_admin/images/login_page2.png similarity index 100% rename from fr/django_admin/images/images/login_page2.png rename to hu/django_admin/images/login_page2.png diff --git a/hu/django_forms/README.md b/hu/django_forms/README.md new file mode 100644 index 00000000000..b27d53ffd34 --- /dev/null +++ b/hu/django_forms/README.md @@ -0,0 +1,396 @@ +# Django űrlapok + +Utolsó lépésként azt fogjuk megcsinálni, hogy a blogposztokat ne csak az admin oldalon hozhassuk létre és szerkeszthessük. A Django `admin` menő, de elég nehéz személyre szabni, és nem is túl szép. A `form`ok (űrlapok) segítségével viszont majdnem mindent meg tudunk csinálni a felületünkön, amit csak szeretnénk! + +A Django formokban az a jó, hogy ha akarjuk, teljesen az alapoktól is megírhatjuk őket, de `ModelForm`-ot is létrehozhatunk, ami az űrlap eredményét a modellbe menti el. + +Pontosan ezt szeretnénk: egy űrlapot a `Post` modellünkhöz. + +Mint minden fontos résznek a Django-ban, a formoknak is megvan a maguk helye: a `forms.py` fájl. + +Hozz létre egy új fájlt ezzel a névvel a `blog` könyvtárban. + + blog + └── forms.py + + +Rendben, most nyisd meg, és írd bele a következő kódot: + +```python +from django import forms + +from .models import Post + +class PostForm(forms.ModelForm): + + class Meta: + model = Post + fields = ('title', 'text',) +``` + +Először importálnunk kell a Django formjait (`from django import forms`), és persze a `Post` modellünket is (`from .models import Post`). + +Valószínűleg már sejted, hogy a `PostForm` az űrlapunk neve lesz. Meg kell mondanunk a Django-nak, hogy ez a form egy `ModelForm` (hogy egy kis Django varázslat kerüljön bele) - ezért a `forms.ModelForm` felelős. + +Aztán a `class Meta` következik, itt mondjuk meg a Django-nak, hogy melyik modellt kell használnia az űrlap elkészítéséhez (`model = Post`). + +Legvégül megadhatjuk, hogy melyik mezők kerüljenek bele az űrlapba. Mi csak a `title` (cím) és a `text` (szöveg) mezőket szeretnénk megjeleníteni - az `author` (szerző) az a felhasználó lesz, aki éppen be van jelentkezve (te magad!), és a `created_date`-et (létrehozás dátumát) automatikusan állítja be a Django, amikor elmented a posztot, emlékszel? + +Ennyi az egész! Most már csak az van hátra, hogy használjuk az űrlapot egy *view*-ban, és megjelenítsük egy template-ben. + +Tehát még egyszer: egy link az oldalhoz, egy URL, egy view és egy template. + +## Link az oldalhoz, ahol az űrlap van + +Itt az ideje, hogy megnyisd a `blog/templates/blog/base.html` fájlt. Itt hozzáadunk egy linket a `page-header` nevű `div`hez: + +```html + +``` + +Figyelem: az új nézetünket `post_new`-nak fogjuk hívni. + +Miután hozzáadtad ezt a sort, így fog kinézni a html fájlod: + +```html +{% load staticfiles %} + + + Django Girls blog + + + + + + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ + +``` + +Ha elmented, és frissíted a http://127.0.0.1:8000 oldalt, az ismerős `NoReverseMatch` hibát kell látnod, igaz? + +## URL + +Nyisd meg a `blog/urls.py` fájlt, és add hozzá ezt a sort: + +```python + url(r'^post/new/$', views.post_new, name='post_new'), +``` + +Így fog kinézni a teljes kód: + +```python +from django.conf.urls import include, 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'), +] +``` + +Ha frissíted az oldalt, egy `AttributeError`t fogsz látni, hiszen még nincs implementálva a `post_new` nevű view. Készítsük el most rögtön. + +## post_new nézet + +Nyisd meg a `blog/views.py` fájlt, és add hozzá a következő sorokat: + +```python +from .forms import PostForm +``` + +és a *view*t: + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Ahhoz, hogy egy új `Post` űrlapot kapjunk, meg kell hívnunk a `PostForm()`-ot, és továbbadni a template-nek. Még visszatérünk erre a *view*-ra, de előbb gyorsan készítsük egy sablont a formnak. + +## Template + +Létre kell hoznunk egy `post_edit.html` nevű fájlt a `blog/templates/blog` könyvtárban. Ahhoz, hogy működjön az űrlapunk, szükségünk van pár dologra: + +* meg kell jelenítenünk az űrlapot. Ezt egyszerűen megtehetjük a `{% raw %}{{ form.as_p }}{% endraw %}` kóddal. +* az előző sort be kell csomagolnunk egy HTML form tagbe: `
...
` +* szükségünk van egy `Save` (Mentés) gombra. Ezt egy HTML gombbal tudjuk létrehozni: `` +* és végül, a nyitó `
` tag után hozzá kell adnunk ezt: `{% raw %}{% csrf_token %}{% endraw %}`. Ez nagyon fontos, mert ettől lesznek biztonságosak az űrlapjaid! A Django panaszkodni fog, ha úgy próbálod elmenteni a formot, hogy kifelejtetted ezt a részt: + +![CSFR tiltott oldal][1] + + [1]: images/csrf2.png + +Rendben, nézzük, hogy néz ki a HTML kód a `post_edit.html`-ben: + +```html +{% extends 'blog/base.html' %} + +{% block content %} +

New post

+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} +``` + +Itt az ideje, hogy frissítsd az oldalt! Juhú! Ott van az űrlapod! + +![Új űrlap][2] + + [2]: images/new_form2.png + +De várjunk csak egy percet! Ha begépelsz valamit a `title` és a `text` mezőbe, és megpróbálod elmenteni - mi történik? + +Semmi! Megint ugyanazon az oldalon vagyunk, és a szöveg eltűnt... és nem jött létre új bejegyzés. Mi romlott el? + +A válasz: semmi. Csak még egy kicsit dolgoznunk kell a *view*-n. + +## Űrlap mentése + +Nyisd meg újra a `blog/views.py` fájlt. Most mindössze ennyi van a `post_new` nézetben: + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Amikor beküldünk egy űrlapot, ugyanabba a nézetbe kerülünk vissza, de ilyenkor a `request`ben több adat van, mint korábban, egész pontosan a `request.POST`-ban (ennek az elnevezésnek nincs köze a blogban lévő "poszt"-hoz, ez annyit jelent, hogy éppen adatokat "posztolunk", vagyis küldünk). Emlékszel, hogy a HTML fájlban a `
` definíciójában szerepelt a `method="POST"` változó? Most az űrlap minden mezője bekerült a `request.POST`-ba. Semmiképp se nevezd át a `POST` (a `method` másik érvényes értéke a `GET` lenne, de most nincs idő elmagyarázni a különbséget). + +Tehát a *view*-ban két különböző esetet kell kezelnünk. Az első: amikor először kerülünk az oldalra, és egy üres űrlapot szeretnénk látni. A második: amikor visszajutunk a *view*-ba, azokkal az adatokkal, amiket épp az előbb gépeltünk be a formba. Ehhez egy feltételt kell hozzáadnunk (az `if`-et fogjuk használni). + +```python +if request.method == "POST": + [...] +else: + form = PostForm() +``` + +Itt az ideje, hogy kitöltsük a `[...]` részeket. Ha a `method` `POST`, akkor egy `PostForm`-ot szeretnénk létrehozni az űrlapban beküldött adatokból, igaz? Ezt így tehetjük meg: + +```python +form = PostForm(request.POST) +``` + +Nem nehéz! A következő, hogy ellenőrizzük, helyes-e az űrlap (minden kötelező mező ki lett-e töltve, és nem készülünk-e helytelen adatokat elmenteni). Ezt csinálja a `form.is_valid()`. + +Megnézzük, hogy érvényes-e a form, és ha igen, elmenthetjük! + +```python +if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() +``` + +Itt lényegében két dolog történik: elmentjük az űrlapot a `form.save` paranccsal, és hozzáadunk egy szerzőt (mivel nem volt `author` mező a `PostForm`-ban, viszont ez a mező kötelező!). A `commit=False` azt jelenti, hogy még nem mentjük el a `Post` modellt - előbb még hozzá akarunk adni egy szerzőt. Az idő nagy részében a `commit=False` nélkül fogod használni a `form.save()`-et, de most szükségünk van erre a részre. A `post.save()` megőrzi a változtatásokat (szerző hozzáadása), és létrehoz egy új blogposztot! + +Végül tök jó lenne, ha egyből a frissen elkészült bejegyzés `post_detail` oldalára jutnánk nem? Ehhez egy újabb importra van szükségünk: + +```python +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) +``` + +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! + +Rendben, elég sokat beszéltünk, de most már látni szeretnéd, hogy néz ki a teljes *view*, igaz? + +```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}) +``` + +Nézzük meg, hogy működik-e. Menj a http://127.0.0.1:8000/post/new/ oldalra, adj hozzá egy `title`-t és egy `text`-et, mentsd el... és voilà! Az új poszt bekerült az adatbázisba, és át lettél irányítva a `post_detail` oldalra! + +Talán észrevetted, hogy a poszt elmentése előtt beállítjuk a közzététel dátumát. Később, a **Django Girls Tutorial: Extensions** részben egy *publish* gombot is készítünk. + +Ez nagyszerű! + +## 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. + +Próbáld meg elmenteni az űrlapot `title` vagy `text` nélkül. Találd ki, mi fog történni! + +![Form validáció][3] + + [3]: images/form_validation2.png + +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). + +Nyisd meg a `blog/templates/blog/post_detail.html` fájlt, és add hozzá ezt a sort: + +```python + +``` + +Így fog kinézni a template: + +```html +{% extends 'blog/base.html' %} + +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} + +

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% endblock %} +``` + +A `blog/urls.py`-ban pedig erre a sorra lesz szükségünk: + +```python + url(r'^post/(?P[0-9]+)/edit/$', views.post_edit, name='post_edit'), +``` + +Itt újrahasznosíthatjuk a `blog/templates/blog/post_edit.html` sablont, szóval már csak egy *view* van hátra. + +Nyisd meg a `blog/views.py`-t, és add hozzá ezt a fájl végén: + +```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}) +``` + +Majdnem pont úgy néz ki, mint a `post_new` view, nem igaz? De nem teljesen. Először is átadunk egy extra `pk` paramétert az url-ekből. Aztán a `Post` modellt a `get_object_or_404(Post, pk=pk)` sorral kapjuk meg, és végül, amikor létrehozzuk a formot, ezt a posztot adjunk át `instance`-ként, amikor elmentjük: + +```python +form = PostForm(request.POST, instance=post) +``` + +és akkor is, amikor megnyitjuk az űrlapot, hogy szerkeszthessük a posztot: + +```python +form = PostForm(instance=post) +``` + +Oké, most teszteljük le, hogy működik-e! Menj a `post_detail` oldalra. Kell lennie egy szerkesztés gombnak a jobb felső sarokban: + +![Szerkesztés gomb][5] + + [5]: images/edit_button2.png + +Ha rákattintasz, megkapod az űrlapot a blogposzttal: + +![Űrlapok szerkesztése][6] + + [6]: images/edit_form2.png + +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/ + +## Biztonság + +Nagyon jó, hogy az új blogposztok írásához csak egy linkre kell kattintani! Viszont most bárki létre tud hozni egy új bejegyzést, aki meglátogatja az oldaladat, és valószínűleg ezt nem szeretnéd. Csináljuk meg, hogy a gombot csak te lásd, és mások ne. + +A `blog/templates/blog/base.html`-ben keresd meg a `page-header` `div`et, és az anchor taget, amit korábban írtál bele. Így néz ki: + +```html + +``` + +Írunk még egy `{% if %}` taget, ami arra lesz jó, hogy csak azoknak az usereknek mutassa a linket, akik be vannak jelentkezve az adminba. Most ez csak te vagy! Változtasd meg a `` taget, hogy így nézzen ki: + +```html +{% if user.is_authenticated %} + +{% endif %} +``` + +Az `{% if %}` miatt a link csak akkor küldődik át a böngészőbe, ha a felhasználó, aki lekérte az oldalt, be van jelentkezve. Ez nem akadályozza meg teljesen az új posztok létrehozását, de kezdésnek jó. A kiegészítő leckékben többet is tanulhatsz a biztonságról. + +Mivel valószínűleg be vagy jelentkezve, semmi változást nem fogsz látni, ha frissítesz. Viszont ha megnyitod az oldalt egy másik böngészőben, vagy egy inkognitóablakban, látni fogod, hogy a link nincs ott! + +## Még egy dolog: itt az ideje egy újabb deploynak! + +Nézzük meg, hogy működik-e ez az egész a PythonAnywhere-en. Itt az ideje egy újabb deploynak! + +* Először is commitold az új kódodat, és pushold GitHubra +``` +$ git status +$ git add -A . +$ git status +$ git commit -m "Added views to create/edit blog post inside the site." +$ git push +``` + +* Aztán írd be ezt a [PythonAnywhere Bash konzol][7]ba: + + [7]: https://www.pythonanywhere.com/consoles/ + + $ cd my-first-blog + $ source myvenv/bin/activate + (myvenv)$ git pull + [...] + (myvenv)$ python manage.py collectstatic + [...] + + +* Végül menj a [Web tab][8]-ra, és nyomj **Reload**ot. + + [8]: https://www.pythonanywhere.com/web_app_setup/ + +Ennyi az egész. Gratulálunk :) diff --git a/fr/django_forms/images/images/csrf2.png b/hu/django_forms/images/csrf2.png similarity index 100% rename from fr/django_forms/images/images/csrf2.png rename to hu/django_forms/images/csrf2.png diff --git a/fr/django_forms/images/images/drafts.png b/hu/django_forms/images/drafts.png similarity index 100% rename from fr/django_forms/images/images/drafts.png rename to hu/django_forms/images/drafts.png diff --git a/fr/django_forms/images/images/edit_button2.png b/hu/django_forms/images/edit_button2.png similarity index 100% rename from fr/django_forms/images/images/edit_button2.png rename to hu/django_forms/images/edit_button2.png diff --git a/fr/django_forms/images/images/edit_form2.png b/hu/django_forms/images/edit_form2.png similarity index 100% rename from fr/django_forms/images/images/edit_form2.png rename to hu/django_forms/images/edit_form2.png diff --git a/fr/django_forms/images/images/form_validation2.png b/hu/django_forms/images/form_validation2.png similarity index 100% rename from fr/django_forms/images/images/form_validation2.png rename to hu/django_forms/images/form_validation2.png diff --git a/fr/django_forms/images/images/new_form2.png b/hu/django_forms/images/new_form2.png similarity index 100% rename from fr/django_forms/images/images/new_form2.png rename to hu/django_forms/images/new_form2.png diff --git a/fr/django_forms/images/images/post_create_error.png b/hu/django_forms/images/post_create_error.png similarity index 100% rename from fr/django_forms/images/images/post_create_error.png rename to hu/django_forms/images/post_create_error.png diff --git a/hu/django_installation/README.md b/hu/django_installation/README.md new file mode 100644 index 00000000000..e1f8f731196 --- /dev/null +++ b/hu/django_installation/README.md @@ -0,0 +1,5 @@ +# Django telepítés + +> **Megjegyzés** Ha elvégezted a legelső, Installáció című fejezetet, már túlvagy ezen - ugorj a következő fejezetre! + +{% include "/django_installation/instructions.md" %} diff --git a/hu/django_installation/instructions.md b/hu/django_installation/instructions.md new file mode 100644 index 00000000000..6019929aa47 --- /dev/null +++ b/hu/django_installation/instructions.md @@ -0,0 +1,113 @@ +> Ennek a fejezetnek egy része a Geek Girls Carrots (http://django.carrots.pl/) tutorialjain alapul. +> +> A fejezet részben a [django-marcador tutorial](http://django-marcador.keimlink.de/)-on alapszik, ami a Creative Commons Attribution-ShareAlike 4.0 International License jogvédelem alatt áll. A django-marcador tutorial jogvédelem alatt áll, Markus Zapke-Gründemann et al által. + +## Virtuális környezet + +Mielőtt feltelepítjük a Django-t, egy rettentő hasznos eszközt fogunk installálni, ami segít, hogy a kódolói környezetedet rendben tartsa a számítógépeden. Át lehet ugrani ezt a lépést, de nem ajánlott. Ha a lehető legjobb kiindulási helyzetből kezded a kódolást, sok bosszúságot megspórolhatsz magadnak a jövőben! + +Tehát először is hozzunk létre egy **virtuális környezetet** (virtual environment), amit *virtualenv*-nek is hívunk. A virtualenv projektenként különíti el a Python/Django környezetet. Ez azt jelenti, hogy ha megváltoztatsz valamit egy weboldalon, az nem lesz hatással a többi weboldalra, amit párhuzamosan fejlesztesz. Jó, igaz? + +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). + +Ehhez a tutorialhoz egy új, `djangogirls` nevű mappát fogunk használni a home könyvtáradon belül: + + mkdir djangogirls + cd djangogirls + + +Most pedig létrehozunk egy `myvenv` nevű virtuális környezetet. A kód általánosan így néz ki: + + 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: + + C:\Users\Name\djangogirls> C:\Python34\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! + +### 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: + + ~/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:** 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 +> +> +> Hogy ezt elkerüld, használd a `virtualenv` parancsot. +> +> ~/djangogirls$ sudo apt-get install python-virtualenv +> ~/djangogirls$ virtualenv --python=python3.4 myvenv +> + +## 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 + + +#### Linus és OS X + +Így indíthatod el a virtuális környezetet: + + ~/djangogirls$ source myvenv/bin/activate + + +Fontos, hogy `myvenv` helyett azt a neved írd be, amit a `virtualenv`-ednek választottál! + +> **MEGJEGYZÉS:** néha a `source` nem elérhető. Ebben az esetben próbáld meg ezt: +> +> ~/djangogirls$ . myvenv/bin/activate +> + +Onnan tudod, hogy a `virtualenv` elindult, hogy a konzolodban a prompt így néz ki: + + (myvenv) C:\Users\Name\djangogirls> + + +vagy: + + (myvenv) ~/djangogirls$ + + +Figyeld meg, hogy megjelent a `(myvenv)` előtag! + +Ha virtuális környezetben dolgozol, a `python` parancs mindig a megfelelő Python verzióra fog mutatni, tehát nyugodtan használhatod a `python`-t `python3` helyett. + +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: `==`). + + (myvenv) ~$ pip install django==1.8 + Downloading/unpacking django==1.8 + Installing collected packages: django + Successfully installed django + Cleaning up... + + +Windowson + +> 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. + +Linuxon + +> 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! \ No newline at end of file diff --git a/hu/django_models/README.md b/hu/django_models/README.md new file mode 100644 index 00000000000..b80121951bf --- /dev/null +++ b/hu/django_models/README.md @@ -0,0 +1,172 @@ +# Django modellek + +Most valami olyasmire van szükségünk, ami eltárolja az összes blogbejegyzést. De ahhoz, hogy létre tudjunk hozni ilyesmit, előbb egy kicsit beszélnünk kell az `objektumokról`. + +## Objektumok + +Létezik egy `objektumorientált programozás` nevű fogalom a programozáson belül. Ennek az az alapötlete, hogy ahelyett, hogy mindent utasítások unalmas sorozataként írnánk le, modellezhetjük is a dolgokat, és definiálhatjuk, hogyan lépnek kapcsolatba egymással. + +Tehát mi az az objektum? Tulajdonságok és tevékenységek gyűjteménye. Furán hangozhat, de mindjárt mutatunk egy példát. + +Ha egy macskát szeretnék modellezni, létrehozunk egy `Cat` (macska) objektumot, aminek van néhány tulajdonsága: `color` (szín), `age` (életkor), `mood` (kedv -például jó, rossz, álmos ;)), és `owner` (tulajdonos - aki egy `Person` (személy) objektum, és talán, ha kóbor macskáról van szó, ez a tulajdonság üres). + +Aztán a `Cat`-hez tartozik néhány tevékenység: `purr` (dorombolás), `scratch` (karmolás), vagy `feed` (evés - ahol a macskának adunk egy kis macskaeledelt, vagyis `CatFood`-ot, ami egy külön objektum, saját tulajdonságokkal, mint például `taste` (íz)). + + Cat + -------- + color + age + mood + owner + purr() + scratch() + feed(cat_food) + + +Tehát az egésznek az az alapötlete, hogy a valós dolgokat kódban tulajdonságokkal (vagyis `object property`-kkel) és tevékenységekkel (vagyis `method`-okkal) írjuk le. + +Hogyan modellezzük a blogposztokat? Egy blogot szeretnénk fejleszteni, ugye? + +Erre a kérdésre keressük a választ: Mi egy blogposzt? Milyen tulajdonságai vannak? + +Nos, a bejegyzésünknek biztos van szövege, és címe, igaz? Azt is jó lenne tudni, hogy ki írta - vagyis szükségünk van egy szerzőre is. Végül tudni szeretnénk, mikor lett megírva és közzétéve a poszt. + + Post + -------- + title + text + author + created_date + published_date + + +Milyen dolgokat lehet csinálni egy blogbejegyzéssel? Jó lenne, ha lenne valamiféle `method`, ami közzéteszi a posztot, nem? + +Tehát szükségünk van egy `publish` methodra. + +Most, hogy tudjuk, mit szeretnénk elérni, kezdjük el modellezni Django-ban! + +## Django modell + +Most, hogy tudjuk, mik az objektumok, már el tudjuk készíteni a blogposzt Django modelljét. + +A Django-ban a modellek speciális objektumok - az `adatbázisban` vannak elmentve. Az adatbázis tulajdonképpen adatok gyűjteménye. Ez az a hely, ahol adatokat tárolhatsz a felhasználókról, a blogposztokról, stb. Mi egy SQLite adatbázist fogunk használni az adataink tárolásához. Ez az alapértelmezett Django adatbázis adapter -- ez egyelőre elég is lesz nekünk. + +Az adatbázisban lévő modellt úgy képzeld el, mint egy táblázatot (pl. az Excelben), ahol oszlopok (mezők) és sorok (adatok) vannak. + +### Készítsünk egy alkalmazást! + +Hogy minden szép rendben maradjon, most a projekten belül egy külön alkalmazást hozunk létre. Jó, ha már az elejétől fogva rendezetten tartjuk a dolgokat. Ahhoz, hogy létrehozzuk az alkalmazást, ezt a parancsot kell futtatnunk a parancssorban (a `djangogirls` könyvtárban, ahol a `manage.py` fájl van): + + (myvenv) ~/djangogirls$ python manage.py startapp blog + + +Azt fogod látni, hogy egy új `blog` könyvtár keletkezett, és már most van benne néhány fájl. Így kell kinézniük a könyvtáraknak és fájloknak a projekten belül: + + 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 + + +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 = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog', +) +``` + +### Hozzuk létre a blogposzt modelljét + +A `Model` nevű objektumokat a `blog/models.py` fájlban definiáljuk - tehát itt fogjuk definiálni a blogposztunkat is. + +Nyisd meg a `blog/models.py`-t, törölj ki mindent, és ezt a kódot írd bele: + +```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 +``` + +> Jól figyelj, hogy mindenképp két underscore (alulvonás) karaktert (`_`) használj a `str` mindkét oldalán. Ez a jelölés gyakran előfordul a Pythonban, és néha "dunder"-nek hívjuk (a "double underscore" - dupla alulvonás rövidítése). + +Ijesztőnek tűnik? Ne aggódj, mindjárt elmagyarázzuk, hogy mit jelentenek ezek a sorok. + +Azok a sorok, amik úgy kezdődnek, hogy `from` vagy `import`, más fájlokban lévő dolgokat adnak hozzá a fájlunkhoz. Ahelyett, hogy minden fájlba átmásolnánk ugyanazokat a dolgokat, beemelhetünk néhány dolgot a `from ... import ...` segítségével.. + +`class Post(models.Model):` - ez a sor definiálja a modellünket (ami egy `objektum`). + +* a `class` egy speciális kulcsszó, ami azt mutatja meg, hogy éppen egy objektumot definiálunk. +* 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ó)?). + +* `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). + +É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. + +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 + +Az utolsó lépés, hogy hozzáadjuk az új modellünket az adatbázishoz. Először valahogy tudatnunk kell a Django-val, hogy változtattunk a modellünkön (vagyis most alkottuk meg!). Gépeld be, hogy `python manage.py makemigrations blog`. Ez fog történni: + + (myvenv) ~/djangogirls$ python manage.py makemigrations blog + Migrations for 'blog': + 0001_initial.py: + - Create model Post + + +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: + + (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 + + +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 diff --git a/hu/django_orm/README.md b/hu/django_orm/README.md new file mode 100644 index 00000000000..7e09e6db212 --- /dev/null +++ b/hu/django_orm/README.md @@ -0,0 +1,158 @@ +# Django ORM és QuerySet-ek + +Ebben a fejezetben megtanulod, hogy hogyan kapcsolódik az adatbázishoz a Django, és hogyan tárol benne adatokat. Ugorjunk fejest! + +## Mi a QuerySet? + +A QuerySet lényegében egy lista, amely egy bizonyos Model objektumait tartalmazza. A QuerySetek segítségével tudsz adatot kinyerni az adatbázisból, szűrheted és sorba rendezheted. + +A legkönnyebb, ha példákon keresztül tanulod meg. Próbáljuk csak ki! + +## Django shell + +Nyisd meg a lokális konzolodat (nem a PythonAnywhere-ét), és gépeld be ezt a parancsot: + + (myvenv) ~/djangogirls$ python manage.py shell + + +Ezt fogod látni: + + (InteractiveConsole) + >>> + + +Most a Django interaktív konzoljában vagy. Olyasmi, mint a Python prompt, csak egy kis extra Django varázslattal :) Természetesen itt is használhatod az összes Python parancsot. + +### Az összes objektum + +Először is próbáljuk meg az összes posztot megjeleníteni. A következő paranccsal tudod megtenni: + + >>> Post.objects.all() + Traceback (most recent call last): + File "", line 1, in + NameError: name 'Post' is not defined + + +Hoppá, egy hiba! Azt mondja, hogy nincs olyan, hogy Post. Igaza van -- elfelejtettük importálni! + + >>> from blog.models import Post + + +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? + +### Objektum létrehozása + +Így hozhatsz létre egy új Post objektumot az adatbázisodban: + + >>> Post.objects.create(author=me, title='Sample title', text='Test') + + +De az egyik összetevő hiányzik: a `me`. Az `User` (felhasználó) modell egy instance-át kell megadnunk author-ként (szerző). Hogy tudjuk ezt megcsinálni? + +Először importáljuk az User modellt: + + >>> from django.contrib.auth.models import User + + +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: + + me = User.objects.get(username='ola') + + +Ahogy láthatod, most hozzájutottunk (`get`) egy `User`-hez, `username`-mel (felhasználónév), ami 'ola'-val egyenlő. Szuper! Természetesen itt a saját felhasználónevedet kell beírnod. + +Most pedig végre létrehozhatjuk a posztot: + + >>> Post.objects.create(author=me, title='Sample title', text='Test') + + +Hurrá! Meg akarod nézni, hogy működött-e? + + >>> Post.objects.all() + [, , ] + + +Ott is van, egy újabb poszt a listában! + +### Hozz létre még néhány posztot + +A móka kedvéért hozz létre még 2-3 posztot, hogy lásd, hogyan működik. Ha ez megvan, továbbléphetsz a következő részre. + +### Objektumok filterezése + +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ó"). + +Megkaphatod az összes közzétett poszt listáját is. Ezt úgy tudod megtenni, hogy az összes poszt között szűrsz azokra, amiknél be van állítva múltbéli `published_date` (vagyis közzététel dátuma): + + >>> from django.utils import timezone + >>> Post.objects.filter(published_date__lte=timezone.now()) + [] + +Sajnos az a poszt, amit a Python konzolban hoztunk létre, még nem lett közzétéve. De ezen könnyen változtathatunk! Először is, hozzá kell férnünk a poszt instance-éhez, amit közzé szeretnénk tenni: + + >>> post = Post.objects.get(title="Sample title") + + +Aztán közzétesszük a `publish` methoddal! + + >>> post.publish() + + +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 + +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 + +A QuerySeteket kombinálhatod is, ha összefűződ őket (**chaining**): + + >>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + + +Ez egy nagyon hatékony módszer, és a segítségével bonyolult query-ket írhatsz. + +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 new file mode 100644 index 00000000000..8657c33ffe7 --- /dev/null +++ b/hu/django_start_project/README.md @@ -0,0 +1,137 @@ +# Az első Django projekted! + +> Ez a fejezet részben a Geek Girls Carrots (http://django.carrots.pl/) tutorial-jain alapszik. +> +> A fejezet néhány része a [django-marcador tutorial][1] alapján készült, ami a Creative Commons Attribution-ShareAlike 4.0 International License alatt áll. A django-marcador tutorial jogait, Markus Zapke-Gründemann és társai birtokolják. + + [1]: http://django-marcador.keimlink.de/ + +Most egy egyszerű blogot fogunk készíteni! + +Az első lépés, hogy indítsunk egy új Django projektet. Ez annyit jelent, hogy lefuttatunk néhány scriptet, amit a Django tartalmaz, ezzel létrehozzuk a projekt vázát. Ez tulajdonképpen néhány mappa és fájl, amit majd később fogunk használni. + +Néhány fájl és könyvtár neve nagyon fontos a Django-ban. A fájlokat, amiket most hozunk létre, ne nevezd át! Az áthelyezésük sem egy jó ötlet. Fontos, hogy megtartsunk egy bizonyos szerkezetet, ami segít a Django-nak, hogy megtalálja a fontos dolgokat. + +> Figyelem: mindent a virtualenv-ben futtass. Ha nem látod a `(myvenv)` előtagot a konzolodban, aktiválnod kell a virtuális környezetedet. Ezt a **Django telepítés** fejezetben írtuk le, a **Virtuális környezetben való fejlesztés** résznél. Windows környezetben a `myvenv\Scripts\activate` parancssal, Mac OS / Linux alatt a `source myvenv/bin/activate` paranccsal tudod megtenni. + +Ha Mac OS-t vagy Linuxot használsz, a következő parancsot kell futtatnod; **ne felejtsd el kitenni a pontot `.` a végén**: + + (myvenv) ~/djangogirls$ django-admin startproject mysite . + + +Ha Windowst használsz: **ne felejtsd el kitenni a pontot `.` a végén**: + + (myvenv) C:\Users\Name\djangogirls> django-admin startproject mysite . + + +> A pont `.` nagyon fontos, mert ez mondja meg a scriptnek, hogy abba a könyvtárba telepítse a Django-t, ahol éppen vagy (a pont `.` egy rövidítése ennek). +> +> **Megjegyzés** Amikor begépeled a fenti parancsokat, csak azokat a részeket írd be, amik úgy kezdődnek, hogy `django-admin` vagy `django-admin.py`. A `(myvenv) ~/djangogirls$` és `(myvenv) C:\Users\Name\djangogirls>` csak példák a parancssorodra, amely azt várja, hogy parancsokat gépelj be neki. + +A `django-admin.py` egy script, ami könyvtárakat és fájlokat hoz létre neked. Most ilyen könyvtárszerkezetednek kell lennie: + + djangogirls + ├───manage.py + └───mysite + settings.py + urls.py + wsgi.py + __init__.py + + +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.. + +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! + +## A beállítások megváltoztatása + +Változtassunk meg néhány dolgot a `mysite/settings.py` fájlban. Nyisd meg a fájlt a kódszerkesztővel, amit korábban telepítettél! + +Jó lenne, ha a weboldalunk a mi időzónánk szerinti időt mutatná. Nézd meg a [wikipedia időzóna listát][2], és másold ki az időzónádat (TZ, time zone). (például `Europe/Budapest` ) + + [2]: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones + +Keresd meg a settings.py azt a sort, ami így keződik: `TIME_ZONE`, és írd át, hogy a saját időzónádat használja: + +```python + TIME_ZONE = 'Europe/Budapest' +``` + +Az "Europe/Budapest"-et változtasd meg kedved szerint. + +Szükségünk lesz még arra, hogy megadjuk a statikus fájlokhoz vezető elérési útvonalat (később mindent megtudhatsz a statikus fájlokról és a CSS-ről). Menj a fájl *végére*, és a `STATIC_URL` bejegyzés alatt adj hozzá egy következő bejegyzést `STATIC_ROOT` névvel: + +```python + STATIC_URL = '/static/' + STATIC_ROOT = os.path.join(BASE_DIR, 'static') +``` + +## Adatbázis létrehozása + +Sok különféle adatbázis-szoftver létezik, ami adatokat tud tárolni a weboldalakhoz. Mi az alapértelmezettet fogjuk használni, az `sqlite3`-ot. + +Ez már be van állítva a `mysite/settings.py` fájlodban: + +```python + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(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: + + (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 + + +Készen is vagyunk! Itt az ideje, hogy elindítsd a webszervert, és meglásd, hogy működik-e. + +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 + + +Ha Windowst használsz, és `UnicodeDecodeError` hibaüzenetet kapsz, ezt a parancsot használd: + + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + + +Most nincs más dolgod, mint ellenőrizni, hogy fut-e a weboldalad. Nyisd meg a böngésződet (Firefox, Chrome, Safari, Internet Explorer, vagy bármi más, amit használsz), és írd be a következő címet: + + 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 + +Készen állsz a következő lépésre? Itt az ideje, hogy létrehozzunk némi tartalmat! \ No newline at end of file diff --git a/fr/django_start_project/images/images/it_worked2.png b/hu/django_start_project/images/it_worked2.png similarity index 100% rename from fr/django_start_project/images/images/it_worked2.png rename to hu/django_start_project/images/it_worked2.png diff --git a/hu/django_templates/README.md b/hu/django_templates/README.md new file mode 100644 index 00000000000..32c44290fbf --- /dev/null +++ b/hu/django_templates/README.md @@ -0,0 +1,106 @@ +# Django sablonok (template) + +Itt az idő, hogy megjelenítsünk pár adatot! Ehhez Django felkínál nekünk pár beépített **template tag**-et számunkra. + +## Mik a template tag-ek? + +Mint látod, a HTML-ben nem tudsz Python kódot írni, mivel a böngészők nem értik, csak a HTML-t. Fontos tudni, hogy a HTML inkább statikus, míg Python inkább dinamikus. + +A **Django template tag-ek** lehetővé teszik, hogy Python-szerű dolgokat írjunk a HTML-be, ezáltal gyorsabban és könnyebben tudsz dinamikus weboldalt készíteni. Éljen! + +## Template a bejegyzések listájához + +Az előző fejezetben hozzáadtuk a template-hez a bejegyzéseink listáját a `post` változóban. Most meg fogjuk ezt jeleníteni a HTML-ben. + +Ahhoz, hogy kiírjunk egy változót a Django template-ben, dupla kapcsos zárójelet használunk, benne a változó nevével, mint itt: + +```html +{{ posts }} +``` + +Próbáld ki a `blog/templates/blog/post_list.html` template-ben. Cserélj ki mindent a második `
` -től a harmadikig a következővel: `{{ posts }}`. Mentsd el a fájlt és frissítsd az oldalt, hogy lásd az eredményt: + +![13.1 ábra][1] + + [1]: images/step1.png + +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: + +```html +{% for post in posts %} + {{ post }} +{% endfor %} +``` + +Próbáld ki a template-edben. + +![13.2 ábra][2] + + [2]: images/step2.png + +És működik! De azt akarjuk, hogy úgy jelenjen meg, mint a statikus bejegyzések, amit korábban készítettünk el a **Bevezetés a HTML-be** című fejezetben. A HTML-t és a template tageket használhatod együtt. A `body` így fog kinézni: + +```html + + +{% for post in posts %} +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% endfor %} +``` + +{% raw %} Minden, amit a `{% for %}` és `{% endfor %}` közé írsz, a lista minden egyes elemére meg fog ismétlődni. Frissítsd az oldalt:{% endraw %} + +![13.3 ábra][3] + + [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 `|linebreaks` kíséri a szöveget, ezáltal egy filteren keresztül új bekezdéssé alakítja az új sorokat. + +## 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 +``` +$ git status +[...] +$ git add -A . +$ git status +[...] +$ git commit -m "Modified templates to display posts from database." +[...] +$ git push +``` + +* Ezután a [PythonAnywhere][4]-en menj a **Bash console**-ba (vagy indíts újat), és futtasd le: + + [4]: https://www.pythonanywhere.com/consoles/ + +``` +$ cd my-first-blog +$ git pull +[...] +``` + +* Végül, a [Web][5] menüpontban klikkelj a **Reload**-ra. A frissítések ott vannak! + + [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. + +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 diff --git a/fr/django_templates/images/images/donut.png b/hu/django_templates/images/donut.png similarity index 100% rename from fr/django_templates/images/images/donut.png rename to hu/django_templates/images/donut.png diff --git a/fr/django_templates/images/images/step1.png b/hu/django_templates/images/step1.png similarity index 100% rename from fr/django_templates/images/images/step1.png rename to hu/django_templates/images/step1.png diff --git a/fr/django_templates/images/images/step2.png b/hu/django_templates/images/step2.png similarity index 100% rename from fr/django_templates/images/images/step2.png rename to hu/django_templates/images/step2.png diff --git a/fr/django_templates/images/images/step3.png b/hu/django_templates/images/step3.png similarity index 100% rename from fr/django_templates/images/images/step3.png rename to hu/django_templates/images/step3.png diff --git a/hu/django_urls/README.md b/hu/django_urls/README.md new file mode 100644 index 00000000000..508f7d895fe --- /dev/null +++ b/hu/django_urls/README.md @@ -0,0 +1,125 @@ +# Django url-ek + +Mindjárt elkészíted az első weblapodat: a blogod honlapját! De előbb tanuljunk egy kicsit a Django url-ekről. + +## Mi az URL? + +Az URL egyszerűen csak egy webes cím. Minden alkalommal látsz URL-eket, amikor meglátogatsz egy weboldalt - a böngésződ címsorában találodm meg (igen! a `127.0.0.1:8000` egy URL! És a `https://djangogirls.com` is egy URL): + +![Url][1] + + [1]: images/url.png + +Az interneten minden oldalnak szüksége van egy saját URL-re. Innen tudja az alkalmazásod, hogy mit mutasson a felhasználónak, aki megnyitott egy URL-t. A Django-ban egy `URLconf` nevű dolgot használunk (URL configuration, vagyis URL beállítások). Az URLConf egy csomó minta, amit a Django megpróbál összehasonlítani az URL-lel, amit kapott, és ez alapján találja meg a helyes view-t. + +## Hogy működnek az URL-ek a Django-ban? + +Nyisd meg a `mysite/urls.py` fájlt a kódszerkesztőben, és nézd meg: + +```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)), +] +``` + +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? + +Az admin URL, amit az előző fejezetben már meglátogattál, már itt van: + +```python + url(r'^admin/', include(admin.site.urls)), +``` + +Ez azt jelenti, hogy minden URL-nél, ami `admin/`-nal kezdődik, a Django meg fogja találni a hozzátartozó *view*-t. Ebben az esetben sok admin URL-t hozzáadunk, hogy ne kelljen az egészet ebbe a kis fájlba tömni - így olvashatóbb és letisztultabb. + +## Regex + +Kíváncsi vagy, hogyan párosítja össze a Django az URL-eket és a view-kat? Na, ez a rész trükkös. A Django `regex`-et használ (a "regular expressions", vagyis reguláris kifejezések rövidítése). A regexnek nagyon (nagyon!) sok szabálya van arra, hogy hogyan épít fel egy keresési mintázatot. Mivel a regex egy magasabb szintű téma, most nem megyünk bele a részletekbe. + +Ha szeretnéd megérteni, hogy hogyan hoztuk létre a mintákat, itt egy példa - csak néhány szabályra van szükségünk, hogy felépítsük a mintát, amit keresünk, például: + + ^ a szöveg eleje + $ a szöveg vége + \d számjegy + + ez azt jelzi, hogy az előző elem egynél többször ismétlődik + () ez a minta egy részét fogja össze + + +A Django minden mást, ami az url definícióban van, szó szerint fog értelmezni. + +Képzeld el, hogy van egy weboldalad ezzel a címmel: `http://www.mysite.com/post/12345/`, ahol a `12345/` a bejegyzésed száma. + +Minden egyes poszt számához új view-t írni nagyon idegesítő lenne. A reguláris kifejezésekkel létrehozhatunk egy mintát, ami megtalálja az URL-t, és kiszedi belőle a számot: `^post/(\d+)/$`. Nézzük meg lépésről lépésre, hogy mi történik itt: + +* A **^post/** azt mondja meg a Django-nak, hogy minden olyan url-t találjon meg, ami `post/`-tal kezdődik (rögtön ezután: `^`) +* A **(\d+)** azt jelenti, hogy ezután egy szám fog következni (egy vagy több számjegyű), és ezt a számot ki szeretnénk olvasni az URL-ből +* A **/** azt mondja meg a Django-nak, hogy utána még egy `/` karakternek kell következnie +* A **$** az URL végét jelzi, vagyis csak azok a stringeket fogja megfeleltetni a mintának, amik így végződnek: `/` + +## Az első Django URL-ed! + +Itt az ideje, hogy létrehozzuk az első URL-t! Azt szeretnénk, ha a 'http://127.0.0.1:8000/' lenne a blog kezdőoldala, és itt egy listát láthatnánk a blogbejegyzésekből. + +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 (`''`). + +A `mysite/urls.py` fájlod most így néz ki: + +```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')), +] +``` + +Mostantól a Django mindent, ami a 'http://127.0.0.1:8000/'-re jön, átirányít a `blog.urls`-re, és ott fogja keresni a további tennivalókat. + +Amikor Pythonban írunk reguláris kifejezéseket, a stringek előtt mindig egy `r` áll. Ez egy hasznos tipp a Pythonnak, hogy a string tartalmazhat speciális karaktereket, de ezek a reguláris kifejezés alkotóelemei, és nem magának a Pythonnak szólnak. + +## blog.urls + +Hozz létre egy új, üres fájlt `blog/urls.py` néven. Nagyszerű! Most írd be az első két sort: + +```python +from django.conf.urls import url +from . import views +``` + +Itt csak annyi történik, hogy importáljuk a Django methodjait és az összes `view`nkat a `blog` alkalmazásból (még egyet sem írtunk meg, de mindjárt ezzel is foglalkozunk!) + +Ezután megírhatjuk az első URL mintát: + +```python +urlpatterns = [ + url(r'^$', views.post_list, name='post_list'), +] +``` + +Amint láthatod, itt egy `post_list` nevű `view`t rendeltünk hozzá a `^$` URL-hez. Ez a regex a `^` karaktert (string kezdete) és az utána következő `$` karaktert (string vége) fogja keresni - vagyis csak az üres string felel meg neki. Ez így helyes, mert a Django URL resolverében a 'http://127.0.0.1:8000/' nem számít az URL részének. Ez a minta mondja meg a Django-nak, hogy ha valaki a 'http://127.0.0.1:8000/' címen lép be a weboldaladra, a `views.post_list` a helyes lépés. + +Az utolsó rész, `name='post_list'` az URL neve, amit a view azonosítására használunk. Ez lehet ugyanaz, mint a view neve, de lehet teljesen más is. A projekt későbbi részeiben ezeket az elnevezett URL-eket fogjuk használni, ezért fontos, hogy az app minden URL-jének nevet adjunk. Törekedj arra, hogy egyedi és könnyen megjegyezhető neveket adj. + +Minden világos? Nyisd meg a http://127.0.0.1:8000/ URL-t a böngésződben, hogy lásd az eredményt. + +![Hiba][2] + + [2]: images/error1.png + +Már nincs ott az "It works", igaz? Ne aggódj, ez csak egy hibaoldal, semmi félelmetes nincs benne! Tulajdonképpen nagyon is hasznos az ilyesmi: + +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 diff --git a/fr/django_urls/images/images/error1.png b/hu/django_urls/images/error1.png similarity index 100% rename from fr/django_urls/images/images/error1.png rename to hu/django_urls/images/error1.png diff --git a/fr/django_urls/images/images/url.png b/hu/django_urls/images/url.png similarity index 100% rename from fr/django_urls/images/images/url.png rename to hu/django_urls/images/url.png diff --git a/hu/django_views/README.md b/hu/django_views/README.md new file mode 100644 index 00000000000..9dabfe619b2 --- /dev/null +++ b/hu/django_views/README.md @@ -0,0 +1,38 @@ +# Django views - itt az ideje alkotni! + +Eljött az idő, hogy megszabaduljunk a hibától, amit az előző fejezetben szereztünk :) + +A *nézet (view)* az a rész, ahova az applikációnk "logikáját" írjuk. Szükség lesz a nemrég elkészült `model`-ben megadott adatokra, amit majd továbbít a `template`-nek. A template-et majd a következő fejezetben hozzuk létre. A nézetek ugyanolyan Python metódusok, mint amiket a **Bevezetés a Python-ba** című fejezetben csináltunk, csak egy kicsit bonyolultabbak. + +A nézetek a `views.py` fájlban találhatók. A *view-kat* a `blog/views.py` fájlba fogjuk írni. + +## blog/views.py + +Ok, nyissuk ki ezt a fájlt és nézzük, mi van benne: + +```python +from django.shortcuts import render + +# Create your views here. +``` + +Egyelőre nem túl sok minden. A legegyszerűbb *view* így néz ki. + +```python +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` + +Mint látod, létrehoztunk egy `post_list` elnevezésű metódust (`def`), ami vesz egy `request`-et és `return`-öl (visszaad) egy `render` metódust, ami összeállítja a `blog/post_list.html` template-et. + +Mentsd el a fájlt, menj a http://127.0.0.1:8000/ címre és lássuk, mink van. + +Újabb hiba! Olvasd el, mi a helyzet: + +![Hiba][1] + + [1]: images/error.png + +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 diff --git a/fr/django_views/images/images/error.png b/hu/django_views/images/error.png similarity index 100% rename from fr/django_views/images/images/error.png rename to hu/django_views/images/error.png diff --git a/hu/domain/README.md b/hu/domain/README.md new file mode 100644 index 00000000000..9c0a403aecf --- /dev/null +++ b/hu/domain/README.md @@ -0,0 +1,71 @@ +# Domain + +Heroku gave you a domain, but it's long, hard to remember, and ugly. It'd be awesome to have a domain name that is short and easy to remember, right? + +In this chapter we will teach you how to buy a domain and direct it to Heroku! + +## Hol tudsz domaint regisztrálni? + +A typical domain costs around $15 a year. There are cheaper and more expensive options, depending on the provider. There are a lot of companies that you can buy a domain from: a simple [google search][1] will give hundreds of options. + + [1]: https://www.google.com/search?q=register%20domain + +Our favourite one is [I want my name][2]. They advertise as "painless domain management" and it really is painless. + + [2]: https://iwantmyname.com/ + +## How to register domain in IWantMyName? + +Go to [iwantmyname][3] and type a domain you want to have in the search box. + + [3]: http://iwantmyname.com + +![][4] + + [4]: images/1.png + +You should now see a list of all available domains with the term you put in the search box. As you can see, a smiley face indicates that the domain is available for you to buy, and a sad face that it is already taken. + +![][5] + + [5]: images/2.png + +We've decided to buy `djangogirls.in`: + +![][6] + + [6]: images/3.png + +Go to checkout. You should now sign up for iwantmyname if you don't have an account yet. After that, provide your credit card info and buy a domain! + +After that, click `Domains` in the menu and choose your newly purchased domain. Then locate and click on the `manage DNS records` link: + +![][7] + + [7]: images/4.png + +Now you need to locate this form: + +![][8] + + [8]: images/5.png + +And fill it in with the following details: - Hostname: www - Type: CNAME - Value: your domain from Heroku (for example djangogirls.herokuapp.com) - TTL: 3600 + +![][9] + + [9]: images/6.png + +Click the Add button and Save changes at the bottom. + +It can take up to a couple of hours for your domain to start working, so be patient! + +## A domain beállítása Herokun + +You also need to tell Heroku that you want to use your custom domain. + +Go to the [Heroku Dashboard][10], login to your Heroku account and choose your app. Then go into app Settings and add your domain in the `Domains` section and save your changes. + + [10]: https://dashboard.heroku.com/apps + +That's it! \ No newline at end of file diff --git a/hu/dynamic_data_in_templates/README.md b/hu/dynamic_data_in_templates/README.md new file mode 100644 index 00000000000..b4c81dc739c --- /dev/null +++ b/hu/dynamic_data_in_templates/README.md @@ -0,0 +1,74 @@ +# Dinamikus adatok a template-ben + +Az összetevőink különböző helyeken vannak: a `Post` modellt a `models.py`-ban definiáltuk, a `post_list` a `views.py`-ban van, és létrehoztunk egy sablont is. De mégis hogyan fogjuk megjeleníteni a bejegyzést a HTML sablonban? Mert pontosan ez az, amit szeretnénk: fogjuk a tartalmat (az adatbázisban elmentett modelleket) és szépen megjelenítjük a sablonunkban. + +Pont ez az, amit a *nézetek (views)* csinálnak: összekötik a modelleket a sablonokkal. A `post_list` *view*-ba kell berakni a modelleket, amiket meg akarunk jeleníteni, és továbbítani a sablonba. Tehát a *nézet*ben eldöntjük, hogy mi fog megjelenni a sablonban. + +OK, hogyan fogjuk ezt megvalósítani? + +Meg kell nyitni a `blog/views.py` fájlt. Eddig így nézett ki a `post_list` *view*: + +```python +from django.shortcuts import render + +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` + +Emlékszel, amikor azt magyaráztuk, hogyan tudsz korábban megírt kódot beletenni más fájlokba? Most itt az alkalom, hogy beletegyük a modelt, amit a `models.py`-ba írtunk. A `from .models import Post` sort a következőképpen adjuk hozzá: + +```python +from django.shortcuts import render +from .models import Post +``` + +A pont a `from` után az *aktuális könyvtárt*, vagy az *aktuális applikációt* jelenti. Mivel a `views.py` és a `models.py` ugyanabban a könyvtárban vannak, elég annyit használnunk, hogy `.` és a fájl nevét (`.py` nélkül). Ezután importáljuk a model nevét.). + +De mi jön ezután? Ahhoz, hogy megkapjuk az aktuális blog bejegyzést a `Post` modelből, szükségünk lesz valamire, amit `QuerySet`-nek hívnak. + +## QuerySet + +Már ismerős lehet, hogy hogyan működik a QuerySet. A [Django ORM (QuerySets)][1] fejezetben már beszéltünk róla. + + [1]: ../django_orm/README.md + +Most azok a bejegyzések érdekelnek minket, amik publikálva vannak és a `published_date` szerint vannak sorba rendezve. Ezt már megtettük a QuerySets fejezetben! + + Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + + +Most ezt a kódrészletet rakjuk a `blog/views.py` fájlba, hozzáadva a `def post_list(request)` function-hoz: + +```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', {}) +``` + +Figyeld meg, hogy létrehozunk egy *változót* a QuerySethez: `posts`. Vedd úgy, hogy ez a QuerySet neve. Innentől kezdve erre a névre hivatkozva használjuk. + +Szintén fontos, hogy a kód a `timezone.now()` function-t tartalmazza, ehhez importálnunk kell a `timezone`-t. + +Az utolsó hiányzó rész, hogy továbbítsuk a `posts`-ot a sablonba (ezt a következő fejezetben kifejtjük). + +A `render` function-ban már van egy `request` paraméterünk (vagyis minden, ami a felhasználótól érkezik az interneten keresztül) és egy template file `'blog/post_list.html'`. Az utolsó paraméter, ami így néz ki: `{}`, egy olyan összetevő, amiben megadhatjuk azokat a dolgokat, amiket használni fogunk a template-ben. El kell neveznünk őket (egyelőre ragaszkodunk a `'posts'`-hoz :)). Így kell kinéznie: `{'posts': posts}`. Ne felejtsd el, hogy a `:` előtti rész egy string, ezt idézőjelbe kell tenned `''`. + +Végül a `blog/views.py` fájlnak így kell kinéznie: + +```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}) +``` + +É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 diff --git a/hu/extend_your_application/README.md b/hu/extend_your_application/README.md new file mode 100644 index 00000000000..c30bbe268f4 --- /dev/null +++ b/hu/extend_your_application/README.md @@ -0,0 +1,192 @@ +# Egészítsd ki az applikációdat + +Most már teljesítettük az összes szükséges lépést a website-unk létrehozásához: tudjuk hogyan írjunk egy modelt, url-t, view-t és template-et. Azt is tudjuk, hogy hogyan csinosítsuk ki az oldalunkat. + +Itt az idő gyakorolni! + +Az első dolog, amire szükségünk van, nyilván egy oldal, ami megjelenít egy bejegyzést, ugye? + +Már van egy `Post` modellünk, úgyhogy nem kell hozzáadnunk semmit a `models.py`-hoz. + +## Template link a bejegyzés részleteihez + +Kezdjük azzal, hogy hozzáadunk egy linket a `blog/templates/blog/post_list.html` fájlhoz. Eddig így kell kinéznie: + +```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+ {% endfor %} +{% endblock content %} +``` + + +{% raw %}Szükségünk van egy linkre a bejegyzések címei és a bejegyzések részletes oldala között. Cseréljük ki a `

{{ post.title }}

` sort úgy, hogy a bejegyzés részletes oldalára vezet: {% endraw %} + +```html +

{{ post.title }}

+``` + +{% raw %}Itt az ideje elmagyarázni a rejtélyes `{% url 'post_detail' pk=post.pk %}` részt. Ahogy gyaníthattad, a `{% %}` jelölés azt jelenti, hogy Django template tag-eket használunk. Ezúttal egy olyat, ami létrehoz egy URL-t nekünk!{% endraw %} + +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. + +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] + + [1]: images/no_reverse_match2.png + +## URL a bejegyzés részleteihez + +Hozzunk létre egy URL-t a `urls.py`-ban a `post_detail` *view*-hoz! + +Az első bejegyzésünk részleteit a kövekező **URL** címen akarjuk megjeleníteni: http://127.0.0.1:8000/post/1/ + +Hozzunk létre egy URL-t a `blog/urls.py` fájlban, ami egy `post_detail` nevű *view*-ra mutat -- ez majd egy egész blogbejegyzést jelenít meg. Add hozzá a `url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'),` sort a `blog/urls.py` fájlhoz. Így kell kinéznie a fájlnak: + +```python +from django.conf.urls import include, 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'), +] +``` + +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*. + +`pk` a `primary key` rövid változata. Ezt a kifejezést gyakran használják Django projektekben. De úgy nevezed el a változódat, ahogy akarod (ne feledd: kisbetűkkel és szóköz helyett `_` karakterrel!). Például `(?P[0-9]+)` esetén használhatunk `post_id` változót, amivel így nézne ki: `(?P[0-9]+)`. + +Ok, hozzáadtunk egy új URL-t a `blog/urls.py`-hoz! Frissítsük az oldalt: http://127.0.0.1:8000/ Boom! Már megint egy újabb hiba! Várható volt! + +![AttributeError][2] + + [2]: images/attribute_error2.png + +Emlékszel, mi a következő lépés? Hát persze: hozzáadni egy új nézetet! + +## Nézet a bejegyzés részleteihez + +Ezúttal adunk a *nézetünknek* egy extra paramétert: `pk`. A *nézetünknek* ezt meg kell kapnia, igaz? Úgyhogy a function-t úgy fogjuk meghatározni, hogy `def post_detail(request, pk):`. Jegyezd meg, hogy pontosan ugyanazt a nevet kell használnunk, amit az url-ben jelöltünk meg (`pk`). A változó kihagyása helytelen, és hibát fog eredményezni! + +Most egyetlen egy blogbejegyzést akarunk szerezni. Ehhez egy ilyen queryset-et használhatunk: + + Post.objects.get(pk=pk) + + +De ennél a kódnál van egy kis gond. Ha nincsen `Post` az adott `primary key`-vel (`pk`), akkor egy nagyon csúnya hibát kapunk! + +![DoesNotExist hiba][3] + + [3]: images/does_not_exist2.png + +Mi ezt nem akarjuk! De, természetesen a Django-nak van valamije, ami ezt megoldja nekünk: `get_object_or_404`. Abban az esetben, ha nincsen `Post` az adott `pk`-val, akkor egy sokkal szebb oldalt ad ki (`Page Not Found 404` oldalt). + +![Az oldal nem található][4] + + [4]: images/404_2.png + +A jó hír az, hogy elkészítheted a saját `Page not found` oldaladat, és olyan szépre alakíthatod, amilyenre akarod. De ez nem olyan fontos egyelőre, úgyhogy átugorhatjuk. + +Oké, itt az idő, hogy hozzáadjuk a *view*-t a `views.py` fájlunkhoz! + +Nyisd meg a `blog/views.py` fájlt és add hozzá a következő kódot: + + from django.shortcuts import render, get_object_or_404 + + +A többi `from` sor mellé. És a fájl alján hozzáadjuk a *view*-t: + + def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) + + +Igen. Ideje frissíteni az oldalt: http://127.0.0.1:8000/ + +![Post list nézet][5] + + [5]: images/post_list2.png + +Sikerült! De mi történik, ha ráklikkelsz egy linkre a blog bejegyzés címében? + +![TemplateDoesNotExist hiba][6] + + [6]: images/template_does_not_exist2.png + +Jaj ne! Egy másik hiba! De már tudjuk, hogyan kezeljük, igaz? Létre kell hoznunk egy template-et! + +## Template a bejegyzés részleteihez + +Létrehozunk egy fájlt a `blog/templates/blog` könyvtárban, és elnevezzük: `post_detail.html`. + +Ez fog történni: + +```html +{% extends 'blog/base.html' %} + +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} +

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% endblock %} +``` + +Itt megint a `base.html`-t bővítjük ki. A `content` blokkban meg szeretnénk jeleníteni a bejegyzés címét, szövegét és a megjelenési idejét (published_date) - ha van. De pár fontos dolgot tisztáznunk kell még, igaz? + +{% raw %}`{% if ... %} ... {% endif %}` egy template tag, amit akkor használni, amikor ellenőrizni akarunk valamit (emlékszel az `if ... else ..` részre a **Bevezetés a Python-ba** fejezetnél?). Ebben az esetben azt akarjuk leellenőrizni, hogy a bejegyzés `published_date` eleme nem üres.{% endraw %} + +Ok, most már frissíthetjük az oldalunkat és kiderül, hogy a `Page not found` eltűnt. + +![Post részletei oldal][7] + + [7]: images/post_detail2.png + +Juppi! Működik! + +## Még egy dolog: itt az ideje egy újabb deploynak! + +Jó lenne ellenőrizni, hogy még mindig működik-e a weboldalad a PythonAnywhere-en, igaz? Próbáld meg újra deployolni. + + $ git status + $ git add -A . + $ git status + $ git commit -m "Added view and template for detailed blog post as well as CSS for the site." + $ git push + + +* Aztán írd be ezt a [PythonAnywhere Bash konzol][8]ba: + + [8]: https://www.pythonanywhere.com/consoles/ + + $ cd my-first-blog + $ source myvenv/bin/activate + (myvenv)$ git pull + [...] + (myvenv)$ python manage.py collectstatic + [...] + + +* Végül menj a [Web tab][9]-ra, és nyomj **Reload**ot. + + [9]: https://www.pythonanywhere.com/web_app_setup/ + +Ennyi az egész. Gratulálunk :) \ No newline at end of file diff --git a/fr/extend_your_application/images/images/404_2.png b/hu/extend_your_application/images/404_2.png similarity index 100% rename from fr/extend_your_application/images/images/404_2.png rename to hu/extend_your_application/images/404_2.png diff --git a/fr/extend_your_application/images/images/attribute_error2.png b/hu/extend_your_application/images/attribute_error2.png similarity index 100% rename from fr/extend_your_application/images/images/attribute_error2.png rename to hu/extend_your_application/images/attribute_error2.png diff --git a/fr/extend_your_application/images/images/does_not_exist2.png b/hu/extend_your_application/images/does_not_exist2.png similarity index 100% rename from fr/extend_your_application/images/images/does_not_exist2.png rename to hu/extend_your_application/images/does_not_exist2.png diff --git a/hu/extend_your_application/images/no_reverse_match2.png b/hu/extend_your_application/images/no_reverse_match2.png new file mode 100644 index 00000000000..306926206f8 Binary files /dev/null and b/hu/extend_your_application/images/no_reverse_match2.png differ diff --git a/fr/extend_your_application/images/images/post_detail2.png b/hu/extend_your_application/images/post_detail2.png similarity index 100% rename from fr/extend_your_application/images/images/post_detail2.png rename to hu/extend_your_application/images/post_detail2.png diff --git a/fr/extend_your_application/images/images/post_list2.png b/hu/extend_your_application/images/post_list2.png similarity index 100% rename from fr/extend_your_application/images/images/post_list2.png rename to hu/extend_your_application/images/post_list2.png diff --git a/fr/extend_your_application/images/images/template_does_not_exist2.png b/hu/extend_your_application/images/template_does_not_exist2.png similarity index 100% rename from fr/extend_your_application/images/images/template_does_not_exist2.png rename to hu/extend_your_application/images/template_does_not_exist2.png diff --git a/hu/how_the_internet_works/README.md b/hu/how_the_internet_works/README.md new file mode 100644 index 00000000000..e645ea1721e --- /dev/null +++ b/hu/how_the_internet_works/README.md @@ -0,0 +1,53 @@ +# Hogy működik az Internet? + +> Ez a fejezet Jessica McKellar "Hogy működik az Internet" (How the Internet works) című előadásán alapul (http://web.mit.edu/jesstess/www/). + +Biztosan minden nap internetezel. Tudod, igazából mi történik, mikor beírod a böngésződben, hogy http://djangogirls.org, és `enter`t nyomsz? + +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. + +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. + +Rendben, de hogy néz ki az Internet? + +Rajzoltunk neked egy képet! Így néz ki: + +![1.1 ábra][1] + + [1]: images/internet_1.png + +Elég zavaros, igaz? Valójában ez egymáshoz kapcsolódó gépek (az előbb emlegetett *szerverek*) hálózata. Több százezer gép! Rengeteg kilométernyi kábel körös-körül a világon! Nézd meg Submarine Cable Map weboldalt (http://submarinecablemap.com), és látni fogod milyen bonyolult a net. Itt egy kép az oldalról: + +![1.2 ábra][2] + + [2]: images/internet_3.png + +Lenyűgöző, igaz? Persze az képtelenség, hogy minden gép össze legyen kötve egymással, ami az Internethez csatlakozik. Ezért hogy elérhessünk egy gépet (például azt, ahol a http://djangogirls.org van elmentve), a kérésünket egy csomó különböző gépen át kell juttatni. + +Így néz ki: + +![1.3 ábra][3] + + [3]: images/internet_2.png + +Képzeld el úgy, hogy amikor beírod a http://djangogirls.org címet, egy levelet írsz: "Kedves Django Girls, szeretném megnézni a djangogirls.org oldalt. Kérlek, küldd el nekem!" + +Először a leveled a hozzád legközelebbi postára megy. Ezután továbbhalad egy olyan postára, ami már kicsit közelebb van a címzettedhez, és így tovább, míg el nem jut a céljához. Az egyetlen egyedi dolog, hogy ha több levelet (*adatcsomagot*) küldesz ugyanarra a helyre, azok valószínűleg teljesen már postákon (*routers*) mennek keresztül. Ez csak attól függ hogyan osztják el az egyes irodákban. + +![1.4 ábra][4] + + [4]: images/internet_4.png + +Ennyire egyszerű! Elküldöd a levelet, és várod a választ. Persze papír és toll helyett adatok byte-jait küldöd, de az ötlet ugyanaz! + +Utcanév, házszám, város és irányítószám helyett IP-címeket használunk. A számítógéped először megkéri a DNS-t (Domain Name System, tartománynévrendszer), hogy fordítsa le a djangogirls.org-ot egy IP címre. Körülbelül úgy működik, mint amikor a régi telefonkönyvekből kikerested valakinek a telefonszámát, és a címét. + +Amikor levelet küldesz, bizonyos dolgokra szükség van, hogy jó helyre szállítsák őket: kell lennie rajta címnek, bélyegnek, stb. Ráadásul olyan nyelven kell írnod, amit a címzett megért. Ugyanez vonatkozik az *adatcsomagokra*, amiket azért küldesz, mert meg szeretnél nézni egy weboldalt. A HTTP (Hypertext Transfer Protocol) protokollt használjuk erre. + +Szóval, amikor van egy weboldalad, akkor szükséged van egy *szerverre* (gép), ahol az oldal lakik. Amikor a *szerver* kap egy beérkező *kérést* (egy levélben), akkor egy válaszban visszaküldi a weboldaladat (egy másik levélben). + +Mivel ez egy Django útmutató, felmerülhet benned a kérdés, hogy a Django ebben a folyamatban milyen szerepet tölt be. Amikor küldesz egy választ, nem mindig pont ugyanazt küldöd mindenkinek. Sokkal jobb, ha a levelek személyesek, főleg, ha annak az embernek szólnak, akinek válaszolsz, nem igaz? A Django segít, hogy személyes és érdekes leveleket írhass :). + +De elég a beszédből, munkára fel! \ No newline at end of file diff --git a/hu/how_the_internet_works/images/internet_1.png b/hu/how_the_internet_works/images/internet_1.png new file mode 100644 index 00000000000..9c5bcf0b003 Binary files /dev/null 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 new file mode 100644 index 00000000000..dd5861f376f Binary files /dev/null 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 new file mode 100644 index 00000000000..a23488e3f2f Binary files /dev/null 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 new file mode 100644 index 00000000000..05f1aed562f Binary files /dev/null and b/hu/how_the_internet_works/images/internet_4.png differ diff --git a/hu/html/README.md b/hu/html/README.md new file mode 100644 index 00000000000..a92097a9dd8 --- /dev/null +++ b/hu/html/README.md @@ -0,0 +1,209 @@ +# Bevezetés a HTML-be + +Mi az a template, kérdezhetnéd? + +A template egy fájl, amit újrahasznosíthatunk, hogy különböző információkat jeleníthessünk meg egységes formában - például, egy template-et használhatsz egy levél megírásakor, ahol ugyan a levelek tartalma eltérhet, és a címzettek is különbözőek lehetnek, de a formájuk azonos. + +A Django template formátumát egy nyelvvel írjuk le, amit HTML-nek hívunk (ez az a HTML, amit a **Hogy működik az Internet?** fejezetben már említettünk). + +## Mi a HTML? + +A HTML egy egyszerű kód, amit a böngésződ értelmez (pl.: Chrome, Firefox, vagy Safari), hogy weboldalakat jelenítsen meg a felhasználóknak. + +A HTML a "HyperText Markup Language" rövidítése. A **HyperText** egy olyan szöveg, amely támogatja a hiperhivatkozásokat oldalak között. A **Markup** azt jelenti, hogy egy dokumentumot kód segítségével jelölésekkel látunk el, hogy leírjuk (ebben az esetben a böngészőnek) hogyan értelmezhető a weboldal. A HTML kód **tagekből** épül fel, amelyek mindegyike `<` jellel kezdődik, és `>` jellel végződik. Ezek a tagek reprezentálják a jelölő **elemeket**. + +## Az első template-ed! + +Egy template elkészítése azt jelenti, hogy létrehozunk egy template fájlt. Minden dolog egy fájl, igaz? Valószínűleg már te is észrevetted ezt. + +A template-eket a `blog/templates/blog` mappába mentjük. Először hozd létre a `templates` könyvtárat a blog mappában. Ezután hozz létre egy `blog` mappát a templates mappádban: + + blog + └───templates + └───blog + + +(Meglepő lehet, hogy miért van szükség két `blog` nevű mappára - később majd rájössz, hogy ez egy hasznos elnevezési konvenció, ami megkönnyíti az életedet, amikor a dolgok bonyolulttá válnak.) + +Ezután hozd létre a `post_list.html` fájlt (egyelőre hagyd üresen) a `blog/templates/blog` mappában. + +Nézd meg, hogy néz ki most a weboldal: http://127.0.0.1:8000/ + +> Ha továbbra is a `TemplateDoesNotExists` hibát kapod, akkor próbáld újraindítani a szervert. Menj a parancssorba, állítsd meg a szervert a Ctrl+C megnyomásával (a Control és C gombot egyszerre nyomd meg), és indítsd el újra a `python manage.py runserver` paranccsal. + +![11.1 ábra][1] + + [1]: images/step1.png + +Nincs több hiba! Ügyes vagy :) Azonban a weboldalad csak egy üres oldalt jelenít meg, mivel a template is üres, amit készítettél. Ezt ki kell javítanunk. + +Add hozzá az alábbi sorokat a template fájlodhoz: + +```html + +

Hi there!

+

It works!

+ +``` + +Szóval, hogy néz ki most a weboldalad? Kattints és nézd meg: http://127.0.0.1:8000/ + +![11.2 ábra][2] + + [2]: images/step3.png + +Működik! Szép munka :) + +* A legalapvetőbb tag a ``, amely minden weboldal elejére kerül, míg a `` a végén szerepel. Láthatod, hogy a weboldal tartalma a kezdő `` tag, és a záró `` tag közé kerül +* A `

` tag a bekezdés (paragrafus) elem; `

` zárja a bekezdéseket + +## Head és body + +Minden HTML oldalt két elemre osztunk: **head** és **body**. + +* A **head** elem információkat tartalmaz a dokumentumról, amit nem jelenítünk meg a képernyőn. + +* A **body** elem tartalmaz minden mást, ami a weboldalon jelenik meg. + +A `` elemet használjuk arra, hogy az oldal konfigurációs beállításait megadjuk a böngészőnek, és a `` elemet arra, hogy leírjuk mi jelenjen meg az oldalon. + +Például a weboldal title elemét rakhatjuk a ``-be: + +```html + + + Ola's blog + + +

Hi there!

+

It works!

+ + +``` + +Mentsd el a fájlt, és frissítsd az oldalt. + +![11.3 ábra][3] + + [3]: images/step4.png + +Észrevetted, hogyan ismerte fel a böngésző, hogy az "Ola's blog" az oldal címe? Értelmezte a `Ola's blog` kódot, és a szöveget a böngésző cím mezőjébe rakta (ezt fogja használja könyvjelzőnek is, és így tovább). + +Valószínűleg azt is észrevetted, hogy minden nyitó taghez tartozik egy *záró tag* egy `/` jellel, és ezek az elemek *egymásba ágyazhatóak* (azaz nem lehet bezárni egy adott taget mindaddig, míg a benne levők nincsenek lezárva). + +Ez éppen olyan mintha különböző dolgokat tennénk dobozokba. Van egy nagy dobozod, a ``; ebben benne van a ``, és ez egy újabb kisebb dobozt tartalmaz: `

`. + +Követned kell a *záró* tagekre, és az *egymásba ágyazható* elemekre vonatkozó szabályokat - ha nem teszed, a böngésző nem tudja majd értelmezni a kódodat megfelelően, és az oldalad hibásan jelenik majd meg. + +## Változtasd meg a template-edet + +Most szórakozásképpen próbáld módosítani a template-edet! Itt van néhány hasznos tag ehhez: + +* `

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 +* `text` dőlt szöveghez +* `text` a szöveg kiemeléséhez +* `
` új sor kezdéséhez (nem mindenhová rakhatsz br-t) +* `link` létrehoz egy linket +* `
  • 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: + +```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.

+
+ + +``` + +Három `div` elemet hoztunk létre. + +* Az első `div` tartalmazza a blogunk címét - ez egy cím, és egy link +* A másik két `div` elem a blog posztjainkat tárolja a publikálás dátumával - egy `h2` van benne a poszt címével, ami kattintható, emellett `p` bekezdések a dátumnak, és a szövegnek. + +Ennek kell megjelenni: + +![11.4 ábra][4] + + [4]: images/step6.png + +Yaaay! A template eddig pontosan **ugyanazt az infót** jeleníti meg - viszont korábban arról volt szó, hogy egy template-tel **különböző** információkat jeleníthetünk meg **azonos formában**. + +Amit igazából szeretnénk, hogy igazi posztokat jelenítünk meg, amiket a Django adminon adunk hozzá - nemsokára ezt is megnézzük. + +## Még egy dolog: deploy! + +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 + +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): + + $ git status + + +A `djangogirls` mappában kell lenned, és a `git`-tel add hozzá az összes változtatást a könyvtáradon belül: + + $ git add -A . + + +> **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. + +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): + + $ git status + + +Már majdnem készen is vagyunk, de előtte el kell mentenünk a változtatásokat az előzményekbe. Egy "commit message"-et adunk meg, ahol leírjuk, hogy mit változtattunk. Akármit beírhatsz, de később hasznos lehet, ha valami olyat adsz meg, ami segít beazonosítani, hogy mit csináltál. + + $ git commit -m "Changed the HTML for the site." + + +> **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: + + $ git push + + +### Pullold az új kódot PythonAnywhere-re, és frissítsd az oldalt + +* Nyisd meg a [PythonAnywhere konzol oldalát][5] és menj a **Bash console**-odra (vagy indíts egy újat). Aztán futtasd ezt: + + [5]: https://www.pythonanywhere.com/consoles/ + + $ cd ~/my-first-blog + $ 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. + +* Végül, kattints át a [Web tab][6]-ra, és nyomj egy **Reload**-ot a web alkalmazásodra. + + [6]: https://www.pythonanywhere.com/web_app_setup/ + +A frissítéseid kint vannak! Frissítsd az weboldalt a böngésződben, és a változtatások már látni fogod :) \ No newline at end of file diff --git a/hu/html/images/step1.png b/hu/html/images/step1.png new file mode 100644 index 00000000000..e9c2f1082d6 Binary files /dev/null and b/hu/html/images/step1.png differ diff --git a/hu/html/images/step3.png b/hu/html/images/step3.png new file mode 100644 index 00000000000..811226fa3fc Binary files /dev/null and b/hu/html/images/step3.png differ diff --git a/hu/html/images/step4.png b/hu/html/images/step4.png new file mode 100644 index 00000000000..bd6c1a044e0 Binary files /dev/null and b/hu/html/images/step4.png differ diff --git a/hu/html/images/step6.png b/hu/html/images/step6.png new file mode 100644 index 00000000000..e42a2fe5388 Binary files /dev/null and b/hu/html/images/step6.png differ diff --git a/hu/images/application.png b/hu/images/application.png new file mode 100644 index 00000000000..6dcba6202c7 Binary files /dev/null and b/hu/images/application.png differ diff --git a/hu/installation/README.md b/hu/installation/README.md new file mode 100644 index 00000000000..71c8329a83f --- /dev/null +++ b/hu/installation/README.md @@ -0,0 +1,49 @@ +# Ha otthon csinálod a tutorialt + +Ha otthon csinálod a tutorialt, nem valamelyik [Django Girls eseményen](http://djangogirls.org/events/), át is ugorhatod ezt a fejezetet, és folytathatod a [Hogy működik az Internet?](../how_the_internet_works/README.md) fejezettel. + +Ez az oldal csak egy helyre gyűjti az installációk leírását, amikkel később úgyis találkozni fogsz a tutorial során. A Django Girls workshopok előtt mindig van egy installációs esemény, amikor mindent telepítünk, hogy a workshopon már ne kelljen ezzel bajlódni, ezért hasznos nekünk, hogy mindent megtalálunk egy helyen. + +Ha te is hasznosnak találod, nyugodtan elvégezheted ezt a fejezetet. De ha inkább fejest szeretnél ugrani a tanulásba, mielőtt egy csomó mindent telepítenél a gépedre, nyugodtan ugord át a fejezetet! Később úgyis elmagyarázzuk az összes telepítést. + +Sok szerencsét! + +# Installáció + +A workshopon egy blogot fogsz elkészíteni. Ehhez el kell végezned néhány telepítési feladatot, hogy a workshop napján már egyből elkezdhess kódolni. + +# A Python telepítése + +{% include "/python_installation/instructions.md" %} + +# Virtuális környezet létrehozása és a Django telepítése + +{% include "/django_installation/instructions.md" %} + +# Kódszerkesztő telepítése + +{% include "/code_editor/instructions.md" %} + +# A Git telepítése + +{% include "/deploy/install_git.md" %} + +# GitHub fiók létrehozása + +Menj a [GitHub.com](http://www.github.com) oldalra, és hozz létre egy új, ingyenes felhasználói fiókot. + +# PythonAnywhere felhasználó létrehozása + +{% include "/deploy/signup_pythonanywhere.md" %} + +# Kezdheted az olvasást + +Gratulálunk, készen állsz a tutorialra! Ha van egy kis időd a workshop előtt, hasznos lehet, ha elolvasod az első néhány fejezetet: + + * [Hogy működik az Internet](../how_the_internet_works/README.md) + + * [Bevezetés a parancsssor használatába](../intro_to_command_line/README.md) + + * [Bevezetés a Pythonba](../python_introduction/README.md) + + * [Mi a Django?](../django/README.md) diff --git a/hu/intro_to_command_line/README.md b/hu/intro_to_command_line/README.md new file mode 100644 index 00000000000..1599cd88f51 --- /dev/null +++ b/hu/intro_to_command_line/README.md @@ -0,0 +1,279 @@ +# Bevezetés a parancssor használatába + +Ez nagyon izgalmas, igaz?! Pár percen belül megírod az első kódsorodat :) + +**Hadd mutassuk be neked az első új barátodat: a parancssort!** + +A következő lépésekben megmutatjuk neked, hogyan használd azt a fekete ablakot úgy, ahogy az összes hacker használja. Első ránézésre kissé ijesztőnek tűnhet, de valójában csak egy egyszerű parancsot vár tőled. + +> **Megjegyzés** A könyvben felváltva használjuk a 'könyvtár' és 'mappa' ('directory' és 'folder') szavakat, de ezek pont ugyanazt jelentik. + +## Mi az a parancssor? + +A **parancssor** (command line, vagy **command-line interface**) nevű ablak egy szöveges alapú alkalmazás, amit arra használhatsz, hogy fájlokat tekinthess meg, szerkeszthess, és különböző műveleteket végezhess rajtuk. Olyasmi, mint a Windows Explorer, vagy Mac gépeken a Finder, de a grafikus felület nélkül. Egyéb megnevezések a parancssorra: *konzol*, *terminál*, *cmd*, *CLI*, *prompt*. + +## A parancssor megnyitása + +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 + +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. + +## Az első parancsod (YAY!) + +Kezdjük valami egyszerűvel. Gépeld be ezt a parancsot: + + $ whoami + + +vagy + + > whoami + + +Majd nyomj `enter`t. Ezt az eredményt kapod: + + $ whoami + olasitarska + + +Amint láthatod, a számítógéped az előbb kiírta a felhasználónevedet. Jó, mi?:) + +> Próbálj meg minden parancsot begépelni, ahelyett, hogy innen másolnád ki. Így többet fogsz megjegyezni! + +## Az alapok + +Minden operációs rendszer parancssora kissé különböző prancsokat igényel, ezért kérlek győzödj meg arról, hogy a te operációs rendszerednek megfelelő utasításokat követed. Próbáljuk ki, rendben? + +### A jelenlegi mappa + +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: + + > cd + C:\Users\olasitarska + + +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'. + +* * * + +### Fájlok és könyvtárak kilistázása + +És mi van benne? Szuper lenne kideríteni. Nézzük meg: + + $ ls + Applications + Desktop + Downloads + Music + ... + + +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 + ... + + +* * * + +### Jelenlegi mappa megváltoztatása + +Most pedig lépjünk be a Desktop (vagy Asztal) mappába: + + $ cd Desktop + + +Windows: + + > cd Desktop + + +Nézzük meg, hogy tényleg megváltozott-e: + + $ pwd + /Users/olasitarska/Desktop + + +Windows: + + > cd + C:\Users\olasitarska\Desktop + + +Itt is van! + +> PRO tipp: ha begépeled a `cd D`-t (vagy ha magyarul használod az operációs rendszeredet, és 'Asztal'-nak hívják a könyvtáradat, a `cd A`-t) és ezután megnyomod a <0>tab-ot, a parancssor automatikusan kiegészíti a nevet, lehetővé téve számodra a gyorsabb navigálást. Amennyiben több mappa is kezdődik ugyanazzal a betűvel, nyomd meg kétszer a `tab`-ot, hogy kilistázza a több opciót. + +* * * + +### Könyvtár létrehozása + +Mit szólnál, ha létrehoznánk egy gyakorló (practice) könyvtárat az asztalon? Így tudod megtenni: + + $ mkdir practice + + +Windows: + + > 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 :) + +> PRO tipp: Ha nem szeretnéd újra és újra ugyanazt a parancsot begépelni, próbáld meg a `felfele` és `lefele nyilakkal` behívni a legutóbb futtatott parancsokat. + +* * * + +### Feladat! + +Egy kis kihívás: hozz létre egy `test` nevű mappát a frissen elkészített `practice` könyvtáradban. Használd a `cd` és `mkdir` parancsokat. + +#### Megoldás: + + $ cd practice + $ mkdir test + $ ls + test + + +Windows: + + > cd practice + > mkdir test + > dir + 05/08/2014 07:28 PM test + + +Gratulálunk! :) + +* * * + +### Takarítás + +Nem szeretnénk káoszt hagyni magunk után, szóval töröljünk le mindent, amit eddig csináltunk. + +Először vissza kell mennünk az Asztal-ra: + + $ cd .. + + +Windows: + + > 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: + + > 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 + + +Windows: + + > rmdir /S practice + practice, Are you sure ? Y + + +Kész! Ellenőrizzük le, hogy tényleg megtörtént-e: + + $ ls + + +Windows: + + > dir + + +### Kilépés + +Ennyi volt! Most már biztonságosan kiléphetsz a parancssorból. Csináljuk hacker módra, jó?:) + + $ exit + + +Windows: + + > exit + + +Szuper, nem? :) + +## Összefoglaló + +Egy kis összefoglalás néhány hasznos parancsról: + +| Parancs (Windows) | Parancs (Mac OS/Linux) | Leírás | Példa | +| ----------------- | ---------------------- | ----------------------------- | ------------------------------------------------- | +| exit | exit | az ablak bezárása | **exit** | +| cd | cd | könyvtár megváltoztatása | **cd test** | +| dir | ls | könyvtárak/fájlok kilistázása | **dir** | +| copy | cp | fájl másolása | **copy c:\test\test.txt c:\windows\test.txt** | +| move | mv | fájl mozgatása | **move c:\test\test.txt c:\windows\test.txt** | +| mkdir | mkdir | új könyvtár létrehozása | **mkdir testdirectory** | +| del | rm | könyvtár/fájl törlése | **del c:\test\test.txt** | + +Ez csak néhány parancs, azok közül, amiket a parancssorban futtathatsz, de ma nem lesz szükséged ennél többre. + +Ha kíváncsi vagy, a [ss64.com][1] oldalon megtalálod az összes parancsot bármelyik operációs rendszerre. + + [1]: http://ss64.com + +## Kész vagy? + +Merüljünk el a Python-ban! \ No newline at end of file diff --git a/hu/python_installation/README.md b/hu/python_installation/README.md new file mode 100644 index 00000000000..8dc956f79b9 --- /dev/null +++ b/hu/python_installation/README.md @@ -0,0 +1,13 @@ +# Kezdjünk ismerkedni a Pythonnal + +Végre itt vagyunk! + +Először is hadd mondjuk el, hogy mi is a Python. A Python egy nagyon népszerű programnyelv, amit weboldalkészítéshez, játékokhoz, tudományos szoftverekhez, grafikához és még csomó minden másra használnak. + +A Pythont a 80-as évek végén alkották meg, és a fő cél az volt, hogy ne csak gépek, hanem emberek számára is olvasható legyen. Ezért néz ki sokkal egyszerűbbnek, mint más programnyelvek. Ez könnyebbé teszi a tanulást, de ne aggódj, a Python igencsak erőteljes nyelv! + +# A Python telepítése + +> **Megjegyzés** Ha már elvégezted az Installáció fejezetet, nem kell újra megtenned - ugorj a következő fejezetre! + +{% include "/python_installation/instructions.md" %} diff --git a/hu/python_installation/images/add_python_to_windows_path.png b/hu/python_installation/images/add_python_to_windows_path.png new file mode 100644 index 00000000000..7946019bc29 Binary files /dev/null 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 new file mode 100644 index 00000000000..47e8984e031 --- /dev/null +++ b/hu/python_installation/instructions.md @@ -0,0 +1,59 @@ +> Ez a fejezet a Geek Girls Carrots (http://django.carrots.pl/) 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. + +### 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á! + +Egy fontos dolog, amire figyelj oda: a telepítővarázsló második képernyőjén ("Customize") görgess lejjebb, és válaszd ki az "Add python.exe to the Path" opciót, ahogy itt láthatod: + +![Ne felejtsd el hozzáadni a Pythont a Path-hoz](../python_installation/images/add_python_to_windows_path.png) + +### Linux + +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: + + $ python3 --version + Python 3.4.3 + + +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: + + $ sudo yum install python3.4 + + +#### Fedora (22+) + +Írd be az alábbi programot a konzolba: + + $ sudo dnf install python3.4 + + +### 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: + + $ python3 --version + Python 3.4.3 + + +* * * + +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. \ No newline at end of file diff --git a/hu/python_introduction/README.md b/hu/python_introduction/README.md new file mode 100644 index 00000000000..1f5413bfbed --- /dev/null +++ b/hu/python_introduction/README.md @@ -0,0 +1,788 @@ +# Bevezetés a Pythonba + +> Ez a fejezet részben a Geek Girls Carrots (http://django.carrots.pl/) tutorialjain alapszik. + +Írjunk egy kis kódot! + +## A Python parancssor + +Hogy elkezdhess a Pythonnal ismerkedni, szükséged lesz a *parancssorra*. Már tudod, hogyan kell -- megtanultad a [ Bevezetés a parancssor használatába][1] fejezetben. + + [1]: ../intro_to_command_line/README.md + +Ha kész vagy, kövesd az alábbi utasításokat. + +Egy Python konzolt szeretnénk megnyitni. Gépeld be a `python` parancsot Windowson, vagy a `python3` parancsot, ha Mac vagy Linux van a gépeden, és nyomj `enter`t. + + $ python3 + Python 3.4.3 (...) + Type "help", "copyright", "credits" or "license" for more information. + >>> + + +## Az első Python parancsod! + +Miután futtattad a Python parancsot, a parancssor megváltozott: `>>>`. Ez azt jelenti, hogy mostantól csak a Python nyelv parancsait használhatjuk. Nem kell beírnod ezt: `>>>` - a Python megcsinálja helyetted. + +Ha bármikor szeretnél kilépni a Python konzolból, csak gépeld be, hogy `exit()`, vagy használd a `Ctrl + Z` billentyűkombinációt Windos-ra, vagy a `Ctrl + D`-t Mac-re/Linux-ra. Ezután már nem fogod látni a `>>>` jelet. + +Most épp nem szeretnénk kilépni a Python konzolból. Inkább többet szeretnénk tanulni róla. Kezdjünk valami nagyon egyszerűvel. Például kezdjünk valami matekkel, mint pl. `2 + 3` majd `enter`. + + >>> 2 + 3 + 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` + +Szórakozz egy kicsit ezzel aztán gyere vissza ide :). + +Amint látod, a Python jó számológép. Ha kíváncsi vagy, mire jó még... + +## Stringek + +Mi a helyzet a neveddel? Gépeld be a neved időzéjelbe téve: + + >>> "Ola" + 'Ola' + + +Épp most hoztad létre az első stringedet! Ez egy karakter-sorozat amit a számítógép fel tud dolgozni. A string kezdetét és végét ugyanazzal a karakterrel jelöljük. Ez lehet szimpla (`'`) vagy dupla (`"`) idézőjel (nincs különbség!) Az idézőjelek mondják meg a Pythonnak, hogy ami köztük van, az egy string. + +A stringeket össze is lehet fűzni. Próbáld ki ezt: + + >>> "Hi there " + "Ola" + 'Hi there Ola' + + +Sokszorosítani is lehet őket: + + >>> "Ola" * 3 + 'OlaOlaOla' + + +Ha aposztrófot szeretnél a stringedbe tenni, kétféleképpen teheted meg. + +Idézőjel segítségével: + + >>> "Runnin' down the hill" + "Runnin' down the hill" + + +vagy pedig escape karakterrel (``) az aposztróf előtt: + + >>> 'Runnin\' down the hill' + "Runnin' down the hill" + + +Jó, mi? Ha nagybetűkkel szeretnéd látni a neved, csak gépeld be ezt: + + >>> "Ola".upper() + 'OLA' + + +Épp most használtad az `upper` **functiont** (függvényt) a stringeden! A függvény, (mint például az `upper()`), egy utasítássorozat, amit a Python végrehajt egy adott objektumon (`"Ola"`), amikor a függvényt meghívod. + +Ha szeretnéd tudni, hogy hány betűből áll a neved, arra is van függvény! + + >>> len("Ola") + 3 + + +Érdekel, miért van az, hogy néha a függvényeket úgy hívjuk meg, hogy a string után egy `.` jön, majd a függvény neve (mint például `"Ola".upper()`), máskor pedig előbb a függvény neve jön, aztán a string a zárójelben? Nos, ez azért van mert néha a függvények objektumokhoz tartoznak, mint az `upper()`, amit csak azokon az objektumokon hívhatunk meg. Ebben az esetben a függvényt **metódusnak** (method) nevezzük. Máskor a függvény nem tartozik egy bizonyos típusú objektumhoz, hanem többféle típusú objektumon is meg lehet hívni, mint például a `len()`. Ezért volt az hogy az `"Ola"`-t paraméterként adtuk át a `len` függvénynek. + +### Összefoglaló + +Oké, elég a stringekből. Tehát ezidáig a következőkről tanultál: + +* **a parancssor** - ha parancsokat (kódot) írunk be a Python parancssorba, a Python végrehajtja azokat +* **számok és stringek** - a Pythonban a számokat matematikai műveletekhez, a stringeket szöveg objektumokhoz használjuk +* **operátorok** - mint a + és a *, két értékből egy újat hoznak létre +* **függvények** - mint az upper() és a len(), objektumokon hajtanak végre műveleteket. + +Ezek volnának az alapjai minden programozási nyelvnek. Készen állsz valami bonyolultabbra? Rajta! + +## Hibák + +Nézzünk valami újat. Vajon megkaphatjuk-e egy szám hosszát ugyanúgy, mint a nevünk hosszát? Írd be, hogy `len(304023)`, majd üss `enter`-t: + + >>> len(304023) + Traceback (most recent call last): + File "", line 1, in + TypeError: object of type 'int' has no len() + + +Megkaptuk az első hibánkat! Azt mondja, az "int" típusú (integerek, egész számok) objektumoknak nincs hosszuk. Most akkor mit tehetünk? Talán leírhatjuk a számunkat stringként? A stringeknek van hosszuk, nem? + + >>> len(str(304023)) + 6 + + +Működött! Használtuk a `str` függvényt a `len` függvény belsejében. A `str()` függvény stringgé alakít egy tetszőleges típusú objektumot. + +* A `str` függvény **stringgé** alakítja a dolgokat +* Az `int` függvény **integerré** alakítja a dolgokat + +> Fontos: számokat (integereket) stringgé bármikor alakíthatunk, de stringet számmá nem feltétlenül - mégis mi lenne az `int('hello')` eredménye? + +## Változók + +A programozásban nagyon fontos a változó fogalma. A változó egy név egy objektumra, amit majd később újra felhasználhatunk. A programozók arra használják a változókat, hogy adatokat tároljanak velük, hogy a kódjukat olvashatóbbá tegyék, és hogy ne kelljen megjegyezniük mindenről, hogy micsoda. + +Tegyük fel, hogy létrehoztál egy változót, aminek a neve `name`: + + >>> name = "Ola" + + +Látod? Egyszerű! Csak ennyi: name egyenlő Ola. + +Amint láthatod, a program nem adott vissza semmilyen eredményt, az eddigiekkel ellentétben. Honnan tudjuk így, hogy a változó létrejött? Egyszerűen írd be, hogy `name`, majd üss `enter`-t: + + >>> name + 'Ola' + + +Juppííí! Az első változód :)! És bármikor megváltoztathatod, hogy mit tartalmaz: + + >>> name = "Sonja" + >>> name + 'Sonja' + + +És függvényekben is használhatod: + + >>> len(name) + 5 + + +Szuper, ugye? Természetesen a változók bármilyen értéket felvehetnek, például szám-értékeket is. Próbáld ki: + + >>> a = 4 + >>> b = 6 + >>> a * b + 24 + + +De mi van akkor, ha rossz nevet használunk? Kitalálod? Próbáljuk ki! + + >>> city = "Tokyo" + >>> ctiy + Traceback (most recent call last): + File "", line 1, in + NameError: name 'ctiy' is not defined + + +Egy hiba! Amint látod a Pythonban különböző típusú hibák vannak, ezt például úgy hívják hogy **NameError**. A Python ezt a hibát dobja, ha olyan változóra hivatkozol, ami nem volt még létrehozva. Ha majd találkozol ezzel a hibával, mindig ellenőrizd a kódod, hogy nem írtál-e el egy nevet. + +Játssz egy kicsit a változókkal, hogy lásd, mi mindenre vagy képes velük! + +## A print függvény + +Próbáld ki ezt: + + >>> name = 'Maria' + >>> name + 'Maria' + >>> print(name) + Maria + + +Amikor beírod, hogy `name`, a Python interpreter a "name" változó szöveges *reprezentációjával* tér vissza, ami a M-a-r-i-a betűkből áll, idézőjelek között. Amikor azt írod: `print(name)`, a Python "kinyomtatja" a változó tartalmát a képernyőre, idézőjelek nélkül, ami sokkal elegánsabb. + +Amint majd látni fogjuk, a `print()` hasznos lesz függvények belsejében is, vagy amikor több sorba szeretnénk nyomtatni. + +## Listák + +A stringek és az integerek mellett a Python még sok más típusú objektumot ismer. Most megmutatunk egy újat, amit úgy hívnak: **lista**. A lista olyan, amilyennek elképzeled: egy objektum, ami más objektumok listája :) + +Hozzunk létre egy listát: + + >>> [] + [] + + +Igen, ez egy üres lista. Nem túl hasznos, ugye? Most hozzunk létre egy listát a lottószámokkal. Nem akarjuk folyton ismételni magunkat, úgyhogy egyenesen egy változóba tesszük: + + >>> lottery = [3, 42, 12, 19, 30, 59] + + +Igen, van egy listánk! Mit lehet vele csinálni? Nézzük meg, hány lottószám van a listában. Van tipped, melyik függvényt fogjuk erre használni? Biztos tudod! + + >>> len(lottery) + 6 + + +Igen! A `len()` megadja, hogy hány objektum van a listában. Hasnzos, ugye? Most akkor rendezzük sorba a listát: + + >>> lottery.sort() + + +Ez nem ad vissza semmit, csak megváltoztatta a számok sorrendjét a listában. Írassuk ki a listát, hogy lássuk, mi történt: + + >>> print(lottery) + [3, 12, 19, 30, 42, 59] + + +Amint látod, a számok a listában most növekvő sorrendben vannak. Gratula! + +Esetleg szeretnéd fordított sorrendbe rendezni? Csináljuk meg! + + >>> lottery.reverse() + >>> print(lottery) + [59, 42, 30, 19, 12, 3] + + +Könnyű, ugye? Ha hozzá akarsz adni valamit a listához, a következő paranccsal teheted: + + >>> lottery.append(199) + >>> print(lottery) + [59, 42, 30, 19, 12, 3, 199] + + +Ha például csak az első számot akarod látni, arra használhatod az **indexelést**. Az index egy szám ami megmondja, hányadikként fordul elő egy elem a listában. A programozók szeretik 0-tól kezdeni a számolást, ezért a lista első eleme a 0-dik indexű helyen van, a következő az 1-nél és így tovább. Próbáld ki ezt: + + >>> print(lottery[0]) + 59 + >>> print(lottery[1]) + 42 + + +Amint látod, a listában előforduló különböző objektumokat elérhetjük a lista nevének, illetve az objektum indexének megjelölésével, ahol az indexet szögletes zárójelbe írjuk. + +Ahhoz, hogy valamit kitöröljünk a listából, szükségünk van az **index** fogalmára, amint azt az előbb tanultuk, valamint a **del** parancsra (a del a delete rövidítése). Nézzünk egy példát hogy megerősítsük az eddig tanultakat; ki fogjuk törölni az első elemet a listánkból. + + >>> print(lottery) + [59, 42, 30, 19, 12, 3, 199] + >>> print(lottery[0]) + 59 + >>> del lottery[0] + >>> print(lottery) + [42, 30, 19, 12, 3, 199] + + +Működik, mint a varázslat! + +Szórakozásból próbálj elérni különböző indexű elemeket: 6, 7, 1000, -1, -6 vagy -1000. Meg tudod-e mondani az eredményt előre? Értelmes-e az eredmény? + +Ebben a Python dokumentációban megtalálod a listákra értelmezett összes metódust: https://docs.python.org/3/tutorial/datastructures.html + +## 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ő: + + >>> {} + {} + + +Épp most definiáltál egy üres szótárat. Hurrá! + +Most pedig próbáld ki a következő parancsot (és próbáld meg használni a saját adataidat): + + >>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} + + +Ezzel a paranccsal létrehoztál egy szótár-változót aminek a neve `participant`, és ami tartalmaz három kulcs-érték (key-value) párt: + +* A `name` kulcs az `'Ola'` értékre mutat (ami egy `string` típusú objektum), +* `country` a `'Poland'`-ra mutat (szintén `string` típusú), +* és `favorite_numbers` a `[7, 42, 92]` objektumra mutat (ami egy `lista` benne három elemmel). + +Lekérdezheted az egyes kulcsokhoz tartozó értékeket a következő szintaxist használva: + + >>> print(participant['name']) + Ola + + +Látod, nagyon hasonlít a listákhoz. Csak épp nem kell indexeket megjegyezned - csupán neveket. + +Vajon mi történik, ha olyan kulcshoz tartozó értéket kérdezünk le a Pythontól, ami nem létezik? Nézzük meg! + + >>> participant['age'] + Traceback (most recent call last): + File "", line 1, in + KeyError: 'age' + + +Jéé, egy újabb hiba! Ezúttal **KeyError**. A Python segítőkész, és megmondja, hogy az `'age'` kulcsnál nem található érték a szótárban. + +Mikor használjunk szótárakat és mikor listákat? Nos, ez egy érdekes kérdés. Gondolkozz el egy kicsit, és próbáld meg magadtól kitalálni, mielőtt elolvasod az alábbi választ. + +* Csak elemek rendezett sorozatára van szükséged? Használj listát. +* Kulcs és érték párokra van szükséged, amiket majd le tudsz kérdezni hatékonyan (kulcs alapján)? Használj szótárat. + +A szótárak, ugyanúgy mint a listák, *módosíthatók*, ami azt jelenti, hogy az objektumot meg lehet változtatni létrehozás után. Hozzá lehet adni egy kulcs-érték párt a szótárhoz a létrehozása után, pl: + + >>> participant['favorite_language'] = 'Python' + + +Ugyanúgy, mint a listáknál, a `len()` metódus visszaadja a szótár hosszát, azaz a kulcs-érték párok számát. Rajta, próbáld ki a következő parancsot: + + >>> len(participant) + 4 + + +Remélem most már világos :) Készen állsz az újabb mókára a szótárakkal? Ugorj a következő sorhoz, és láss lenyűgöző dolgokat. + +Használd a `del` parancsot, hogy kitörölj egy elemet a szótárból. Mondjuk ki akarod törölni a `'favorite_numbers'` kulcsnál található elemet. Csak írd be a következőt: + + >>> del participant['favorite_numbers'] + >>> participant + {'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} + + +Amint azt a kimenetből látod, a 'favorite_numbers' kulcshoz tartozó elem eltűnt a szótárból. + +Az előbbihez hasonlóan, meg is tudod változtatni egy kulcsnál a hozzá tartozó értéket a szótárban. Írd ezt: + + >>> participant['country'] = 'Germany' + >>> participant + {'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} + + +Amint látod, a `'country'` kulcsnál levő érték megváltozott `'Poland'`-ról `'Germany'`-ra. :) Izgalmas, ugye? Hurrá! Most ismét tanultál egy nagyszerű dolgot. + +### Összefoglaló + +Nagyszerű! Most már tudsz egy csomó mindent a programozásról. Ebben az utolsó részben a következőkről tanultál: + +* **hibák** - tudod, hogyan olvasd és értsd meg a hibákat, amiket a Python ad, amikor nem tudja értelmezni a parancsodat +* **változók** - nevek az objektumokhoz, hogy a kód könnyebben írható és könnyebben olvasható legyen +* **listák** - lista meghatározott sorrendben lévő objektumokból +* **szótárak** - objektumok, amiket kulcs-érték párokként tárolunk + +Felkészültél a következő részre? :) + +## Dolgok összehasonlítása + +A számítástechnikában nagyon fontos, hogy össze tudjunk hasonlítani dolgokat. Mik a legegyszerűbb dolgok, amiket össze tudunk hasonlítani? Hát a számok. Nézzük meg ez hogy működik: + + >>> 5 > 2 + True + >>> 3 < 1 + False + >>> 5 > 2 * 2 + True + >>> 1 == 1 + True + >>> 5 != 2 + True + + +Adtunk a Pythonnak néhány számot, hogy összehasonlítsa azokat. Amint látod, a Python nem csak számokat, de műveleti eredményeket is össze tud hasonlítani. Jó, ugye? + +Azon gondolkozol, miért kellett két egyenlőség jelet `==` tenni, amikor azt néztük, hogy két szám egyenlő-e? Az egyetlen `=` jelet arra használjuk, hogy a változóknak értéket adjunk. Mindig, de **mindig** két `==` jelet kell használni ha két dolog egyenlőségét akarod tesztelni. Azt is ki tudjuk fejezni, hogy két dolog nem egyenlő. Erre a `!=` szimbólumot használjuk, amint az alábbi példában is. + +Adj a Pythonnak két új parancsot: + + >>> 6 >= 12 / 2 + True + >>> 3 <= 2 + False + + +A `>` és a `<` egyszerűek, de vajon a `>=` és a `<=` mit jelentenek? Ezeket úgy kell olvasni, hogy: + +* x `>` y azt jelenti: x nagyobb, mint y +* x `<` y azt jelenti: x kisebb, mint y +* x `<=` y azt jelenti: x kisebb vagy egyenlő y-nal +* x `>=` y azt jelenti: x nagyobb vagy egyenlő y-nal + +Nagyszerű! Szeretnél még egy példát? Próbáld ki ezt: + + >>> 6 > 2 and 2 < 3 + True + >>> 3 > 2 and 2 < 1 + False + >>> 3 > 2 or 2 < 1 + True + + +Annyi összehasonlítást kombinálhatsz össze, amennyit csak akarsz, és a Python kiszámolja az eredményt. Okos, ugye? + +* **and** (azaz: és) - amikor az `and` operátort használod, a kifejezés mindkét oldalán igaz értéknek kell állnia ahhoz, hogy az eredmény igaz legyen +* **or** (azaz: vagy) - amikor az `or` operátort használod, elég csak az egyik oldalon igaz értéknek állnia ahhoz, hogy az eredmény igaz legyen + +Hallottad már azt a kifejezést hogy "almákat narancsokkal összehasonlítani"? Nézzük meg ennek a python-beli megfelelőjét: + + >>> 1 > 'django' + Traceback (most recent call last): + File "", line 1, in + TypeError: unorderable types: int() > 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. + +## Boolean (Logikai) + +Véletlenül épp megismerkedtél egy újabb Python típussal. Úgy hívják: **Boolean** -- és valószínűleg ez a legegyszerűbb típus ami létezik. + +Egy Boolean objektum két lehetséges értéket vehet fel: - Igaz - Hamis + +De ahhoz, hogy a Python megértse, pontosan így kell írni: 'True' (az első betű nagybetű, a többi kisbetű). **true, TRUE, tRUE mind nem jók -- csak az True helyes.** (És ugyanígy a 'False' esetében) + +A Booleanok is lehetnek változók! Nézd: + + >>> a = True + >>> a + True + + +Sőt, ezt is írhatod: + + >>> a = 2 > 5 + >>> a + False + + +Gyakorold egy kicsit és játssz a Booleanokkal, pl próbáld ki a következő parancsokat: + +* `True and True` +* `False and True` +* `True or 1 == 1` +* `1 != 2` + +Gratulálunk! A Booleanok a programozás egyik legmenőbb elemei, és te épp megtanultad használni őket! + +# Mentsd el! + +Egész mostanig a python interpreterbe írkáltuk a parancsokat, ami arra korlátoz minket hogy, egyszerre csak egy sort írjunk. A gyakorlatban a programokat fájlba mentjük, és utána futtatjuk a programnyelv **interpreter**-e vagy **compiler**-e révén. Mi mindeddig a Python **interpreter**-ével futtatuk a programjainkat, soronként. A következő feladatokhoz többsoros programokra is szükségünk lesz, úgyhogy gyorsan: + +* Lépjünk ki a Python interpreterből +* Nyissunk meg egy kódszerkesztőt +* 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()~~~: + + >>> exit() + $ + + +Ezzel visszatértünk a parancssorba. + +Egy előző részben már kiválasztottuk a kedvenc [kódszerkesztő][2]nket. Most nyissuk meg az editort és az új üres fájlba írjuk bele: + + [2]: ../code_editor/README.md + +```python + 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. + +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 /Users//Desktop + + +Linuxon így (A "Desktop" lehet, hogy le van fordítva a te nyelvedre): + + $ cd /home//Desktop + + +És Windowson így néz ki: + + > cd C:\Users\\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! + + +Rendben! Épp lefuttattad az első Python programodat fájlból. Jó érzés, ugye? + +Most akkor továbbmehetünk egy újabb kulcsfontosságú programozási elemre: + +## If...elif...else + +Sokszor előfordul a programozásban, hogy egyes kódrészleteknek csak akkor kell lefutniuk, ha bizonyos feltételek teljesülnek. Ezért vannak a Pythonban az **if statement**ek (if állítások). + +Cseréld ki a **python_intro.py** fájlban lévő kódot erre: + +```python + if 3 > 2: +``` + +Ha ezt elmented és lefuttatod, ezt a hibaüzenetet fogod látni: + + $ python3 python_intro.py + File "python_intro.py", line 2 + ^ + SyntaxError: unexpected EOF while parsing + + +A Python arra számít, hogy további utasításokat kap arra az esetre, ha a `3 > 2` teljesül, vagyis `True` lesz. Vegyük rá a Pythont, hogy kiírja: "It works!" ("Működik!"). Változtasd meg erre a **python_intro.py** fájlban lévő kódot: + +```python + if 3 > 2: + print('It works!') +``` + +Megfigyelted, hogy a következő sort 4 szóközzel indentáltuk? Erre azért van szükség, hogy a Python tudja, melyik kódrészletet kell lefuttatnia, ha a feltétel teljesül. Egy szóközt is használhatnál, de szinte az összes Python programozó 4 szóközt használ, hogy rendezetten nézzen ki a kód. Egy `tab` is 4 szóköznek számít. + +Mentsd el, és futtasd le még egyszer: + + $ python3 python_intro.py + It works! + + +### Mi történik, ha egy feltétel nem teljesül (vagyis nem True)? + +A korábbi példákban a kód csak akkor futott le, ha a feltétel teljesült. De a Pythonnak van `elif` és `else` statementje is: + +```python + if 5 > 2: + print('5 is indeed greater than 2') + else: + print('5 is not greater than 2') +``` + +Ha ezt lefuttatod, a következőt kapod: + + $ python3 python_intro.py + 5 is indeed greater than 2 + + +Ha a 2 nagyobb lenne, mint az 5, a második parancs futott volna le. Egyszerű, igaz? Nézzük, hogy működik az `elif`: + +```python + name = 'Sonja' + if name == 'Ola': + print('Hey Ola!') + elif name == 'Sonja': + print('Hey Sonja!') + else: + print('Hey anonymous!') +``` + +lefuttatva: + + $ python3 python_intro.py + Hey Sonja! + + +Látod, mi történt itt? Az `elif` arra jó, hogy plusz feltételeket írhass a kódodba, ami akkor fut le, ha a korábbi feltételek nem teljesülnek. + +Az első `if` statement után annyi `elif` állítást írhatsz, amennyit csak akarsz. Például: + +```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!:(")! :(") +``` + +A Python sorban mindegyik feltételt megnézi, és kiírja: + + $ python3 python_intro.py + Perfect, I can hear all the details + + +### Ö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. + +Elérkeztünk a fejezet utolsó részéhez! + +## A saját függvényeidhez! + +Emlékszel például a `len()` fügvényre, amit lefuttathatsz Pythonban? Jó hírünk van - most megtanulod, hogyan írhatsz saját függvényeket! + +A függvény utasítások sorozata, amit a Python lefuttat. Minden Python függvény a `def` kulcsszóval kezdődik, van neve, és lehetnek paraméterei. Kezdjük egy könnyűvel. Cseréld ki a **python_intro.py** kódját erre: + +```python + def hi(): + print('Hi there!') + print('How are you?') + + hi() +``` + +Oké, kész is az első függvény! + +Talán elgondolkodtál, miért írtuk a függvény nevét a fájl aljára. Erre azért van szükség, mert a Python felülről lefelé olvassa be és futtatja le a fájlt. Tehát ahhoz, hogy használni tudjuk a függvényünket, újra le kell írnunk a fájl alján. + +Futtassuk le, és nézzük meg, mi történik: + + $ python3 python_intro.py + Hi there! + How are you? + + +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á: + +```python + def hi(name): +``` + +Ahogy láthattad, a függvény most kapott egy paramétert, amit `name`-nek hívunk: + +```python + def hi(name): + if name == 'Ola': + print('Hi Ola!') + elif name == 'Sonja': + print('Hi Sonja!') + else: + print('Hi anonymous!') + + hi() +``` + +Fontos: a `print` függvény 4 szóközzel van indentálva az `if` statementen belül. Erre azért van szükség, hogy ez a függvény a feltétel teljesülése esetén fusson le. Nézzük, hogy működik: + + $ 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' + + +Hoppá, egy hiba. Szerencsére a Python elég hasznos hibaüzeneteket ad nekünk. Azt mondja, a `hi()` függvénynek (vagyis annak, amit az előbb definiáltunk) egy kötelező paramétere van (amit `name`-nek hívnak), és ezt elfelejtettük beadni, amikor meghívtuk a függvényt. Javítsuk ki a fájl alján: + +```python + hi("Ola") +``` + +És futtassuk le újra: + + $ python3 python_intro.py + Hi Ola! + + +És ha megváltoztatjuk a nevet? + +```python + hi("Sonja") +``` + +Futtasd le: + + $ python3 python_intro.py + Hi Sonja! + + +Mit gondolsz, mi fog történni, ha egy harmadik nevet írsz be? Próbáld ki, és nézd meg, jól gondoltad-e. Ezt kell kapnod: + + Hi anonymous! + + +Ez fantasztikus, nem? Így nem kell állandóan ismételned magad, ha meg szeretnéd változtatni az ember nevét, akinek a függvény köszön. Pont emiatt van szükségünk függvényekre - soha ne ismételd meg a kódodat! + +Most csináljunk valami okosabbat - több mint két név van a világon, és nehéz lenne mindegyikhez egy külön feltételt írni, nem? + +```python + def hi(name): + print('Hi ' + name + '!') + + hi("Rachel") +``` + +Most hívjuk meg a kódot: + + $ python3 python_intro.py + Hi Rachel! + + +Gratulálunk! Megtanultad, hogy kell függvényeket írni :) + +## Ciklusok (loopok) + +Ez már tényleg az utolsó rész. Gyors volt, nem igaz? :) + +A programozók nem szeretik ismételni magukat. A programozás arról szól, hogy dolgokat automatizáljunk, így nem kell minden alkalommal kézzel beírni mindenkinek a nevét, akit üdvözölni akarunk. Ilyenkor jönnek jól a ciklusok. + +Még emlékszel a listákra? Írjunk egy listát lányokból: + +```python + girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +``` + +Mindegyiküket üdvözölni szeretnénk. Ehhez már megvan a `hi` függvényünk, tegyük bele egy loopba: + +```python + 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. + +Itt a teljes kód, ami a fájlban lesz: + +```python + def hi(name): + print('Hi ' + name + '!') + + girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] + for name in girls: + hi(name) + print('Next girl') +``` + +És amikor futtatjuk: + + $ python3 python_intro.py + Hi Rachel! + Next girl + Hi Monica! + Next girl + Hi Phoebe! + Next girl + Hi Ola! + Next girl + Hi You! + Next girl + + +Amint láthattad, minden, amit indentálva a `for` statementbe tettél, megismétlődik a `girls` lista minden elemével. + +A `for`-t számokon is használhatod, a `range` függvénnyel: + + for i in range(1, 6): + print(i) + + +Ezt kapjuk: + + 1 + 2 + 3 + 4 + 5 + + +A `range` függvény létrehoz egy egymás után következő számokból álló listát (ezeket a számokat te adod meg paraméterként). + +Figyeld meg, hogy a két szám közül a második már nincs benne a listában, amit a Python visszaad (vagyis a `range(1, 6)` 1-től 5-ig számol, de nem tartalmazza a 6-ot). Ez azért van, mert a "range" félig nyitott, ez pedig azt jelenti, hogy az első értéket tartalmazza, de az utolsót már nem. + +## Összefoglaló + +Meg is vagyunk. **Szuper vagy!** Ez egy nehéz fejezet volt, büszke lehetsz magadra. Mi nagyon büszkék vagyunk rád, amiért idáig eljutottál! + +Most talán tarthatnál egy kis szünetet - nyújtózkodj, sétálj egy kicsit, pihentesd a szemeidet - mielőtt továbbmennénk a következő fejezetre. :) + +![Cupcake][3] + + [3]: images/cupcake.png \ No newline at end of file diff --git a/hu/python_introduction/images/cupcake.png b/hu/python_introduction/images/cupcake.png new file mode 100644 index 00000000000..fa2f3baeae6 Binary files /dev/null and b/hu/python_introduction/images/cupcake.png differ diff --git a/hu/template_extending/README.md b/hu/template_extending/README.md new file mode 100644 index 00000000000..a7286f56d9a --- /dev/null +++ b/hu/template_extending/README.md @@ -0,0 +1,122 @@ +# Template-kiegészítés + +Egy másik szuper dolog, amit a Django tud, a **template extending**, vagyis template-kiegészítés. Mit jelent ez? Azt, hogy a HTML-ed egyes részeit több oldalon is fel tudod használni az alkalmazásodban. + +Így nem kell megismételned magad minden fájlban, ha ugyanazt az információt szeretnéd felhasználni, vagy ugyanolyan layout-ot tervezel. És ha meg szeretnél változtatni valamit, nem kell minden sablonban külön megtenned, csak egyszer! + +## Hozd létre az alap template-et + +A base (alap) template a legegyszerűbb sablon, amit az alkalmazásod összes oldalán kiegészítesz. + +Hozz létre egy `base.html` fájlt a `blog/templates/blog/`-ban: + + blog + └───templates + └───blog + base.html + post_list.html + + +Majd nyisd meg, és másolj át mindent a `post_list.html`-ből a `base.html`-be, így: + +```html +{% load staticfiles %} + + + Django Girls blog + + + + + + + + +
+
+
+ {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+ {% endfor %} +
+
+
+ + +``` + +Aztán a `base.html`-ben cseréld ki az egész ``-t (mindent a `` és a `` között) erre: + +```html + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ +``` + +Lényegében a `{% for post in posts %}{% endfor %}` részt kicseréltük erre: + +```html +{% block content %} +{% endblock %} +``` + +Ez mit is jelent? Létrehoztál egy `block`-ot. Ez egy olyan template tag, amely segítségével HTML-t illeszthetsz be a blokkba más template-ekben, ezzel kiegészítve a `base.html`-t. Máris megmutatjuk, hogy működik. + +Most mentsd el, és nyisd meg újra a `blog/templates/blog/post_list.html`-t. Törölj ki mindent a body-n kívül, és a `` részt is, hogy így nézzen ki a fájl: + +```html +{% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% endfor %} +``` + +És most add hozzá ezt a sort a fájl elejéhez: + + {% 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 %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+ {% endfor %} +{% endblock content %} +``` + +Ez az! Nézd meg, hogy még mindig működik-e a weboldalad :) + +> Ha `TemplateDoesNotExists` (a template nem létezik) hibát kapsz, ami azt mondja, nincs `blog/base.html` fájlod, és fut a `runserver` a konzolban, próbáld meg leállítani (Ctrl+C-vel, vagyis egyszerre nyomd meg a Control és a C billentyűt) és indítsd el újra a `python manage.py runserver` paranccsal. \ No newline at end of file diff --git a/hu/whats_next/README.md b/hu/whats_next/README.md new file mode 100644 index 00000000000..566c539ddaa --- /dev/null +++ b/hu/whats_next/README.md @@ -0,0 +1,40 @@ +# Következő lépések + +Gratulálj magadnak! **Szuper vagy**. Nagyon büszkék vagyunk rád! <3 + +### És most? + +Tarts egy kis szünetet, és pihenj. Valami egészen hatalmas dolgot csináltál. + +Aztán majd ne felejtsd el: + +* Követni a Django Girlst [Facebook][1]on vagy [Twitter][2]en, hogy mindenről értesülj + + [1]: http://facebook.com/djangogirls + [2]: http://twitter.com/djangogirls + +### Tudunk-e ajánlani bármilyen tananyagot? + +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/ + +Később megpróbálkozhatsz a lenti listában lévő anyagokkal is. Ezeket mind nagyon ajánljuk! + +- [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]: 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 \ No newline at end of file diff --git a/it/GLOSSARY.md b/it/GLOSSARY.md new file mode 100644 index 00000000000..5ebfa17670a --- /dev/null +++ b/it/GLOSSARY.md @@ -0,0 +1,3 @@ +# editor di codice + +L'editor di codice è un'applicazione che ti permette di salvare il tuo codice e di potervi tornare in seguito. Puoi capire come procurartene uno nel [capitolo Editor di codice](./code_editor/README.md) \ No newline at end of file diff --git a/it/README.md b/it/README.md new file mode 100644 index 00000000000..6e88a119455 --- /dev/null +++ b/it/README.md @@ -0,0 +1,48 @@ +# 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) + +> Questo lavoro è sotto la licenza internazionale di Creative Commons Attribution-ShareAlike 4.0. Per vedere una copia di questa licenza, visita http://creativecommons.org/licenses/by-sa/4.0/ + +## 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? + +Beh, abbiamo buone notizie per te! La programmazione non è così complicata come sembra e vogliamo dimostrati 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. + +Speriamo di essere in grado di farti amare la tecnologia come lo facciamo 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! + +Assomiglierà (più o meno) a questo: + +![Figure 0.1][2] + + [2]: images/application.png + +> 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...][3] + + [3]: ./how_the_internet_works/README.md + +## Informazioni e contribuzioni + +Questo tutorial è mantenuto da [DjangoGirls][4]. Se trovi errori o se vuoi aggiornare questo tutorial, [segui le linee guida per i collaboratori][5]. + + [4]: http://djangogirls.org/ + [5]: https://github.com/DjangoGirls/tutorial/blob/master/README.md + +## Vorresti aiutarci a tradurre il tutorial in un altra lingua? + +Attualmente, le traduzioni vengono mantenute sulla piattaforma crowdin.com in: + +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 diff --git a/it/SUMMARY.md b/it/SUMMARY.md new file mode 100644 index 00000000000..694b07fd6b9 --- /dev/null +++ b/it/SUMMARY.md @@ -0,0 +1,26 @@ +# Indice + +* [Introduzione](README.md) +* [Installazione](installation/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 a Python](python_introduction/README.md) +* [Che cos'è Django?](django/README.md) +* [Installazione di Django](django_installation/README.md) +* [Il tuo primo progetto Django!](django_start_project/README.md) +* [I modelli di Django](django_models/README.md) +* [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) +* [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) +* [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 diff --git a/it/code_editor/README.md b/it/code_editor/README.md new file mode 100644 index 00000000000..8261e76f6cb --- /dev/null +++ b/it/code_editor/README.md @@ -0,0 +1,7 @@ +# Code Editor + +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! + +{% include "/code_editor/instructions.md" %} diff --git a/it/code_editor/instructions.md b/it/code_editor/instructions.md new file mode 100644 index 00000000000..fb6ff4b7456 --- /dev/null +++ b/it/code_editor/instructions.md @@ -0,0 +1,31 @@ +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. + +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. + +## Gedit + +Gedit è un editor open-source e gratuito, disponibile per tutti i sistemi operativi. + +[Scaricalo qui](https://wiki.gnome.org/Apps/Gedit#Download) + +## Sublime Text 2 + +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. + +[Scaricalo qui](http://www.sublimetext.com/2) + +## Atom + +Atom è un nuovo editor di codice creato da [GitHub](http://github.com/). È gratuito, open-source, facile da installare e da usare. È disponibile per Windows, OSX e Linux. + +[Scaricalo qui](https://atom.io/) + +## Perché installiamo 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. + +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 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. + +Vedremo tutto ciò più tardi. Il tuo fidato code editor sarà presto uno dei tuoi strumenti preferiti :) \ No newline at end of file diff --git a/it/css/README.md b/it/css/README.md new file mode 100644 index 00000000000..cdcac12abf7 --- /dev/null +++ b/it/css/README.md @@ -0,0 +1,294 @@ +# CSS - dagli un bel aspetto! + +Il nostro blog sembra ancora un pochino brutto, vero? È arrivato il momento di abbellirlo! Per fare ciò useremo CSS. + +## Che cos'è 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 ;). + +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. + +## Usiamo Bootstrap! + +Bootstrap è uno dei più popolari framework HTML e CSS per costruire bellissimi siti internet: http://getbootstrap.com/ + +È stato scritto da programmatori che lavoravano per Twitter ed è ora sviluppato da volontari da ogni parte del mondo. + +## Installa Bootstrap + +Per installare Bootstrap, avrai bisogno di aggiungere questo nel tag `` del tuo file `.html` (`blog/templates/blog/post_list.html`): + +```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] + + [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. + +### 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`. + +Lo facciamo creando una cartella denominata `static` all'interno dela nostra app blog: + + djangogirls + ├── blog + │ ├── migrations + │ └── static + └── 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. + +## 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? + + djangogirls + └─── blog + └─── static + └─── css + └─── blog.css + + +È 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. + + [2]: http://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 + +Aggiungi il seguente codice nel tuo file `static/css/blog.css`: + +```css +h1 a { +    color: #FCA205; +} +``` + +`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! + +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`: + +```html + +``` + +Per saperne di più puoi leggere [CSS Selectors in w3schools][4]. + + [4]: http://www.w3schools.com/cssref/css_selectors.asp + +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: + +```html +{% load staticfiles %} +``` + +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): + +```html + +``` + +Stiamo dicendo al nostro template dove trovare i nostri file CSS. + +Il tuo file dovrebbe avere questo aspetto: + +```html +{% load staticfiles %} + +     +        Django Girls blog +         +         +         +     +     +         + +        {% for post in posts %} +            
+                

published: {{ post.published_date }}

+                

{{ post.title }}

+                

{{ post.text|linebreaks }}

+            
+        {% endfor %} +     + +``` + +OK, salviamo il file e ricarichiamo la pagina web! + +![Figura 14.2][5] + + [5]: 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! + +```css +body { +    padding-left: 15px; +} +``` + +Aggiungi questo al tuo CSS, salva il file e guarda il risultato! + +![Figura 14.3][6] + + [6]: 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`: + +```html + +``` + +Questa riga consente di importare un font chiamato *Lobster* da Google Fonts (https://www.google.com/fonts). + +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: + +```css +h1 a { +    color: #FCA205; +    font-family: 'Lobster'; +} +``` + +![Figura 14.3][7] + + [7]: 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. + +Prova a dare dei nomi ad alcune parti dell'HTML. Aggiungi una classe chiamta `page-header` al tuo `div` che contiene l'intestazione così: + +```html + +``` + +E ora aggiungi una classe `post` al tuo `div` che contiene un articolo del blog. + +```html +
+    

published: {{ post.published_date }}

+    

{{ post.title }}

+    

{{ post.text|linebreaks }}

+
+``` + +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`: + +```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; +} +``` + +Ora aggiungi all'esterno del codice HTML riguardante i posts all'interno del blog alcuni elementi con definizione di classi. Sostituisci questo: + +```html +{% for post in posts %} +    
+        

published: {{ post.published_date }}

+        

{{ post.title }}

+        

{{ post.text|linebreaks }}

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

{{ post.title }}

+                    

{{ post.text|linebreaks }}

+                
+            {% endfor %} +        
+    
+
+``` + +Salva entrambi i file e ricarica la pagina web. + +![Figura 14.4][8] + + [8]: 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. + +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! + +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. + +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 new file mode 100644 index 00000000000..f7e1f57536c Binary files /dev/null and b/it/css/images/bootstrap1.png differ diff --git a/it/css/images/color2.png b/it/css/images/color2.png new file mode 100644 index 00000000000..c191d399356 Binary files /dev/null and b/it/css/images/color2.png differ diff --git a/it/css/images/final.png b/it/css/images/final.png new file mode 100644 index 00000000000..f90070b1aa5 Binary files /dev/null and b/it/css/images/final.png differ diff --git a/it/css/images/font.png b/it/css/images/font.png new file mode 100644 index 00000000000..8561bb1cb03 Binary files /dev/null and b/it/css/images/font.png differ diff --git a/it/css/images/margin2.png b/it/css/images/margin2.png new file mode 100644 index 00000000000..5ecba91ae54 Binary files /dev/null and b/it/css/images/margin2.png differ diff --git a/it/deploy/README.md b/it/deploy/README.md new file mode 100644 index 00000000000..e9591f31f42 --- /dev/null +++ b/it/deploy/README.md @@ -0,0 +1,311 @@ +# Deploy! + +> **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. + +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 :). + +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. + + [1]: http://pythonanywhere.com/ + +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]: http://www.github.com + +Useremo GitHub come trampolino di lancio per importare ed esportare il nostro codice su PythonAnywhere. + +# 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. + +{% include "/deploy/install_git.md" %} + +## Inizializzare un repository Git + +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`. + + $ git init + Initialized empty Git repository in ~/djangogirls/.git/ + $ git config --global user.name "Your Name" + $ 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). + +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: + + *.pyc + __pycache__ + myvenv + db.sqlite3 + .DS_Store + + +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. + +È 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: + + $ git status + On branch master + + Initial commit + + Untracked files: + (use "git add ..." to include in what will be committed) + + .gitignore + blog/ + manage.py + mysite/ + + 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 -A . + $ git commit -m "La mia app Django Girls, primo commit" + [...] + 13 files changed, 200 insertions(+) + create mode 100644 .gitignore + [...] + 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!) + +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. + +![][3] + + [3]: 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`. + +Nella schermata successiva, ti verrà mostrato l'URL per clonare il tuo repo: + +![][4] + + [4]: images/github_get_repo_url_screenshot.png + +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 il account GitHub, ma senza le parentesi angolari): + + $ 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: + + 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. + + + + +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 + +# 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. + +{% include "/deploy/signup_pythonanywhere.md" %} + +## 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. + +> **Nota** PythonAnywhere è basato su Linux, quindi se sei su Windows, la console apparirà un po' diversa da quella sul tuo computer. + +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 ``): + + $ git clone https://github.com//my-first-blog.git + + +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 + + +### Creare un virtualenv su PythonAnywhere + +Proprio come hai fatto sul tuo computer, puoi creare un virtualenv su PythonAnywhere. Nella console di Bash, digita: + + 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 + + +> **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. + +Scopriremo un po' di più sui file statici più tardi nell'esercitazione, quando modificheremo il CSS per il nostro sito. + +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. + + (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 + + +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... + + 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'. + + +### Creare il database su PythonAnywhere + +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. + +Possiamo inizializzare il database sul server proprio come abbiamo fatto sul tuo computer, con `migrate` e `createsuperuser`: + + (mvenv) $ python manage.py migrate + Operations to perform: + [...] + Applying sessions.0001_initial... OK + + + (mvenv) $ 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] + + [7]: images/pythonanywhere_web_tab_virtualenv.png + +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. + +> **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 + +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()) +``` + +> **Nota** non dimenticare di mettere il tuo nome utente dove dice `` + +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". + +Clicca **Save** e poi torna alla scheda **Web**. + +Abbiamo finito! Premi il grande pulsante verde **Reload** e potrai vedere la tua applicazione. Troverai un link nella parte superiore della pagina. + +## 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. + +* Commettere un errore nel percorso del virtualenv sulla scheda Web -- di solito c'è un piccolo messaggio di errore in rosso, se c'è un problema. + +* Commettere un errore nel file di configurazione WSGI -- il percorso che hai trovato per tua cartella my-first-blog è corretto? + +* 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 + +E ricorda, il tuo coach è qui per aiutarti! + +# Sei 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. + +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! diff --git a/it/deploy/images/github_get_repo_url_screenshot.png b/it/deploy/images/github_get_repo_url_screenshot.png new file mode 100644 index 00000000000..44412f84823 Binary files /dev/null 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 new file mode 100644 index 00000000000..6e19174ec88 Binary files /dev/null and b/it/deploy/images/new_github_repo.png differ diff --git a/it/deploy/images/pythonanywhere_web_tab_virtualenv.png b/it/deploy/images/pythonanywhere_web_tab_virtualenv.png new file mode 100644 index 00000000000..cafa22c2d97 Binary files /dev/null and b/it/deploy/images/pythonanywhere_web_tab_virtualenv.png differ diff --git a/it/deploy/install_git.md b/it/deploy/install_git.md new file mode 100644 index 00000000000..5e25a4e955e --- /dev/null +++ b/it/deploy/install_git.md @@ -0,0 +1,15 @@ +### Windows + +È possibile scaricare Git da [git-scm.com](http://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. + +### MacOS + +Scarica Git da [git-scm.com](http://git-scm.com/) e segui le istruzioni. + +### Linux + +Se non è già installato, git dovrebbe essere disponibile tramite il gestore di pacchetti, prova a cercare: + + sudo apt-get install git + # oppure + sudo yum install git \ No newline at end of file diff --git a/it/deploy/signup_pythonanywhere.md b/it/deploy/signup_pythonanywhere.md new file mode 100644 index 00000000000..d70701156de --- /dev/null +++ b/it/deploy/signup_pythonanywhere.md @@ -0,0 +1,5 @@ +Ora è il momento di registrarsi per un account gratuito "Beginner" su PythonAnywhere. + + * [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +> **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 diff --git a/it/django/README.md b/it/django/README.md new file mode 100644 index 00000000000..5bcc3f74e2e --- /dev/null +++ b/it/django/README.md @@ -0,0 +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. + +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. + +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. + +I frameworks esistono per evitare che tu debba reinventare la ruota e ti semplificano il lavoro quando crei un nuovo sito. + +## 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. + +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. + +## 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*). + +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. + +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. + +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 diff --git a/it/django_admin/README.md b/it/django_admin/README.md new file mode 100644 index 00000000000..de3fcc57f64 --- /dev/null +++ b/it/django_admin/README.md @@ -0,0 +1,47 @@ +# Django admin + +Per aggiungere, modificare e cancellare i post che abbiamo appena strutturato useremo Django admin. + +Apri il file `blog/admin.py` e sostituisci il suo contenuto con: + + 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: + +![Login page][1] + + [1]: images/login_page2.png + +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): + + (myvenv) ~/djangogirls$ python manage.py createsuperuser + Username: admin + Email address: admin@admin.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 + +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 :). + +Assicurati che almeno due o tre post (ma non tutti) abbiano la data in cui sono stati pubblicati. Ti sarà utile più tardi. + +![L'admin di Django][3] + + [3]: 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/ + +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 diff --git a/it/django_admin/images/django_admin3.png b/it/django_admin/images/django_admin3.png new file mode 100644 index 00000000000..a450b4f9630 Binary files /dev/null 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 new file mode 100644 index 00000000000..c8572a73e7d Binary files /dev/null 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 new file mode 100644 index 00000000000..47153ef6960 Binary files /dev/null and b/it/django_admin/images/login_page2.png differ diff --git a/it/django_forms/README.md b/it/django_forms/README.md new file mode 100644 index 00000000000..2556c7b898a --- /dev/null +++ b/it/django_forms/README.md @@ -0,0 +1,398 @@ +# I form di 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! + +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. + +Questo è esattamente quello che stiamo per fare: stiamo per creare un form per il nostro modello dei `Post`. + +Come ogni parte importante di Django, i forms hanno il proprio file: `forms.py`. + +Dobbiamo creare un file con questo nome all'interno della cartella `blog`. + + blog + └── forms.py + + +OK, apriamo questo file e inseriamo: + +```python +from django import forms + +from .models import Post + +class PostForm(forms.ModelForm): + + 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. + +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? + +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. + +## Link ad una pagina usando il form + +È tempo di aprire `blog/templates/blog/base.html`. Aggiungeremo un link nel `div` chiamato `page-header`: + +```html + +``` + +Nota che vogliamo chiamare la nostra nuova view `post_new`. + +Dopo aver aggiunto quanto detto, il tuo file html dovrebbe essere simile a questo: + +```html +{% load staticfiles %} + + + 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? + +## URL + +Apri il file `blog/urls.py` e aggiungi: + +```python +    url(r'^post/new/$', views.post_new, name='post_new'), +``` + +Il risultato finale sarà: + +```python +from django.conf.urls import include, 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'), +] +``` + +Dopo aver aggiornato il sito, vedremo un `AttributeError` dal momento che non abbiamo ancora creato `post_new`. Aggiungiamolo adesso. + +## post_new view + +Apri il file `blog/views.py` e aggiungi quanto segue con il resto delle importazioni `from`: + +```python +from .forms import PostForm +``` + +e la nostra *view*: + +```python +def post_new(request): +    form = PostForm() +    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. + +## 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 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: + +![CSFR Forbidden page][1] + + [1]: images/csrf2.png + +OK, il tuo HTML `post_edit.html` dovrebbe apparire così: + +```html +{% extends 'blog/base.html' %} + +{% block content %} +    

New post

+    {% csrf_token %} +        {{ form.as_p }} +         +    
+{% endblock %} +``` + +Ora aggiorna la pagina! Yeah! Puoi ora visualizzare il tuo form! + +![New form][2] + + [2]: 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? + +Niente! Siamo di nuovo sulla stessa pagina di prima e il nostro testo é sparito...e non compare nessun nuovo post. Che cosa abbiamo sbagliato? + +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` é: + +```python +def post_new(request): +    form = PostForm() +    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). + +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`). + +```python +if request.method == "POST": +    [...] +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: + +```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()`. + +Se la forma viene ritenuta valida verrà salvata! + +```python +if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + 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! + +Infine, non sarebbe fantastico se potessimo immediatamente essere indirizzati alla pagina `post_detail` del nuovo blog post appena creato? Per fare ciò dobbiamo importare: + +```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. + +```python +return redirect('blog.views.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! + +Ok, abbiamo parlato abbastanza ora e forse sei curioso/a di vedere l'aspetto della nostra *view*, giusto? + +```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}) +``` + +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` ! + +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**. + +Fantastico! + +## Validazione del Form + +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. + +Prova a salvare il form senza `title` e `text`. Indovina che cosa accade! + +![Validazione del form][3] + + [3]: images/form_validation2.png + +Django si sta prendendo cura di controllare che tutti i campi nel nostro form siano corretti. Non è fantastico? + +> 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!**. + +![Logged in error][4] + + [4]: images/post_create_error.png + +## Modifica il form + +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` e aggiungi: + +```python + +``` + +per cui il tuo template sarà così: + +```html +{% extends 'blog/base.html' %} + +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} + +

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% endblock %} +``` + +In `blog/urls.py` aggiugi: + +```python +    url(r'^post/(?P[0-9]+)/edit/$', views.post_edit, name='post_edit'), +``` + +Riutilizzeremo il model `blog/templates/blog/post_edit.html`, quindi l'ultima cosa che manca è una *view*. + +Apriamo `blog/views.py` e aggiungiamo alla fine del file: + +```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}) +``` + +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: + +```python +form = PostForm(request.POST, instance=post) +``` + +e quando abbiamo appena aperto un form con questo post da modificare: + +```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] + + [5]: images/edit_button2.png + +Quando ci clicchi, vedrai il modulo con i nostri post del blog: + +![Modifica il form][6] + + [6]: images/edit_form2.png + +Sentiti libero di cambiare il titolo o il testo e salva 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/ + +## 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. + +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ì: + +```html + +``` + +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ì: + +```html +{% if user.is_authenticated %} + +{% 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. + +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'è! + +## Ultima cosa: ora di fare il deploy! + +Vediamo se funziona su PythonAnywhere. È l'ora di un altro deploy! + +* Innanzitutto, fai un commit del tuo nuovo codice e fai il push per caricarlo su Github + +``` +$ git status +$ git add -A . +$ git status +$ git commit -m "Added views to create/edit blog post inside the site." +$ git push +``` + +* Poi, in una [console PythonAnywhere Bash][7]: + + [7]: https://www.pythonanywhere.com/consoles/ + +``` +$ 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**. + + [8]: https://www.pythonanywhere.com/web_app_setup/ + +Fatto! Congratulazioni :) \ No newline at end of file diff --git a/it/django_forms/images/csrf2.png b/it/django_forms/images/csrf2.png new file mode 100644 index 00000000000..9dd1a9a4baa Binary files /dev/null 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 new file mode 100644 index 00000000000..f984ec2a4ae Binary files /dev/null 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 new file mode 100644 index 00000000000..f402eadd00b Binary files /dev/null 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 new file mode 100644 index 00000000000..329674ee5ad Binary files /dev/null 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 new file mode 100644 index 00000000000..0e81288c33e Binary files /dev/null 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 new file mode 100644 index 00000000000..8180ce66a06 Binary files /dev/null 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 new file mode 100644 index 00000000000..ae4650a575a Binary files /dev/null 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 new file mode 100644 index 00000000000..15f3758fbdd --- /dev/null +++ b/it/django_installation/README.md @@ -0,0 +1,5 @@ +# 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! + +{% include "/django_installation/instructions.md" %} diff --git a/it/django_installation/instructions.md b/it/django_installation/instructions.md new file mode 100644 index 00000000000..5fe7fbb9616 --- /dev/null +++ b/it/django_installation/instructions.md @@ -0,0 +1,113 @@ +> Una parte di questo capitolo si basa sui tutorial delle Geek Girls Carrots (http://django.carrots.pl/). +> +> 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. + +## Ambiente virtuale + +Prima di installare Django, ti vogliamo far installare uno strumento estremamente utile per tenere in ordine l'ambiente in cui programmerai sul tuo computer. Potresti saltare questo passaggio, ma è caldamente consigliato soffermarsi. Se inizi con la migliore configurazione possibile, ti risparmierai un sacco di problemi per il futuro! + +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). + +Per questo tutorial useremo una nuova directory `djangogirls` dalla tua home directory: + + mkdir djangogirls + cd djangogirls + + +Ora creeremo un virtualenv dal nome `myvenv`. Questo è il formato del comando generale: + + python3 -m venv myvenv + + +### Windows + +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: + + C:\Users\Name\djangogirls> C:\Python34\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! + +### 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 + + +`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! + +> **NOTA:** Avviare il virtualenv su Ubuntu 14.04 in questa maniera al momento darà il seguente errore: +> +> 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 +> + +## 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). + +#### Windows + +Avvia il tuo virtualenv digitando: + + C:\Users\Name\djangogirls> myvenv\Scripts\activate + + +#### Linux and OS X + +Avvia il tuo virtualenv digitando: + + ~/djangogirls$ source myvenv/bin/activate + + +Ricordati di sostituire `myvenv` con il nome `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 +> + +Saprai con certezza che hai avviato `virtualenv` quando vedrai che il prompt dei comandi nella console si presenta così: + + (myvenv) C:\Users\Name\djangogirls> + + +oppure: + + (myvenv) ~/djangogirls$ + + +Fai caso al prefisso `(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 `python3`. + +OK, abbiamo tutte le dipendenze importanti pronte. Finalmente possiamo installare Django! + +## 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: `==`). + + (myvenv) ~$ pip install django==1.8 + Downloading/unpacking django==1.8 + Installing collected packages: django + Successfully installed django + Cleaning up... + + +Su Windows + +> 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 + +> 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! diff --git a/it/django_models/README.md b/it/django_models/README.md new file mode 100644 index 00000000000..9c826a11556 --- /dev/null +++ b/it/django_models/README.md @@ -0,0 +1,172 @@ +# Modelli 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. + +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). + +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`). + + Gatto + -------- + colore + età + umore + padrone + fare le fusa() + graffiare() + alimentare(cat_food) + + +Quindi in pratica l'idea è quella di descrivere cose vere in codice con delle proprietà (chiamate `proprietà di oggetti`) e azioni (chiamate `metodi`). + +Quindi come faremo a modellare i post del blog? vogliamo costruire un blog, giusto? + +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. + + Post + -------- + titolo + testo + autore + data_creazione + data_pubblicazione + + +Che tipo di cose si potrebbero fare con un post? Sarebbe bello avere qualche `metodo` che pubblica il post, vero? + +Quindi avremo bisogno di un metodo `pubblicare`. + +Dal momento che sappiamo già cosa vogliamo ottenere, iniziamo a modellarlo in Django! + +## Modello Django + +Sapendo cos'è un oggetto, possiamo creare un modello Django per il nostro post. + +Un modello in Django è uno speciale tipo di oggetto - è salvato nel `database`. Un database è un insieme di dati. È un posto in cui archivierai informazioni sui tuoi utenti, sui tuoi post, ecc. Useremo un database SQLite per archiviare i nostri dati. Questo è l'adattatore Django di database predefinito -- ci basterà per adesso. + +Puoi pensare ad un modello nel database come ad un foglio elettronico con colonne (campi) e righe (dati). + +### 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`): + + (myvenv) ~/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 + ├── manage.py + └── blog + ├── migrations + | __init__.py + ├── __init__.py + ├── admin.py + ├── models.py + ├── tests.py + └── views.py + + +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: + +```python +INSTALLED_APPS = ( +    'django.contrib.admin', +    'django.contrib.auth', +    'django.contrib.contenttypes', +    'django.contrib.sessions', +    'django.contrib.messages', +    'django.contrib.staticfiles', +    'blog', +) +``` + +### Creazione di un modello blog post + +Nel file `blog/models.py` definiamo tutti gli oggetti chiamati `Models` - Questo è il posto dove definiremo il nostro blog post. + +Apriamo `blog/models.py`, cancella tutto quello che è lì e scrivi un codice come questo: + +```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 +``` + +> 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"). + +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 ...`. + +`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. + +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?). + +* `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). + +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. + +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: + + (myvenv) ~/djangogirls$ python manage.py makemigrations blog + Migrations for 'blog': + 0001_initial.py: + - Create model Post + + +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: + + (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! diff --git a/it/django_orm/README.md b/it/django_orm/README.md new file mode 100644 index 00000000000..4dfb21c3c89 --- /dev/null +++ b/it/django_orm/README.md @@ -0,0 +1,157 @@ +# Django ORM e i QuerySet + +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. + +È più facile impararlo con un esempio. Proviamo, ti va? + +## La shell di Django + +Apri la tua console locale (non su PythonAnywhere) e digita questo comando: + + (myvenv) ~/djangogirls$ python manage.py shell + + +L'effetto dovrebbe essere come questo: + + (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. + +### 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 + + +Ops! È comparso un errore. Ci dice che non c'è nessun Post. È corretto -- ci siamo dimenticati di importarlo! + + >>> 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() + [, ] + + +È 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? + +### Creare oggetti + +Così si crea un nuovo oggetto Post nel database: + + >>> 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 + + +Quali utenti abbiamo nel nostro database? Prova questo: + + >>> User.objects.all() + [] + + +È il superuser che abbiamo creato prima! Ora prendiamo un'istanza del user: + + 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. + +Adesso possiamo finalmente creare il nostro post: + + >>> Post.objects.create(author=me, title='Sample title', text='Test') + + +Evviva! Vuoi controllare se funziona? + + >>> Post.objects.all() + [, , ] + + +Eccolo, un altro post nell'elenco! + +### Aggiungi altri post + +Ora puoi divertirti un po' ed aggiungere altri post per vedere come funziona. Aggiungi altri 2 o 3 e vai alla prossima parte. + +### 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: + + >>> 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') + [, ] + + +> **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". + +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()) + [] + +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") + + +Ora pubblicalo con il nostro metodo `publish`! + + >>> 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()) + [] + + +### 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') + [, , , ] + + +Possiamo anche invertire l'ordine aggiungendo `-` all'inizio: + + >>> Post.objects.order_by('-created_date') + [, , , ] + + +### QuerySet di concatenamento + +Puoi anche combinare QuerySet ** concatenandole** insieme: + + >>> 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 diff --git a/it/django_start_project/README.md b/it/django_start_project/README.md new file mode 100644 index 00000000000..7cccc9c031b --- /dev/null +++ b/it/django_start_project/README.md @@ -0,0 +1,137 @@ +# Il tuo primo progetto Django! + +> Parte di questo capitolo è basato su esercitazioni di Geek Girls (http://django.carrots.pl/). +> +> 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. + + [1]: http://django-marcador.keimlink.de/ + +Creeremo un semplice 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. + +Dovresti eseguire nella tua console MacOS o Linux il seguente comando; **non dimenticarti di aggiungere il punto `.` alla fine **: + + (myvenv) ~/djangogirls$ django-admin startproject mysite . + + +Su Windows; **non dimenticarti di aggiungere il punto `.` alla fine**: + + (myvenv) C:\Users\Name\djangogirls> django-admin startproject mysite . + + +> 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. + +`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` è 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. + +Il file `settings.py` contiene la configurazione del tuo sito web. + +Ricordi quando abbiamo parlato di un postino che controlla dove rilasciare la lettera? il file `urls.py` contiene una lista di schemi usati da `urlresolver`. + +Ignoriamo gli altri file per ora dal momento che non li modificheremo. L'unica cosa da ricordare è di non cancellarli per sbaglio! + +## Modificare le impostazioni + +Facciamo qualche cambiamento in `mysite/settings.py`. Apri il file usando il code editor che hai installato 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`) + + [2]: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones + +In settings.py, trova la riga che contiene `TIME_ZONE` e modificala per scegliere il tuo fuso orario: + +```python +TIME_ZONE = 'Europe/Berlin' +``` + +Modifica "Europe/Berlin" nel modo corretto + +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`: + +```python +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'static') +``` + +## 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`: + +```python +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(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: + + (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 + + +E abbiamo finito! Tempo di avviare il server web e vedere se il nostro sito Web funziona! + +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`: + + (myvenv) ~/djangogirls$ python manage.py runserver + + +Se sei su Windows e non funziona con `UnicodeDecodeError`, usa questo comando: + + (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: + + http://127.0.0.1:8000/ + + +Il server web assumerà il 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 and C insieme (su Windows, è probabile che tu deva premere Ctrl+Break). + +Congratulazioni! Hai appena creato il tuo primo sito e l'hai avviato usando un web server! Non è fantastico? + +![Ha funzionato!][3] + + [3]: images/it_worked2.png + +Pronto/a per il prossimo passo? È ora di creare un po' di contenuti! \ No newline at end of file diff --git a/it/django_start_project/images/it_worked2.png b/it/django_start_project/images/it_worked2.png new file mode 100644 index 00000000000..4412ecfc49e Binary files /dev/null and b/it/django_start_project/images/it_worked2.png differ diff --git a/it/django_templates/README.md b/it/django_templates/README.md new file mode 100644 index 00000000000..2406a24809e --- /dev/null +++ b/it/django_templates/README.md @@ -0,0 +1,105 @@ +# I templates di Django + +È l'ora di visualizzare alcuni dati! Django ci dà alcuni **template tags** già pronti per farlo. + +## Cosa sono i template tags? + +In HTML non puoi scrivere codice Python, perché i browser non lo capiscono. Essi conoscono solo l'HTML. Noi sappiamo che l'HTML è piuttosto statico, mentre Python è molto più dinamico. + +I **Django template tags** ci permettono di trasferire le cose simili a Python in HTML, in modo che tu possa costruire siti web in modo più veloce e facile. Accidenti! + +## Mostra il template con la lista di post + +Nel capitolo precedente abbiamo dato al nostro template una lista di posts nella variabile `posts`. Adesso lo mostreremo nell'HTML. + +Per stampare una variabile nel template Django, usiamo doppie parentesi graffe con il nome della variabile all'interno, così: + +```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] + + [1]: images/step1.png + +Come vedi, quello che abbiamo è: + + [, ] + + +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ì: + +```html +{% for post in posts %} + {{ post }} +{% endfor %} +``` + +Prova ad inserirlo nel tuo template. + +![Figura 13.2][2] + + [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: + +```html + + +{% for post in posts %} +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% 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] + + [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 `|linebreaks` stanno spingendo il testo dei post attraverso un filtro per trasformare le line-breaks in paragrafi. + +## 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 + + $ git status + [...] + $ git add -A . + $ git status + [...] + $ git commit -m "Modified templates to display posts from database." + [...] + $ git push + + +* Poi, ritorna su [PythonAnywhere][4] e vai alla tua **console di Bash** (o iniziane una nuova) ed esegui: + + [4]: https://www.pythonanywhere.com/consoles/ + + $ cd my-first-blog + $ git pull + [...] + + +* Infine, vai sulla [Web tab][5] e premi **Reload** sulla tua web app. L'aggiornamento dovrebbe essere live! + + [5]: https://www.pythonanywhere.com/web_app_setup/ + +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. + +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 diff --git a/it/django_templates/images/donut.png b/it/django_templates/images/donut.png new file mode 100644 index 00000000000..64d38b4e889 Binary files /dev/null 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 new file mode 100644 index 00000000000..113e145c943 Binary files /dev/null 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 new file mode 100644 index 00000000000..464a7645731 Binary files /dev/null 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 new file mode 100644 index 00000000000..b56b64f142e Binary files /dev/null and b/it/django_templates/images/step3.png differ diff --git a/it/django_urls/README.md b/it/django_urls/README.md new file mode 100644 index 00000000000..966e18fa916 --- /dev/null +++ b/it/django_urls/README.md @@ -0,0 +1,125 @@ +# Django URL + +Stiamo per costruire la nostra pagina web: una homepage per il tuo blog! Ma prima, impariamo un po' di più sulle url di Django. + +## 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.com` è una URL): + +![Url][1] + + [1]: 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. + +## Come funzionano le URL in Django? + +Apriamo il file `mysite/urls.py` nel code editor che hai scelto e vediamo com'è: + +```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)), +] +``` + +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? + +L'admin URL , che hai visto nel capitolo precedente è già qui: + +```python +    url(r'^admin/', include(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. + +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. + +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 (`''`). + +Il tuo file `mysite/urls.py` ora dovrebbe avere questo aspetto: + +```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')), +] +``` + +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. + +## blog.urls + +Crea un nuovo file `blog/urls.py`. Perfetto! Ora aggiungi queste prime due righe: + +```python +from django.conf.urls import url +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!) + +Dopo di che, possiamo aggiungere il nostro primo modello di URL: + +```python +urlpatterns = [ + url(r'^$', 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. + +![Errore][2] + + [2]: images/error1.png + +Non funziona, vero? Non ti preoccupare, è solo una pagina di errore, niente di cui spaventarsi! In realtà sono molto utili: + +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. + +> 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 diff --git a/it/django_urls/images/error1.png b/it/django_urls/images/error1.png new file mode 100644 index 00000000000..cc17593d19d Binary files /dev/null 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 new file mode 100644 index 00000000000..6cd1bd96291 Binary files /dev/null and b/it/django_urls/images/url.png differ diff --git a/it/django_views/README.md b/it/django_views/README.md new file mode 100644 index 00000000000..a65540fc789 --- /dev/null +++ b/it/django_views/README.md @@ -0,0 +1,38 @@ +# Le views di Django - è arrivata l'ora di creare! + +È 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**. + +Le views vengono collocate nel file `views.py`. Noi aggiungeremo le nostre *views* nel file `blog/views.py`. + +## blog/views.py + +OK, apriamo questo file e scopriamo cosa c'è dentro: + +```python +from django.shortcuts import render + +# Create your views here. +``` + +Non c'è molto per ora. La *view* più semplice può essere simile a questa. + +```python +def post_list(request): +    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`. + +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 + +Questo è facile: *TemplateDoesNotExist*. Sistemiamo il bug e creiamo un template nel prossimo capitolo! + +> 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 diff --git a/it/django_views/images/error.png b/it/django_views/images/error.png new file mode 100644 index 00000000000..391c9e61e16 Binary files /dev/null and b/it/django_views/images/error.png differ diff --git a/it/domain/README.md b/it/domain/README.md new file mode 100644 index 00000000000..0a007cc16a0 --- /dev/null +++ b/it/domain/README.md @@ -0,0 +1,71 @@ +# 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]: http://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 new file mode 100644 index 00000000000..b3479a7996f --- /dev/null +++ b/it/dynamic_data_in_templates/README.md @@ -0,0 +1,74 @@ +# 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? + +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. + +OK, quindi come facciamo a farlo? + +Dobbiamo aprire il nostro `blog/views.py`. Per ora `post_list` *view* si vede così: + +```python +from django.shortcuts import render + +def post_list(request): + 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ì: + +```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`). + +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]. + + [1]: ../django_orm/README.md + +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! + + Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + + +Adesso mettiamo questo pezzo di codice nel file `blog/views.py` aggiungendolo alla funzione `def post_list(request)`: + +```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', {}) +``` + +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. + +Il codice utilizza anche la funzione `timezone.now()`, quindi dobbiamo aggiungere un import per `timezone`. + +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 `''`. + +Il nostro file `blog/views.py` dovrà risultare così: + +```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}) +``` + +È 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 diff --git a/it/extend_your_application/README.md b/it/extend_your_application/README.md new file mode 100644 index 00000000000..fb4c3c7cda2 --- /dev/null +++ b/it/extend_your_application/README.md @@ -0,0 +1,193 @@ +# 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. + +Ora di far pratica! + +La prima cosa di cui abbiamo bisogno nel nostro blog è, ovviamente, una pagina per rendere visibile un post, vero? + +Abbiamo già un modello dei `Post`, quindi non abbiamo bisogno di aggiungere niente in `models.py`. + +## 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: + +```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+ {% endfor %} +{% endblock content %} +``` + + +{% 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 %} + +```html +

{{ 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*. + +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: + +![Errore: nessuna corrispondenza inversa][1] + + [1]: images/no_reverse_match2.png + +## Crea una URL per i dettagli di un post + +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: + +```python +from django.conf.urls import include, 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'), +] +``` + +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*. + +`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]+)`. + +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! + +![Errore attributo][2] + + [2]: 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! + +Ora, noi vogliamo ottenere un unico post. Per farlo possiamo utilizzare le queryset così: + + 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`). + +![Pagina non trovata][4] + + [4]: 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: + + from django.shortcuts import render, get_object_or_404 + + +Vicino ad altre righe `from` ed alla fine del file aggiungeremo la nostra *view*: + +```python + def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) +``` + +Si, è giunta l'ora di aggiornare la pagina: http://127.0.0.1:8000/ + +![Visualizzazione elenco post][5] + + [5]: images/post_list2.png + +Ha funzionato! Ma cosa succede se clicchi su un link nel titolo del post? + +![Errore: il template non esiste][6] + + [6]: images/template_does_not_exist2.png + +Oh no! Un altro errore! Ma sappiamo già come occuparcene, giusto? Dobbiamo aggiungere un template! + +## Crea un template per il post detail + +Creeremo un file in `blog/templates/blog` chiamato `post_detail.html`. + +Il risultato somiglierà a questo: + +```html +{% extends 'blog/base.html' %} + +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} +

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% 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 %} + +Ok, possiamo aggiornare la nostra pagina e vedere se `Page not found` non c'è più. + +![Pagina di dettaglio del post][7] + + [7]: images/post_detail2.png + +Si! Ha funzionato! + +## Ultima cosa: ora di fare il deploy! + +Sarebbe bello vedere se il tuo sito Web sarà ancora funzionante in PythonAnywhere, vero? Proviamo a fare un alrto deploy. + + $ git status + $ git add -A . + $ 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][8]: + + [8]: https://www.pythonanywhere.com/consoles/ + + $ cd my-first-blog + $ source myvenv/bin/activate + (myvenv)$ git pull + [...] + (myvenv)$ python manage.py collectstatic + [...] + + +* Infine, vai su il [Web tab][9] e premi **Reload**. + + [9]: https://www.pythonanywhere.com/web_app_setup/ + +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 new file mode 100644 index 00000000000..a8cb53172af Binary files /dev/null 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 new file mode 100644 index 00000000000..6edcd9933c3 Binary files /dev/null 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 new file mode 100644 index 00000000000..023d8720081 Binary files /dev/null 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 new file mode 100644 index 00000000000..306926206f8 Binary files /dev/null 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 new file mode 100644 index 00000000000..240dc447b51 Binary files /dev/null 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 new file mode 100644 index 00000000000..8ae30c71311 Binary files /dev/null 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 new file mode 100644 index 00000000000..335ce2569ef Binary files /dev/null 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 new file mode 100644 index 00000000000..df4d4110902 --- /dev/null +++ b/it/how_the_internet_works/README.md @@ -0,0 +1,53 @@ +# Come funziona Internet + +> Questo capitolo è ispirato ad un discorso di Jessica McKellar "How the Internet Works" (http://web.mit.edu/jesstess/www/). + +Scommettiamo che usi Internet tutti i giorni. Ma sai davvero che cosa succede quando digiti un indirizzo come http://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. + +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. + +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. + +OK, ma tu vuoi sapere com'è internet, vero? + +Abbiamo creato un'immagine! Ecco com'è: + +![Figura 1.1][1] + + [1]: images/internet_1.png + +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][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 http://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 + +Immagina che quando digiti http://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 + +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! + +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. + +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 :). + +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 new file mode 100644 index 00000000000..9c5bcf0b003 Binary files /dev/null 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 new file mode 100644 index 00000000000..dd5861f376f Binary files /dev/null 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 new file mode 100644 index 00000000000..a23488e3f2f Binary files /dev/null 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 new file mode 100644 index 00000000000..05f1aed562f Binary files /dev/null and b/it/how_the_internet_works/images/internet_4.png differ diff --git a/it/html/README.md b/it/html/README.md new file mode 100644 index 00000000000..2381fec3443 --- /dev/null +++ b/it/html/README.md @@ -0,0 +1,209 @@ +# Introduzione all'HTML + +Ti potresti chiedere, cos'è un template? + +Un template è un file che possiamo riutilizzare per presentare informazioni diverse in un formato consistente - per esempio, potresti utilizzare un template per aiutarti a scrivere una lettera, perché anche se ciascuna lettera potrebbe contenere un messaggio diverso ed essere a sua volta indirizzata ad una persona diversa, condivideranno lo stesso formato. + +Un template Django viene descritto in un linguaggio chiamato HTML (è lo stesso HTML che abbiamo menzionato nel primo capitolo **Come funziona l'Internet**). + +## Cos'è l'HTML? + +HTML è un semplice codice che viene interpretato dal tuo browser - come Chrome, Firefox o Safari - per rendere un sito web visibile all'utente. + +HTML sta per "HyperText Markup Language". **HyperText** significa che è un tipo di testo che supporta i collegamenti ipertestuali tra le pagine. **Markup** significa che abbiamo preso un documento e l'abbiamo contrassegnato con il codice per dire a qualcosa (in questo caso, un browser) come interpretare la pagina. Il codice HTML è costruito con **tags**, ognuno inizia con `<` e finisce con `>`. Questi tag rappresentano gli **elementi** di markup. + +## Il tuo primo template! + +Creare un template significa creare un file template. Tutto è un file, vero? Probabilmente l'hai già notato. + +I template vengono salvati in una cartella `blog/templates/blog`. Quindi prima crea una directory chiamata `templates` nella directory del tuo blog. Quindi crea un'altra directory chiamata `blog` all'interno della tua directory templates: + + 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 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`. + +![Figura 11.1][1] + + [1]: images/step1.png + +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. + +Aggiungi quanto segue nel tuo file template: + +```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] + + [2]: images/step3.png + +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 + +## Head & body + +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. + +* **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ì: + +```html + + + Ola's blog + + +

Hi there!

+

It works!

+ + +``` + +Salva il file e aggiorna la tua pagina. + +![Figura 11.3][3] + + [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). + +Probabilmente hai anche notato che ogni tag di apertura è abbinato ad un *tag di chiusura*, con un `/`, e che gli elementi sono *annidati* (i.e. non puoi chiudere un tag particolare fino a quando tutti quelli che erano al suo interno sono stati chiusi a loro volta). + +È come mettere le cose in delle scatole. Hai una grossa scatola, ``; al suo interno c'è ``, che contiene scatole ancora più piccole: `

`. + +Devi seguire queste regole di tag *di chiusura*, e di elementi *annidati* - se non lo fai, il browser potrebbe non essere in grado di interpretarli correttamente e la tua pagina verrà visualizzata incorrettamente. + +## Personalizza il tuo template + +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: + +```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.

+
+ + +``` + +Abbiamo creato tre sezioni `div` 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. + +Ci dà questo effetto: + +![Figura 11.4][4] + + [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**. + +Quello che vogliamo è visualizzare i veri post aggiunti nel nel nostro Django admin - è quello che faremo adesso. + +## Un'ultima cosa: il deploy! + +Sarebbe bello vedere tutto questo live su Internet, giusto? Facciamo un altro deploy su PythonAnywhere: + +### Committa e pubblica il tuo codice su GitHub + +Prima di tutto, vediamo quali file sono cambiati dall'ultimo deploy (esegui questi comandi localmente, non su PythonAnywhere): + + $ git status + + +Assicurati di essere nella directory `djangogirls` e diciamo a `git` di includere tutte le modifiche in questa directory: + + $ git add -A . + + +> **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. + +Prima di caricare tutti i file, proviamo a controllare cosa caricherà `git` (tutti i file che caricherà `git` ora appariranno in verde): + + $ 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." + + +> **Nota** Assicurati di usare doppie virgolette attorno al messaggio di commit. + +Quando hai finito, caricheremo (push) le nostre modifiche su Github: + + 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: + + [5]: https://www.pythonanywhere.com/consoles/ + + $ cd ~/my-first-blog + $ source myvenv/bin/activate + (myvenv)$ git pull + [...] + (myvenv)$ python manage.py collectstatic + [...] + + +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. + + [6]: https://www.pythonanywhere.com/web_app_setup/ + +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 new file mode 100644 index 00000000000..e9c2f1082d6 Binary files /dev/null and b/it/html/images/step1.png differ diff --git a/it/html/images/step3.png b/it/html/images/step3.png new file mode 100644 index 00000000000..811226fa3fc Binary files /dev/null and b/it/html/images/step3.png differ diff --git a/it/html/images/step4.png b/it/html/images/step4.png new file mode 100644 index 00000000000..bd6c1a044e0 Binary files /dev/null and b/it/html/images/step4.png differ diff --git a/it/html/images/step6.png b/it/html/images/step6.png new file mode 100644 index 00000000000..e42a2fe5388 Binary files /dev/null and b/it/html/images/step6.png differ diff --git a/it/images/application.png b/it/images/application.png new file mode 100644 index 00000000000..6dcba6202c7 Binary files /dev/null and b/it/images/application.png differ diff --git a/it/installation/README.md b/it/installation/README.md new file mode 100644 index 00000000000..67c68355c14 --- /dev/null +++ b/it/installation/README.md @@ -0,0 +1,49 @@ +# Se stai facendo il tutorial a casa + +Se stai facendo il tutorial a casa e non durante uno degli [eventi Django Girls ](http://djangogirls.org/events/), puoi saltare questo capitolo e andare direttamente a [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. + +Buona fortuna! + +# 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. + +# Installare Python + +{% include "/python_installation/instructions.md" %} + +# Preparare virtualenv e installare Django + +{% include "/django_installation/instructions.md" %} + +# Installare un editor di codice + +{% include "/code_editor/instructions.md" %} + +# Installare Git + +{% include "/deploy/install_git.md" %} + +# Creare un account GitHub + +Vai su [GitHub.com](http://www.github.com) e iscriviti per un nuovo account gratuito. + +# Creare un account PythonAnywhere + +{% 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: + + * [Come funziona Internet](../how_the_internet_works/README.md) + + * [Introduzione alla riga di comando](../intro_to_command_line/README.md) + + * [Introduzione a Python](../intro_to_command_line/README.md) + + * [Che cos'è Django?](../django/README.md) diff --git a/it/intro_to_command_line/README.md b/it/intro_to_command_line/README.md new file mode 100644 index 00000000000..fd63b8bfca7 --- /dev/null +++ b/it/intro_to_command_line/README.md @@ -0,0 +1,279 @@ +# Introduzione alla linea di comando + +Eccitante, vero? Scriverai la tua prima riga di codice in pochi minuti :) + +**Ti presentiamo il tuo primo nuovo amico: la linea 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. + +## Cos'è la command line? + +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*. + +## Aprire l'interfaccia di command-line + +Per cominciare a sperimentare dobbiamo aprire l'interfaccia della nostra command-line. + +### Windows + +Vai a menù Start → tutti i programmi → accessori → prompt dei comandi. + +### Mac OS X + +Applicazioni → utilità → terminal. + +### Linux + +Probabilmente è sotto Applicazioni → Accessori → Terminal, ma quello potrebbe dipendere dal tuo sistema. Se non è lì cercalo su Google :) + +## 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, è un segno `>`, come questo: + + > + + +Ogni comando sarà preceduto da questo simbolo e da uno spazio, ma tu non hai bisogno di digitarlo. Il 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%. In questo tutorial lo semplificheremo al massimo. + +## Il tuo primo comando (YAY!) + +Cominciamo con qualcosa di veramente semplice. Digita questo comando: + + $ whoami + + +oppure + + > whoami + + +Premi `invio`. Questo è il nostro risultato: + + $ whoami + olasitarska + + +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! + +## Nozioni di base + +Ogni sistema operativo ha un insieme di comandi leggermente diverso per la command line, per cui assicurati di seguire le istruzioni per il tuo sistema operativo. Proviamo questo, ti va? + +### Cartella corrente + +Sarebbe bello sapere dove siamo adesso, vero? Vediamo. Digita questo commando e premi `invio`: + + $ pwd + /Users/olasitarska + + +Se sei su Windows: + + > cd + C:\Users\olasitarska + + +Probabilmente vedrai qualcosa di simile sul tuo computer. Quando apri la command-line normalmente inizi sulla tua directory home. + +> Nota: 'pwd' sta per 'stampa directory di lavoro'. + +* * * + +### Elenco di file e cartelle + +Cosa c'è dentro? Sarebbe bello scoprirlo. Vediamo come: + + $ ls + Applications + Desktop + Downloads + Music + ... + + +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 + ... + + +* * * + +### Cambiare cartella corrente + +Ora, andiamo nella nostra directory Desktop: + + $ cd Desktop + + +Windows: + + > cd Desktop + + +Controlla ora se ti sei veramente spostato/a: + + $ pwd + /Users/olasitarska/Desktop + + +Windows: + + > 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. + +* * * + +### Creare una directory + +Che ne dici di creare una directory di pratica sul tuo desktop? Puoi farlo in questo modo: + + $ mkdir practice + + +Windows: + + > 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 :) + +> 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. + +* * * + +### Esercizio! + +Piccola sfida per te: nella tua directory appena creata `practice` crea una directory chiamata `test`. usa i comandi `cd` e `mkdir`. + +#### Soluzione: + + $ cd practice + $ mkdir test + $ ls + test + + +Windows: + + > cd practice + > mkdir test + > dir + 05/08/2014 07:28 PM test + + +Congratulazioni! :) + +* * * + +### Facciamo ordine + +Non vogliamo lasciare un pasticcio, per cui rimuoviamo tutto quello che abbiamo fatto fino a questo punto. + +Per prima cosa dobbiamo tornare al Desktop: + + $ cd .. + + +Windows: + + > 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: + + $ pwd + /Users/olasitarska/Desktop + + +Windows: + + > 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. + + $ rm -r practice + + +Windows: + + > rmdir /S practice + practice, Are you sure ? Y + + +Fatto! Per essere sicuri che sia stato effettivamente cancellato, controlliamo: + + $ ls + + +Windows: + + > dir + + +### Uscire dalla command line + +Questo è tutto per ora! puoi tranquillamente chiudere la tua command line. Facciamolo alla maniera degli hacker, va bene?:) + + $ exit + + +Windows: + + > exit + + +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** | + +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 + +## Fatto? + +Tuffiamoci in Python! diff --git a/it/python_installation/README.md b/it/python_installation/README.md new file mode 100644 index 00000000000..bb131b68683 --- /dev/null +++ b/it/python_installation/README.md @@ -0,0 +1,13 @@ +# Iniziamo con Python + +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. + +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! + +# 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! + +{% include "/python_installation/instructions.md" %} diff --git a/it/python_installation/images/add_python_to_windows_path.png b/it/python_installation/images/add_python_to_windows_path.png new file mode 100644 index 00000000000..7946019bc29 Binary files /dev/null and b/it/python_installation/images/add_python_to_windows_path.png differ diff --git a/it/python_installation/instructions.md b/it/python_installation/instructions.md new file mode 100644 index 00000000000..5fced54f179 --- /dev/null +++ b/it/python_installation/instructions.md @@ -0,0 +1,59 @@ +> Questa sezione si basa su un tutorial fatto da Geek Girls Carrots (http://django.carrots.pl/) + +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. + +### Windows + +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: + +![Non dimenticare di aggiungere Python al Path](../python_installation/images/add_python_to_windows_path.png) + +### Linux + +È 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: + + $ python3 --version + Python 3.4.3 + + +Se non hai Python installato o se vuoi una versione diversa, puoi installarla come segue: + +#### Debian o Ubuntu + +Digita questo comando nella tua console: + + $ sudo apt-get install python3.4 + + +#### Fedora (fino a 21) + +Usa questo comando nella tua console: + + $ sudo yum install python3.4 + + +#### Fedora (22+) + +Usa questo comando nella tua console: + + $ sudo dnf install python3.4 + + +### OS X + +Devi andare sul sito https://www.python.org/downloads/release/python-343/ e scarica il programma d'installazione di Python: + + * 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`: + + $ python3 --version + Python 3.4.3 + + +* * * + +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. \ No newline at end of file diff --git a/it/python_introduction/README.md b/it/python_introduction/README.md new file mode 100644 index 00000000000..1d11f7e5a76 --- /dev/null +++ b/it/python_introduction/README.md @@ -0,0 +1,789 @@ +# Introduzione a Python + +> Parte di questo capitolo è basato su esercitazioni di Geek Girls Carrots (http://django.carrots.pl/). + +Scriviamo un pò 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]. + + [1]: ../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`. + + $ python3 + Python 3.4.3 (...) + 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. + +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ù `>>>`. + +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`. + + >>> 2 + 3 + 5 + + +Fantastico! Hai visto come è comparsa la risposta? Python conosce la matematica! potresti provare altri comandi come: - `4 * 5` - `5 - 1` - `40 / 2` + +Divertiti con questo per un pò e dopo torna 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' + + +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' + + +Puoi anche moltiplicare le stringhe con un numero: + + >>> "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" + + +o facendo l'escape dell'apostrofo (cioè trattandolo come un carattere qualunque) con una barra rovesciata ( \ ): + + >>> 'Correre verso l\'albero' + "Correre verso l'albero" + + +Bello, eh? Per vedere il tuo nome in maiuscolo, digita: + + >>> "Ola".upper() + 'OLA' + + +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"`). + +Se vuoi sapere il numero delle lettere presenti nel tuo nome, c'è una funzione anche per quello! + + >>> 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`. + +### 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. + +Queste sono le basi di ogni linguaggio di programmazione che impari. Pronta per qualcosa di più complicato? Scommetto che lo sei! + +## 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`: + + >>> 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? + + >>> len(str(304023)) + 6 + + +Ha funzionato! Usiamo 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** + +> 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. + +Diciamo che vogliamo creare una nuova variabile chiamata `nome`: + + >>> nome = "Ola" + + +Vedi? È facile! è semplicemente: nome è uguale a 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`: + + >>> nome + 'Ola' + + +Evvai! La tua prima variabile :)! Puoi sempre modificare a cosa si riferisce: + + >>> nome = "Sonja" + >>> nome + 'Sonja' + + +La puoi utilizzare anche nelle funzioni: + + >>> len(nome) + 5 + + +Fantastico, vero? Certo, le variabile possono essere qualsiasi cosa, così come i numeri! Prova questo: + + >>> 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 + + +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. + +Giocaci per un po' e vedi cosa puoi fare! + +## La funzione print + +Prova questo: + + >>> nome = 'Maria' + >>> nome + 'Maria' + >>> print(nome) + Maria + + +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. + +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 :) + +Vai avanti e crea una lista: + + >>> [] + [] + + +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: + + >>> lotteria = [3, 42, 12, 19, 30, 59] + + +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! + + >>> len(lotteria) + 6 + + +Si! `len()` può darti il numero di oggetti in una lista. Utile, vero? Forse abbiamo risolto: + + >>> 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] + + +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] + + +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] + + +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 + + +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 **del** (del è un'abbreviazione di delete). Proviamo a fare qualcosa per rafforzare quanto imparato prima; elimineremo il primo numero della lista. + + >>> print(lotteria) + [59, 42, 30, 19, 12, 3, 199] + >>> print(lotteria[0]) + 59 + >>> del lotteria[0] + >>> print(lotteria) + [42, 30, 19, 12, 3, 199] + + +Ha funzionato a meraviglia! + +Prova altri indici: 6, 7, 1000, -1, -6 o -1000. Prova a prevedere il risultato ancora prima di eseguire il comando. Hanno senso i risultati? + +Per saperne di più su i metodi disponibili per le liste puoi consultare questo capitolo della documentazione Python: https://docs.python.org/3/tutorial/datastructures.html + +## Dizionari + +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 è: + + >>> {} + {} + + +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]} + + +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). + +Puoi controllare il contenuto di chiavi individuali con questa sintassi: + + >>> 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à' + + +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. + +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' + + +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: + + >>> 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 `del` per cancellare un elemento nella directory. Se vuoi cancellare la voce che corrisponde alla chiave `'numeri_preferiti'`, digita il seguente comando: + + >>> del partecipante['numeri_preferiti'] + >>> partecipante + {'paese': 'Polonia', 'linguaggio_preferito': 'Python', 'nome': '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'} + + +Come puoi vedere, il valore della chiave `'paese'` è stato cambiato da `'Polonia'` a `'Germania'`. :) Eccitante, vero? Evviva! Hai già imparato un'altra cosa fantastica. + +### Indice + +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 + +Sei emozionato/a per la prossima parte? :) + +## Confrontare le cose + +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 + + +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? + +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 + + +`>` 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 + +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 + + +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 + +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() + + +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. + +Ci sono solo due oggetti Boolean: +- True +- False + +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 + + +Lo puoi fare anche in questa forma: + + >>> a = 2 > 5 + >>> a + False + + +Fai pratica e divertiti con i Boolean provando ad eseguire i seguenti comandi: + +* `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! + +# 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: + +* Uscire dall'interprete di Python +* Aprire l'editor di codice che abbiamo scelto +* Salvare un po' di codice in un file python +* Eseguirlo! + +Per uscire dall'interprete di Python che è quello che stavamo utilizzando, digita la funzione ```exit()``` : + + >>> 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: + + [2]: ../code_editor/README.md + +```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. + +Su un Mac, il comando assomiglierà a questo: + + $ cd /Users//Desktop + + +Su Linux, sarà come questo (la parola "Desktop" potrebbe essere tradotta nella tua lingua): + + $ cd /home//Desktop + + +E su windows, sara come questo: + + > cd C:\Users\\Desktop + + +Se rimani bloccata, chiedi aiuto. + +Ora usa Python per eseguire il codice nel file: + + $ python3 python_intro.py + Ciao, Django girls! + + +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 + +Molte cose dovrebbero essere eseguite soltanto quando si incontrano certe condizioni. È per questo che Python ha gli **if statements**. + +Sostituisci il codice nel file **python_intro.py** con questo: + +```python +if 3 > 2: +``` + +Se salviamo questo codice e lo eseguiamo, incontriamo un errore come questo: + + $ python3 python_intro.py + File "python_intro.py", line 2 + ^ + SyntaxError: unexpected EOF while parsing + + +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: + +```python +if 3 > 2: + print('Funziona!') +``` + +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. + +Salvalo ed eseguilo di nuovo: + + $ python3 python_intro.py + Funziona! + + +### 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: + +```python +if 5 > 2: + print('5 è infatti maggiore di 2') +else: + print('5 non è maggiore di 2') +``` + +Quando viene lanciato, mostrerà: + + $ 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`: + +```python +nome = 'Sonja' +if nome == 'Ola': + print('Ciao Ola!') +elif nome == 'Sonja': + print('Ciao Sonja!') +else: + print('Ciao anonimo!') +``` + +ed eseguito: + + $ python3 python_intro.py + Ciao 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: + +```python +volume = 57 +if volume < 20: + print("Piuttosto basso.") +elif 20 <= volume < 40: + print("Adatto per musica di sottofondo") +elif 40 <= volume < 60: + print("Perfetto, posso apprezzare ogni dettaglio") +elif 60 <= volume < 80: + print("Ideale per le feste") +elif 80 <= volume < 100: + print("Un po' altino!") +else: + print("Oddio, le mie orecchie! :(") +``` + +Python esegue ogni singolo test in sequenza e scrive: + + $ python3 python_intro.py + Perfetto, posso apprezzare ogni dettaglio + + +### 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. + +È ora dell'ultima parte del capitolo! + +## Le funzioni personalizzate! + +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: + +```python +def ciao(): + print('Ciao!') + print('Come stai?') + +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. + +Eseguiamolo e vediamo cosa succede: + + $ 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: + +```python +def ciao(nome): +``` + +Come puoi vedere, abbiamo dato alla nostra funzione un parametro chiamato `nome`: + +```python +def ciao(nome): + if nome == 'Ola': + print('Ciao Ola!') + elif nome == 'Sonja': + print('Ciao Sonja!') + else: + print('Ciao anonimo!') + +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: + + $ python3 python_intro.py + Traceback (most recent call last): + File "python_intro.py", line 10, in + ciao() + 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: + +```python +ciao("Ola") +``` + +Ed eseguiamo di nuovo: + + $ python3 python_intro.py + Ciao Ola! + + +E se cambiamo il nome? + +```python +ciao("Sonja") +``` + +Ed eseguilo: + + $ 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: + + 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? + +```python +def ciao(nome): + print('Ciao ' + nome + '!') + +ciao("Rachel") +``` + +Ora chiamiamo il codice: + + $ python3 python_intro.py + Ciao Rachel! + + +Congratulazioni! Hai appena imparato a scrivere delle funzioni :) + +## Loop + +È 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: + +```python +ragazze = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'Tu'] +``` + +Vogliamo salutare tutte loro per nome. Abbiamo la funzione `ciao` per farlo, quindi usiamola in loop: + +```python +for nome in ragazze: +``` + +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: + +```python +def ciao(nome): + print('Ciao ' + nome + '!') + +ragazze = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'Tu'] +for nome in ragazze: + ciao(nome) + print('Prossima ragazza') +``` + +E quando lo eseguiamo: + + $ python3 python_intro.py + Ciao Rachel! + Prossima ragazza + Ciao Monica! + Prossima ragazza + Ciao Phoebe! + Prossima ragazza + Ciao Ola! + Prossima ragazza + Ciao You! + Prossima ragazza + + +Come puoi vedere, tutto quello che metti all'interno di un `for` statement con una spaziatura si ripeterà per ogni elemento della lista `girls`. + +Puoi anche utilizzare `for` su numeri usando la funzione `range`: + +```python +for i in range(1, 6): + print(i) +``` + +Che stamperà: + + 1 + 2 + 3 + 4 + 5 + + +`range` è una funzione che crea una lista di numeri che si seguono uno dopo l'altro (questi numeri vengono forniti da te come parametri). + +Nota che il secondo di questi due numeri non è incluso nella lista prodotta da Python ( ciò significa che `range(1, 6)` conta da 1 a 5, ma non include il numero 6). Questo perché "range" è mezzo-aperto e con ciò intendiamo che include il primo valore, man non l'ultimo. + +## Indice + +È 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! + +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) diff --git a/it/python_introduction/images/cupcake.png b/it/python_introduction/images/cupcake.png new file mode 100644 index 00000000000..fa2f3baeae6 Binary files /dev/null and b/it/python_introduction/images/cupcake.png differ diff --git a/it/template_extending/README.md b/it/template_extending/README.md new file mode 100644 index 00000000000..9c1e2c9e056 --- /dev/null +++ b/it/template_extending/README.md @@ -0,0 +1,123 @@ +# Estendere il template + +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! + +## Crea un template di base + +Un template base è il template più semplice. Lo puoi estendere su ogni pagina del tuo sito. + +Creiamo un file `base.html` in `blog/templates/blog/`: + + blog + └───templates + └───blog + base.html + post_list.html + + +Poi aprilo e copia tutto da `post_list.html` e incollalo sul file `base.html`, così: + +```html +{% load staticfiles %} + + + Django Girls blog + + + + + + + + +
+
+
+ {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+ {% endfor %} +
+
+
+ + +``` + +Poi nel `base.html`, rimpiazza tutto il tuo `` (tutto quello che si trova tra `` e ``) con questo: + +```html + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ +``` + +Abbiamo praticamente rimpiazzato tutto quello tra `{% for post in posts %}{% endfor %}` con: + +```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. + +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ì: + +```html +{% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% endfor %} +``` + +Ed ora aggiungi questa riga all'inizio del file: + +```python +{% extends 'blog/base.html' %} +``` + +{% 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 %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+ {% endfor %} +{% endblock content %} +``` + +È tutto! Controlla se il tuo sito sta ancora funzionando 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 diff --git a/it/whats_next/README.md b/it/whats_next/README.md new file mode 100644 index 00000000000..0722681595f --- /dev/null +++ b/it/whats_next/README.md @@ -0,0 +1,39 @@ +# Quali sono le prospettive? + +Complimenti! **Sei veramente incredibile**. Siamo orgogliosi! < 3 + +### Cosa si fa ora? + +Prenditi una pausa e rilassati. Hai veramente fatto un passo da gigante. + +Dopo di che, assicurati di: + +* Seguire Django Girls su [Facebook][1] o [Twitter][2] per rimanere aggiornata + + [1]: http://facebook.com/djangogirls + [2]: http://twitter.com/djangogirls + +### Mi puoi consigliare ulteriori risorse? + +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]: 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 \ No newline at end of file diff --git a/pt/README.md b/pt/README.md index 51da235254f..838f89c7fb9 100755 --- a/pt/README.md +++ b/pt/README.md @@ -8,7 +8,43 @@ ## Translation -This tutorial has been translated from English to Portuguese by a group of awesome volunteers. Special thanks for help goes out to Willie Lawrence, Vivian Macedo, Cleiton Lima, danieltex, Leandro Silva Araujo, Adailton do Nascimento, Pablo Palacios, Paulo Alem, Eric Hideki, Joao Luiz Lorencetti, clemente.jnr, Leonardo Alves dos Santos, joepreludian, Gabriela Cavalcante da Silve, Rafael Biagioni de Fazio, Fabio C. Barrionuevo da Luz, ffabiorj, Lucas Magnum, 1pedro, Adjamilton Junior, Leandro Barbosa, Kleber C Pinheiro, Katyanna Moura, Annanda Sousa, Flavio Barros, Marcel Ribeiro Dantas, Adam Victor Nazareth Brandizzi, Bernardo Fontes, Antonio Luis, Raony Guimares Correo do Carmo Lisboa Cardenas, Camilla Achutti and Carla Suarez. Wow! <3 <3 +This tutorial has been translated from English to Portuguese by a group of awesome volunteers. + +Special thanks for help goes out to: + +*Adailton do Nascimento +*Adam Victor Nazareth Brandizzi +*Antonio Luis +*Annanda Sousa +*Adjamilton Junior +*Bernardo Fontes +*Camilla Achutti +*Carla Suarez +*Cleiton Lima +*clemente.jnr +*danieltex +*Eric Hideki +*Flavio Barros +*Fabio C. Barrionuevo da Luz +*ffabiorj +*Gabriela Cavalcante da Silva +*Leandro Silva Araujo +*Lucas Magnum +*1pedro +*Joao Luiz Lorencetti +*Katyanna Moura +*Kleber C Pinheiro +*Leandro Barbosa +*Leonardo Alves dos Santos +*Marcel Ribeiro Dantas +*joepreludian +*Rafael Biagioni de Fazio +*Pablo Palacios +*Paulo Alem +*Raony Guimares Correo do Carmo Lisboa Cardenas +*Vivian Macedo +*Willie Lawrence +Wow! <3 <3 ## Introdução diff --git a/tr/GLOSSARY.md b/tr/GLOSSARY.md new file mode 100755 index 00000000000..1e503fa6881 --- /dev/null +++ b/tr/GLOSSARY.md @@ -0,0 +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 \ No newline at end of file diff --git a/tr/README.md b/tr/README.md new file mode 100755 index 00000000000..4c31f739c56 --- /dev/null +++ b/tr/README.md @@ -0,0 +1,52 @@ +# 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) + +> 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. + +## Çeviri + +Bu döküman İngilizce'den Türkçe'ye 27 kişiden oluşan tamamen gönüllü bir ekip tarafından çevrildi: Elif Kuş, Suzan Üsküdarlı, okb-1100, Şirin Saygılı, 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, 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! + +## Giriş + +Hiç dünyanın her geçen gün daha teknolojik 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ü? + +Ö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. + +Bu eğitim sihirli bir şekilde sizi bir programcıya dönüştürmeyecek. Eğer bu konuda iyi olmak istiyorsanız, aylara ve hatta yıllara dayanan bir öğrenme ve pratiğe ihtiyacınız var. Fakat biz size programlamanın ya da websayfası oluşturmanın göründüğü kadar da karmaşık olmadığını göstermek istiyoruz. Farklı parçaları, değişik kısımları anlatabildiğimiz kadar iyi anlatmaya gayret edeceğiz ki artık teknoloji gözünüzü korkutmasın. + +Ümit ederiz ki sizin de teknolojiyi bizim kadar sevmenizi sağlayabiliriz! + +## 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 online hale getireceğinizi de göstereceğiz ki başkaları da çalışmanızı görebilsin! + +Aşağı yukarı şu şekilde gözükecek: + +![Şekil 0.1][2] + + [2]: images/application.png + +> 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...][3] + + [3]: ./how_the_internet_works/README.md + +## Hakkında ve katkıda bulunma + +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]. + + [4]: http://djangogirls.org/ + [5]: https://github.com/DjangoGirls/tutorial/blob/master/README.md + +## Bu eğitimi başka dillere çevirmemize yardımcı olmak ister misiniz? + +Hali hazırda, ç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 \ No newline at end of file diff --git a/tr/SUMMARY.md b/tr/SUMMARY.md new file mode 100755 index 00000000000..42a5a7207f5 --- /dev/null +++ b/tr/SUMMARY.md @@ -0,0 +1,26 @@ +# Özet + +* [Giriş](README.md) +* [Kurulum](installation/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) +* [Kod editörü](code_editor/README.md) +* [Python'a giriş](python_introduction/README.md) +* [Django nedir?](django/README.md) +* [Django kurulumu](django_installation/README.md) +* [İlk Django projen!](django_start_project/README.md) +* [Django modelleri](django_models/README.md) +* [Django admin](django_admin/README.md) +* [Yayına alın!](deploy/README.md) +* [Django url'leri](django_urls/README.md) +* [Django views - yaratma zamanı geldi!](django_views/README.md) +* [HTML'ye giriş](html/README.md) +* [Django ORM (Querysets - Sorgu setleri)](django_orm/README.md) +* [Şablonlarda dinamik veri](dynamic_data_in_templates/README.md) +* [Djago şablonları](django_templates/README.md) +* [CSS - sayfanı güzelleştir](css/README.md) +* [Template(Şablon) extending(devam ettirme)](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) \ No newline at end of file diff --git a/tr/code_editor/README.md b/tr/code_editor/README.md new file mode 100755 index 00000000000..da33bb10459 --- /dev/null +++ b/tr/code_editor/README.md @@ -0,0 +1,7 @@ +# Kod editörü + +İ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 yapmış olabilirsiniz. Öyleyse, doğrudan bir sonraki bölüme geçebilirsiniz! + +{% 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 new file mode 100755 index 00000000000..9f5ab50d5cf --- /dev/null +++ b/tr/code_editor/instructions.md @@ -0,0 +1,31 @@ +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. + +## Gedit + +Gedit açık kaynaklı, özgür yazılım editörüdür. Tüm işletim sistemlerinde kullanılabilir. + +[Buradan indirin](https://wiki.gnome.org/Apps/Gedit#Download) + +## Sublime Text 2 + +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. + +[Buradan indirin](http://www.sublimetext.com/2) + +## Atom + +Atom [GitHub](http://github.com/) tarafından geliştirilen oldukça yeni bir editör. Atom özgür, açık kaynak kodlu, kurulumu ve kullanımı basit bir editördür. Windows, OSX ve Linux işletim sistemlerinde kullanılabilir. + +[Buradan indirin](https://atom.io/) + +## Neden bir kod editörü kuruyoruz? + +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. + +İ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. + +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 :) \ No newline at end of file diff --git a/tr/css/README.md b/tr/css/README.md new file mode 100755 index 00000000000..0f85f54cb89 --- /dev/null +++ b/tr/css/README.md @@ -0,0 +1,295 @@ +# CSS - 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 ;). + +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. + +## Hadi 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/ + +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`): + +```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! + +![Şekil 14.1][1] + + [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. + +### Django'da statik dosyaları nereye koymalı + + +`collectstatic` sunucu da çalıştırdığımızda, gördüğümüz gibi Django "admin" uygulaması için statik dosyaları nerede bulacağını biliyor. Şimdi kendi yerleşik uygulamamız `blog`için statik dosyalar eklemeliyiz. + +Bunu blog uygulamamızın içerisinde `static` isimli bir klasör oluşturarak yapacağız: + + djangogirls + ├── blog + │ ├── migrations + │ └── static + └── mysite + + +Django uygulama klasörlerinizin altındaki "static" isimli tüm klasörleri otomatik olarak bulacak ve içindekileri statik dosya olarak kullanabilecektir. + +## İ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? + + 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. + + [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 + +`blog/static/css/blog.css` dosyanıza şu kodu eklemelisiniz: + +```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! + +Bir CSS dosyasında, HTML dosyasındaki öğeler için stil belirleriz. Öğeler, öğenin ismi (örn. `a`, `h1`, `body`), `class` (sınıf) özniteliği (attribute) ya da `id` özniteliği ile tanımlanırlar. Class 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: + +```html + +``` + +Daha fazla bilgi için [w3schools'da CSS seçicileri][4]ni okuyabilirsin. + + [4]: http://www.w3schools.com/cssref/css_selectors.asp + +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: + +```html +{% load staticfiles %} +``` + +Burada yaptığımız yalnızca statik dosyaları yüklemek. :) Sonrasında, `` ve ``, tagları arasına, Bootstrap CSS dosyalarına yönelik linklerden sonra (web tarayıcımız bu satırları yazıldıkları sırası içerinde okuduğundan, bizim dosyamızdaki kodlar Bootstrap dosyasının içerisindekileri geçersiz kılabilir), eklemelisiniz: + +```html + +``` + +Az evvel şablonumuza (template) CSS dosyamızın nerede olduğunu söylemiş olduk. + +Dosyanız şu şekilde gözüküyor olmalı: + +```html +{% load staticfiles %} + + + Django Girls blog + + + + + + + + {% for post in posts %} +
+

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

+

{{ post.baslik }}

+

{{ post.yazi|linebreaks }}

+
+ {% endfor %} + + +``` + +Tamamdır, dosyayı kaydedip sayfayı yenileyebilirsiniz. + +![Şekil 14.2][5] + + [5]: images/color2.png + +Güzel, belki sitemize biraz hava verebiliriz. Sol taraftaki kenar boşluğunu (margin'i) arttırabiliriz. Hadi deneyelim! + +```css +body { + padding-left: 15px; +} +``` + +Bunu CSS dosyanıza ekleyin, dosyayı kaydedin ve nasıl çalıştığını görelim! + +![Şekil 14.3][6] + + [6]: images/margin2.png + +Belki de başlığımızın yazı tipini değiştirebiliriz? Aşağıdaki satırı `blog/templates/blog/post_list.html` dosyasının içinde `` etiketi arasına kopyalayın: + +```html + +``` + +Bu satır Google Font'larından (https://www.google.com/fonts) *Lobster*'ı sayfamıza aktarır. + +Ş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: + +```css +h1 a { + color: #FCA205; + font-family: 'Lobster'; +} +``` + +![Şekil 14.3][7] + + [7]: 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 tane div'inizin olması son derece yararlı, fakat ikisi da son derece farklı şeyler yapıyorlar (örneğin biri başlık diğeri gönderinin metni), bu nedenle ikisinin de aynı gözükmesini istemezsin. + +Devam edelim ve HTML kodumuzun bir kısmına isim verelim. Başlığı içeren `div`'e `page-header` isimli bir class ekleyelim: + +```html + +``` + +Şimdi de blog postunu içeren `div`'e `post` isimli bir class ekleyelim. + +```html +
+

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

+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+``` + +Şimdi farklı seçicilere (selector'lara) deklarasyon blokları ekleyeceğiz. `.` ile başlayan seçiciler (selector'lar) sınıflara işaret eder. Aşağıdaki kodu anlamanıza yardıcı olacak CSS hakkında pek çok tutorial ve açıklama mevcut. Şimdilik sadece bu kodu kopyalayıp `blog/static/css/blog.css` dosyamıza yapıştıralım: + +```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; +} +``` + +Sonrasında blog postlarımızı gösteren HTML kodunun etrafını class deklarasyonları ile saralım. Aşağıdaki kodları değiştirin: + +```html +{% for post in posts %} +
+

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

+

{{ post.baslik }}

+

{{ post.yazi|linebreaks }}

+
+{% endfor %} +``` + +`blog/templates/blog/post_list.html` dosyasının içierisindeki kodu bununla: + +```html +
+
+
+ {% for post in posts %} +
+
+ {{ post.yayinlama_tarihi }} +
+

{{ post.baslik }}

+

{{ post.yazi|linebreaks }}

+
+ {% endfor %} +
+
+
+``` + +Bu dosyaları kaydedin ve websayfanızı yenileyin. + +![Şekil 14.4][8] + + [8]: 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. + +Css ile oynamaktan korkmayın. Birşeyleri değiştirmeyi deneyin. Bir şeylerin bozulduğunu düşünürseniz, yaptığınızı her zaman geri alabilirsiniz! + +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. + +Sonraki bölüm için hazır mısınız? :) \ No newline at end of file diff --git a/tr/css/images/bootstrap1.png b/tr/css/images/bootstrap1.png new file mode 100644 index 00000000000..f7e1f57536c Binary files /dev/null and b/tr/css/images/bootstrap1.png differ diff --git a/tr/css/images/color2.png b/tr/css/images/color2.png new file mode 100644 index 00000000000..c191d399356 Binary files /dev/null and b/tr/css/images/color2.png differ diff --git a/tr/css/images/final.png b/tr/css/images/final.png new file mode 100644 index 00000000000..f90070b1aa5 Binary files /dev/null and b/tr/css/images/final.png differ diff --git a/tr/css/images/font.png b/tr/css/images/font.png new file mode 100644 index 00000000000..8561bb1cb03 Binary files /dev/null and b/tr/css/images/font.png differ diff --git a/tr/css/images/margin2.png b/tr/css/images/margin2.png new file mode 100644 index 00000000000..5ecba91ae54 Binary files /dev/null and b/tr/css/images/margin2.png differ diff --git a/tr/deploy/README.md b/tr/deploy/README.md new file mode 100755 index 00000000000..762a6dd31c5 --- /dev/null +++ b/tr/deploy/README.md @@ -0,0 +1,306 @@ +# 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. + +Ş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 :). + +Öğ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 ücretisiz yani sizin için kesinlikle yeterli olacaktır. + + [1]: http://pythonanywhere.com/ + +Dışardan 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. + +# 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. + +{% 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. + + $ 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. + +> **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. +> **Not** db.sqlite3 dosyası .gitignore dosyasının içinde belirlediğiniz dosyalardan biridir. Bu dosya yerel -sizin bilgisayarınızdaki- tüm bilgileri depoladığınız veritabanıdır. PythonAnywhere'deki websiteniz farklı bir veritabanı kullanacağından, bu dosyayı kod reponuza eklemek istemiyoruz. Bu farklı veritabanı SQLite olabilir -sizin geliştirmede kullandığınız gibi- ama genellikle SQLite'dan daha çok site ziyaretçisini kabul edebilen MySQL veritabanını kullanacağız. Ayrıca Github'daki kopyanızda SQLite veritabanınızı göz ardı ettiğinizde, yarattığınız postlar kendi bilgisayarınızda kalarak sadece yerel olarak ulaşılacaktır. Ama bu verileri uygulamanıza (production) ekleyebilirsiniz. Yerel veritabanınızı iyi bir oyun alanı gibi düşünebilirsiniz, farklı şeyler deneyebilecek, blogunuzdaki gerçek postları silmekten korkmayacaksınız. + +`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: + + $ git status + On branch master + + Initial commit + + Untracked files: + (use "git add ..." to include in what will be committed) + + .gitignore + blog/ +   manage.py + mysite/ + + nothing added to commit but untracked files present (use "git add" to track) + +Ve son olarak değişikliklerimizi kaydediyoruz. Konsole gidin ve aşağıdaki komutları çalıştırın: + + $ git add -A + $ git commit -m "My Django Girls app, first commit" + [...] + 13 files changed, 200 insertions (+) + create mode 100644 .gitignore + [...] + create mode 100644 mysite/wsgi.py + +## Kodunuzu Github'a gönderme + +[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!) + +Arkasından "my-first-blog" (veya "ilk-blogum") 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. + +![][3] + + [3]: images/new_github_repo.png + +> **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. + +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: + +![][4] + + [4]: images/github_get_repo_url_screenshot.png + +Şimdi bilgisayarınızdaki Git reposunu Github'daki repo ile ilişkilendirmemiz gerekiyor. + +Aşağıdakini konsolounuza 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): + + $ git remote add origin https://github.com//ilk-blogum.git + $ git push -u origin master + +Github kullanıcı adı ve şifrenizi girin, arkasından aşağıdakine benzer birşey görmeniz gerekiyor: + + 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. + + + +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 :) + + [5]: https://github.com/django/django + [6]: https://github.com/DjangoGirls/tutorial + +# Blogumuzun PythonAnywhere üzerinde kurulumu + +> **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' 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 kendı 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 oluşturmak + +Bilgisayarınızda nasıl bir virtualenv oluşturduysanız, aynı şekilde PythonAnywhere üzerinde de oluşturabilirsiniz. Bash konsoluna, aşağıdakileri yazın: + +``` +$ cd ilk-blogum + +$ 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 +``` + + +> **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. + + + +### Statik dosyaların toplanması. + +"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. + +Tutorial'ın ilerleyen kısımlarında sitemizin CSS'ini düzenlerken statik dosyalar konusuna biraz daha fazla gireceğiz. + +Şimdilik sadece sunucuda `collectstatic` diye ek bir komut çalıştıracağız. Bu komut, Django'ya sunucudaki bütün statik dosyaları toparlamasını söyler. An itibariyle bunlar çoğunlukla admin sitesini güzelleştiren dosyalar. + + (mvenv) $ python manage.py collectstatic + + You have requested to collect static files at the destination + location as specified in your settings: + + /home/edith/ilk-blogum/static + + This will overwrite existing files! + Are you sure you want to do this? + + Type 'yes' to continue, or 'no' to cancel: yes + +"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... + + Copying '/home/edith/ilk-blogum/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/actions.min.js' + Copying '/home/edith/ilk-blogum/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/inlines.min.js' + [...] + Copying '/home/edith/ilk-blogum/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/css/changelists.css' + Copying '/home/edith/ilk-blogum/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/css/base.css' + 62 static files copied to '/home/edith/ilk-blogum/static'. + +### PythonAnywhere üzerinde veritabanının oluşturulması + +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. + +Sunucudaki veritabanına aynen bilgisayardaki gibi `migrate` ve `createsuperuser` komutlarıyla oluşturup ilk örnek verilerle ile doldurabiliriz: + + (mvenv) $ python manage.py migrate + Operations to perform: + [...] + Applying sessions.0001_initial... OK + + + (mvenv) $ python manage.py createsuperuser + +## Blog'umuzu web uygulaması olarak yayınlama + +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! + +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 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/myenv`. 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 editö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' # buraya kendi kullanici adinizi yazin +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ısma 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** butonuna tıklayın. Uygulamanıza girip görebileceksiniz. Sayfanın tepesinde uygulamaya giden linki bulabilirsiniz. + +## 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. 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 unutlması: virtualenv'in oluşturulması, çalışır hale getirilmesi, içine Django'nun kurulumu, collectstatic'in çalıştırılması, veritabanının migrate ettirilmesi. + +* Web sekmesinde virtualenv dizin yolunda bir hata yapılması -- eğer problem varsa, ilgili yerde küçük kırmızı bir hata mesajı olur. + +* WSGI ayar dosyasına bir hata yapmak -- ilk-blogum dizinine olan yolu doğru yazdığınızdan emin misiniz? + +* 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 genel hata ayıklama önerileri][9] bulunuyor. + + [9]: https://www.pythonanywhere.com/wiki/DebuggingImportError + +Ve eğitmeniniz size yardıma hazır, unutmayın! + +# Siteniz canlıda! + +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. + +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 new file mode 100644 index 00000000000..44412f84823 Binary files /dev/null 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 new file mode 100644 index 00000000000..6e19174ec88 Binary files /dev/null and b/tr/deploy/images/new_github_repo.png differ diff --git a/tr/deploy/images/pythonanywhere_web_tab_virtualenv.png b/tr/deploy/images/pythonanywhere_web_tab_virtualenv.png new file mode 100644 index 00000000000..cafa22c2d97 Binary files /dev/null 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 new file mode 100755 index 00000000000..5db9d77b3b8 --- /dev/null +++ b/tr/deploy/install_git.md @@ -0,0 +1,15 @@ +### Windows + +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. + +### MacOS + +Git'i [git-scm.com](http://git-scm.com/)'den indirin ve yönergeleri izleyin. + +### GNU/Linux + +Halihazırda yüklü değilse, git'i paket yöneticinizle indirebilirsiniz. Şunlardan birini deneyin: + + sudo apt-get install git + # veya + sudo yum install git \ No newline at end of file diff --git a/tr/deploy/signup_pythonanywhere.md b/tr/deploy/signup_pythonanywhere.md new file mode 100755 index 00000000000..2c74b993403 --- /dev/null +++ b/tr/deploy/signup_pythonanywhere.md @@ -0,0 +1,5 @@ +Sırada PythonAnywhere sitesinde bedava bir "Beginner" ( yeni başlayan) hesabı açma işi var. + + * [www.pythonanywhere.com](https://www.pythonanywhere.com/) + +> **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. \ No newline at end of file diff --git a/tr/django/README.md b/tr/django/README.md new file mode 100755 index 00000000000..35aefa45846 --- /dev/null +++ b/tr/django/README.md @@ -0,0 +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. + +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. + +Şansınıza çok önceden başka insanlar yeni bir site oluştururken web geliştiricilerinin benzer problemlerle karşı karşıya kaldığını farketti ve bir araya gelip iskeletler (Django bunlardan biri) oluşturdular. Bu iskeletler size kullanabileceğiniz hazır bileşenler verir. + +İ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. + +## Neden bir iskelete ihtiyacınız var? + +Django'nun tam olarak ne işe yaradığını anlamak için sunucular konusunda daha çok girmemiz gerekiyor. İlk bilmeniz gereken şey, sunucunuzun onun bir web sayfası sunmasını istediğini 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 websayfası içeren bir cevap gönderiyor. 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 websitesi için istek gönderdiğinde (request ettiğinde) ne olur? + +Web sunucusuna bir istek geldiğinde tam olarak ne istendiğini çıkarmak için Django'ya geçirilir. Ö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ı yukardan 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 *görünüm* (view)'a karşılık geliyor). + +Mektubu olan 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! + +*Görünüm* (view) işlevinde her türlü ilginç şey yapılıyor: bilgi almak için veritabanına bakabiliriz. Belki kullanıcı veride birşeyin değişmesini istedi? "Lütfen iş tanımımı değiştirin" diye bir mektup gibi. *Görünüm* buna yapmaya izniniz var mı diye kontrol edebilir, arkasından da sizin için iş tanımınızı güncelleyip geriye "Yapıldı!" diye bir mesaj döner. Arkasından *görünüm* bir cevap üretir ve Django bunu kullanıcının web tarayıcısına gönderebilir. + +Tabi ki yukardaki açıklama biraz basitleştirilmiş bir açıklama, ama şimdilik bir sürü teknik detayı 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! \ No newline at end of file diff --git a/tr/django_admin/README.md b/tr/django_admin/README.md new file mode 100755 index 00000000000..66bc099f5ed --- /dev/null +++ b/tr/django_admin/README.md @@ -0,0 +1,47 @@ +# Django admin + +Modelini hazırladığımız yazıları eklemek, düzenlemek ve silmek için Django admin'i kullanacağız. + +Hadi `blog/admin.py` dosyasını açalım ve içeriğini şununla değiştirelim: + +```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.. + +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: + +![Giriş sayfası][1] + + [1]: images/login_page2.png + +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`'a basıp devam edin. Çıktısı aşağıdaki formatta olacaktır (kullanıcı adı ve email sizinki olacak): + + (myvenv) ~/djangogirls$ python manage.py createsuperuser + Username: admin + Email address: admin@admin.com + Password: + Password (again): + Superuser created successfully. + +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][2] + + [2]: images/django_admin3.png + +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. :) + +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. + +![Django admin][3] + + [3]: images/edit_post3.png + +Eğer Django admin ile ilgili daha fazla şey öğrenmek istiyorsanız Django'nun dokümantasyonlarına göz atabilirsiniz: https://docs.djangoproject.com/en/1.8/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. :) \ No newline at end of file diff --git a/tr/django_admin/images/django_admin3.png b/tr/django_admin/images/django_admin3.png new file mode 100644 index 00000000000..a450b4f9630 Binary files /dev/null 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 new file mode 100644 index 00000000000..c8572a73e7d Binary files /dev/null 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 new file mode 100644 index 00000000000..47153ef6960 Binary files /dev/null and b/tr/django_admin/images/login_page2.png differ diff --git a/tr/django_forms/README.md b/tr/django_forms/README.md new file mode 100755 index 00000000000..c4aafb04762 --- /dev/null +++ b/tr/django_forms/README.md @@ -0,0 +1,397 @@ +# Django formları + +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. `Formlar` kullanarak 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 iyi olmasının nedeni, ister sıfırdan bir form tanımlayabiliriz ister sonuçları modele kaydedecek bir `ModelForm` oluşturabiliriz. + +Bu tam da bizim yapmak istediğimiz şey: `Post` modelimiz için bir form oluşturmak. + +Django'nun diğer önemli parçaları gibi, formlarda kendi dosyalarına sahipler: `forms.py`. + +`Blog` dizinimizde bu isimde bir dosya oluşturmalıyız. + + Blog └── forms.py + + +Tamam, hadi dosyayı açalım ve aşağıdaki kodu yazalım: + +```python +from django import forms + +from .models import Post + +class PostForm(forms.ModelForm): + + class Meta: + model = Post + fields = ('title', 'text',) +``` + +Önce Django formları (`from django import forms`) ve tabi ki de `Post` modelimizi (`from .models import Post`) import etmeliyiz). + +`PostForm`, muhtemelen tahmin ettiğiniz gibi, formumuzun ismi. Django'ya bu formun bir `ModelForm` olduğunu anlatmalıyız. 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). + +Son olarak, bizim formumuza hangi alan(lar)ın girmesi 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 (yani kod içinde) `created_date` otomatik olarak ayarlanmalıdır, değil mi? + +Hepsi bu kadar! Şimdi tek yapmamız gereken formu bir *view* (görünüm) içinde kullanıp, şablon içinde göstermek. + +Bir kez daha: sayfaya bir bağlantı, bir URL, bir görünüm ve bir şablon üreteceğiz. + +## Form içeren sayfaya link oluşturma + +Şimdi `blog/templates/blog/base.html` görünümünü açma zamanı. Öncelikle `page-header` adlı `div` öğesinin içine bir link ekleyeceğiz: + +```html + +``` + +Yeni view'i `post_new` olarak isimlendirdik. + +Yukarıdaki satırı ekledikten sonra html dosyanız böyle gözükmeli: + +```html +{% load staticfiles %} + + + Django Girls blog + + + + + + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ + +``` + +Dökümanı kaydedip http://127.0.0.1:8000 sayfasını yeniledikten sonra, siz de `NoReverseMatch` hatasına benzer bir hata görüyor olmalısınız, değil mi? + +## URL + +`blog/urls.py` dosyasını açalım ve yeni bir satır ekleyelim: + +```python + url(r'^post/new/$', views.post_new, name='post_new'), +``` + +Ve son kod şu şekilde gözükecektir: + +```python +from django.conf.urls import include, 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'), +] +``` + +Sayfayı yeniledikten sonra, `AttributeError` şeklinde bir hata görmeliyiz. Bunun sebebi de henüz `post_new` görünümünü kodlamamış olmamız. Şimdi bu dosyayı da ekleyelim. + +## post_new view + +Şimdi `blog/views.py` dosyasını açıp aşağıdaki satırları `from` satırının olduğu yere ekleyelim: + +```python +from .forms import PostForm +``` + +ve bizim *view*'ımız: + +```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ğırıp dönüş değerini template katmanına iletmeliyiz. Bu *view*'a geri döneceğiz, fakat öncesinde form için bir template oluşturalım. + +## Template + +Öncelikle `blog/templates/blog` klasöründe `post_edit.html` isimli bir dosya yaratmalıyız. Çalışan bir form oluşturmak için yapılması gerekler şunlar: + +* 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: `` +* sonunda, tam `
` taginden sonra `{% raw %}{% csrf_token %}{% endraw %}` i eklememiz lazım. Bu çok önemlidir, çünkü formlarımızı güvenli yapar! Django bunu yapmadan çalıştırmaya kalkarsak şikayet eder: + +![CSFR Korumalı sayfa][1] + + [1]: images/csrf2.png + +Peki, şimdi de `post_edit.html` in içindeki HTML kodunun nasıl görünmesi gerektiğine bakalım: + +```html +{% extends 'blog/base.html' %} + +{% block content %} +

Yeni gönderi

+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} +``` + +Yenileme zamanı! Hey! Formun görüntülendi! + +![Yeni form][2] + + [2]: images/new_form2.png + +Ama, bir dakika! `title` ve `text` alanlarına birşey yazıp kaydettiğimizde ne olacak? + +Hiç birşey! Yine aynı sayfaya döndük ve bütüm yazdıklarımız kayboldu... ve de yeni bir post da eklenmemiş. Ne hata yaptık? + +Yanıt: Hiç bir hata olmadı. *view* da biraz daha iş yapmak gerekiyor. + +## Form'u kaydetme + +Tekrar `blog/views.py` dosyasını açalım. Şuan `post_new` view'ı içinde sadece bunlar var: + +```python +def post_new(request): + form = PostForm() + return render(request, 'blog/post_edit.html', {'form': form}) +``` + +Form'u gönderdiğimizde tekrar aynı view'e yönlendirileceğiz, ama bu sefer `request` nesnesinde daha spesifik olmak gerekirse `request.POST` (isimlendirmesinin bizim blog "post"umuz (gönderimiz) ile alakası yok, gerçekte veri gönderdiğimiz ("postaladığımız") için isimlendirme bu şekilde) içerisinde daha fazla veri olacak. HTML dosyasındaki `
` tanımında `method="POST"` adında bir değişken olduğunu hatırlıyor musun? Formdaki tüm alanlarda şimdi `request.POST` var. `POST` un ismini değiştirmememiz lazım (`method` için geçerli olan diğer değer sadece `GET` dir, ama şimdi bunların farklarını anlatacak kadar vaktimiz yok). + +Yarattığımız *view* da iki farklı durumu halletmemiz gerek. İlk olarak: sayfamız ilk erişildiği zaman boş bir form olmasını istiyoruz. İkincisi: *view* a geri dönüldüğü zaman form'u daha önce girilmiş bütün verilerle beraber görmek istiyoruz. Yani bir koşul eklememiz gerekiyor (bunun için `if` kullanacağız). + +```python +if request.method == "POST": + [...] +else: + form = PostForm() +``` + +Şimdi `[...]` ları doldurma zamanı geldi. `method` `POST` ise o zaman `PostForm` u verilerle oluşturmamız lazım, değil mi? Bunu yapmak için: + +```python +form = PostForm(request.POST) +``` + +Çok kolay! Şimdi de formu doğrulamamız lazım (yani tüm alanların oluştuğu ve hatalı değerlerin saklanmadığı). Bunuda `form.is_valid()` ile yapıyoruz. + +Formun doğruluğunu kontrol ediyoruz ve doğru ise kaydedebiliriz! + +```python +if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() +``` + +Burada iki basit şey yaptık: formu `form.save` ile kaydettik, ve bir yazar ekledik (`PostForm`'da daha önce bir `author` tanımlı değildi, oysa ki bu zorunlu bir alan!). `commit=False`, `Post` modelini henüz kaydetmek istemediğimizi belirtir - zira ilk önce yazarı eklememiz lazım. Genellikle `form.save()`, `commit=False` olmadan kullanılır, ama bu sefer, kullanmamız gerekiyor. `post.save()` değişiklikleri korur (yazarı ekler) ve yeni blog postunu yaratır! + +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: + +```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. + +```python +return redirect('blog.views.post_detail', pk=post.pk) +``` + +`blog.views.post_detail` gitmek istediğimiz view un ismidir. Unutmayalım ki bu *view* için bir `pk` değişkeni lazım. Bu değeri viewlara aktarmak için `pk=post.pk` yazarız. Burada `post` yeni yarattığımız blog postudur! + +Çok şey söyledik ama herhalde *view* u tümüyle bir görmek isteriz artık, değil mi? + +```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}) +``` + +Bakalım çalışacak mı? http://127.0.0.1:8000/post/new/ sayfasına gidip bir `başlık` ve `yazı` ekleyelim, sonra da kaydedelim... ve işte! Yeni blog postu eklenmiş ve `post_detail` sayfasına yönlendirildik! + +Postu kaydetmeden önce yayin tarihine değer atandığını fark etmiş olabilrsin. Daha sonra *yayına butonu* nu **Django Girls Tutorial: Ek konular** da anlatacağız. + +Süper! + +## Form doğrulama + +Şimdi de Django formlarının ne kadar cool olduğunu görelim. Bir blog postunun `başlık` ve `yazı` alanları olmalı. `Post` modelimizde bu alanlar mecburi değil demedik ( `published_date` demiş olduğumuz gibi), dolayısı ile Django bu alanlara değer atanması gerektiğini varsayar. + +`Başlık` veya `yazı` olmadan formu kaydetmeye çalışın. Ne olacak, tahmin et! + +![Form doğrulama][3] + + [3]: images/form_validation2.png + +Django tüm alanlara doğru tür değerlerin atandığını bizim için kontrol ediyor. Ne güzel, değil mi? + +> Yakın zamanda Django'nun admin arayüzünü kullandığımız için, sistem bizi hala oturumda varsayıyor. Bazı durumlar bizim oturumdan çıkmış olmamı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üvenik ekleme!** bölümünde anlatılacak. + +![Oturum hatası][4] + + [4]: images/post_create_error.png + +## Form editleme (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). + +`blog/templates/blog/post_detail.html` dosyasını açıp şu satırı ekleyelim: + +```python + +``` + +ki şablonumuz buna benzesin: + +```html +{% extends 'blog/base.html' %} + +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} + +

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% endblock %} +``` + +`blog/urls.py` dosyasına şu satırı ekleyelim: + +```python + url(r'^post/(?P[0-9]+)/edit/$', views.post_edit, name='post_edit'), +``` + +Daha önce kullandığımız `blog/templates/blog/post_edit.html` şablonunu tekrar kullanacağız, tek eksik bir *view*. + +Şimdi `blog/views.py` dosyasını açıp en sonuna şu satırı ekleyelim: + +```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}) +``` + +Bu nerdeyse bizim `post_new` view a benziyor, değil mi? Ama, tam de 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 `instance` olarak hem formu kaydettiğmizde yolluyoruz: + +```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: + +```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] + + [5]: images/edit_button2.png + +Butona tıklarsak blog postunu görmemiz lazım: + +![Formu düzenle][6] + + [6]: images/edit_form2.png + +İstediğimiz gibi başlık ve yazıyı değiştirebilir ve sonra da kaydedebilriz! + +Tebrikler! Uygulaman gittikçe tamamlanıyor! + +Django formları hakkında daha fazla bilgi bulmak için https://docs.djangoproject.com/en/1.8/topics/forms/ adresindeki dokümanlara bakabilirsin + +## Güvenlik + +Bir linke 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. + +`blog/templates/blog/base.html` dosyasında yarattığımız `page-header` `div` ve anchor taglarını bulalım. Şuna benziyor olmalı: + +```html + +``` + +Şimdi bir `{% if %}` tagi daha ekleyeceğiz ki link sadece admin olarak oturum açmış kişilere görünsün. Şimdilik, bu kişi sadece sensin! `` tagini şöyle değiştirelim: + +```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ı refresh edersek, farklı bir şey görmeyeceğiz. Sayfayı farklı bir tarayıcıda veya incognito bir pencerede yükleyelim. O zaman linkin görünmeyecek! + +## Bir şey daha: deployment zamanı! + +Bakalım PythonAnywhere'de calışacak mı? Tekrar deploy edelim! + +* İlk önce kodumuzu commit edelim, sonra Github'a push edelim + +``` +$ git status +$ git add -A . +$ git status +$ git commit -m "Web sitesinde blog yaratacak ve güncelleyecek viewlar eklendi." +$ git push +``` + +* Sonra bir [PythonAnywhere Bash console][7] una gidip: + + [7]: https://www.pythonanywhere.com/consoles/ + +``` +$ cd my-first-blog +$ source myvenv/bin/activate +(myvenv)$ git pull +[...] +(myvenv)$ python manage.py collectstatic +[...] +``` + +* Nihayet, [Web tab][8] ına gidip **Reload** edelim. + + [8]: https://www.pythonanywhere.com/web_app_setup/ + +O kadar! Tebrikler :) \ No newline at end of file diff --git a/tr/django_forms/images/csrf2.png b/tr/django_forms/images/csrf2.png new file mode 100644 index 00000000000..9dd1a9a4baa Binary files /dev/null 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 new file mode 100644 index 00000000000..f984ec2a4ae Binary files /dev/null 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 new file mode 100644 index 00000000000..f402eadd00b Binary files /dev/null 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 new file mode 100644 index 00000000000..329674ee5ad Binary files /dev/null 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 new file mode 100644 index 00000000000..0e81288c33e Binary files /dev/null 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 new file mode 100644 index 00000000000..8180ce66a06 Binary files /dev/null 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 new file mode 100644 index 00000000000..ae4650a575a Binary files /dev/null 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 new file mode 100755 index 00000000000..8b9f1c6c65c --- /dev/null +++ b/tr/django_installation/README.md @@ -0,0 +1,5 @@ +# Django Kurulumu + +> **Not** Eğer kurulum adımlarını zaten yaptıysanız diğer adıma geçebilirsiniz! + +{% 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 new file mode 100755 index 00000000000..2f3ea22d82d --- /dev/null +++ b/tr/django_installation/instructions.md @@ -0,0 +1,113 @@ +> 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. + +## 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 **sanal ortam**(diğer adıyla *virtualenv*) kuralım. Virtualenv Python/Django kurulumunuzu proje bazlı 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 `C:\Users\İsim` (`İsim` kısmı kullanıcı adınız olacak şekilde). + +Bu eğitim için giriş dizininizde `djangogirls` adlı bir klasör kullanacağız: + + mkdir djangogirls + cd djangogirls + + +`myvenv` adında bir virtualenv oluşturacağız. Genel komut aşağıdaki şekilde olacak: + + python3 -m venv myvenv + + +### Windows + +Yeni bir `virtualenv` (sanal ortam) 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. Şu şekilde görünmeli: + + C:\Users\İsim\djangogirls> C:\Python34\python -m venv myvenv + + +`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` (sanal ortam) oluşturmak `python3 -m venv myvenv` komutunu çalıştırmak kadar kolay. Komut şu şekilde görünecektir: + + ~/djangogirls$ python3 -m venv myvenv + + +Burada `myvenv` sizin sanal ortamınız olan `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. + +> **NOT:** Ubuntu 14.04 işletim sisteminde sanal ortam yaratmaya çalışırken şu hatayla karşılaşabilirsiniz: +> +> Error: Command '['/home/eddie/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 +> + +## Sanal ortamda çalışmak + +Yukarıdaki komutlar `myvenv` (veya seçtiğiniz isimde) bir klasör oluşturacaktır. Sanal ortam (birkaç klasör ve dosya) bu klasörün içindedir. + +#### Windows + +Sanal ortamınızı çalıştırarak başlatın: + + C:\Users\Name\djangogirls> myvenv\Scripts\activate + + +#### GNU/Linux ve OS X + +Sanal ortamınızı çalıştırarak başlatın: + + ~/djangogirls$ source myvenv/bin/activate + + +Eğer `virtualenv` sanal ortamınız için `myvenv` yerine başka bir isim seçtiyseniz komutlarınızı buna göre güncellemeyi 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 +> + +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ştaki `(myvenv)`'e dikkat edin! + +Sanal ortamda çalışırken `python` otomatik olarak doğru sürümü çalıştıracaktır. Yani `python3` yerine `python` komutuyla çalışmaya devam edebilirsiniz. + +Artık bütün gerekli uygulamaları bir araya getirdiğimize göre sonunda Django'yu yükleyebiliriz! + +## Django'yu Yüklemek + +`virtualenv` sanal ortamınızı başlattığınız için artık Django'yu `pip` kullanarak yükleyebiliriz. Konsola `pip install django==1.8` komutunu yazın. (İki tane eşittir işareti kullandık: `==`). + + (myvenv) ~$ pip install django==1.8 + Downloading/unpacking django==1.8 + Installing collected packages: django + Successfully installed django + Cleaning up... + + +Windows'ta + +> Eğer Windows işletim sisteminde çalışıyorsanız ve pip komutunu kullanırken bir hatayla karşılaştıysanız proje adresinizin boşluk veya özel karakter içerip içermediğini kontrol edin. (`C:\Users\User Name\djangogirls` gibi). Eğer böyle bir durum sözkonusuysa projenizi boşluk veya özel karakter içermeyen bir yere taşıyın. (`C:\djangogirls` gibi). Taşıma işleminden sonra yukarıdaki komutları tekrar deneyin. + +Linux'te + +> Eğer Ubuntu 12.04 işletim sisteminde pip komutunu çağırırken bir hata mesajıyla karşılaştıysanız `python -m pip install -U --force-reinstall pip` komutunu çalıştırarak sanal ortamdaki pip yüklemesini düzeltmeyi deneyin. + +İşte bu! 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 new file mode 100755 index 00000000000..a22433f06e8 --- /dev/null +++ b/tr/django_models/README.md @@ -0,0 +1,176 @@ +# Django modelleri + +Şimdi blogumuzdaki bütün yazıları kaydedebileceğimiz bir şey oluşturmak istiyoruz. Ama bunu yapabilmek için önce `nesneler`den (objects) bahsetmemiz gerekiyor. + +## Nesneler + +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ımlayabilmek. + +Peki bir nesne nedir? Özelliklerin ve hareketlerin bir bütünüdür. Kulağa garip geliyor olabilir ama bir örnekle açıklayacağız. + +Eğer bir kediyi modellemek istiyorsak `Kedi` nesnesini oluştururuz ve bu nesne şöyle özelliklere sahip olur:`renk`, `yaş`, `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). + +`Kedi` bazı hareketlere sahiptir: `miyavla`, `tırmala` ya da `beslen` (bu durumda kediye biraz `Kedi Maması` vermemiz gerekir ki bu özelliklere sahip başka bir nesne olur. Özelliklere örnek olarak `tat` verilebilir). + + Kedi + -------- + renk + yaş + ruh_hali + sahibi + miyavla() + tırmala() + beslen(kedi_maması) + + KediMaması + -------- + tat + + +Yani aslında ana fikir, gerçek nesneleri kod içinde özellikleriyle (`nesne özellikleri`) ve hareketleriyle (`metodlar`) tanımlamak. + +Ö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? + +Tabii ki blog gönderimizin (post) içeriği için bir metin, 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 ne zaman yayınlandığını da bilmek isteriz. + + Post + ------ + baslik + yazi + yazar + yaratilis_tarihi + yayinlama_tarihi + + +Bir blog gönderisi ile ne tür şeyler yapılabilir? Gönderiyi yayınlayan bir `metod` olması güzel olurdu, değil mi? + +Bu yüzden `yayinla` yöntemine ihtiyacımız olacak. + +Ne elde etmek istediğimizi bildiğimize göre, haydi bunu Django'da modellemeye başlayalım! + +## Django modeli + +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 - `database` içinde kaydedilir. Veritabanı veri topluluğuna verilen isimdir. Burası, kullanıcılar, blog gönderilerimiz, vb. hakkında bilgileri saklayacağımız yerdir. Verilerimizi depolamak için SQLite veritabanını kullanıyor olacağız. SQLite, Django için varsayılan veritabanıdır - şimdilik bizim için yeterli olacaktır. + +Veritabanındaki bir modeli, sütünları (alan adı) ve satırları (veri) olan bir hesap tablosuna (spreadsheet) benzetebiliriz. + +### 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 (`manage.py` dosyasının olduğu `djangogirls` klasörünün içinde olmalıyız): + + (myvenv) ~/djangogirls$ python manage.py startapp blog + + +Yeni bir `blog` klasörü ve içinde bir kaç dosya oluştuğunu fark edeceksiniz. Projemizdeki klasörler ve dosyalar şöyle olmalı: + + 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 + + +Bir uygulama oluşturduktan sonra, Django'ya bunu kullanmasını da söylememiz lazım. Bunu `mysite/settings.py` dosyasında yapıyoruz. `INSTALLED_APPS` girdisini bulup `'blog'`u tam `)` karakterinin üzerine yazmamız lazım. Sonunda yüklenilen uygulamalar (INSTALLED_APPS) listesi şuna benzemelidir: + +```python +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog', +) +``` + +### Blog gönderisi modeli oluşturma + +`blog/models.py` dosyasında `Models` olarak adlandırdığımız tüm nesneleri tanımlarız - burası bizim blog gönderisini tanımlayacağımız yer. + +Şimdi `blog/models.py` dosyasını açalım ve içindeki herşeyi silelim ve şu kodu yazalım: + +```python +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() + yaratilis_tarihi = models.DateTimeField( + default=timezone.now) + yayinlanma_tarihi = models.DateTimeField( + blank=True, null=True) + + def yayinla(self): + self. yayinlama_tarihi = timezone.now() + self.save() + + def __str__(self): + return self.baslik +``` + +> `str` nin her iki tarafında 2 tane alt çizgi (`_`) kullandığınızdan emin olun. Bu tarz Python dilinde sık olarak kullanılır ve bazen "dunder" (double underscore kısaltması) olarak ifade edilir. + +Biraz korkunç görünüyor, değil mi? Ama merak etmeyin, her şeyin ne demek olduğunu 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ı bütün dosyalarımıza kopyalamak yerine, bu kodların bir kısmını `from ... import ...` ile kodumuza dahil edebiliriz. + +`class Post(models.Model):` - bu satır modelimizi tanımlar (bir `nesne` dir). + +* `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: `baslik`,`yazi`, `yaratilis_tarihi`, `yayinlama_tarihi` ve `yazar` (Türkçe karakterleri kullanamadığımız unutmayalım). Bunun için her alanın tipini belirtmemiz lazım (Yazı mı? Numara mı? Tarih mi? Başka bir nesneye referans mı, ör. Kullanıcı?). + +* `models.CharField` - kısıtlı uzunlukta yazı tanımlamak için kullanır. +* `models.TextField` - karakter limiti olmayan uzun yazıları tanımlar. Blog gönderilerinin içeriği için biçilmiş kaftan, değil mi? +* `models.DateTimeField` - gün ve saati tanımlamada kullanılır. +* `models.ForeignKey` - başka bir model ile ilişkilendirir. + +Burada her detayı anlatmıyoruz, çünkü çok fazla vakit alır. Eğer detayları merak ederseniz veya farklı tür alanlar (Model fields) tanımlamak isterseniz Django'nun dokümantasyonlarınıza bakabilirsiniz (https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-types). + +Peki `def yayinla(self):` nedir? Daha önce bahsettiğimiz `yayinla` metodudur. `def` bir fonksiyon/metod olduğunu belirtir, `yayinla` ise bu metodun adıdır. İstersen metodun ismini değiştirebilirsin. Metodlara isim verme kuralı küçük harf ve boşuk yerine alt çizgi ( _ ) kullanmaktır. Örneğin ortalama fiyatı hesaplayan bir metoda `ortalama_fiyati_hesapla` ismi verilebilir. + +Genellikle metodlar birşey geri döndürür (`return` anahtar kelimesi döndür anlamına gelir). `__str__` metodunda buna bir örnek görebiliriz. Bu senaryoda `__str__()` unu çağırdığımızda Post başlığının yazısını (**string**) elde ederiz. + +Şu noktada 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 nesneler 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 eklemesini sağlamak. İlk önce Django'ya modelde bir takım değişikliklerin olduğunu haber vermemiz gerek (daha yeni yaptığımız değişiklikleri yani!). `python manage.py makemigrations blog` yazın. Şöyle görünmeli: + + (myvenv) ~/djangogirls$ python manage.py makemigrations blog + Migrations for 'blog': + 0001_initial.py: + - Create model Post + + +Django bize bir migrasyon(migration) dosyası oluşturdu ve bunu veritabanımıza uygulamamız lazım. `python manage.py migrate blog` yazdığın zaman şunu görmelisin: + + (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! diff --git a/tr/django_orm/README.md b/tr/django_orm/README.md new file mode 100755 index 00000000000..ffccc12a7e1 --- /dev/null +++ b/tr/django_orm/README.md @@ -0,0 +1,157 @@ +# Django ORM (Nesne-İlişkisel Eşleme) ve QuerySets (Sorgu Setleri) + +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, esas olarak, verilen bir modelin nesnelerinin listesidir. QuerySet veritabanından veri okumamıza, veriyi filtrelememize ve sıralamamıza imkan sağlar. + +En kolayı örnekle öğrenmektir. Hadi deneyelim, olur mu? + +## Django çekirdeği (shell) + +Lokal konsolumuzu açalım (PythonAnywhere'de değil) ve şu komutu yazalım: + + (myvenv) ~/djangogirls$ python manage.py shell + + +Etkisi aşağıdaki gibi olmalı: + + (InteractiveConsole) + >>> + + +Şuan Django'nun interaktif konsolundayız. Python istemine benziyor, ama bazı ek Django büyüsüyle :) Tabi ki, burada da tüm Python komutlarını kullanabiliriz. + +### Tüm nesneler + +Önce tüm gönderilerimizi görüntülemeyi deneyelim. Bunu aşağıdaki komut ile yapabiliriz: + + >>> Post.objects.all() + Traceback (most recent call last): + File "", line 1, in + NameError: name 'Post' is not defined + + +Oops! Bir hata meydana geldi. Bize bir gönderi olmadığını söylüyor. Doğru - önce gönderiyi almayı unuttuk! + + >>> 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: + + >>> 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? + +### Nesne oluşturma + +Veritabanına yeni bir gönderi eklemek için: + + >>> Post.objects.create(yazar=ben, baslik=u'Örnek Başlık', yazi=u'Test') + + +Ancak bir eksiğimiz var: `ben`. Gönderinin yazar özelliğine `User` modelinden türetilen bir nesneyi parametre olarak vermemiz gerekiyor. Nasıl verebiliriz? + +Öncelikle kullanıcı modelini dahil edelim: + + >>> from django.contrib.auth.models import User + + +Veritabanımızda hangi kullanıcılar var? Şu şekilde görebiliriz: + + >>> User.objects.all() + [] + + +Daha önce yarattığımız ayrıcalıklı kullanıcı! Şimdi veritabanından kullanıcı nesnesi alalım: + + ben = User.objects.get(username='ahmet') + + +Gördüğünüz gibi, `username` özelliği 'Ahmet' 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önderimizi artık kaydedebiliriz: + + >>> Post.objects.create(yazar=ben, baslik=u'Örnek Başlık', yazi=u'Test') + + +Yaşasın! Çalışıp çalışmadığını kontrol etmek ister misin? + + >>> Post.objects.all() + [, , ] + + +İşte bu kadar, listede bir gönderi daha! + +### Daha fazla gönderi 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. + +### Nesneleri filtrelemek + +QuerySets in büyük bir parçası nesneleri filtreleyebilme kabiliyetidir. Diyelim ki, kullanıcı Ola tarafından yazılmış tüm gönderileri bulmak istiyoruz. `Post.objects.all()` yapısı içindeki `all` yerine `filter` kullanacağız. Parantez içinde, bir blog gönderisinin sorgu setimizin içinde yer alması için hangi şartı(ları) sağlaması gerektiğini belirteceğiz. Örneğimizde, `yazar` özelliği `ben` nesnesine eşitti. Django'da bu filtre şöyle yazılır: `yazar=ben`. Şuan bizim kod parçacığımız şöyle görünüyor: + + >>> Post.objects.filter(yazar=ben) + [, , , ] + + +Ya da belki `title` alanında içinde 'başlık' kelimesini içeren tüm gönderileri görmek istiyoruz? + + >>> Post.objects.filter(baslik__contains=u'başlık') + [, ] + + +> **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 title_contains" hatası alırsı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: + + >>> from django.utils import timezone + >>> Post.objects.filter(yayinlanma_tarihi__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: + + >>> post = Post.objects.get(baslik="Örnek başlık") + + +Ardından `yayinla` metodu ile gönderiyi yayınlayalım! + + >>> 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): + + >>> Post.objects.filter(yayinlama_tarihi__lte=timezone.now()) + [] + + +### Nesneleri Sıralama + +QuerySets ayrıca nesne listesini sıralamanızı da sağlar. Nesneleri `yaratilis_tarihi` özelliğine göre sıralamayı deneyelim: + + >>> Post.objects.order_by('yaratilis_tarihi') + [, , , ] + + +Başlangıçta `-` ekleyerek sıralamayı tersine de çevirebiliriz: + + >>> Post.objects.order_by('-yaratilis_tarihi') + [, , , ] + + +### Sorgu Setlerini Zincirlemek + +Sorgu setlerini **zincirleyerek** beraber kullanabilirsiniz: + + >>> Post.objects.filter(yayinlama_tarihi__lte=timezone.now()).order_by('published_date') + + +Zincirleme gerçekten çok güçlüdür ve oldukça kompleks sorgular yazmanıza imkan sağlar. + +Güzel! Şimdi bir sonraki bölüm için hazırız. Çekirdeği kapatmak için, şunu yazalım: + + >>> exit() + $ diff --git a/tr/django_start_project/README.md b/tr/django_start_project/README.md new file mode 100755 index 00000000000..8a61b8de40c --- /dev/null +++ b/tr/django_start_project/README.md @@ -0,0 +1,128 @@ +# İlk Django projen! + +> Bu bölümün kaynağı Geek Girls Carrots (http://django.carrots.pl/) tutorial'ıdır. +> +> 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. + + [1]: http://django-marcador.keimlink.de/ + +Basit bir blog oluşturacağız! + +İlk adım yeni bir Django projesi başlatmaktır. Temel olarak Django tarafından sağlanan bazı scriptleri (komut dizilerini) çalıştırarak, Django projesinin iskeleti oluşturulacaktır. 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 önemli şeyleri bulabilmek 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 aktive etmelisiniz. **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 de `source myvenv/bin/activate` yazmak sizin için bunu yapacaktır. + +MacOS veya Linux konsolunuzda aşağıdaki komutu çalıştırmalısınız; ** sonunda nokta `(.)` koymayı unutmayın **: + + (myvenv) ~/djangogirls$ django-admin startproject mysite . + +Windows'da; ** sonunda nokta `(.)` koymayı unutmayın**: + + (myvenv) C:\Users\Name\djangogirls > django-admin startproject mysite . + +> Nokta `.` çok önemli çünkü şu an bulunduğunuz dizine Django'yu yüklemek için koda söyler. ( nokta `. ` kısayol referansıdır) +> +> **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$` and `(myvenv) C:\Users\Name\djangogirls>` kısımları komut satırınızdaki girdilerinizi çağıracak olan komut isteği örnekleridir. + +`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 + +`manage.py` site yönetimine yardımcı olan bir komut dosyasıdır. Biz bununla bilgisayarımızda diğer şeyler arasında hiçbir şey kurmadan bir web sunucusunu başlatabileceğiz. + +`settings.py` dosyası, web sitesinizin yapılandırması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ücü) tarafından kullanılan url örnekleri listesi 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. + +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/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 "Europe/Berlin" yazan kısmı uygun şekilde değiştirerek (örneğin "Europe/Istanbul") kendi seçtiğiniz zaman dilimine göre uyarlayın: + +```python +TIME_ZONE = 'Europe/Berlin' +``` + +Sabit dosyalar için de bir tane yol (path) eklememiz gerekecek (Daha sonra eğitimde sabit dosyalar ve CSS hakkında herşeyi öğreneceğiz). Dosyanın *sonuna* en aşağıya `STATIC_URL` girdisinin altına gidin ve `STATIC_ROOT` adında bir girdi ekleyin: + +```python +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'static') +``` + +## Veritabanı Kurulumu + +Web uygulamalarınız için farklı birçok veritabanı yazılımı vardır. Biz varsayılan olanı kullanacağız, `sqlite3`. + +Sqlite varsayılan olduğu için zaten `mysite/settings.py` dosyamızda kurulu: + +```python +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} +``` + +Blogumuzun veritabanını oluşturmak için terminalde şu komutu çalıştırın:`python manage.py migrate` (komutu çalıştırırken `manage.py` dosyasının olduğu `djangogirls` klasörünün içinde 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 + +Bu kadar! Şimdi web sunucumuzu ayağa kaldırma ve websitemizin çalıştığını görme zamanı! + +Öncelikle `manage.py` dosyasının bulunduğu dizinde olmalısınız (`djangogirls` klasörü). `python manage.py runserver` komutunu çalıştırarak terminal'den web sunucunuzu başlatabilirsiniz: + + (myvenv) ~/djangogirls$ python manage.py runserver + +Eğer Windows'taysanız ve `UnicodeDecodeError` hatası varsa, bu komutu kullanın: + + (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + +Şimdi tek yapmanız gereken şey sitenizin çalışıp çalışmadığını kontrol etmek. Tarayıcınızı açın (Firefox, Chrome, Safari, Internet Explorer ya da ne kullanıyorsanız) ve şu adresi girin: + + http://127.0.0.1:8000/ + +Siz durdurana kadar web sunucusu komut istemi alacaktır. Sunucu çalışıyorken daha fazla komut girebilmek için yeni bir terminal penceresi açın ve virtualenv'inizi aktive edin. Web sunucunuzu durdurmak için çalıştığı pencereye tekrar gelin ve CTRL+C ye - Control ve C butonlarına aynı anda - basın (Windows için Ctrl+Break'e basmanız gerekiyor olabilir). + +Tebrikler! ilk websitenizi oluşturdunuz ve bunu bir web sunucusu kullanarak yaptınız! Harika, değil mi? + +![İşte çalışıyor!][3] + + [3]: images/it_worked2.png + +Sonraki adım için hazır mısınız? İçerikleri oluşturma zamanı geldi! diff --git a/tr/django_start_project/images/it_worked2.png b/tr/django_start_project/images/it_worked2.png new file mode 100644 index 00000000000..4412ecfc49e Binary files /dev/null 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 new file mode 100755 index 00000000000..20f71cfe743 --- /dev/null +++ b/tr/django_templates/README.md @@ -0,0 +1,107 @@ +# Django templateleri(şablonlar) + +Bazı verileri gösterme zamanı! Django bunun için bize bazı faydalı hazır şablon etiketleri sunuyor. + +## Şablon Etiketleri nedir? + +Görüyoruz ki aslında, HTML'de Python kodu yazamayız, çünkü tarayıcılar bunu anlamaz. Tarayıcılar yalnızca HTML'den anlar. Biliyoruz ki Python daha dinamik bir dil iken, HTML oldukça statiktir. + +Django şablon etiketleri Python-benzeri yapıların HTML'e transfer edilmesine olanak sağlar, böylece dinamik web siteleri daha kolay ve hızlı oluşturabiliriz. + +## Gönderi Listesi Şablonunu Gösterme + +Bir önceki bölümde, şablonumuza `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ıvırcık parantezi içinde şu şekilde kullanırız: + +```html +{{ posts }} +``` + +Bunu `blog/templates/blog/post_list.html` template ile 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] + + [1]: images/step1.png + +Sadece bunu görüyoruz: + + [, ] + + +Django bunu bir liste nesne olarak algılamış. Python'a Giriş'ten listelerin nasıl gösteridiğini hatırlayalım. Evet, döngülerle! Bir Django şablonunda böyle yapılır: + +```html +{% for post in posts %} + {{ post }} +{% endfor %} +``` + +Bunu kendi şablonumuzda deneyelim. + +![Şekil 13.2][2] + + [2]: images/step2.png + +İşe yarıyor! Fakat, bunların daha önce **HTML'e Giriş** bölümde oluşturduğumuz statik gönderiler gibi görünmesini istiyoruz. HTLM ve şablon etiketlerini karıştırabiliriz. `body` şöyle görünecektir: + +```html + + +{% for post in posts %} +
+

published: {{ post.published_date }}

+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% endfor %} +``` + +{% raw %} `{% for %}` ve `{% endfor %}` arasına koyduğumuz her şey listedeki her nesne için tekrarlanır. Sayfanı yenile:{% endraw %} + +![Şekil 13.3][3] + + [3]: images/step3.png + +`{{ post.title }}` ve `{{ post.text }}` in biraz farkı şekilde yazıldığı dikkatini çekti mi? `Post` modelinde tanımlanan alanlardaki verilere ulaşıyoruz. Ek olarak `|linebreaks` postlardaki yeni satırları paragraflara çeviren bir filtreden geçiriyor. + +## Bir şey daha + +Web sitemizin İnternet'te hala çalıştığını görmek iyi bir fikir, değil mi? PythonAnywhere yükleyelim yine. Adımları hatırlayalım... + +* İ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 şablonları değiştirdim." +[...] +$ git push +``` + +* [PythonAnywhere][4] a bağlanalım ve **Bash konsolu** na gidelim (veya yeni bir konsol açalım) ve şunu çalıştıralım: + + [4]: https://www.pythonanywhere.com/consoles/ + +``` +$ cd my-first-blog +$ git pull +[...] +``` + +* Nihayet [Web tab][5] sekmesine gidip web uygulamamızdaki **Reload** a basalım. Şimdi uygulamamız güncellenmiş olmalı! + + [5]: https://www.pythonanywhere.com/web_app_setup/ + +Tebrikler! Şimdi devam edelim ve Django admininde yeni bir gönderi eklemeyi deneyelim (published_date eklemeyi unutmayalım!), sonrasında gönderinin görünüp görünmediğini görmek için sayfayı yenileyelim. + +Mükemmel çalışıyor, değil mi? Kendimizle gurur duyabiliriz! Şimdi bilgisayarımızdan bir süreliğine uzaklaşalım, çünkü bir arayı hak ettik. :) + +![Şekil 13.4][6] + + [6]: 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 new file mode 100644 index 00000000000..64d38b4e889 Binary files /dev/null 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 new file mode 100644 index 00000000000..113e145c943 Binary files /dev/null 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 new file mode 100644 index 00000000000..464a7645731 Binary files /dev/null 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 new file mode 100644 index 00000000000..b56b64f142e Binary files /dev/null and b/tr/django_templates/images/step3.png differ diff --git a/tr/django_urls/README.md b/tr/django_urls/README.md new file mode 100755 index 00000000000..0ea5619b512 --- /dev/null +++ b/tr/django_urls/README.md @@ -0,0 +1,125 @@ +# 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 bir URL görürsünüz - tarayıcınızın adres barında görünür (evet! `127.0.0.1:8000` bir URL'dir! Ve `https://djangogirls.com` de bir URL'dir): + +![Url][1] + + [1]: images/url.png + +Internetteki her sayfanın kendi URL'si olması gerekir. Böylelikle uygulamanız bir kullanıcı URL'ye gittiğinde ne göstermesi gerektiğini bilir. Django'da `URLconf` (URL konfigürasyonu) denilen birşey kullanıyoruz. URLconf, Django'nun doğru görünümü bulmak için gelen URL'yi eşlemeye çalıştığı kalıplardan oluşur. + +## 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: + +```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)), +] +``` + +Gördüğünüz gibi Django bizim için birşeyler koymuş bile. + +`#` 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? + +Geçen bölümde gittiğimiz admin URL şimdiden burda: + +```python + url(r'^admin/', include(admin.site.urls)), +``` + +`admin` ile başlayan her URL için Django ona denk gelen bir *görünüm* 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 + +Django'nun URL'leri görünümlerle 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: + + ^ 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ı. + +Her gönderi için ayrı bir görünüm yazmak hakkaten 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: + +* **^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 Django url'niz! + +İlk URL'imizi oluşturma zamanı! 'http://127.0.0.1:8000/' adresinin blogumuzun ana sayfası olmasını istiyoruz ve bize bir gönderi listesi göstermesini istiyoruz. + +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). + +Yorum satırlarını silin (`#` ile başlayan satırları) ve main 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: + +```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')), +] +``` + +Django artık 'http://127.0.0.1:8000/' adresine gelen herşeyi `blog.urls`'e yönlendirecek ve oradaki 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. + +## blog.urls + +`blog/urls.py` adında yeni boş bir dosya oluşturun. Harika! Şu iki satırı ekleyin: + +```python +from django.conf.urls import url +from . import views +``` + +Burada sadece Django'nun metodlarını ve `blog` uygulamasındaki tüm `görünüm`leri içeri aktarıyoruz (uygulamamız henüz yok, ama birazdan o kısma da geçeceğiz!) + +Bundan sonra ilk URL kalıbımızı ekleyebiliriz: + +```python +urlpatterns = [ + url(r'^$', views.post_list, name='post_list'), +] +``` + +Gördüğünüz üzere, `^$` URL'sine `post_list` adında bir `view` (görünüm) 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'` görünümü (view'ü) tanımlamak için kullanılan URL'nin adı. Bu görünümün adı ile aynı olabilir ama tamamen farklı birşey de olabilir. İsimlendirilmiş URL'leri (named URLs) 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/' adresine gidin ve sonuçları görün. + +![Hata][2] + + [2]: images/error1.png + +Artık "It works" demiyor, di mi? Meraklanmayın, sadece bir hata sayfası, korkacak birşey yok! Aslında çok kullanışlılar: + +Sayfada gördüğünüz şey: **no attribute 'post_list'**. Peki *post_list* size birşey hatırlatıyor mu? Bu görünümüzün ismi! Bu herşey yerli yerinde sadece henüz *view*'ımız (görünümümüz) yok manasına geliyor. Hiç merak etmeyin, oraya da geleceğiz. + +> Django URLconfs ile ilgili daha fazla bilgi edinmek istiyorsanız resmi dokümantasyona bakabilirsiniz: https://docs.djangoproject.com/en/1.8/topics/http/urls/ diff --git a/tr/django_urls/images/error1.png b/tr/django_urls/images/error1.png new file mode 100644 index 00000000000..cc17593d19d Binary files /dev/null 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 new file mode 100644 index 00000000000..6cd1bd96291 Binary files /dev/null and b/tr/django_urls/images/url.png differ diff --git a/tr/django_views/README.md b/tr/django_views/README.md new file mode 100755 index 00000000000..31bdeba3708 --- /dev/null +++ b/tr/django_views/README.md @@ -0,0 +1,38 @@ +# Django views - yaratma zamanı geldi! + +Evvelki bölümde yaptığımız hatayı yok edelim :) + +*Görünüm* uygulamanın "mantığı"nın ifade edildiği yerdir. Daha önce oluşturulan `model` den bilgi alıp `template`'a iletir. Gelecek bölümde bir template oluşturacağız. Görünümler bildiğiniz Python metodlarıdır. Ancak, **Python'a Giriş** bölümünde yazdığımız metodlardan biraz daha karmaşıktır. + +Görünümler `views.py` doyasına yazılır. Şimdi, `blog/views.py` dosyasına *görünüm (view)* ekleyelim. + +## blog/views.py + +Dosyayı açıp inceleyelim: + +```python +from django.shortcuts import render + +# Görünümler buraya yazılacak. +``` + +Henüz fazla bir şey görünmüyor. En basitinden *görünüm* şöyle olabilir. + +```python +def post_list(request): + return render(request, 'blog/post_list.html', {}) +``` + +Burada, `request` i alıp şablonumuzu `blog/post_list.html` ile görüntüleyen `render` metodunu `döndüren` (return) `post_list` isimli bir metod yarattık. + +Dosyamızı kaydedelim ve http://127.0.0.1:8000/ e gidip bakalım. + +Yine hata! Okuyup anlamaya çalışalım: + +![Hata][1] + + [1]: images/error.png + +Bu hatayı düzeltmek kolay: *TemplateDoesNotExist* (Şablon yok). Şablonu (Template) bulamadı. Bu hatayı şablonu oluşturarak gelecek bölümde düzeltelim! + +> Django görünümleri(view) hakkında daha fazla bilgi edinmek için resmi dokümantasyonları okuyun: https://docs.djangoproject.com/en/1.8/topics/http/views/ diff --git a/tr/django_views/images/error.png b/tr/django_views/images/error.png new file mode 100644 index 00000000000..391c9e61e16 Binary files /dev/null and b/tr/django_views/images/error.png differ diff --git a/tr/domain/README.md b/tr/domain/README.md new file mode 100755 index 00000000000..21bf9dfc461 --- /dev/null +++ b/tr/domain/README.md @@ -0,0 +1,71 @@ +# Alan Adı (Domain) + +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: basir 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! \ No newline at end of file diff --git a/tr/dynamic_data_in_templates/README.md b/tr/dynamic_data_in_templates/README.md new file mode 100755 index 00000000000..ed083f42abe --- /dev/null +++ b/tr/dynamic_data_in_templates/README.md @@ -0,0 +1,74 @@ +# Şablonlarda 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 şablonu ekledik. Ama gönderilerimiz 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 şablonumuzda göster, değil mi? + +Bu tam olarak *görünüm*'lerin yapmasını beklediğimiz şey: modelleri ve şablonları bağlamak. `post_list` *görünüm*'üzde göstermek istediğimiz modelleri alıp şablona iletmemiz gerekecek. Yani temelde bir *görünüm*de şablonda neyin (hangi modelin) gösterileceğine karar veriyoruz. + +Peki, bunu nasıl yapacağız? + +`blog/views.py`'ı açacağız. Şu anda `post_list` *görünüm*ü şöyle: + +```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? Şimdi `models.py`'de yazdığımız modeli ekleme zamanı. `from .models import Post` satırını şu şekilde ekleyeceğiz: + +```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 içeri alıyoruz (import ediyoruz). + +Sırada ne var? `Post` modelinden gönderileri almamız için `QuerySet` dediğimiz birşeye ihtiyacımız var. + +## QuerySet + +QuerySet'in nasıl çalıştığı konusunda bir fikriniz oluşmuştur. [Django ORM (QuerySets) bölümü][1]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 listesine istiyoruz, değil mi? Bunu QuerySets bölümünde yapmıştık zaten! + + Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') + + +Şimdi bu kodu `blog/views.py` dosyasında `def post_list(request)` fonksiyonuna ekleyelim: + +```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'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 kalan kısım `posts` QuerySet'ini şablona iletmek (nasıl göstereceğimizi bir sonraki bölümde işleyeceğiz). + +`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 şablon dosyamız `'blog/post_list.html'` var. `{}` şeklindeki son parametremiz, şablonda 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 `''`. + +Nihayetinde `blog/views.py` şu şekle gelmiş olmalı: + +```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}) +``` + +İşte bu kadar! Şablonumuza 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.8/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 new file mode 100755 index 00000000000..02c060045ba --- /dev/null +++ b/tr/extend_your_application/README.md @@ -0,0 +1,186 @@ +# 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. + +Pratik zamanı! + +Blog'umuzda lazım olan ilk şey bir gönderiyi göstermek için bir sayfa, değil mi? + +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 + +`blog/templates/blog/post_list.html` dosyasına bir link ekleyerek başlayacağız. Şu ana kadar yaptıklarımız şöyle gözüküyor olması lazım: + +```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

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

{{ post.title }}

`'i gönderinin detay sayfasına link verecek şekilde değiştirelim:{% endraw %} + +```html +

{{ 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 şablon 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. + +Ş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: + +![NoReverseMatch error (Tersi yok hatası)][1] + + [1]: 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! + +İ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: + +```python +from django.conf.urls import include, 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'), +] +``` + +Ş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 **/<1> 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'a 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 **/** - `$` - "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*'a 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]+)`. + +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! + +![AttributeError (Özellik hatası)][2] + +Bir sonraki adımın ne olduğunu hatırlıyor musunuz? Tabi ki: view'u eklemek! + +## Gönderi detayı için bir view ekleyin + +Bu sefer *view*'umuza `pk` adında bir parametre ekleyeceğiz. *view*'umuzun 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: + + 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] + +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ı). + +![Page not found (Sayfa bulunamadı)][4] + +İ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* (görünüm) ekleme zamanı! + +`blog/views.py` dosyasını açıp aşağıdaki kodu ekleyelim: + + from django.shortcuts import render, get_object_or_404 + + +Bunu diğer `from` satırlarının yakınına eklememiz gerekiyor. Dosyanın sonuna *view*'umuzu ekleyeceğiz: + + 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] + +Çalıştı! Fakat blog gönderisi başlığındaki bir bağlantıya tıkladığınızda ne oluyor? + +![TemplateDoesNotExist error (Şablon yok hatası)][6] + +Of hayır! Başka bir hata! Ama onu nasıl halledeceğimizi biliyoruz, di mi? Bir şablon (template) eklememiz gerekiyor! + +## Gönderi detayı için bir şablon oluşturun + +`blog/templates/blog` dizininde `post_detail.html` adında bir dosya oluşturacağız. + +Şöyle görünmeli: + +```html +{% extends 'blog/base.html' %} + +{% block content %} +
+ {% if post.published_date %} +
+ {{ post.published_date }} +
+ {% endif %} +

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% endblock %} +``` + +Bir kere daha `base.html` dosyasını genişleteceğiz. `content` bloğunda bir gönderinin varsa yayınlanma tarihini (published_date), başlığını ve metnini 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 şablon etiketidir (template tag) ( **Introduction to Python** bölümünden <1>if ... else .. 'i hatırladınız mı?). Bu senaryoda gönderinin `published_date` (yayınlanma tarihi) boş olup olmadığına bakmak istiyoruz.{% endraw %} + +Tamam, sayfamızı tazeleyip `Sayfa bulunamadı` hatasının gidip gitmediğine bakabiliriz. + +![Post detail page (Gönderi detay sayfası)][7] + +Heyo! Çalışıyor! + +## Bir şey daha: deployment 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 "Added view and template for detailed blog post as well as CSS for the site." +$ git push +``` + +* Sonra bir [PythonAnywhere Bash console][8] una gidip: + +``` +$ cd my-first-blog +$ source myvenv/bin/activate +(myvenv)$ git pull +[...] +(myvenv)$ python manage.py collectstatic +[...] +``` + +* Nihayet, [Web tab][9] ına gidip **Reload** edelim. + +O kadar! Tebrikler :) + + [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/ \ 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 new file mode 100644 index 00000000000..a8cb53172af Binary files /dev/null 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 new file mode 100644 index 00000000000..6edcd9933c3 Binary files /dev/null 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 new file mode 100644 index 00000000000..023d8720081 Binary files /dev/null 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 new file mode 100644 index 00000000000..306926206f8 Binary files /dev/null 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 new file mode 100644 index 00000000000..240dc447b51 Binary files /dev/null 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 new file mode 100644 index 00000000000..8ae30c71311 Binary files /dev/null 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 new file mode 100644 index 00000000000..335ce2569ef Binary files /dev/null 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 new file mode 100755 index 00000000000..5fc2edb46e6 --- /dev/null +++ b/tr/how_the_internet_works/README.md @@ -0,0 +1,53 @@ +# İ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/). + +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? + +Ö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. + +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*. + +Peki, fakat İnternet'in nasıl göründüğünü bilmek istiyorsunuz. Değil mi? + +Size bir resmini çizdik, İnternet işte buna benzer: + +![Şekil 1.1][1] + + [1]: images/internet_1.png + +Ç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][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. + +Şöyle gözükmekte: + +![Şekil 1.3][3] + + [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. + +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 + +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. + +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 - Üstmetin 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. + +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 kadar konuşma yeter, bir şeyler yaratma vakti! \ 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 new file mode 100644 index 00000000000..9c5bcf0b003 Binary files /dev/null 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 new file mode 100644 index 00000000000..dd5861f376f Binary files /dev/null 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 new file mode 100644 index 00000000000..a23488e3f2f Binary files /dev/null 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 new file mode 100644 index 00000000000..05f1aed562f Binary files /dev/null and b/tr/how_the_internet_works/images/internet_4.png differ diff --git a/tr/html/README.md b/tr/html/README.md new file mode 100755 index 00000000000..362ae6849ef --- /dev/null +++ b/tr/html/README.md @@ -0,0 +1,210 @@ +# HTML'ye giriş + +Şablon nedir diye sorabilirsiniz. + +Ş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 şablon 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 şablonunun 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). + +## Nedir HTML? + +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 "HyperText Markup Language" (HiperMetin İşaretleme Dili) anlamına gelir. **Hypertext** sayfalar arası bağlantıları destekleyen türden bir metin demektir. **İşaretleme (Markup)**, 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. + +## İlk şablonunuz! + +Bir şablon oluşturmak bir şablon dosyası oluşturmak demektir. Her şey bir dosyadır, değil mi? Bunu muhtemelen zaten fark etmişsinizdir. + +Şablonlar `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 + + +(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.) + +Şimdi de `blog/templates/blog` dizini içine `post_list.html` adlı bir dosya yaratalım (şimdilik içini boş bırakalım). + +Web sitemizin nasıl göründiğüne bir bakalım: http://127.0.0.1:8000/ + +> Eğer `TemplateDoesNotExists` hatası alırsan sunucuyu yeniden başlatmayı dene. 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. + +![Şekil 11.1][1] + + [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ü şablonumuz boş. Bunu düzeltelim. + +Template dosyamıza şunları ekleyelim: + +```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] + + [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 + +## Head ve body + +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. + +* **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 başlık elemanını `` 'in içine böyle koyabilirsiniz: + +```html + + + Ola'nın blogu + + +

Merhaba!

+

Çalışıyor!

+ + +``` + +Dosyayı kaydedin ve sayfanızı yenileyin. + +![Şekil 11.3][3] + + [3]: images/step4.png + +Tarayıcınızın "Ola'nın blogu" başlığını nasıl anladığını fark ettiniz mi? `Ola's blog` kısmını başlık olarak yorumlayarak yazıyı tarayıcının başlık kısmına yerleştirdi. (Bu yazı bookmark vb gibi yerlerde de kullanılır). + +Büyük ihtimal her açılan etiketin benzer bir *kapatan etiket*, `/` ıle başlayan, ile kapatıldığını da fark ettiniz. Ayrıca bu etiketler *iç içe* yerleştirilmekte (bu da bir etiketi kapatabilmek için, içindeki tüm etiketlerin kapanmış olması gerekir demektir). + +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. + +## Şablonunuzu özelleştirin + +Şimdi artık biraz eğlenip şablonunuzu özelleştirmeyi deneyebilirsiniz! İşte bunun için faydalı birkaç etiket: + +* `

Bir başlık

` - en önemli 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 +* `
` - başka bir satıra gider (br içine birşey konulmaz) +* `bağlantı` bir bağlantı oluşturur +* `
  • ilk madde
  • ikinci madde
` - tıpkı bunun gibi bir liste yapar! +* `
` sayfada bir bölümü tanımlar + +İşte tam bir şablon örneği: + +```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. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

+
+ +
+

published: 14.06.2014, 12:14

+

İkinci gönderim

+

mefailün feilatün mefailün feilün. Ne kadar zevkli bir işmiş bilgisayarlarla uğraşmak. Artık bilgisayar başından kalkmam. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut f.

+
+ + +``` + +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. + +Bize yaşattığı duygu: + +![Şekil 11.4][4] + + [4]: images/step6.png + +Yaşasın! Şimdiye dek, şablonumuz tam olarak sadece **aynı bilgiyi ** görüntüledi - öncesinde ise şablonların **farklı** bilgiyi **aynı formatta** görüntülememize izin verdiğinden bahsetmiştik. + +Gerçekten yapmak istediğimiz ise Django adminde ekli gerçek gönderileri göstermek - ve bir sonraki adımımız da bu. + +## Birşey daha: dağıtım! + +Bunları İnternet'te canlı olarak görmek çok güzel olur, değil mi: + +### Kodumuzu commit ve push ile Github'a yükleyelim + +İlk önce son yayınlamadan (deployment) sonra hangi dosyaların değiştiğine bakalım. Bu komutları yerel (local) bilgisayarımızda çalıştıralım, PythonAnywhere'de değil: + + $ 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 . + + +> **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). + +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 + + +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." + + +> **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: + + 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: + + [5]: https://www.pythonanywhere.com/consoles/ + +``` +$ cd ~/my-first-blog +$ source myvenv/bin/activate +(myvenv)$ git pull +[...] +(myvenv)$ python manage.py collectstatic +[...] +``` + +Kodumuzun indirilmesini izleyelim. Kodun geldiğini kontrol etmek istersek **Files sekme**sini açıp PythonAnywhere'de kodumuzu görebiliriz. + +* Son olarak, [Web sekmesi][6]ne gidip uygulamanızın **Reload (Yenile)** butonuna basın. + + [6]: https://www.pythonanywhere.com/web_app_setup/ + +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 new file mode 100644 index 00000000000..e9c2f1082d6 Binary files /dev/null and b/tr/html/images/step1.png differ diff --git a/tr/html/images/step3.png b/tr/html/images/step3.png new file mode 100644 index 00000000000..811226fa3fc Binary files /dev/null and b/tr/html/images/step3.png differ diff --git a/tr/html/images/step4.png b/tr/html/images/step4.png new file mode 100644 index 00000000000..bd6c1a044e0 Binary files /dev/null and b/tr/html/images/step4.png differ diff --git a/tr/html/images/step6.png b/tr/html/images/step6.png new file mode 100644 index 00000000000..e42a2fe5388 Binary files /dev/null and b/tr/html/images/step6.png differ diff --git a/tr/images/application.png b/tr/images/application.png new file mode 100644 index 00000000000..6dcba6202c7 Binary files /dev/null and b/tr/images/application.png differ diff --git a/tr/installation/README.md b/tr/installation/README.md new file mode 100755 index 00000000000..033a2bf8056 --- /dev/null +++ b/tr/installation/README.md @@ -0,0 +1,49 @@ +# 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 [Internet nasıl çalışır?](../how_the_internet_works/README.md) bölümüne gidebilirsiniz. + +Çü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. + +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. + +İyi şanslar! + +# Kurulum + +Atölyede bir blog yapıyor olacaksınız, eğitim günü kodlamaya hazır olmanız için önceden ayarlamakta fayda olan birkaç kurulum var. + +# Python Yükleyin + +{% include "/python_installation/instructions.md" %} + +# Bir "virtualenv" kurun ve Django'yu yükleyin + +{% include "/django_installation/instructions.md" %} + +# Bir kod editörü yükleyin + +{% include "/code_editor/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. + +# PythonAnywhere hesabı oluşturun + +{% include "/deploy/signup_pythonanywhere.md" %} + +# Okumaya başlayın + +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) + + * [Komut satırına giriş](../intro_to_command_line/README.md) + + * [Python'a giriş](../intro_to_command_line/README.md) + + * [Django nedir?](../django/README.md) \ No newline at end of file diff --git a/tr/intro_to_command_line/README.md b/tr/intro_to_command_line/README.md new file mode 100755 index 00000000000..d36a58ff7a6 --- /dev/null +++ b/tr/intro_to_command_line/README.md @@ -0,0 +1,281 @@ +# Komut satırı arayüzüne giriş + +Ha, heyecan verici, değil mi?! İlk kodunuzu birkaç dakika içinde yazacaksınız :) + +**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. + +## 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. + +## Komut satırı arabirimini açın + +Birkaç deneme yapmak için önce komut satırı arabirimini açmamız gerekir. + +### Windows + +Başlat menüsü → Tüm Programlar → Donatılar → Komut Satırı. + +### Mac OS X + +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 :) + +## Komut İstemcisi + +Ş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: + + $ + + +Windows'da ise `>` işareti göreceksiniz, bunun gibi: + + > + + +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. + +Yukarıdaki $ ve > işaretlerini gösteren kısım komut istemcisi ya da kısaca istemci diye adlandırılır. Sizden girdi isteminde bulunur. + +Eğitim boyunca, komut yazmanızı istediğimizde $ ve > kısımlarını yazmanıza gerek yok, kalan kısmı yazmanızı isteyeceğiz. + +## İlk komutunuz(Yaşasın!) + +Basit bir şeyle başlayalım. Aşağıdaki komutu yazın: + + $ whoami + + +ya da + + > whoami + + +Ve ardından `enter` tuşuna basın. Sonucumuz bu: + + $ whoami olasitarska + + +Gördüğünüz gibi, bilgisayar az önce kullanıcı adınızı yazdı. Muntazam, değil mi?:) + +> Her komutu yazmaya çalışın, kopyala-yapıştır yapmayın. Bu şekilde daha akılda kalıcı olur! + +## Temeller + +Tüm işletim sistemleri komut satırı için birbirinden biraz farklı komutlar kullanır, bu nedenle işletim sisteminize uygun yönergeleri izlediğinizden emin olun. Deneyelim mi? + +### Geçerli Dizin + +Nerede olduğumuzu bilmek güzel olurdu, değil mi? Bakalım. Bu komutu yazın ve `enter` tuşuna basın: + + $ pwd + /Users/olasitarska + + +Windows'ta iseniz: + + > cd + C:\Users\olasitarska + + +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. + +> Not: 'pwd'nin anlamı "print working directory" yani "çalışma dizinini yazdır"dır. + +* * * + +### 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\olasitarska + 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 + ... + + +* * * + +### Geçerli dizini değiştir + +Şimdi, haydi Masaüstü dizinimize gidelim: + + $ cd Masaüstü + + +Windows: + + > cd Masaüstü + + +Gerçekten değişmiş mi bir bakalım: + + $ pwd + /Users/olasitarska/Masaüstü + + +Windows: + + > cd + C:\Users\olasitarska\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. + +* * * + +### Dizin oluşturun + +Uygulamalı yapmak için masaüstünüzde bir dizin oluşturmaya ne dersiniz? Bu şekilde yapabilirsiniz: + + $ mkdir uygulama + + +Windows: + + > 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 :) + +> 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. + +* * * + +### 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. + +#### Çözüm: + + $ cd uygulama + $ mkdir test + $ ls + test + + +Windows: + + > cd uygulama + > mkdir test + > dir + 05/08/2014 07:28 PM test + + +Tebrikler! :) + +* * * + +### Temizlik + +Ortalığı dağınık bırakmak istemeyiz, haydi yaptığımız her şeyi silelim. + +İlk önce masaüstüne geri dönmemiz gerek: + + $ cd .. + + +Windows: + + > cd .. + + +`cd` komutu ile `..` kullanmak sizi bir üst dizine götürür (Bu sizin şuanki dizininizi tutan ana dizindir). + +Nerede olduğunuzu kontrol edin: + + $ pwd + /Users/olasitarska/Masaüstü + + +Windows: + + > cd + C:\Users\olasitarska\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. + + $ rm -r uygulama + + +Windows: + + > rmdir /S uygulama + uygulama, Emin misiniz ? E + + +Bitti! Gerçekten silindiğinden emin olalım: + + $ ls + + +Windows: + + > dir + + +### Çıkış + +Şimdilik bu kadar! Şimdi komut satırını güvenle kapatabilirsiniz. Bunu "hacker" tarzında yapalım, tamam mı?:) + + $ exit + + +Windows: + + > 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** | + +Bu kullanabileceğiniz komutlardan sadece birkaçı, fakat bugün bundan daha fazlasını kullanmayacaksınız. + +Eğer meraklı iseniz, [ss64.com][1] adresinden tüm işletim sistemleri için tüm komutların kullanımına ulaşabilirsiniz. + + [1]: http://ss64.com + +## Hazır mısınız? + +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 new file mode 100755 index 00000000000..4018e00dfc8 --- /dev/null +++ b/tr/python_installation/README.md @@ -0,0 +1,13 @@ +# Hadi Python ile başlayalım + +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 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! + +{% 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 new file mode 100644 index 00000000000..7946019bc29 Binary files /dev/null and b/tr/python_installation/images/add_python_to_windows_path.png differ diff --git a/tr/python_installation/instructions.md b/tr/python_installation/instructions.md new file mode 100755 index 00000000000..d1cefb62c03 --- /dev/null +++ b/tr/python_installation/instructions.md @@ -0,0 +1,59 @@ +> Bu bölüm Geek Girls Carrots tarafından yapılan bir eğitime dayanılarak hazırlanmıştır. (http://django.carrots.pl/) + +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. + +### 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ık) ve yönergeleri izleyin. Python kurulumunu yaptığınız dizinin yolunu unutmamanız önemli. Daha sonra lazım olacak! + +Dikkat: "Customize" (Özelleştir) 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" seçeneğini seçin: + +![Python'u arama yoluna eklemeyi unutmayın](../python_installation/images/add_python_to_windows_path.png) + +### GNU/Linux + +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 + + +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 + + +#### Fedora (21'e kadar) + +Terminalde kullanmanız gereken komut: + + $ sudo yum install python3.4 + + +#### Fedora (22+) + +Terminalde kullanmanız gereken komut: + + $ sudo dnf install python3.4 + + +### OS X + +Python kurulum dosyasını indirmek için resmi siteye gitmelisiniz: https://www.python.org/downloads/release/python-342/: + + * *Mac OS X 64-bit/32-bit installer* dosyasını indirin, + * *python-3.4.3-macosx10.6.pkg* dosyasına çift tıklayarak yükleyiciyi çalıştırın. + +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.4.3 + + +* * * + +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. \ No newline at end of file diff --git a/tr/python_introduction/README.md b/tr/python_introduction/README.md new file mode 100755 index 00000000000..73736a5f108 --- /dev/null +++ b/tr/python_introduction/README.md @@ -0,0 +1,789 @@ +# Python'a Giriş + +> Bu bölümün bazı kısımları Geek Girls Carrots (http://django.carrots.pl/) öğreticisinden alınmıştır. + +Biraz kod yazalım! + +## Python komut istemcisi (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. + + [1]: ../intro_to_command_line/README.md + +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. + >>> + + +## İlk Python komutunuz! + +Python komutunu çalıştırdıktan sonra, komut istemcisi `>>>` ş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. + +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. + + >>> 2 + 3 + 5 + + +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` + +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... + +## String'ler (dizgiler) + +Mesela ismin? İsmini tırnak işaretleri içerisinde şu şekilde yaz: + + >>> "Ola" + 'Ola' + + +İlk string'ini oluşturdun! String (dizgi), 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: + + >>> "Hi there " + "Ola" + 'Hi there Ola' + + +Ayrıca stringleri bir sayı ile çarpabilirsin: + + >>> "Ola" * 3 + 'OlaOlaOla' + + +Eğer stringinin içerisine kesme işareti koymak istiyorsan, bunun için iki seçeneğin var. + +Çift tırnak kullanarak: + + >>> "Runnin' down the hill" + "Runnin' down the hill" + + +veya sola eğik çizgi (\) kullanarak: + + >>> 'Runnin\' down the hill' + "Runnin' down the hill" + + +Hoş değil mi? İsminin tamamını büyük harf yapmak için, sadece şunu yazman yeterli: + + >>> "Ola".upper() + 'OLA' + + +Stringin üzerinde `upper` **fonksiyon**unu kullandın! Fonksiyon (`upper()` gibi) , çağırıldığında(calling) Python'un verilen bir obje (`"Ola"`) ü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! + + >>> len("Ola") + 3 + + +Fonksiyonları neden bazen stringin sonunda bir `.` ile (`"Ola".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 `"Ola"` stringini `len` fonksiyonuna bir parametre olarak veriyoruz. + +### Özet + +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. + +Bunlar öğreneceğiniz her programlama dilinin temelleri. Biraz daha zor bir şey için hazır mısın? İddiaya gireriz öylesin! + +## Errors (Hatalar) + +Şimdi yeni bir şey deneyelim. Bir sayının uzunluğunu, bir string'in uzunluğunu bulduğumuz gibi bulabilir miyiz? Bu görmek için `len(304023)` yazıp `enter`a basalım: + + >>> 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? + + >>> 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 **string'e** çeviriyor +* `int` fonksiyonu değişkenleri **integer'a** (tam sayıya) çeviriyor + +> Önemli: Tam sayıları yazıya çevirebiliriz, fakat yazıları(text) sayılara çeviremeyiz - `int('selamlar')` bir anlam ifade etmiyor. + +## Variables (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. + +`name` adında bir değişken yaratmak istediğimizi varsayalım: + + >>> name = "Ayşe" + + +Gördünüz mü? Ne kadar kolay: name değişkeni "Ayşe" oldu. + +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: + + >>> name + 'Ayşe' + + +İşte bu sizin ilk değişkeniniz! name değişkeninin referansını(içini) istediğiniz zaman değiştirebilirsiniz: + + >>> name = "Sonja" + >>> name + 'Sonja' + + +Bu değişkeni fonksiyonlar içinde de kullanabilirsiniz: + + >>> len(name) + 5 + + +Harika değil mi? Tabii ki değişkenler, sayılar da dahil herhangi bir şey olabilir. Şunu deneyin: + + >>> a = 4 + >>> b = 6 + >>> a * b + 24 + + +Peki ya değişkenin adını yanlış kullanırsak? Ne olacağını tahmin ediyor musunuz? Deneyelim! + + >>> city = "Tokyo" + >>> ctiy + Traceback (most recent call last): + 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. + +Bununla biraz oynayıp, neler yapabildiğinizi görün! + +## Print (yazdır) işlevi + +Şunu deneyin: + + >>> name = 'Maria' + >>> name + 'Maria' + >>> print(name) + Maria + + +Sadece `name` yazdığınız zaman, Python yorumlayıcısından 'name' değişkeninin dize olarak *temsili* döner, yani tek tırnaklar içine alınmış M-a-r-i-a harfleri. Eğer `print(name)` derseniz Python ekrana değişkenin içeriğini yazdıracaktır, bu kez tırnaklar olmaksızın, daha temiz biçimde. + +Daha ileride göreceğimiz gibi `print()`, işlevlerin içindeyken bir şey yazdırmak istediğimizde ya da bazı şeyleri birden fazla satırda yazdırmak istediğimizde de kullanışlıdır. + +## Lists (Listeler) + +Python, string ve integerın yanı sıra, çok değişik türlerde nesnelere sahiptir. Şimdi, **list** 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: + + >>> [] + [] + + +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: + + >>> 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! + + >>> len(lottery) + 6 + + +Evet! `len()` listedeki nesne sayısını verir. Kullanışlı, değil mi? Belki de şu an listeyi sıralarız: + + >>> 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: + + >>> 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! + + >>> lottery.reverse() + >>> print(lottery) + [59, 42, 30, 19, 12, 3] + + +Kolay, değil mi? Listeye yeni bir eleman eklemek isterseniz, bu komutu yazarak yapabilirsiniz: + + >>> lottery.append(199) + >>> print(lottery) + [59, 42, 30, 19, 12, 3, 199] + + +Sadece listedeki ilk elemanı göstermek isterseniz, **indexes** (indisler) ile yapabilirsiniz. İndis 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: + + >>> 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. + +Listeden eleman silmek için yukarıda öğrendiğimiz gibi **indisleri** ve **del** komutunu kullanman gerekir (del silmenin(delete) kısaltmasıdır). Bir örnekle öğrendiklerimizi pekiştirelim; listeden ilk numarayı sileceğiz. + + >>> print(lottery) + [59, 42, 30, 19, 12, 3, 199] + >>> print(lottery[0]) + 59 + >>> del lottery[0] + >>> print(lottery) + [42, 30, 19, 12, 3, 199] + + +Kusursuz çalıştı! + +Daha fazla eğlence için diğer indeksleri de deneyin: 6, 7, 1000, -1, -6 veya -1000. Denemeden önce komutların sonuçlarını tahmin etmeye çalışın. Sonuçlar mantıklı mıydı? + +Bütün liste fonksiyonlarını Python dökümantasyonunun bu bölümünde bulabilirsin: https://docs.python.org/3/tutorial/datastructures.html + +## Dictionaries (Sözlükler) + +Dictionary (Sözlük) listeye benzerdir ancak sözlük değerlerine indeks(indis) 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: + + >>> {} + {} + + +Bu boş bir sözlük oluşturduğunuzu gösterir. Yaşasın! + +Şimdi, bu komutu yazmayı deneyin (kendi bilgilerinle değiştir): + +```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: + +* 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: + + >>> print(participant['name']) + Ola + + +Gördün mü, listeye benzer. Ancak indeksini hatırlamana gerek yok - sadece ismi. + +Python'a olmayan bir anahtarın değerini sorarsak ne olur? Tahmin edebiliyor musun? Hadi deneyip görelim! + + >>> participant['age'] + Traceback (most recent call last): + File "", line 1, in + KeyError: 'age' + + +Bir başka hata! **KeyError** (Anahtar hatası) verdi. 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. + +* 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: + + >>> 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: + + >>> 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: + + >>> 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: + + >>> 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. + +### Özet + +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 + +Bir sonraki part 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). + + >>> 5 > 2 + True + >>> 3 < 1 + False + >>> 5 > 2 * 2 + True + >>> 1 == 1 + True + >>> 5 != 2 + 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. + +Python' a iki görev daha verin: + + >>> 6 >= 12 / 2 + True + >>> 3 <= 2 + False + + +`>` ve `<` işaretleri kolay, fakat `>=` ve `<=` ne anlama geliyor? + +* 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: + + >>> 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 + +Portakallarla elmaları karşılaştılaştırabilir miyiz? Bunun Python'daki eşdeğerini deneyelim: + + >>> 1 > 'django' + Traceback (most recent call last): + File "", line 1, in + TypeError: unorderable types: int() > str() + + +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. + +Sadece iki tane boolean nesnesi var: - True (Doğru) - False (Yanlış) + +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: + + >>> a = True + >>> a + True + + +Ayrıca bu şekilde de yapabilirsiniz: + + >>> 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` + +Tebrikler! Boolean'lar programlamadaki en havalı özelliklerden, ve az önce onları nasıl kullanmanız gerektiğini öğrendiniz! + +# Kaydet! + +Ş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! + +Kullandığımız Python yorumlayıcısından çıkmak için sadece ```exit()``` fonksiyonunu yazmanız yeterlidir: + + >>> 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: + + [2]: ../code_editor/README.md + +```python +print('Hello, 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. + +Mac'de bu komut şunun gibi görünecektir: + + $ cd /Users//Desktop + + +Linux'ta ise bu şekilde ("Desktop" kelimesi "Masaüstü" olarak da görünebilir): + + $ cd /home//Desktop + + +Ve Windows'ta, bu şekilde olacak: + + > cd C:\Users\\Desktop + + +Bir problem olursa yardım istemekten çekinmeyin. + +Şimdi dosyadaki komutları çalıştırmak için Python'u kulllanın: + + $ python3 python_intro.py + Hello, 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ış) + +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: + +```python +if 3 > 2: +``` + +Eğer bunu kaydedip çalıştırsaydık şu hatayla karşılaşacaktık: + + $ 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: + +```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. + +Kaydedip çalıştırmayı deneyelim: + + $ python3 python_intro.py + Çalışıyor! + + +### 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: + +```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 + + +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: + +```python +name = 'Zeynep' +if name == 'Ayşe': + print('Selam Ayşe!') +elif name == 'Zeynep': + print('Selam Zeynep!') +else: + print('Selam yabancı!') +``` + +ve çalıştırılınca: + + $ 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. + +`if` cümlenizden sonra istediğiniz kadar `elif` cümlesi ekleyebilirsiniz. Mesela: + +```python +volume = 57 +if volume < 20: + print("Çok sessiz.") +elif 20 <= volume < 40: + print("Güzel bir fon müziği") +elif 40 <= volume < 60: + print("Harika, her notayı duyabiliyorum") +elif 60 <= volume < 80: + print("Parti başlasın") +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: + + $ python3 python_intro.py + Harika, her notayı duyabiliyorum + + +### Özet + +Son üç alıştırmada öğ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. + +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! + +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: + +```python +def hi(): + print('Merhaba!') + print('Nasılsın?') + +hi() +``` + +Tamam, ilk fonksiyonumuz hazır! + +Fonksiyon adını neden dosyanın en altına yazdığımızı merak edebilirsiniz. Bunun nedeni, Python'ın dosyayı okuyup, onu yukarıdan aşağı doğru işlemesi. Yani fonksiyonumuzu kullanabilmek için, onu en alt kısımda yeniden yazmalıyız. + +Haydi şimdi bunu çalıştıralım ve neler olacağını görelim: + + $ python3 python_intro.py + Merhaba! + Nasılsın? + + +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: + +```python +def hi(name): +``` + +Gördüğünüz gibi, fonksiyonumuza `name` (isim) adında bir parametre ekledik: + +```python +def hi(name): + if name == 'Ayşe': + print('Selam Ayşe!') + elif name == 'Zeynep': + print('Selam Zeynep!') + else: + print('Selam 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' + + +Ü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: + +```python +hi("Ayşe") +``` + +Ve tekrar çalıştıralım: + + $ python3 python_intro.py + Selam Ayşe! + + +Ve eğer ismi değiştirirsek ne olur? + +```python +hi("Zeynep") +``` + +Ve çalıştırın: + + $ 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ı! + + +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? + +```python +def hi(name): + print('Selam ' + name + '!') + +hi("Seda") +``` + +Şimdi kodu çağıralım: + + $ python3 python_intro.py + Selam Seda! + + +Tebrikler! Az önce fonksiyonları nasıl yazacağınızı öğrendiniz! :) + +## Döngüler + +Bu da zaten son parça. Hızlı oldu, değil mi? :) + +Programcılar kendilerini tekrar etmeyi sevmezler. Programlama tamamen işleri otomatikleştirmek ise, herkesin ismini tek tek elle yazarak 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: + +```python +girls = ['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: + +```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. + +Dosyada yer alacak tam kod aşağıdadır: + +```python +def hi(name): + print('Selam ' + name + '!') + +girls = ['Seda', 'Gül', 'Pınar', 'Ayşe', 'Sen'] +for name in girls: + hi(name) + print('Sıradaki') +``` + +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 + + +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: + + for i in range(1, 6): + print(i) + + +Çalıştırırsak: + + 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. + +## Ö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 :) + +![Kek][3] + + [3]: 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 new file mode 100644 index 00000000000..fa2f3baeae6 Binary files /dev/null and b/tr/python_introduction/images/cupcake.png differ diff --git a/tr/template_extending/README.md b/tr/template_extending/README.md new file mode 100755 index 00000000000..1e0c230d1b1 --- /dev/null +++ b/tr/template_extending/README.md @@ -0,0 +1,122 @@ +# Şablon genişletmek + +Django'nun size sunduğu başka bir güzellik de **şablon 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 şablonlarda yapmanıza gerek kalmaz, bir kere değiştirmek yeterlidir! + +## Temel şablonu oluşturma + +Temel şablonunuz sizin diğer bütün sayfalarda genişletebileceğiniz en basit şablonunuzdur. + +Şimdi `blog/templates/blog/` klasörü içinde `base.html` adlı dosyayı oluşturalım: + + blog + └───templates + └───blog + base.html + post_list.html + + +Sonra, `post_list.html` dosyasındaki her şeyi `base.html`'ye kopyalayalım, şu şekilde: + +```html +{% load staticfiles %} + + + Django Girls blog + + + + + + + + +
+
+
+ {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+ {% endfor %} +
+
+
+ + +``` + +Sonra, `base.html` dosyasındaki ``'nizi (`` ve `` arasında kalan her şeyi) şununla değiştirin: + +```html + + +
+
+
+ {% block content %} + {% endblock %} +
+
+
+ +``` + +Aslında sadece `{% for post in posts %}{% endfor %}` arasındaki her şeyi şununla değiştirmiş olduk: + +```html +{% block content %} +{% endblock %} +``` + +Peki bu ne anlama geliyor? Az önce bir `block` oluşturdunuz. Bloklar şablon etiketleridir, blokların içine HTML ekleyerek `base.html`'yi genişleten şablonlara erişebilirsiniz. Bunun nasıl yapıldığını da hemen göstereceğiz. + +Şimdi kaydedin, ve tekrar `blog/templates/blog/post_list.html` dosyasını 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: + +```html +{% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+{% endfor %} +``` + +Ve şimdi bu satırı sayfanın başına ekleyin: + + {% extends 'blog/base.html' %} + + +{% raw %}Bu şu anlama geliyor: `post_list.html` dosyasında `base.html` şablonunu 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 %} + +```html +{% extends 'blog/base.html' %} + +{% block content %} + {% for post in posts %} +
+
+ {{ post.published_date }} +
+

{{ post.title }}

+

{{ post.text|linebreaks }}

+
+ {% endfor %} +{% endblock content %} +``` + +İşte bu! 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. \ No newline at end of file diff --git a/tr/whats_next/README.md b/tr/whats_next/README.md new file mode 100755 index 00000000000..070d9c33957 --- /dev/null +++ b/tr/whats_next/README.md @@ -0,0 +1,40 @@ +# Sırada ne var? + +Kendini tebrik et! **Kesinlikle harikasın**. Seninle gurur duyuyoruz! <3 + +### Şimdi ne yapmak gerek? + +Bir ara ver ve rahatla. Gerçekten çok büyük bir şey yaptın. + +Bundan sonra şunları yaptığına emin ol: + +* Güncel kalmak için Django Girls'ü [Facebook][1] ya da [Twitter][2] dan takip et + + [1]: http://facebook.com/djangogirls + [2]: http://twitter.com/djangogirls + +### Daha geniş kapsamlı kaynaklar önerebilir misiniz? + +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.8/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 \ No newline at end of file diff --git a/zh/README.md b/zh/README.md index 1a73448e4d1..bc7c42b6aaf 100644 --- a/zh/README.md +++ b/zh/README.md @@ -24,7 +24,7 @@ [2]: images/application.png -> 如果你独自学习这个教程而苦于没有一位能帮你答疑解惑的的教练,我们给你提供交流的平台:[!\[Gitter\](https://badges.gitter.im/Join Chat.svg)][1]。 我们要求我们的教练以及之前的参与者时不时到那里去,帮助其他人参与本教程! 不要担心什么,尽管大胆地提问吧! +> 如果你独自学习这个教程而苦于没有一位能帮你答疑解惑的的教练,我们给你提供交流的平台:[![Gitter](https://badges.gitter.im/Join Chat.svg)][1]。 我们要求我们的教练以及之前的参与者时不时到那里去,帮助其他人参与本教程! 不要担心什么,尽管大胆地提问吧! 好嘞,[我们从头开始...][3] diff --git a/zh/code_editor/README.md b/zh/code_editor/README.md index eba54bcca0c..aa5f317f017 100755 --- a/zh/code_editor/README.md +++ b/zh/code_editor/README.md @@ -4,4 +4,4 @@ > **注意**在之前章节你可能已经完成了这一步,如果那样的话,你可以直接进入下一章节。 -{% include "code_editor/instructions.md" %} \ No newline at end of file +{% include "/code_editor/instructions.md" %} diff --git a/zh/css/README.md b/zh/css/README.md index 3c86f582172..1bace424811 100644 --- a/zh/css/README.md +++ b/zh/css/README.md @@ -41,11 +41,13 @@ Bootstrap是最流行的HTML和CSS框架之一,它可以用来开发炫酷的 我们在blog应用的目录下创建一个名为`static`的文件夹,创建后目录结构如下: +``` djangogirls ├── blog │ ├── migrations │ └── static └── mysite +``` Django会自动找到你应用文件夹下全部名字叫“static”的文件夹,并能够使用其中的静态文件。 @@ -54,11 +56,13 @@ Django会自动找到你应用文件夹下全部名字叫“static”的文件 现在让我们创建一个 CSS 文件,为了在您的 web 页中添加你自己的风格。 创建一个新的目录称为 `css` 里面你 `static` 的目录。 然后,在这个 `css` 目录里创建一个新的文件,称为 `blog.css` 。 准备好了吗? +``` djangogirls └─── blog └─── static └─── css └─── blog.css +``` 是时候来写一些CSS了!首先用你的代码编辑器打开`blog/static/css/blog.css`。 @@ -73,16 +77,20 @@ Django会自动找到你应用文件夹下全部名字叫“static”的文件 在你的`blog/static/css/blog.css`文件中添加下面的代码: +```css h1 a { color: #FCA205; } +``` `h1 a`是CSS选择器。 这意味着我们要将我们的样式应用于在 `h1` 元素的任何 `a` 元素 (例如当我们的代码中有类似:`

link

`)。 在这种情况下,我们会告诉它要改变其颜色为 `#FCA205`,它是橙色的。 当然,你可以把自己的颜色放在这里! 在 CSS 文件中,我们决定HTML 文件中元素的样式。 由该元素的名称 (即 `a`,`h1`,`body`)、 属性 `class` 或属性 `id` 来标识元素。 类和 id 是你自己给该元素的名称。 类定义元素组,并指向特定元素的 id。 例如,可能由 CSS 使用标记名称 `a`、 类 `external_link` 或 id `link_to_wiki_page` 标识以下标记: +```html +``` 阅读有关 [CSS Selectors in w3schools][4]. @@ -91,18 +99,23 @@ Django会自动找到你应用文件夹下全部名字叫“static”的文件 然后,我们还需要告诉我们的 HTML 模板,我们添加一些 CSS。打开 `blog/templates/blog/post_list.html` 文件并在最开始的地方它添加以下行: +```html {% load staticfiles %} +``` 我们刚刚加载了静态文件到这里(译者注:这里实际上是为模板引入staticfiles相关的辅助方法):)。 然后,在`` 和 ``之间,在Bootstrap的CSS文件的引导之后(浏览器按照给定文件的顺序读取文件,所以我们的文件中的代码可能会覆盖引导数据库文件中的代码),添加以下行: +```html +``` 我们只是告诉我们的模板我们的 CSS 文件所在的位置。 现在,您的文件应该像这样: +```html {% load staticfiles %} @@ -125,6 +138,7 @@ Django会自动找到你应用文件夹下全部名字叫“static”的文件 {% endfor %} +``` 好的保存该文件并刷新网站 ! @@ -135,9 +149,11 @@ Django会自动找到你应用文件夹下全部名字叫“static”的文件 干得好 !我想,也许我们也给我们的网站一点空间并增加左边缘。让我们来试试这个 ! +```css body { padding-left: 15px; } +``` 将它添加到你的 css 代码,保存该文件并查看它如何工作 ! @@ -148,17 +164,21 @@ Django会自动找到你应用文件夹下全部名字叫“static”的文件 也许我们可以在我们的头中自定义字体吗?粘贴到你的 `< head >` 在 `blog/templates/blog/post_list.html` 文件中: +```html +``` 这行将从谷歌的字体 (https://www.google.com/fonts) 中导入称为 *龙虾*的字体 。 现在添加一行 `font-family: 'Lobster';` 到CSS文件 `blog/static/css/blog.css` 的 `h1 a` 声明块中(花括弧 `{` 与 `}` 之间的代码),然后刷新页面: +```css h1 a { color: #FCA205; font-family: 'Lobster'; } +``` ![图 14.3][7] @@ -171,22 +191,27 @@ Django会自动找到你应用文件夹下全部名字叫“static”的文件 继续命名部分HTML 代码。添加一个称为 `page-header` 的类到您的 `div`中,其中包含您的标头,像这样: +```html +``` 和现在将包含一篇博客文章的类`post`添加到您的 `div` 。 +```html

published: {{ post.published_date }}

{{ post.title }}

{{ post.text|linebreaks }}

+``` 现在,我们将向不同的选择器添加声明块。 选择器以 `.` 开始,关联到类。 网络上有很多很棒的CSS教程以及相关解释,帮助您理解下面的代码。 至于现在,就简单地复制粘贴到你的 `blog/static/css/blog.css` 文件中吧。 +```css .page-header { background-color: #ff9400; margin-top: 0; @@ -234,10 +259,12 @@ Django会自动找到你应用文件夹下全部名字叫“static”的文件 .post h1 a, .post h1 a:visited { color: #000000; } +``` 然后将文章的HTML代码用类声明包裹起来。替换以下内容: +```html {% for post in posts %}

published: {{ post.published_date }}

@@ -245,10 +272,12 @@ Django会自动找到你应用文件夹下全部名字叫“static”的文件

{{ post.text|linebreaks }}

{% endfor %} +``` 在 `blog/templates/blog/post_list.html` 是这样的: +```html
@@ -264,6 +293,7 @@ Django会自动找到你应用文件夹下全部名字叫“static”的文件
+``` 保存这些文件并刷新您的网站。 diff --git a/zh/deploy/README.md b/zh/deploy/README.md index a85a5e65504..68a84d83fad 100755 --- a/zh/deploy/README.md +++ b/zh/deploy/README.md @@ -22,7 +22,7 @@ Git是一个被大量程序员使用的"版本控制系统"。 此软件可以 > **注意** 如果你已经做过安装步骤了,你可以直接跳过这个步骤开始创建你自己的Git版本库。 -{% include "deploy/install_git.md" %} +{% include "/deploy/install_git.md" %} ## 开始我们自己的Git版本库 @@ -129,7 +129,7 @@ Git会追踪这个目录下所有文件和文件夹的更改,但是有一些 > **注意** 你可能在之前的安装步骤中已经创建 PythonAnywhere 账户 — 如果是的话,那么无需再来一次。 -{% include "deploy/signup_pythonanywhere.md" %} +{% include "/deploy/signup_pythonanywhere.md" %} ## 在 PythonAnywhere 上拉取我们的代码 diff --git a/zh/django_forms/README.md b/zh/django_forms/README.md index 8ff70a8b092..7ac3dfcfaf2 100755 --- a/zh/django_forms/README.md +++ b/zh/django_forms/README.md @@ -10,12 +10,15 @@ Django表单的一个好处就是我们既可以从零开始自定义,也可 我们需要创建一个文件,把它的名字放在`blog`目录下。 +``` blog └── forms.py +``` 好吧,让我们打开它,然后键入以下代码: +```python from django import forms from .models import Post @@ -25,6 +28,7 @@ Django表单的一个好处就是我们既可以从零开始自定义,也可 class Meta: model = Post fields = ('title', 'text',) +``` 首先我们需要导入Django表单(`from django import forms`)然后,显然是我们的`Post`模型(`from .models import Post

@@ -43,13 +47,16 @@ Django表单的一个好处就是我们既可以从零开始自定义,也可 是时候打开`blog/templates/blog/base.html`了。我们将添加一个链接到`div`,命名为`page-header`: +```html +``` 请注意我们想要调用我们的新视图`post_new`. 添加了新的行后,你的html文件现在应该看起来像这样: +```html {% load staticfiles %} @@ -74,6 +81,7 @@ Django表单的一个好处就是我们既可以从零开始自定义,也可
+``` 然后保存,刷新http://127.0.0.1:8000页面,你可以明显地看到一个熟悉的`NoReverseMatch`错误信息,是吧? @@ -82,11 +90,14 @@ Django表单的一个好处就是我们既可以从零开始自定义,也可 我们打开`blog/urls.py`然后添加一个新行: +```python url(r'^post/new/$', views.post_new, name='post_new'), +``` 最终代码会看起来像这样: +```python from django.conf.urls import include, url from . import views @@ -95,6 +106,7 @@ Django表单的一个好处就是我们既可以从零开始自定义,也可 url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'), url(r'^post/new/$', views.post_new, name='post_new'), ] +``` 刷新网页后,我们看到一个`AttributeError`,因为我们没有实现`post_new`视图。让我们现在把它加上吧。 @@ -103,14 +115,18 @@ Django表单的一个好处就是我们既可以从零开始自定义,也可 现在打开`blog/views.py`文件,加入下面的各行到`from`行下: +```python from .forms import PostForm +``` 还有我们的*view*: +```python def post_new(request): form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) +``` 为了创建一个新的`Post`表单,我们需要调用`PostForm()`,然后把它传递给模板。 我们会回到这个*视图*,但是现在,让我们为这个表单快速创建一个模板。 @@ -130,6 +146,7 @@ Django表单的一个好处就是我们既可以从零开始自定义,也可 好,让我们看看HTML 在`post_edit.html`里应该看起来什么样: +```html {% extends 'blog/base.html' %} {% block content %} @@ -139,6 +156,7 @@ Django表单的一个好处就是我们既可以从零开始自定义,也可 {% endblock %} +``` 现在刷新!哇!你的表单显示出来了! @@ -157,53 +175,66 @@ Django表单的一个好处就是我们既可以从零开始自定义,也可 再一次打开`blog/views,py`。我们在看到`post_new`中的视图内容是: +```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`,但是我们没有时间去解释它们两者的区别是什么)。 所以在我们的*视图*里,我们有了两种不同的情况去处理。 首先:当我们首次访问一个页面,我们想要得到一个空白的页面。 第二:当我们回到*视图*,要有我们所有我们刚刚键入的数据。 所以我们需要添加一个条件判断(我们为此使用`if`)。 +```python if request.method == "POST": [...] else: form = PostForm() +``` 现在去填写`[...]`。如果`method` 是 `POST`,那么我们要用表单里的数据构建`PostForm`,对吗?我们会这样做: +```python form = PostForm(request.POST) +``` 很容易吧!下一件事情就是去检查表单是否正确(所有必填字段都要被设置并且不会保存任何不正确的值)。我们将使用`form.is_valid()`来实现. 我们检查表单是否正确,如果是我们就保存它! +```python if form.is_valid(): post = form.save(commit=False) post.author = request.user post.published_date = timezone.now() post.save() +``` 基本上,我们这里有两件事情:我们使用`form.save`保存表单,我们添加一个作者(因为 `PostForm` 中没有`author`字段,然而这个字段是必须的!)。 `commit=False`意味着我们还不想保存`Post`模型—我们想首先添加作者。 大多数情况下,当你使用`form.save()`时,不会使用`commit=False`,但是在这种情况下,我们需要这样做。 `post.save()`会保留更改(添加作者),并创建新的博客文章! 最后,如果我们能够立即去`post_detail`页面创建新的博客内容,那将很酷,对吗?为了做到这点,我们需要再导入一个: +```python from django.shortcuts import redirect +``` 把它添加到你文件的最开始处。现在我们可以说:创建完新帖子我们就转去`post_detail`页面。 +```python return redirect('blog.views.post_detail', pk=post.pk) +``` `blog.views.post_detail` 是我们想去的视图的名字。 还记得这个*视图* 需得具有一个 `pk` 变量吗? 为了把它传递给视图我们使用`pk=post.pk`, 其中 `post` 就是我们刚刚创立的博客帖子! 好吧,我们已经说了很多了,但可能我们想看到整个*视图*现在看起来什么样,对吗? +```python def post_new(request): if request.method == "POST": form = PostForm(request.POST) @@ -216,6 +247,7 @@ Django表单的一个好处就是我们既可以从零开始自定义,也可 else: form = PostForm() return render(request, 'blog/post_edit.html', {'form': form}) +``` 让我们看看它是否正常工作。 转到页 http://127.0.0.1:8000//post/new/,添加 `title` 和 `text`,将它保存... 看! 新博客文章已经加进来了,我们被重定向到`post_detail`页面! @@ -248,11 +280,14 @@ Django会处理验证我们表单里的所有字段都是正确的。这不是 打开 `blog/templates/blog/post_detail.html` 并添加以下行: +```html +``` 所以模板看起来像这样: +```html {% extends 'blog/base.html' %} {% block content %} @@ -267,17 +302,21 @@ Django会处理验证我们表单里的所有字段都是正确的。这不是

{{ post.text|linebreaks }}

{% endblock %} +``` 在`blog/urls.py`里我们添加这行: +```python url(r'^post/(?P[0-9]+)/edit/$', views.post_edit, name='post_edit'), +``` 我们将复用模板`blog/templates/blog/post_edit.html`,所以最后缺失的东西就是 *view*. 让我们打开`blog/views.py`,并在文件的最后加入: +```python def post_edit(request, pk): post = get_object_or_404(Post, pk=pk) if request.method == "POST": @@ -291,16 +330,21 @@ Django会处理验证我们表单里的所有字段都是正确的。这不是 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)`,然后当我们创建了一个表单我们用一个`实例`来传递这篇文章,当我们想保存它: +```python form = PostForm(request.POST, instance=post) +``` 当我们只是打开这篇文章的表单来编辑时: +```python form = PostForm(instance=post) +``` 好,让我们来试试它是否可以工作!让我们先去`post_detail`页面。在右上角应该有一个编辑按钮: @@ -327,14 +371,18 @@ Django会处理验证我们表单里的所有字段都是正确的。这不是 在 `blog/templates/blog/base.html`中,找到我们 `page-header` `div` 和你早些时候在放那里锚点标记。看起来应该像这样: +```html +``` 我们要将另一个 `{% if %}` 标记到这, 这会使链接仅在以管理者身份登录的用户访问时显示。现在来说,管理员就是你! 像这样修改 `` 标记: +```html {% if user.is_authenticated %} {% endif %} +``` 这个 `{% if %}` 会使得链接仅仅发送到哪些已经登陆的用户的浏览器。 这并不能完全保护发布新文章,不过这是很好的第一步。 我们将在扩展课程中包含更多安全部分。 @@ -347,23 +395,28 @@ Django会处理验证我们表单里的所有字段都是正确的。这不是 * 首先,提交你的新代码,然后将它推送到 Github 上 + +``` $ git status $ git add -A . $ git status $ git commit -m "Added views to create/edit blog post inside the site." $ git push +``` * 然后,在一个 [PythonAnywhere 的 Bash 终端][7]里运行: [7]: https://www.pythonanywhere.com/consoles/ +``` $ cd my-first-blog $ source myvenv/bin/activate (myvenv)$ git pull [...] (myvenv)$ python manage.py collectstatic [...] +``` * 最后,跳到 [Web 标签页][8] 并点击**重新载入**. diff --git a/zh/django_installation/README.md b/zh/django_installation/README.md index 997ccc3640c..03e24e663cb 100755 --- a/zh/django_installation/README.md +++ b/zh/django_installation/README.md @@ -2,4 +2,4 @@ > **注意**如果你已完成了安装步骤,可以直接进入下一章。 -{% include "django_installation/instructions.md" %} \ No newline at end of file +{% include "/django_installation/instructions.md" %} diff --git a/zh/django_templates/README.md b/zh/django_templates/README.md index 4f4021daaf7..30363d0feb6 100755 --- a/zh/django_templates/README.md +++ b/zh/django_templates/README.md @@ -14,7 +14,9 @@ 为了用模板标签在HTML中显示变量, 我们会使用两个大括号, 并将变量包含在里面,正如这样 +```html {{ posts }} +``` 在你的 `blog/templates/blog/post_list.html` 文件中进行如下的操作。 将所有 `
` to the third `
` 中的 to the third 用 `{{ posts }}` 代替。 并保存文件,刷新页面后去看看我们做的那些改变。 @@ -25,15 +27,19 @@ 如你所见,我们得到如下: +``` [, ] +``` 这意味着Django视它为对象的列表。 还记得在 **Python入门介绍** 里我们怎么展现列表的吗? 是的, 我们可以使用循环! 在dajngo模板中使用循环去遍历它们。如下所示: +```html {% for post in posts %} {{ post }} {% endfor %} - +``` + 在你的模板里试试这个。 @@ -43,6 +49,7 @@ 它工作了! 但是想让他们展现的像我们之前在**HTML介绍**章节里创建的静态文章一样 你可以混合HTML和模板标签。 我们的`body`将长得像这样: +```html @@ -54,6 +61,7 @@

{{ post.text|linebreaks }}

{% endfor %} +``` {% raw %}所有的在`{% for %}` 和 `{% endfor %}` 之间的内容将会被Django对象列表中的每个对象所代替。刷新页面去看看:{% endraw %} @@ -70,6 +78,7 @@ * 首先,我们将我们的代码放到Github +``` $ git status [...] $ git add -A . @@ -78,15 +87,18 @@ $ git commit -m "Modified templates to display posts from database." [...] $ git push +``` * 然后,重新登陆 [PythonAnywhere][4] 并进入**Bash 控制台** (或重开一个),并运行: [4]: https://www.pythonanywhere.com/consoles/ +``` $ cd my-first-blog $ git pull [...] +``` * 最后, 我们返回 [Web tab][5] 重新加载我们的应用程序, 此时我们应该可以看到更新后的程序运行情况了。 diff --git a/zh/extend_your_application/README.md b/zh/extend_your_application/README.md index c6decd59d8f..7221e96966d 100755 --- a/zh/extend_your_application/README.md +++ b/zh/extend_your_application/README.md @@ -12,6 +12,7 @@ 我们将从在`blog/templates/blog/post_list.html`里添加一个链接开始。目前它应该看起来像这样: +```html {% extends 'blog/base.html' %} {% block content %} @@ -25,12 +26,15 @@ {% endfor %} {% endblock content %} +``` {% raw %}我们在博文列表的博文标题处添加一个链接用于跳转到该博文的详细页面。 让我们编辑 `

{{ post.title }}

` 使得它能链接到博文详情页面:。{% endraw %} +```html

{{ post.title }}

+``` {% raw %}是解释神秘的 `{% url 'post_detail' pk=post.pk %}` 时候了。 正如你所猜想的,`{% %}`标记意味着我们正在使用Django模板标签。 这一次我们将使用一个能为我们创建URL的!{% endraw %} @@ -51,6 +55,7 @@ 让我们在 `blog/urls.py` 文件中增加一个 URL 来指引 Django 到名为 `post_detail` 的 *view*,它将用来显示整篇博客文章。 增加这行 `url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'),` 到 `blog/urls.py` 文件。 文件应当如下所示: +```python from django.conf.urls import include, url from . import views @@ -58,6 +63,7 @@ url(r'^$', views.post_list, name='post_list'), url(r'^post/(?P[0-9]+)/$', 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/`是完全OK的! - `/` - 然后我们再次需要 **/** - `$` - "结尾"! @@ -80,7 +86,9 @@ 现在,我们想要有一个并且只有一个博客帖子。为了做到这一点,我们需要使用下面的请求集合: +```python Post.objects.get(pk=pk) +``` 但是这段代码有一个问题。如果没有`Post`和给定`主键`(`pk`)我们将有一个非常丑陋的错误! @@ -101,14 +109,18 @@ 我们应该打开 `blog/views.py` 并添加以下代码: +```python from django.shortcuts import render, get_object_or_404 +``` 在 `from`附近 行。并在文件的末尾,我们将增加我们的 *view*: +```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/ @@ -131,6 +143,7 @@ 它看起来会像这样: +```python {% extends 'blog/base.html' %} {% block content %} @@ -144,6 +157,7 @@

{{ post.text|linebreaks }}

{% endblock %} +``` 现在,我们要扩展 `base.html`。 在`content` 块中,我们想要显示一篇文章的published_date (如果存在的话), 标题和文本。 但我们应该讨论一些重要的东西,对不对吗? @@ -162,23 +176,27 @@ 你的网站如果还能在 PythonAnywhere 正常运转就好了,对吧?让我们再次部署。 +``` $ git status $ git add -A . $ git status $ git commit -m "Added view and template for detailed blog post as well as CSS for the site." $ git push +``` * 然后,在一个 [PythonAnywhere 的 Bash 终端][8]里运行: [8]: https://www.pythonanywhere.com/consoles/ +``` $ cd my-first-blog $ source myvenv/bin/activate (myvenv)$ git pull [...] (myvenv)$ python manage.py collectstatic [...] +``` * 最后,跳到 [Web 标签页][9] 并点击**重新载入**. diff --git a/zh/installation/README.md b/zh/installation/README.md index 5730cbf9b19..0e86f174312 100755 --- a/zh/installation/README.md +++ b/zh/installation/README.md @@ -14,19 +14,19 @@ # 安装Python -{% include "python_installation/instructions.md" %} +{% include "/python_installation/instructions.md" %} # 配置 virtualenv 与安装 Django -{% include "django_installation/instructions.md" %} +{% include "/django_installation/instructions.md" %} # 安装一个代码编辑器 -{% include "code_editor/instructions.md" %} +{% include "/code_editor/instructions.md" %} # 安装 Git -{% include "deploy/install_git.md" %} +{% include "/deploy/install_git.md" %} # 创建一个 Github 账户 @@ -34,7 +34,7 @@ # 创建一个 PythonAnywhere 帐户 -{% include "deploy/signup_pythonanywhere.md" %} +{% include "/deploy/signup_pythonanywhere.md" %} # 开始阅读 @@ -46,4 +46,4 @@ * [Python 简介](../intro_to_command_line/README.md) - * [Django 是什么?](../django/README.md) \ No newline at end of file + * [Django 是什么?](../django/README.md) diff --git a/zh/python_installation/README.md b/zh/python_installation/README.md index 596f7d82250..399fa3d1182 100755 --- a/zh/python_installation/README.md +++ b/zh/python_installation/README.md @@ -10,4 +10,4 @@ Python 起源于 1980 年代后期,该语言的重要目标是源代码的人 > 需要说明的是,如果你已经熟悉Python的安装步骤,那你就无需看这章,直接跳到下一章好了。 -{% include "python_installation/instructions.md" %} \ No newline at end of file +{% include "/python_installation/instructions.md" %} diff --git a/zh/template_extending/README.md b/zh/template_extending/README.md index 81a97485698..0baf96575b5 100755 --- a/zh/template_extending/README.md +++ b/zh/template_extending/README.md @@ -10,15 +10,18 @@ 让我们创建一个`base.html`文件到`blog/templates/blog/`: +``` blog └───templates └───blog base.html post_list.html +``` 然后将它打开,从`post_list.html`中复制所有东西到`base.html`文件,就像这样: +```html {% load staticfiles %} @@ -50,10 +53,12 @@ +``` 然后在`base.html`中,替换你所有的 ``(所有的在`` 和 ``之间的内容)像这样: +```html +``` 用如下内容替换所有在 `{% for post in posts %}{% endfor %}`之间的代码: +```html {% block content %} {% endblock %} +``` 这是什么意思呢? 你刚刚创建了一个`block(块)`,这个模板标签允许你在其中插入扩展自`base.html`的模板的HTML代码。 我们一会儿将给你展示这个如何使用。 现在保存它,然后再次打开你的`blog/templates/blog/post_list.html`。 删除一切body外的代码,然后删除 ``,此时文件会看起来像这样: +```html {% for post in posts %}
@@ -88,15 +97,19 @@

{{ post.text|linebreaks }}

{% endfor %} +``` 然后现在将这行加到文件的开始: +```html {% extends 'blog/base.html' %} +``` {% raw %}这意味着我们在 `post_list.html`模板文件中扩展了 `base.html` 模板的内容。 还有一件事:将所有(除了我们刚刚加入的那行) 内容置于`{% block content %}`和 `{% endblock content %}`之间。。 像这样:{% endraw %} +```html {% extends 'blog/base.html' %} {% block content %} @@ -110,6 +123,7 @@
{% endfor %} {% endblock content %} +``` 好了,就是它了!检查你的网站还能正常工作:) diff --git a/zh/whats_next/README.md b/zh/whats_next/README.md index 256df79d8cd..72f6744d804 100755 --- a/zh/whats_next/README.md +++ b/zh/whats_next/README.md @@ -19,7 +19,15 @@ [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] +稍后,你可以试试利用以下的资源。 他们非常值得推荐啊! +- [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/ @@ -28,4 +36,5 @@ [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 \ No newline at end of file + [11]: http://twoscoopspress.com/products/two-scoops-of-django-1-8 +