` 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
-
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 `
`). 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 `
-```
-
+ ```
-Maintenant, ajouter la classe `post` à votre `div` contenant votre blog post.
+Maintenant, ajoutez la classe `post` à votre `div` contenant votre blog post.
-```
+```html
```
-
-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/nomdutilisateur1>/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/0>. 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 ``
+* 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 `
{% 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 %}
-
{% 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 %}
{% 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 `
` 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 `
```
+{% 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
-
-
-
Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.
Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut f.
-
-
-
-
+Voici un exemple de template utilisant plusieurs balises :
+
+```html
+
+
+ Django Girls blog
+
+
+
Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.
Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut 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: `
+ {% 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
+
+```
+
+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
+
+
+
+
+
+
+
+
+
+```
+
+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ó `
+{% 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 `
{% 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文件里,我们的`