Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# AfroPython Tutorial

Esse tutorial é uma modificação do [tutorial original](https://tutorial.djangogirls.org/pt/) disponível na página do Django Girls.
O tutorial original pode ser dividido em duas partes: preparação do ambiente e trabalho direto com programação e Python. Mas a primeira parte, a instalação dos programas, era difícil e costumava dar vários tipos de erro, então, nos últimos eventos, temos optado por usar o Codeanywhere (leia mais sobre ele no próximo capítulo!). Por isso o tutorial precisou ser levemente adaptado, tirando partes desnecessárias ou que causavam problema no Codeanywhere.
O tutorial original pode ser dividido em duas partes: preparação do ambiente e trabalho direto com programação e Python. Mas a primeira parte, a instalação dos programas, era difícil e costumava dar vários tipos de erro, então, nos últimos eventos, temos optado por usar o Sourcelair (leia mais sobre ele no próximo capítulo!). Por isso o tutorial precisou ser levemente adaptado, tirando partes desnecessárias ou que causavam problema no Sourcelair.
Mas não se preocupe, o objetivo final continua o mesmo! Você vai sair da oficina com seu blog no ar e uma ótima introdução ao mundo da programação!
28 changes: 14 additions & 14 deletions amplie_sua_aplicacao/amplie_sua_aplicacao.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ blog/templates/blog/post_list.html

`blog.views.post_detail` é um caminho para uma *view* `post_detail` que queremos criar. Preste atenção: `blog` é o nome da sua aplicação (o diretório `blog`), `views` vem do nome do arquivo `views.py` e, a última parte - `post_detail` - é o nome da *view*.

Agora quando formos para: `http://<<sua_url>>.codeanyapp.com:8080/` teremos um erro (como esperado, já que não temos uma URL ou uma *view* para `post_detail`). Vai se parecer com isso:
Agora quando formos para sua página inicial, teremos um erro (como esperado, já que não temos uma URL ou uma *view* para `post_detail`). Vai se parecer com isso:

![NoReverseMatch error](images/no-reverse-match-error.png)

Expand All @@ -48,34 +48,34 @@ Agora quando formos para: `http://<<sua_url>>.codeanyapp.com:8080/` teremos um e

Vamos criar a URL em `urls.py` para a nossa *view* `post_detail`!

Nós queremos que nosso primeiro detalhe de postagem seja exibido através dessa **URL**: http://<<sua_url>>.codeanyapp.com:8080/post/1/
Nós queremos que nosso primeiro detalhe de postagem seja exibido através dessa **URL**: http://<<sua_url>>/post/1/

Vamos criar uma URL no arquivo `blog/urls.py` para direcionar o Django para uma *view* de nome `post_detail`, que irá exibir uma postagem de blog completa. Adicione a linha `url(r'^post/(?P<pk>\d+)/$', views.post_detail, name='post_detail'),` ao arquivo `blog/urls.py`. O arquivo deve ficar dessa forma:
Vamos criar uma URL no arquivo `blog/urls.py` para direcionar o Django para uma *view* de nome `post_detail`, que irá exibir uma postagem de blog completa. Adicione a linha `path(r'^post/(?P<pk>\d+)/$', views.post_detail, name='post_detail'),` ao arquivo `blog/urls.py`. O arquivo deve ficar dessa forma:

blog/urls.py
```p
from django.conf.urls import url
from . import views
```
from django.urls import path
from blog import views

urlpatterns = [
url(r'^$', views.post_list),
url(r'^post/(?P<pk>[0-9]+)/$', views.post_detail, name='post_detail'),
path('', views.post_list),
path(r'^post/(?P<pk>[0-9]+)/$', views.post_detail, name='post_detail')
]

```

O trecho ``^post/(?P<pk>\d+)/$`` parece assustador, mas não se preocupe – nós iremos explicar ele para você:
- ele começa com `^` novamente - "o início".
- `post/` apenas significa que após o início, a URL deve ter a palavra __post__ e um __/__. Até aqui, tudo bem.
- `(?P<pk>\d+)` - essa parte é mais complicada. Isso significa que o Django vai pegar tudo que você colocar aqui e transferir para uma view através de uma variável chamada `pk`. `\d` também nos diz que só pode ser um número, não uma letra (tudo entre 0 e 9). `+` significa que precisa existir um ou mais dígitos. Então, algo como `http://<<sua_url>>.codeanyapp.com:8080/post//`, não é válido, mas `http://<<sua_url>>.codeanyapp.com:8080/post/1234567890/` é perfeitamente ok!
- `(?P<pk>\d+)` - essa parte é mais complicada. Isso significa que o Django vai pegar tudo que você colocar aqui e transferir para uma view através de uma variável chamada `pk`. `\d` também nos diz que só pode ser um número, não uma letra (tudo entre 0 e 9). `+` significa que precisa existir um ou mais dígitos. Então, algo como `http://<<sua_url>>/post//`, não é válido, mas `http://<<sua_url>>/post/1234567890/` é perfeitamente ok!
- `/` - então precisamos de um __/__ outra vez.
- `$` - "o fim"!

Isso significa que, se você digitar `http://<<sua_url>>.codeanyapp.com:8080/post/5/` em seu navegador, Django vai entender que você está procurando uma *view* chamada `post_detail` e transferir a informação de que `pk` é igual a `5` para aquela *view*.
Isso significa que, se você digitar `http://<<sua_url>>/post/5/` em seu navegador, Django vai entender que você está procurando uma *view* chamada `post_detail` e transferir a informação de que `pk` é igual a `5` para aquela *view*.

`pk` é uma abreviação para `primary key` (chave primária). Esse é o nome geralmente usado nos projetos feitos em Django. Mas você pode dar o nome que quiser às variáveis (lembre-se: minúsculas e `_` ao invés de espaços em branco!). Por exemplo em vez de `(?P<pk>\d+)` podemos ter uma variável `post_id`, então esta parte ficaria como: `(?P<post_id>\d+)`.

OK, nós adicionamos um novo padrão de URL ao `blog/urls.py`! Vamos atualizar a página: `http://<<sua_url>>.codeanyapp.com:8000/` Boom! O servidor parou de funcionar novamente. Dê uma olhada no console – como esperado, temos outro erro!

![AttributeError](images/attribute-error.png)
OK, nós adicionamos um novo padrão de URL ao `blog/urls.py`! Vamos atualizar a página: `http://<<sua_url>>` Boom! O servidor parou de funcionar novamente. Dê uma olhada no console – como esperado, temos outro erro!

Você se lembra qual é o próximo passo? Claro: adicionar uma view!

Expand Down Expand Up @@ -120,7 +120,7 @@ def post_detail(request, pk):
return render(request, 'blog/post_detail.html', {'post': post})
```

Sim. Está na hora de atualizar a página: http://<<sua_url>>.codeanyapp.com:8080/
Sim. Está na hora de atualizar sua página inicial.

![Post list view](images/listando-postagens.png)

Expand Down
2 changes: 1 addition & 1 deletion css/bootstrap.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ blog/templates/blog/post_list.html
Isso não adiciona nenhum arquivo ao seu projeto. O código apenas aponta para arquivos que existem na internet. Apenas siga em frente, abra seu site e atualize a página. Veja como está!


![Página usando Bootstrap](bootstrap.png)
![Página usando Bootstrap](images/bootstrap.png)
Já parece mais bonito!
3 changes: 1 addition & 2 deletions css/estaticos_do_django.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ Django já sabe onde encontrar os arquivos estáticos para o app padrão "admin"

Fazemos isso através da criação de uma pasta chamada `static` dentro do aplicativo do blog:

afropython
├── blog
│ ├── migrations
│ ├── static
│ └── templates
└── mysite
└── afropython


Django encontrará automaticamente todas as pastas chamadas "static" dentro de qualquer uma das pastas dos seus apps, e será capaz de usar seu conteúdo como arquivos estáticos.
11 changes: 6 additions & 5 deletions css/primeiro_arquivo_css.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

Vamos criar um arquivo CSS agora, para adicionar seu próprio estilo para sua página da web. Crie um novo diretório chamado `css` dentro de seu diretório `static`. Em seguida, crie um novo arquivo chamado `blog.css` dentro do diretório `css`. Pronto?

afropython
└─── blog
└─── static
└─── css
└─── blog.css
blog
└─── static
└─── css
└─── blog.css


Hora de escrever CSS! Abra o arquivo `static/css/blog.css` no seu editor de código.
Expand Down Expand Up @@ -80,6 +79,8 @@ blog/templates/blog/post_list.html

OK, salve o arquivo e atualize o site!

> Dica: se nada acontecer, tente reinicar o servidor. Abra a Command Pallete pelo ícone no menu lateral, procure por `Restart Server` e aperte Enter.

![Blog com as cores do AfroPython](images/blog-com-cores-afropython.png)

Bom trabalho! Talvez a gente também queira dar um pouco de ar ao nosso site e aumentar a margem do lado esquerdo? Vamos tentar!
Expand Down
2 changes: 1 addition & 1 deletion estendendo_templates/estendendo_templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,4 @@ blog/templates/blog/post_list.html

É isso! Veja se o seu site ainda está funcionando direito :)

> Se ocorrer um erro de `TemplateDoesNotExists`, que diz que não existe nenhum arquivo chamado `blog/base.html` e se você tiver o `runserver` executando no terminal, tenta interrompê-lo (precionando Ctrl+C - o botão Control mais o botão C juntos) e reinicie ele rodando o comando `python3 manage.py runserver 0.0.0.0`.
> Se ocorrer um erro de `TemplateDoesNotExists`, que diz que não existe nenhum arquivo chamado `blog/base.html`, tente reiniciar o servidor. Abra a Command Pallete pelo ícone no menu lateral, procure por `Restart Server` e aperte Enter.
Binary file added formularios/botao_editar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions formularios/editando_formularios.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Em `blog/urls.py` adicionamos esta linha:

blog/urls.py
```python
url(r'^post/(?P<pk>\d+)/edit/$', views.post_edit, name='post_edit'),
path(r'^post/(?P<pk>\d+)/edit/$', views.post_edit, name='post_edit'),
```

Nós reutilizaremos o modelo `blog/templates/blog/post_edit.html`, então a última coisa que falta é uma *view*.
Expand Down Expand Up @@ -73,11 +73,11 @@ form = PostForm(instance=post)

Ok, vamos testar se funciona! Vamos para a página `post_detail`. Deve haver um botão editar no canto superior direito:

![Botão editar](edit_button2.png)
![Botão editar](botao_editar.png)

Quando você clicar nele você verá o formulário com a nossa postagem:

![Editando o formulário](edit_form2.png)
![Editando o formulário](editar.png)

Sinta-se livre para mudar o título ou o texto e salvar as mudanças!

Expand Down
Binary file added formularios/editar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion formularios/introducao.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,4 @@ blog/templates/blog/base.html
</html>
```

Depois de salvar e recarregar a página `http://<<sua_url>>.codeanyapp.com:8080/` você verá, obviamente, um erro familiar: `NoReverseMatch`, certo?
Depois de salvar e recarregar sua página, você verá um erro familiar: `NoReverseMatch`, certo?
Binary file added formularios/novo_post.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 2 additions & 4 deletions formularios/salvando_formularios.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,8 @@ def post_new(request):
return render(request, 'blog/post_edit.html', {'form': form})
```

Vamos ver se funciona. Vá para o página `http://<<sua_url>>.codeanyapp.com:8080/post/new/`, adicione um `title` e o `text`, salve... e voilà! O novo blog post é adicionado e nós somos redirecionados para a página de `post_detail`!
Vamos ver se funciona. Vá para o página `http://<<sua_url>>/post/new/`, adicione um `title` e o `text`, salve... e voilà! O novo blog post é adicionado e nós somos redirecionados para a página de `post_detail`!

Isso é incrível!

> Como nós recentemente usamos a interface de administração do Django, o sistema ainda pensa que nós estamos "logados". Existem algumas situações que poderiam nos levar a estar "deslogados" (fechando o browser, reiniciando o banco de dados, etc.). Se, durante a criação de uma postagem, você perceber que está recebendo erros referentes a falta de um usuário "logado", vá para a página de administração http://<<sua_url>>.codeanyapp.com:8080/admin e faça o login novamente. Isso resolverá o problema temporariamente.

![Erro de login](post_create_error.png)
> Como nós recentemente usamos a interface de administração do Django, o sistema ainda pensa que nós estamos "logados". Existem algumas situações que poderiam nos levar a estar "deslogados" (fechando o browser, reiniciando o banco de dados, etc.). Se, durante a criação de uma postagem, você perceber que está recebendo erros referentes a falta de um usuário "logado", vá para a página de administração http://<<sua_url>>/admin e faça o login novamente. Isso resolverá o problema temporariamente.
6 changes: 2 additions & 4 deletions formularios/template.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ Precisamos criar um arquivo `post_edit.html` na pasta `blog/templates/blog`. Pra
- Temos que exibir o formulário. Podemos fazer isso com (por exemplo) um simplesmente {% raw %}`{{ form.as_p }}`{% endraw %}.
- A linha acima precisa estar entre as tags HTML form: `<form method="POST">...</form>`
- Precisamos de um botão `Salvar`. Fazemos isso com um botão HTML: `<button type="submit">Save</button>`
- E finalmente, depois de abrir a tag `<form ...>` precisamos adicionar um {% raw %}`{% csrf_token %}`{% endraw %}. Isso é muito importante, pois faz com que nosso formulário seja seguro! O Django vai reclamar se você esquecer de adicionar isso e tentar salvar o formulário:

![CSFR Página Proibida](csrf2.png)
- E finalmente, depois de abrir a tag `<form ...>` precisamos adicionar um {% raw %}`{% csrf_token %}`{% endraw %}. Isso é muito importante, pois faz com que nosso formulário seja seguro! O Django vai reclamar se você esquecer de adicionar isso e tentar salvar o formulário.

Beleza, então vamos ver como ficou o HTML `post_edit.html`:

Expand All @@ -26,7 +24,7 @@ blog/templates/blog/post_edit.html

Hora de atualizar! Há! Seu formulário apareceu!

![Formulário novo](new_form2.png)
![Formulário novo](novo_post.png)

Mas, espere um minuto! Quando você digita alguma coisa nos campos `title` e `text` e tenta salvar, o que acontece?

Expand Down
12 changes: 6 additions & 6 deletions formularios/url_e_views.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ Vamos abrir o arquivo `blog/urls.py` e escrever:

blog/urls.py
```python
url(r'^post/new/$', views.post_new, name='post_new'),
path(r'^post/new/$', views.post_new, name='post_new'),
```

O código final deve se parecer com isso:

blog/urls.py
```python
from django.conf.urls import url
from . import views
from django.urls import path
from blog import views

urlpatterns = [
url(r'^$', views.post_list, name='post_list'),
url(r'^post/(?P<pk>\d+)/$', views.post_detail, name='post_detail'),
url(r'^post/new/$', views.post_new, name='post_new'),
path('', views.post_list),
path(r'^post/(?P<pk>[0-9]+)/$', views.post_detail, name='post_detail'),
path(r'^post/new/$', views.post_new, name='post_new'),
]
```

Expand Down
Binary file added formularios/validacao.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion formularios/validacao_formularios.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ Agora, nós lhe mostraremos como os formulários são legais. A postagem do blog

Tente salvar o formulário sem `title` e `text`. Adivinhe o que vai acontecer!

![Validação de formulário](form_validation2.png)
![Validação de formulário](validacao.png)

Django está tomando conta da validação de todos os campos de nosso formulário, certificando que estão corretos. Não é incrível?
2 changes: 1 addition & 1 deletion linha_de_comando/basico.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# O básico

Cada sistema operacional tem o seu próprio conjunto de instruções para a linha de comando, mas no codeanywhere usamos um sistema Linux.
Cada sistema operacional tem o seu próprio conjunto de instruções para a linha de comando, mas no sourcelair usamos um sistema Linux.

Para informações de outros sistemas, acesse [Introdução à linha de comando](https://tutorial.djangogirls.org/pt/intro_to_command_line/) do [Tutorial Django Girls](https://tutorial.djangogirls.org/pt/).
2 changes: 1 addition & 1 deletion linha_de_comando/resumo.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Aqui vai uma lista de alguns comandos úteis:

| Comando (Windows)|Comando (MacOS/Linux/Codeanywhere)| Descrição | Exemplo |
| Comando (Windows)|Comando (MacOS/Linux/Sourcelair)| Descrição | Exemplo |
|:----------------:|:-------------------:| -------------- |--------------|
| exit | exit | Fecha a janela | **exit** |
| cd | cd | Muda a pasta | **cd teste** |
Expand Down