Tutorial Django Parte 6: Lista genérica e detail views - Aprendendo desenvolvimento web

Tutorial Django Parte 6: Lista genérica e detail views
======================================================

* Anterior
* Menu: Django
* Próxima

Este tutorial estende nosso website LocalLibrary, adicionando páginas de lista e detalhes para livros e autores. Aqui, aprenderemos sobre visualizações genéricas baseadas em classe e mostraremos como elas podem reduzir a quantidade de código que você precisa escrever para casos de uso comuns. Também abordaremos o tratamento de URLs em mais detalhes, mostrando como executar a correspondência básica de padrões.

|  |  |
| --- | --- |
| Pré-requisitos: |
 Conclua todos os tópicos do tutorial anterior, incluindo
 Django Tutorial Part 5: Creating our home page.
  |
| Objetivo: |
 Para entender onde e como usar modos de exibição genéricos baseados em
 classe e como extrair padrões de URLs e passar as informações para modos
 de exibição.
  |

Visão global
------------

Neste tutorial, vamos concluir a primeira versão do website LocalLibrary adicionando páginas de lista e detalhes de livros e autores (ou, para ser mais preciso, mostraremos como implementar as páginas do livro e você mesmo irá criar as páginas dos autores!)

O processo é semelhante à criação da página index, que mostramos no tutorial anterior. Ainda precisamos criar mapas de URL, views e templates. A principal diferença é que, para as páginas de detalhes, teremos o desafio adicional de extrair informações de padrões no URL e passá-las para a visualização. Para essas páginas, demonstraremos um tipo de exibição completamente diferente: lista genérica baseada em classe e exibições detalhadas. Isso pode reduzir significativamente a quantidade de código de visualização necessária, facilitando a gravação e a manutenção.

A parte final do tutorial demonstrará como paginar seus dados ao usar visualizações de lista genéricas baseadas em classe.

Book list page
--------------

A página da lista de livros exibirá uma lista de todos os registros de livros disponíveis na página, acessados usando o URL: `catalog/books/`. A página exibirá um título e um autor para cada registro, com o título sendo um hiperlink para a página de detalhes do livro associada. A página terá a mesma estrutura e navegação que todas as outras páginas do site e, portanto, podemos estender o modelo base (**base\_generic.html**) que criamos no tutorial anterior.

### URL mapping

Abra **/catalog/urls.py** e copie na linha mostrada em negrito abaixo. Quanto à página index, a função `path()` define um padrão para corresponder ao URL (**'books/'**), a função view que será chamado se o URL corresponder (`views.BookListView.as_view()`), e um nome para esse mapeamento específico.

```python
urlpatterns = [
    path('', views.index, name='index'),
    path('books/', views.BookListView.as_view(), name='books'),
]
```

Conforme discutido no tutorial anterior, o URL já deve ter correspondencia `/catalog`, então a visualização será realmente chamada para o URL: `/catalog/books/`.

A função view tem um formato diferente do que antes - é porque essa view será realmente implementada como uma classe. Herdaremos de uma função view genérica existente que já faz a maior parte do que queremos que essa função view faça, em vez de escrever a nossa a partir do zero.

Para as class-based views do Django, acessamos uma função de visualização apropriada chamando o método de classe `as_view()`. Isso faz todo o trabalho de criar uma instância da classe e garantir que os métodos do manipulador certo sejam chamados para solicitações HTTP recebidas.

### View (class-based)

Poderíamos escrever com facilidade a view da lista de livros como uma função regular (assim como a view index anterior), que consultaria todos os livros no banco de dados e depois chamaria `render()` para passar a lista para um modelo especificado. No entanto, usaremos uma view de lista genérica class-based (`ListView`) — uma classe que herda de uma view existente. Como a view genérica já implementa a maioria das funcionalidades necessárias e segue as práticas recomendadas do Django, poderemos criar uma exibição de lista mais robusta com menos código, menos repetições e, finalmente, menos manutenção.

Abra **catalog/views.py**, e copie o seguinte código na parte inferior do arquivo:

```python
from django.views import generic

class BookListView(generic.ListView):
    model = Book
```

É isso aí! A view genérica consultará o banco de dados para obter todos os registros para o modelo especificado (`Book`) em seguida, renderize um template localizado em **/locallibrary/catalog/templates/catalog/book\_list.html** (que criaremos abaixo). Dentro do template, você pode acessar a lista de livros com a variável de template denominada `object_list` OU `book_list` (i.e. genericamente "`the_model_name_list`").

**Nota:** Esse caminho estranho para a localização do template não é um erro de impressão - as visualizações genéricas procuram modelos em `/application_name/the_model_name_list.html` (`catalog/book_list.html` nesse caso) dentro do aplicativo `/application_name/templates/` diretório (`/catalog/templates/)`.

Você pode adicionar atributos para alterar o comportamento padrão acima. Por exemplo, você pode especificar outro arquivo do template se precisar ter várias visualizações que usem esse mesmo modelo ou se desejar usar um nome de variável de template diferente se `book_list` não é intuitivo para o seu caso de uso de template específico. Possivelmente, a variação mais útil é alterar/filtrar o subconjunto de resultados retornados - portanto, em vez de listar todos os livros, você pode listar os cinco principais livros que foram lidos por outros usuários.

```python
class BookListView(generic.ListView):
    model = Book
    context_object_name = 'my\_book\_list'   # your own name for the list as a template variable
    queryset = Book.objects.filter(title__icontains='war')[:5] # Get 5 books containing the title war
    template_name = 'books/my\_arbitrary\_template\_name\_list.html'  # Specify your own template name/location
```

#### Substituindo métodos em class-based views

Embora não precisemos fazer isso aqui, você também pode substituir alguns dos métodos da classe.

Por exemplo, podemos substituir o método `get_queryset()` para alterar a lista de registros retornados. Isso é mais flexível do que apenas definir o atributo `queryset` como fizemos no fragmento de código anterior (embora não haja nenhum benefício real neste caso):

```python
class BookListView(generic.ListView):
    model = Book

    def get\_queryset(self):
        return Book.objects.filter(title__icontains='war')[:5] # Get 5 books containing the title war
```

Também podemos substituir `get_context_data()` para passar variáveis de contexto adicionais para o template (por exemplo, a lista de livros é passada por padrão). O fragmento abaixo mostra como adicionar uma variável chamada "`some_data`" para o contexto (estaria disponível como uma variável de template).

```python
class BookListView(generic.ListView):
    model = Book

    def get\_context\_data(self, \*\*kwargs):
        # Call the base implementation first to get the context
        context = super(BookListView, self).get_context_data(\*\*kwargs)
        # Create any data and add it to the context
        context['some\_data'] = 'This is just some data'
        return context
```

Ao fazer isso, é importante seguir o padrão usado acima:

* Primeiro obtenha o contexto existente da nossa superclasse.
* Em seguida, adicione as novas informações de contexto.
* Em seguida, retorne o novo contexto (atualizado).

**Nota:** Confira Built-in class-based generic views (Django docs) para muitos mais exemplos do que você pode fazer.

### Criando o template List View

Crie o arquivo HTML **/locallibrary/catalog/templates/catalog/book\_list.html** e copie o texto abaixo. Como discutido acima, este é o arquivo de template padrão esperado pela list view genérica da class-based view (para um modelo chamado `Book` em um aplicativo chamado `catalog`).

Os templates para visualizações genéricas são como qualquer outro template (*embora*, é claro, o contexto/informações passadas para o template possam ser diferentes). Assim como em nosso template *index*, estendemos nosso template base na primeira linha e substituímos o bloco denominado `content`.

```django
{% extends "base\_generic.html" %}

{% block content %}
  <h1>Book List</h1>
  {% if book\_list %}
  <ul>
    {% for book in book\_list %}
      <li>
        <a href="{{ book.get\_absolute\_url }}">{{ book.title }}</a> ({{book.author}})
      </li>
    {% endfor %}
  </ul>
  {% else %}
    <p>There are no books in the library.</p>
  {% endif %}
{% endblock %}
```

A view passa o contexto (lista de livros), por padrão, um `object_list` e `book_list` aliases; qualquer um funcionará.

#### Execução conditional

Nós usamos o `if`, `else`, e `endif` template tags para verificar se o `book_list` foi definido e não está vazio. E se `book_list` está vazio, então a cláusula `else` exibe o texto explicando que não há livros para listar. E se `book_list` não estiver vazio, percorreremos a lista de livros.

```django
{% if book\_list %}
  <!-- code here to list the books -->
{% else %}
  <p>There are no books in the library.</p>
{% endif %}
```

A condição acima verifica apenas um caso, mas você pode testar em condições adicionais usando a template tag `elif` (e.g. `{% elif var2 %}`). Para obter mais informações sobre operadores condicionais, consulte: if, ifequal/ifnotequal, e ifchanged em Built-in template tags and filters (Django Docs).

#### For loops

O template usa as template tags for e `endfor` para percorrer a lista de livros, como mostrado abaixo. Cada iteração preenche a variável de template `book` com informações para o item da lista atual.

```django
{% for book in book\_list %}
  <li><!-- code here get information from each book item --></li>
{% endfor %}
```

Embora não seja usado aqui, dentro do loop, o Django também criará outras variáveis que você pode usar para rastrear a iteração. Por exemplo, você pode testar a variável `forloop.last` para executar o processamento condicional na última vez em que o loop é executado.

#### Acessando variáveis

O código dentro do loop cria um item de lista para cada livro que mostra o título (como um link para a exibição de detalhes ainda a ser criada) e o autor.

```html
<a href="{{ book.get\_absolute\_url }}">{{ book.title }}</a> ({{book.author}})
```

Acessamos os *campos* do registro de livro associado usando a "notação de ponto" (e.g. `book.title` e `book.author`), onde o texto após o item `book` é o nome do campo (conforme definido no modelo).

Também podemos chamar *funções* no modelo de dentro do nosso template - nesse caso, chamamos `Book.get_absolute_url()` para obter um URL que você pode usar para exibir o registro de detalhe associado. Isso funciona desde que a função não tenha argumentos (não há como passar argumentos!)

**Nota:** Temos que ter um pouco de cuidado com os "efeitos colaterais" ao chamar funções em templates. Aqui apenas exibimos um URL, mas uma função pode fazer praticamente qualquer coisa - não queremos excluir nosso banco de dados (por exemplo) apenas renderizando nosso template!

#### Atualize o template base

Abra o template base (**/locallibrary/catalog/templates/*base\_generic.html***) e insira **{% url 'books' %}** no link da URL para **All books**,como mostrado abaixo. Isso habilitará o link em todas as páginas (podemos colocá-lo em prática agora que criamos o mapeador de URL "books").

```python
<li><a href="{% url 'index' %}">Home</a></li>
<li><a href="{% url 'books' %}">All books</a></li>
<li><a href="">All authors</a></li>
```

### Com o que se parece?

Ainda não será possível criar a lista de livros, porque ainda falta uma dependência - o mapa de URL para as páginas de detalhes do livro, necessário para criar hiperlinks para livros individuais. Mostraremos as visualizações de lista e de detalhes após a próxima seção.

Pagina Book detail
------------------

A página book detail exibirá informações sobre um livro específico, acessado usando o URL `catalog/book/<id>` (onde `<id>` é a chave primária do livro). Além dos campos no model `Book` (author, summary, ISBN, language, e genre), também listaremos os detalhes das cópias disponíveis (`BookInstances`) incluindo o status, data prevista de retorno, impressão e ID. Isso permitirá que nossos leitores não apenas saibam sobre o livro, mas também confirmem se/quando ele está disponível.

### URL mapping

Abra **/catalog/urls.py** e adicione a URL '**book-detail**' mostrado em negrito abaixo. Esta função `path()` define um padrão, exibição de detalhes genérica associada à classe associada e um nome.

```python
urlpatterns = [
    path('', views.index, name='index'),
    path('books/', views.BookListView.as_view(), name='books'),
    path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail'),
]
```

Para o path *book-detail* o padrão de URL usa uma sintaxe especial para capturar o ID específico do livro que queremos ver. A sintaxe é muito simples: colchetes angulares definem a parte da URL a ser capturada, incluindo o nome da variável que a view pode usar para acessar os dados capturados. Por exemplo, **<something>** , capturará o padrão marcado e passará o valor para a visualização como uma variável "alguma coisa". Opcionalmente, você pode preceder o nome da variável com um converter specification que define o tipo de dados (int, str, slug, uuid, path).

Neste caso, usamos `'<int:pk>'` para capturar o ID do livro, que deve ser uma sequência especialmente formatada e passá-la para a view como um parâmetro chamado `pk` (abreviatura de primary key). Esta é a id que está sendo usado para armazenar o livro exclusivamente no banco de dados, conforme definido no Book Model.

**Nota:** Como discutido anteriormente, nosso URL correspondente é realmente `catalog/book/<digits>` (porque estamos no aplicativo de **catalog**, `/catalog/` é assumido).

**Aviso:** **Importante**: A view de detalhes genérica class-based *espera* receber um parâmetro chamado **pk**. Se você estiver escrevendo sua própria função view, poderá usar o nome de qualquer parâmetro que desejar, ou mesmo transmitir as informações em um argumento sem nome.

#### Correspondência avançada de caminhos/iniciador de expressão regular

**Nota:** Você não precisará desta seção para concluir o tutorial! Nós fornecemos isso porque conhecer essa opção provavelmente será útil no seu futuro centrado no Django.

The pattern matching provided by `path()` is simple and useful for the (very common) cases where you just want to capture *any* string or integer. If you need more refined filtering (for example, to filter only strings that have a certain number of characters) then you can use the re\_path() method.

This method is used just like `path()` except that it allows you to specify a pattern using a Regular expression. For example, the previous path could have been written as shown below:

```python
re_path(r'^book/(?P<pk>\d+)$', views.BookDetailView.as_view(), name='book-detail'),
```

*Regular expressions* are an incredibly powerful pattern mapping tool. They are, frankly, quite unintuitive and scary for beginners. Below is a very short primer!

The first thing to know is that regular expressions should usually be declared using the raw string literal syntax (i.e. they are enclosed as shown: **r'<your regular expression text goes here>'**).

The main parts of the syntax you will need to know for declaring the pattern matches are:

| Symbol | Meaning |
| --- | --- |
| ^ | Match the beginning of the text |
| $ | Match the end of the text |
| \d | Match a digit (0, 1, 2, ... 9) |
| \w | Match a word character, e.g. any upper- or lower-case character in the alphabet, digit or the underscore character (\_) |
| + | Match one or more of the preceding character. For example, to match one or more digits you would use `\d+`. To match one or more "a" characters, you could use `a+` |
| \* | Match zero or more of the preceding character. For example, to match nothing or a word you could use `\w*` |
| ( ) | Capture the part of the pattern inside the brackets. Any captured values will be passed to the view as unnamed parameters (if multiple patterns are captured, the associated parameters will be supplied in the order that the captures were declared). |
| (?P<*name*>...) | Capture the pattern (indicated by ...) as a named variable (in this case "name"). The captured values are passed to the view with the name specified. Your view must therefore declare an argument with the same name! |
| [ ] | Match against one character in the set. For example, [abc] will match on 'a' or 'b' or 'c'. [-\w] will match on the '-' character or any word character. |

Most other characters can be taken literally!

Let's consider a few real examples of patterns:

| Pattern | Description |
| --- | --- |
| **r'^book/(?P<pk>\d+)$'** | This is the RE used in our URL mapper. It matches a string that has `book/` at the start of the line (**^book/**), then has one or more digits (`\d+`), and then ends (with no non-digit characters before the end of line marker).It also captures all the digits **(?P<pk>\d+)** and passes them to the view in a parameter named 'pk'. \*\*The captured values are always passed as a string!\*\*For example, this would match `book/1234` , and send a variable `pk='1234'` to the view. |
| **r'^book/(\d+)$'** | This matches the same URLs as the preceding case. The captured information would be sent as an unnamed argument to the view. |
| **r'^book/(?P<stub>[-\w]+)$'** | This matches a string that has `book/` at the start of the line (**^book/**), then has one or more characters that are *either* a '-' or a word character (**[-\w]+**), and then ends. It also captures this set of characters and passes them to the view in a parameter named 'stub'.This is a fairly typical pattern for a "stub". Stubs are URL-friendly word-based primary keys for data. You might use a stub if you wanted your book URL to be more informative. For example `/catalog/book/the-secret-garden` rather than `/catalog/book/33`. |

You can capture multiple patterns in the one match, and hence encode lots of different information in a URL.

**Nota:** Como desafio, considere como você pode codificar um URL para listar todos os livros lançados em um determinado ano, mês, dia e o RE que poderia ser usado para correspondê-lo.

#### Passando opções adicionais em seus mapas de URL

Um recurso que não usamos aqui, mas que você pode achar valioso, é que você pode declarar e passar opções adicionais para a view. As opções são declaradas como um dicionário que você passa como o terceiro argumento sem nome para a função `path()`. Essa abordagem pode ser útil se você desejar usar a mesma visualização para vários recursos e transmitir dados para configurar seu comportamento em cada caso (abaixo, fornecemos um modelo diferente em cada caso).

```python
path('url/', views.my_reused_view, {'my\_template\_name': 'some\_path'}, name='aurl'),
path('anotherurl/', views.my_reused_view, {'my\_template\_name': 'another\_path'}, name='anotherurl'),
```

**Nota:** As opções extras e os padrões capturados nomeados são passados para a view como argumentos *nomeados*. Se você usar o **mesmo nome** para um padrão capturado e uma opção extra, somente o valor do padrão capturado será enviado para a visualização (o valor especificado na opção adicional será descartado).

### View (class-based)

Abra **catalog/views.py**, e copie o seguinte código na parte inferior do arquivo:

```python
class BookDetailView(generic.DetailView):
    model = Book
```

É isso aí! Tudo o que você precisa fazer agora é criar um modelo chamado **/locallibrary/catalog/templates/catalog/book\_detail.html**, e a visualização passará as informações do banco de dados para o registro `Book` extraído pelo mapeador de URL. Dentro do modelo, você pode acessar a lista de livros com a variável de modelo denominada `object` ou `book` (i.e. genericamente "`the_model_name`").

Se necessário, você pode alterar o template usado e o nome do objeto de contexto usado para referenciar o livro no template. Você também pode substituir métodos para, por exemplo, adicionar informações adicionais ao contexto.

#### O que acontece se o registro não existir?

Se um registro solicitado não existir, a view de detalhes genérica class-based levantará uma exceção `Http404` para você automaticamente — em produção, isso exibirá automaticamente uma página apropriada de "resource not found", que você pode personalizar se desejar.

Apenas para lhe dar uma idéia de como isso funciona, o fragmento de código abaixo demonstra como você implementaria a exibição baseada em classe como uma função se você não estivesse usando a view de detalhe genérica class-based.

```python
def book\_detail\_view(request, primary_key):
    try:
        book = Book.objects.get(pk=primary_key)
    except Book.DoesNotExist:
        raise Http404('Book does not exist')

    return render(request, 'catalog/book\_detail.html', context={'book': book})
```

A view tenta primeiro obter o registro de livro específico do modelo. Se isso falhar, a view deve gerar uma exceção `Http404` para indicar que o livro "não foi encontrado". A etapa final é, como sempre, chamar `render()` com o nome do template e os dados do livro no parâmetro `context` (como um dicionário).

Como alternativa, podemos usar a função `get_object_or_404()` como um atalho para levantar uma exceção `Http404` se o registro não for encontrado.

```python
from django.shortcuts import get_object_or_404

def book\_detail\_view(request, primary_key):
    book = get_object_or_404(Book, pk=primary_key)
    return render(request, 'catalog/book\_detail.html', context={'book': book})
```

### Criando o template Detail View

Crie o arquivo HTML **/locallibrary/catalog/templates/catalog/book\_detail.html** e forneça o conteúdo abaixo. Conforme discutido acima, este é o nome do arquivo de template padrão esperado pela view de *detalhes* genérica class-based (para um modelo chamado `Book` no aplicativo chamado `catalog`).

```django
{% extends "base\_generic.html" %}

{% block content %}
  <h1>Title: {{ book.title }}</h1>

  <p><strong>Author:</strong> <a href="">{{ book.author }}</a></p> <!-- author detail link not yet defined -->
  <p><strong>Summary:</strong> {{ book.summary }}</p>
  <p><strong>ISBN:</strong> {{ book.isbn }}</p>
  <p><strong>Language:</strong> {{ book.language }}</p>
  <p><strong>Genre:</strong> {% for genre in book.genre.all %} {{ genre }}{% if not forloop.last %}, {% endif %}{% endfor %}</p>

  <div style="margin-left:20px;margin-top:20px">
    <h4>Copies</h4>

    {% for copy in book.bookinstance\_set.all %}
      <hr>
      <p class="{% if copy.status == 'a' %}text-success{% elif copy.status == 'm' %}text-danger{% else %}text-warning{% endif %}">{{ copy.get\_status\_display }}</p>
      {% if copy.status != 'a' %}
        <p><strong>Due to be returned:</strong> {{copy.due\_back}}</p>
      {% endif %}
      <p><strong>Imprint:</strong> {{copy.imprint}}</p>
      <p class="text-muted"><strong>Id:</strong> {{copy.id}}</p>
    {% endfor %}
  </div>
{% endblock %}
```

**Nota:** O link do autor no template acima tem um URL vazio porque ainda não criamos uma página de detalhes do autor. Uma vez que isso exista, você deve atualizar o URL assim:

```django
<a href="{% url 'author-detail' book.author.pk %}">{{ book.author }}</a>
```

Embora um pouco maior, quase tudo neste template foi descrito anteriormente:

* Estendemos nosso modelo básico e substituímos o bloco "content".
* Usamos o processamento condicional para determinar se deve ou não exibir conteúdo específico.
* Usamos `for` loops para percorrer as listas de objetos.
* Acessamos os campos de contexto usando a notação de ponto (porque usamos a exibição genérica detalhada, o contexto é chamado `book`; também poderíamos usar "`object`")

A única coisa interessante que não vimos antes é a função `book.bookinstance_set.all()`. Este método é "automagicamente" construído pelo Django para retornar o conjunto de registros `BookInstance` associados com um `Book` em particular.

```django
{% for copy in book.bookinstance\_set.all %}
  <!-- code to iterate across each copy/instance of a book -->
{% endfor %}
```

Este método é necessário porque você declara um campo `ForeignKey` (um-para-muitos) somente no lado "um" do relacionamento. Como você não faz nada para declarar o relacionamento nos outros modelos ("muitos"), ele não possui nenhum campo para obter o conjunto de registros associados. Para superar esse problema, o Django constrói uma função "pesquisa reversa" chamada de forma apropriada, que você pode usar. O nome da função é construído com letras minúsculas no nome do modelo em que o `ForeignKey` foi declarado, seguido por `_set` (i.e. então a função criada em `Book` é `bookinstance_set()`).

**Nota:** Aqui usamos `all()` para obter todos os registros (o padrão). Enquanto você pode usar o método `filter()` para obter um subconjunto de registros no código, não é possível fazer isso diretamente nos modelos, porque não é possível especificar argumentos para funções.

Observe também que, se você não definir um pedido (na sua class-based view ou modelo), também verá erros do servidor de desenvolvimento como este:
```

[29/May/2017 18:37:53] "GET /catalog/books/?page=1 HTTP/1.1" 200 1637
/foo/local_library/venv/lib/python3.5/site-packages/django/views/generic/list.py:99: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <QuerySet [<Author: Ortiz, David>, <Author: H. McRaven, William>, <Author: Leigh, Melinda>]>
  allow_empty_first_page=allow_empty_first_page, **kwargs)
```

Isso acontece porque o objeto paginator espera ver algum ORDER BY sendo executado no seu banco de dados subjacente. Sem ele, não é possível garantir que os registros que estão sendo retornados estejam na ordem certa!

Este tutorial não atingiu a **Paginação** (ainda, mas em breve), mas como você não pode usar `sort_by()` e passar um parâmetro (o mesmo com `filter()` descrito acima), você terá que escolher entre três opções:

1. Adicione um `ordering` dentro de uma declaração `class Meta` no seu model.
2. Adicione um atributo `queryset` na sua class-based view, especificando um `order_by()`.
3. Adicione um método `get_queryset` à sua class-based view personalisada e também especifique o `order_by()`.

Se você decidir ir com uma `class Meta` no model `Author` (provavelmente não tão flexível quanto personalizar o class-based view, mas fácil o suficiente), você terminará com algo assim:

```python
class Author(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    date_of_birth = models.DateField(null=True, blank=True)
    date_of_death = models.DateField('Died', null=True, blank=True)

    def get\_absolute\_url(self):
        return reverse('author-detail', args=[str(self.id)])

    def \_\_str\_\_(self):
        return f'{self.last\_name}, {self.first\_name}'

    class Meta:
        ordering = ['last\_name']
```

Obviamente, o campo não precisa ser `last_name`: poderia ser qualquer outro.

E por último, mas não menos importante, você deve classificar por um atributo/coluna que realmente tenha um índice (exclusivo ou não) em seu banco de dados para evitar problemas de desempenho. Obviamente, isso não será necessário aqui (e provavelmente estamos nos adiantando muito) com tão poucos livros (e usuários!), Mas é algo a ser lembrado em projetos futuros.

Com o que se parece agora?
--------------------------

Nesse ponto, deveríamos ter criado tudo o necessário para exibir a lista de livros e as páginas de detalhes do livro. Execute o servidor (`python3 manage.py runserver`) e abra no seu navegador `http://127.0.0.1:8000/`.

**Aviso:** Não clique em nenhum autor ou link de detalhes do autor ainda - você os criará no desafio!

Clique no link **All books** para exibir a lista de livros.

![Book List Page](/pt-BR/docs/Learn/Server-side/Django/Generic_views/book_list_page_no_pagination.png)

Em seguida, clique no link de um dos seus livros. Se tudo estiver configurado corretamente, você deverá ver algo como a seguinte captura de tela.

![Book Detail Page](/pt-BR/docs/Learn/Server-side/Django/Generic_views/book_detail_page_no_pagination.png)

Paginação
---------

Se você tiver apenas alguns registros, nossa página da lista de livros ficará bem. No entanto, à medida que você entra nas dezenas ou centenas de registros, a página levará progressivamente mais tempo para carregar (e terá muito conteúdo para navegar com sensatez). A solução para esse problema é adicionar paginação às exibições de lista, reduzindo o número de itens exibidos em cada página.

O Django possui excelente suporte embutido para paginação. Melhor ainda, isso é incorporado às exibições de lista genéricas baseadas em classes, para que você não precise fazer muito para habilitá-lo!

### Views

Abra **catalog/views.py**, e adicionea linha `paginate_by` mostrado em negrito abaixo.

```python
class BookListView(generic.ListView):
    model = Book
    paginate_by = 10
```

Com essa adição, assim que você tiver mais de 10 registros, a visualização começará a paginar os dados que envia para o modelo. As diferentes páginas são acessadas usando os parâmetros GET - para acessar a página 2, você usaria o URL: `/catalog/books/?page=2`.

### Templates

Agora que os dados estão paginados, precisamos adicionar suporte ao modelo para rolar pelo conjunto de resultados. Como podemos fazer isso em todas as visualizações de lista, faremos isso de uma maneira que possa ser adicionada ao modelo base.

Abra **/locallibrary/catalog/templates/*base\_generic.html*** e copie no seguinte bloco de paginação, abaixo do nosso bloco de conteúdo (destacado abaixo em negrito). O código primeiro verifica se a paginação está ativada na página atual. Nesse caso, adiciona os links seguintes e anteriores, conforme apropriado (e o número da página atual).

```django
{% block content %}{% endblock %}

{% block pagination %}
  {% if is\_paginated %}
    <div class="pagination">
      <span class="page-links">
        {% if page\_obj.has\_previous %}
          <a href="{{ request.path }}?page={{ page\_obj.previous\_page\_number }}">previous</a>
        {% endif %}
        <span class="page-current">
          Page {{ page\_obj.number }} of {{ page\_obj.paginator.num\_pages }}.
        </span>
        {% if page\_obj.has\_next %}
          <a href="{{ request.path }}?page={{ page\_obj.next\_page\_number }}">next</a>
        {% endif %}
      </span>
    </div>
  {% endif %}
{% endblock %}
```

O `page_obj` é um objeto de Paginator que existirá se a paginação estiver sendo usada na página atual. Permite obter todas as informações sobre a página atual, as páginas anteriores, quantas páginas existem, etc.

Usamos `{{ request.path }}` para obter o URL da página atual para criar os links de paginação. Isso é útil porque é independente do objeto que estamos paginando.

É isso aí!

### Com o que se parece agora?

A captura de tela abaixo mostra a aparência da paginação - se você não inseriu mais de 10 títulos no banco de dados, pode testá-lo com mais facilidade, abaixando o número especificado na linha `paginate_by` no seu arquivo **catalog/views.py**. Para obter o resultado abaixo, alteramos para `paginate_by = 2`.

Os links de paginação são exibidos na parte inferior, com os links seguinte/anterior, dependendo da página em que você está.

![Book List Page - paginated](/pt-BR/docs/Learn/Server-side/Django/Generic_views/book_list_paginated.png)

Challenge yourself
------------------

The challenge in this article is to create the author detail and list views required to complete the project. These should be made available at the following URLs:

* `catalog/authors/` — The list of all authors.
* `catalog/author/<id>` — The detail view for the specific author with a primary key field named `<id>`

The code required for the URL mappers and the views should be virtually identical to the `Book` list and detail views we created above. The templates will be different but will share similar behaviour.

**Nota:**

* Once you've created the URL mapper for the author list page you will also need to update the **All authors** link in the base template. Follow the same process as we did when we updated the **All books** link.
* Once you've created the URL mapper for the author detail page, you should also update the book detail view template (**/locallibrary/catalog/templates/catalog/book\_detail.html**) so that the author link points to your new author detail page (rather than being an empty URL). The line will change to add the template tag shown in bold below.

```django
<p>
  <strong>Author:</strong>
  <a href="{% url 'author-detail' book.author.pk %}">{{ book.author }}</a>
</p>
```

When you are finished, your pages should look something like the screenshots below.

![Author List Page](/pt-BR/docs/Learn/Server-side/Django/Generic_views/author_list_page_no_pagination.png)

![Author Detail Page](/pt-BR/docs/Learn/Server-side/Django/Generic_views/author_detail_page_no_pagination.png)

Summary
-------

Congratulations, our basic library functionality is now complete!

In this article, we've learned how to use the generic class-based list and detail views and used them to create pages to view our books and authors. Along the way we've learned about pattern matching with regular expressions, and how you can pass data from URLs to your views. We've also learned a few more tricks for using templates. Last of all we've shown how to paginate list views so that our lists are manageable even when we have many records.

In our next articles, we'll extend this library to support user accounts, and thereby demonstrate user authentication, permissons, sessions, and forms.

See also
--------

* Built-in class-based generic views (Django docs)
* Generic display views (Django docs)
* Introduction to class-based views (Django docs)
* Built-in template tags and filters (Django docs).
* Pagination (Django docs)
* Anterior
* Menu: Django
* Próxima


Introdução ao Django - Aprendendo desenvolvimento web

Introdução ao Django
====================

* Menu: Django
* Próxima

Neste primeiro artigo do Django, respondemos a pergunta "O que é o Django?" e daremos uma visão geral do que torna este framework web especial. Vamos descrever os principais recursos, incluindo algumas das funcionalidades avançadas que não teremos tempo para abordar detalhadamente neste módulo. Também mostraremos alguns dos principais blocos de construção de um aplicativo Django (embora neste momento você ainda não tenha um ambiente de desenvolvimento para testá-lo).

|  |  |
| --- | --- |
| Pré-requisitos: |
 Conhecimentos básicos em computação. Um entendimento geral de
 programação de websites do lado do servidor
 e, em particular, a mecânica de
 interações cliente-servidor em websites.
  |
| Objetivos: |
 Ganhar familiaridade com o que é o Django, quais funcionalidades ele
 fornece e os principais blocos de construção de uma aplicação django.
  |

O que é Django?
---------------

Django é um framework web Python de alto nível que permite o rápido desenvolvimento de sites seguros e de fácil manutenção. Construido por desenvolvedores experientes, o Django cuida de grande parte do trabalho de desenvolvimento web, para que você possa se concentrar em escrever seu aplicativo sem precisar reinventar a roda. É gratuito e de código aberto, tem uma comunidade próspera e ativa, ótima documentação e muitas opções de suporte gratuito e pago.

Django ajuda você a escrever programas que são:

Completo

Django segue a filosofia de "baterias incluídas" e fornece quase tudo que desenvolvedores possam querer fazer "fora da caixa". Como tudo o que você precisa é parte de um "produto", tudo funciona perfeitamente junto, seguindo princípios de design consistentes, contando uma extensa e atualizada documentação.

Versátil

Django pode ser (e tem sido) utilizado para construir quase todo tipo de website - desde sistema de gestão de conteúdo e wikis, passando por redes sociais e sites de notícias. Ele pode trabalhar com qualquer framework do lado do cliente, e pode entregar conteúdo em praticamente qualquer formato (incluindo HTML, feeds RSS, JSON, XML, etc). Esse site que você está lendo agora é baseado em Django.

À medida em que, internamente, fornece opções para quase todo tipo de funcionalidade que você possa querer (por exemplo: vários banco de dados que são populares, motores de template, etc), ele pode também ser extendido para utilizar outros componentes, caso seja necessário.

Seguro

Django ajuda os desenvolvedores a evitar os erros de segurança mais comuns, fornecendo um framework que foi desenhado para "fazer as coisas certas", de modo a proteger o website automaticamente. Por exemplo, Django fornece uma maneira segura de gerenciar as contas dos usuários e suas senhas, evitando erros comuns, tais como colocar informações da sessão em cookies, onde ficam vulneráveis (ao invés disso os cookies contém apenas uma chave e os dados são armazenados no banco de dados), ou armazenar as senhas de forma direta, ao invés de gravar um hash para essas senhas.

*Um hash de senha é um valor fixed-length (tamanho-fixo) criado mandando a senha por uma cryptographic hash function (função hash criptográfica). Django pode checar se uma senha inserida está correta executando ela pela função hash e comparando a saída com o valor hash armazenado. Porém devido a natureza "one-way" ("um-caminho") da função, mesmo que o valor hash armazenado estiver comprometido, é difcil para uma pessoa comentendo um ataque resolver a senha original.*

O Django ativa a proteção contra muitas vulnerabilidades por padrão, incluindo SQL injection (injeção de SQL), cross-site scripting, cross-site request forgery (Falsificação de solicitação entre sites), e clickjacking ("furto de click") (veja Segurança de sites para mais detalhes de tais ataques).

Escalável

Django usa uma arquitetura baseada em componentes "shared-nothing" ("nada-compartilhado") (cada parte da arquitetura é independente das outras, e consequentemente podem ser substituídas ou mudadas caso necessário). Ter uma separação clara entre as partes diferentes significa que pode se escalar para um tráfego aumentado adicionando hardware em qualquer nível: servidores de cache, servidores de banco de dados ou servidores de aplicação. Alguns dos sites mais ocupados escalaram o Django com sucesso para cumprir com as suas demandas (ex: Instagram e Disqus).

Sustentável

O código do Django é escrito usando princípios de design e padrões que encorajam a criação de codigo sustentável (que facilita a manutenção) e reusável. Em particular, isso utiliza o principio DRY - Don't Repeat Yourself (Não Repita a Si Mesmo) para que não haja duplicações desnecessárias, reduzindo a quantidade de código. O Django também promove o agrupamento de funcionalidades relacionadas para aplicativos reusáveis e, em um nível mais baixo, grupos de código relacionados para modulos (juntamente as linhas do padrão MVC - Model View Controller).

Portável

Django é escrito em Python, que executa em muitas plataformas. Isso significa que você não esta preso em nenhuma plataforma de servidor em particular, e pode executar seus aplicativos em muitas distrubuições do Linux, Windows e Mac OS X. Além disso, o Django tem um bom suporte em muitos provedores de servidores de web, que muitas vezes provem infraestrutura especifca e documentação para hospedar sites feitos com Django.

De onde o Django veio?
----------------------

Django foi inicialmente desenvolvido entre 2003 e 2005 por um time de web que era responsável por criar e manter sites de jornal. Depois de criar um número de sites, o time começou a fatorar e reutilizar muitos de seus códigos comuns e padrões de design. Esse código comum evoluiu para um framework genérico de desenvolvimento web, que foi lançado como um projeto de código aberto nomeado "Django" em Julho de 2005.

Django continou a crescer e aprimorar, desde seu lançamento (1.0) em Setembro de 2008 até a versão recentemente lançada 2.0 em 2017. Cada lançamento adicionou novas funcionalidades e consertou falhas, variando entre suportar novos tipos de banco de dados, mecanismos de template e caches, até a adição de funções view "genéricas" e classes (que reduzem a quantidade de código que os desenvolvedores tem que escrever para um número de tarefas de programação).

**Nota:** Cheque as notas de lançamento no site do Django para ver o que mudou nas versões mais recentes, e quanto trabalho esta sendo feito para tornar o Django melhor.

Django é um projeto de código aberto, colaborativo e próspero, com milhares de usuários contribuindo. Embora ainda tenha alguns recursos que refletem sua origem, Django evoluiu para um framework versátil que é capaz de desenvovler qualquer tipo de website.

Quão popular é o Django?
------------------------

Não há nenhum método disponível e definitivo para medir a popularidade dos framework server-side (lado do servidor) (apesar de sites como Hot Frameworks tentam acessar a popularidade usando mecanismos como contar o numero de projetos no GitHub e perguntas no StackOverflow para cada cada platafroma). Uma questão melhor é se o Django é "popular o suficiente" para evitar problemas de plataformas não populares. Ele continua a evoluir? Você consegue ajuda se precisar? Existem oportunidades para você ganhar dinheiro se voce aprender Django?

Baseado no número de sites com alto perfil que usam Django, o número de pessoas contribuindo para a base de código, e o número de pessoas provendo ambos suporte gratuito e pago, então sim, Django é um framework popular!

Alguns sites de alto perfil que usam Django são: Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic, Open Knowledge Foundation, Pinterest, and Open Stack (fonte: Página inicial do django).

O Django é opinativo?
---------------------

Frameworks de web frequentemente referem a si mesmos como "opinativo" e "não opinativo".

Frameworks opinativos são aqueles com opiniões sobre o "modo correto" de como lidar com uma tarefa em particular. Eles frequentemente auxiliam no desenvolvimento rapido *em um domínio em particular* (resolvendo problemas de um tipo em particular) porque o modo correto de fazer qualquer coisa normalmente já foi bem compreendido e bem documentado. Porém eles podem ser menos flexíveis para resolver problemas fora de seu principal domínio, e tendem a oferecer menos opções para quais componentes e abordagens eles podem usar.

Frameworks não opinativos, em contraste, possuem bem menos restrições sobre a melhor maneira de unir os componentes para atingir um objetivo, ou até mesmo quais componentes devem ser usados. Eles tornam mais fácil para os desenvolvedores usar as ferramentas mais adequadas para completar uma tarefa em particular, apesar do custo de você mesmo ter que achar esses componentes.

Django é "moderadamente opinativo" e, portantanto, oferece o "melhor dos dois mundo". Ele fornece um conjunto de componentes para lidar com a maioria das tarefas de desenvolvimento web, e uma (ou duas) maneiras preferidas de usá-las. No entanto, a arquitetura desacoplada do Django significa que você geralmente pode escolher entre várias opções diferentes, ou adicionar suporte para outras completamente novas, se desejar.

Com o que o código do Django parece?
------------------------------------

Em um site data-driven (orientado a dados) tradicional, um aplicativo web aguarda solicitações HTTP do navegador da web (ou outro cliente). Quando uma solicitação é recebida, o aplicativo calcula o que é necessário com base na URL e possivelmente nas informações dos dados `POST` ou `GET`. Dependendo do que for necessário, ele poderá ler ou gravar informações de um banco de dados ou executar outras tarefas necessárias para satisfazer a solicitação. O aplicativo retornará uma resposta para o navegador da web, normalmente criando dinamicamente uma página HTML para o navegador exibir, inserindo os dados recuperados em espaços reservados em um template HTML.

Aplicativos web feitos com Django geralmente agrupam o código que manipula cada uma dessas etapas em arquivos separados:

![](https://i.postimg.cc/W4yzpVcd/arq.png)

* **URLs:** Embora seja possível processar solicitações de cada URL por meio de uma única função, é muito mais simples fazer a manutenção do código escrevendo uma função view (vista) separada para manipular cada recurso. Um mapeador de URLs é usado para redirecionar solicitações HTTP para a view apropriada com base na URL da solicitação. O mapeador de URLs também pode corresponder padrões específicos de strings (cadeia de caracteres) ou dígitos que aparecem em um URL e transmiti-los a uma função view como dados.
* **View (Vista):** Uma view é uma função manipuladora de solicitações, que recebe solicitações HTTP e retorna respostas HTTP. As views acessam os dados necessários para satisfazer solicitações por meio dos *models (modelos)* e encarregam a formatação da resposta aos *templates*.
* **Models (Modelos):** Modelos são objetos em Python que definem a estrutura dos dados de um aplicativo, e fornecem mecanismos para gerenciar (adicionar, modificar e excluir) e consultar registros no banco de dados.
* **Templates:** Um template é um arquivo de texto que define a estrutura ou o layout de um arquivo (como uma página HTML), com espaços reservados usados para representar o conteúdo real. Uma *view* pode criar dinamicamente uma página HTML usando um template HTML, preenchendo-a com dados de um *model (modelo)*. Um template pode ser usado para definir a estrutura de qualquer tipo de arquivo; não precisa ser HTML!

**Nota:** Django refere a essa organização como uma arquitetura nomeada "Model View Template (MVT)" ("Modelo Vista Template"). Ela tem muitas semelhanças com a familiar arquitetura Model View Controller (Modelo Vista Controlador).

As seções abaixo lhe darão uma idéia de como essas partes principais de um aplicativo do Django se parecerão (nos vamos entrar em mais detalhes mais tarde no curso, assim que configurarmos um ambiente de desenvolvimento).

### Enviando a solicitação para a view correta (urls.py)

Um mapeador de URLs normalmente é armazenado em um arquivo chamado **urls.py**. No exemplo abaixo, o mapeador (`urlpatterns`) (*padrões de url*) define uma lista de mapeamentos entre *rotas* (*padrões* específicos de URL) e funções view correspondentes. Se uma solicitação HTTP for recebida com uma URL correspondente a um padrão especificado, a função view associada será chamada e a solicitação/requisição sera transmitida.
```

urlpatterns = [
    path('admin/', admin.site.urls),
    path('book/<int:id>/', views.book-detail, name='book-detail'),
    path('catalog/', include('catalog.urls')),
    re_path(r'^([0-9]+)/$', views.best),
]

# favor utilizar o código acima no seu projeto ao invés do que está abaixo
# urlpatterns = [
#     path('admin/', admin.site.urls),
#     path('livro/<int:id>/', views.livro-detalhes, name='livro-detalhes'),
#     path('catalogo/', include('catalogo.urls')),
#     re_path(r'^([0-9]+)/$', views.melhor),
# ]
```

O objeto `urlpatterns` é uma lista de funções `path()` (caminhos) e/ou `re_path()` (listas em Python são definidas usando colchetes, onde os itens são separados por vírgulas e podem conter opcionalmente uma vírgula no final. Por exemplo: **`[item1, item2, item3,]`**).

O primeiro argumento para ambos os métodos é uma rota (padrão) que será correspondida. O método `path()` usa sinais de menor e maior (<, >) para definir partes de uma URL que serão capturadas e passadas para a função view como argumentos nomeados. A função `re_path()` usa uma abordagem de correspondência de padrões flexível, conhecida como expressão regular. Nós vamos falar sobre isso em um artigo posterior!

O segundo argumento é outra função que será chamada quando o padrão for correspondido. A notação `views.book-detail` (`views.livro-detalhes`) indica que a função é chamada de `book-detail()` (`livro-detalhes()`) e pode ser encontrada em um módulo chamado `views` (ou seja, dentro de um arquivo chamado `views.py`)

### Manipulando a solicitação (views.py)

As view são o coração do aplicativo web, recebendo solicitações HTTP de clientes da web e retornando respostas HTTP. No meio disto, eles preparam os outros recursos do framework para acessar bancos de dados, renderizar (exibir) templates, etc.

O exemplo abaixo mostra uma função view mínima chamada `index()`, que poderia ter sido chamado pelo nosso mapeador de URLs na seção anterior. Como todas as funções *view*, ele recebe um objeto `HttpRequest` como um parâmetro (`request`) e retorna um objeto `HttpResponse`. Nesse caso, não fazemos nada com a solicitação, e nossa resposta simplesmente retorna uma string. Mostraremos uma solicitação que faz algo mais interessante em uma seção posterior.

```python
## filename: views.py (Django view functions)

from django.http import HttpResponse

def index(request):
    # Get an HttpRequest - the request parameter
    # perform operations using information from the request.
    # Return HttpResponse
    return HttpResponse('Hello from Django!')

# favor utilizar o código acima no seu projeto ao invés do que está abaixo
## nome do arquivo: views.py (Onde as funções view ficam)

from django.http import HttpResponse

def index(requisito):
    # Recebe um HttpRequest - o parametro requisito
    # Executar operações usando informações do requisito (solicitação).
    # Retornar HttpResponse
    return HttpResponse('Um oi do Django!')
```

**Nota:** Um pouquinho de Python:

* Módulos do Python são "bibliotecas" de funções, armazenadas em arquivos separados, que podemos utilizar em nosso código. Aqui nós importamos apenas o objeto `HttpResponse` do módulo `django.http` para que possamos usá-lo em nossa view: `from django.http import HttpResponse`. Existem outras maneiras de importar alguns ou todos os objetos de um módulo.
* As funções em Python são declaradas usando a palavra-chave `def` como mostrado acima, com parâmetros nomeados listados entre parênteses após o nome da função; a linha inteira termina em dois pontos. Observe como as próximas linhas são todas **recuadas**. O recuo é importante, pois especifica que as linhas de código estão dentro desse bloco específico (a indentação obrigatória é um recurso chave do Python e é um dos motivos pelos quais o código Python é tão fácil de ler).

Views geralmente são armazenadas em um arquivo chamado **views.py**.

### Definindo o modelo dos dados (models.py)

Os aplicativos web feitos com Django gerenciam e consultam dados por meio de objetos do Python chamados de modelos. Os modelos definem a estrutura dos dados armazenados, incluindo os *tipos* do campo e possivelmente também seu tamanho máximo, valores padrão, opções de lista de seleção, texto de ajuda para documentação, texto de etiqueta (label) para formulários etc. A definição do modelo é independente do banco de dados subjacente — você pode escolher um dentre vários como parte das configurações do seu projeto. Uma vez que você escolheu qual banco de dados você quer usar, você não precisa se comunicar diretamente com ele — você apenas escreve a estrutura dos seus modelos e qualquer outro código, e o Django lida com todo o trabalho de se comunicar com o banco de dados para você.

O trecho de código abaixo mostra um modelo simples do Django para um objeto `Team` (Time). A classe `Team` é derivada da classe do Django `models.Model`. Ela define o nome e o nível da equipe como campos de caractere e especifica um número máximo de caracteres a serem armazenados para cada registro. O `team_level` (time\_nivel) pode ser um de vários valores, portanto, o definimos como um campo de opção e fornecemos um mapeamento entre as opções a serem exibidas e os dados a serem armazenados, junto com um valor padrão.

```python
## filename: models.py

from django.db import models

class Team(models.Model):
    team_name = models.CharField(max_length=40)

    TEAM_LEVELS = (
        ('U09', 'Under 09s'),
        ('U10', 'Under 10s'),
        ('U11', 'Under 11s'),
        ...  #list other team levels
    )

    team_level = models.CharField(max_length=3,choices=TEAM_LEVELS,default='U11')

# favor utilizar o código acima no seu projeto ao invés do que está abaixo
## nome do arquivo: models.py

from django.db import models

class Time(models.Model):
    # models.CharField define um campo de caractere no banco de dados e max\_length define o tamanho maximo permitido
    time_nome = models.CharField(max_length=40)

    TIME_NIVEIS = (
        ('A09', 'Abaixo de 09'),
        ('A10', 'Abaixo de 10'),
        ('A11', 'Abaixo de 11'),
        ... #list other team levels
    )

    time_nivel = models.CharField(max_length=3,choices=TIME_NIVEIS,default='A11') # choices-opções / default-padrão
```

**Nota:** Um pouquinho de Python:

* O Python suporta "programação orientada a objetos", um estilo de programação onde organizamos nosso código em objetos, que incluem dados e funções relacionadas para operar nesses dados. Os objetos também podem herdar/estender/derivar de outros objetos, permitindo que um comportamento comum entre objetos relacionados seja compartilhado. Em Python, usamos a palavra-chave `class` (classe) para definir o "blueprint" (modelo/planta/plano) de um objeto. Podemos criar várias *instâncias* específicas do tipo de objeto com base no modelo da classe.
 Por exemplo, aqui temos uma classe `Team` (Time), que deriva da classe `Model`. Isso significa que é um modelo e conterá todos os métodos de um modelo, mas também podemos fornecer recursos especializados próprios. Em nosso modelo, definimos os campos que nosso banco de dados precisará para armazenar nossos dados, dando-lhes nomes específicos. O Django usa essas definições, incluindo os nomes dos campos, para criar o banco de dados subjacente.

### Consultando dados (views.py)

O modelo Django fornece uma query API simples para buscas no banco de dados. Isto pode combinar com um grande número de campos ao mesmo tempo utilizando diversos critérios (ex.: exato, maiúsculas e minúsculas (case-sensitive), maior que, etc.), e pode suportar definições complexas (por exemplo, você pode especificar a busca por times U11 que tem os nomes começando com 'Fr" ou terminando com "al").

O trecho de código mostra uma função da View (manipulador de recursos) para exibir todos os nossos times U09. A linha em negrito mostra como podemos usar a API modelo de consulta para filtrar todos os registros em que o campo `team_level` possui exatamente o texto 'U09' (observe como esse critério é passado para a função `filter()` com o argumento no campo de nome e o tipo de busca de correspondência (**exact**) separado por um sublinhado duplo: **`team_level__exact`**).

```python
## filename: views.py

from django.shortcuts import render
from .models import Team

def index(request):
    list_teams = Team.objects.filter(team_level__exact="U09")
    context = {'youngest\_teams': list_teams}
    return render(request, '/best/index.html', context)

# favor utilizar o código acima no seu projeto ao invés do código abaixo
## nome do arquivo: views.py

from django.shortcuts import render
from .models import Team

def index(request):
    lista_times = Team.objects.filter(team_level__exact="U09")
    contexto = {'times\_jovens': lista_times}
    return render(request, '/best/index.html', contexto)
```

A função `index()` usa a função `render()` para criar o `HttpResponse` que é enviado de volta para o navegador. Essa função é um atalho, ela cria um arquivo HTML combinando um modelo HTML específico com alguns dados (fornecidos pela variável denominada "`context`"). Na próxima seção, mostramos como os dados são inseridos no modelo para criar HTML.

### Renderizando dados (Modelos HTML)

O sistema de modelo permite especificar a estrutura de um documento de saída, usando espaços reservados para dados que serão preenchidos quando uma página for gerada. Os modelos geralmente são usados para criar HTML, mas também podem criar outros tipos de documentos. O Django suporta o sistema de modelos nativo e outra biblioteca Python popular chamada Jinja2 pronta para uso (também pode ser feita para suportar outros sistemas, se necessário).

O trecho de código mostra a aparência do modelo HTML chamado pela função `render()` na seção anterior. Este modelo foi escrito sob a premissa de que ele terá acesso a uma variável do tipo lista chamada `youngest_teams` quando for renderizada (contida na variável `context` dentro da função `render()` acima). Dentro do esqueleto HTML, temos um a expressão que primeiro verifica se a variável `youngest_teams` existe e a itera em um loop `for`. Em cada iteração, o modelo exibe o valor `team_name` de cada equipe em um elemento `<li>`.

```python
## filename: best/templates/best/index.html

<!DOCTYPE html>
<html lang="en">
<body>

 {% if youngest_teams %}
    <ul>
    {% for team in youngest_teams %}
        <li>{{ team.team_name }}</li>
    {% endfor %}
    </ul>
{% else %}
    <p>No teams are available.</p>
{% endif %}

</body>
</html>

#favor utilizar o código acima no seu projeto ao invés do código abaixo
## nome do arquivo: best/templates/best/index.html

<!DOCTYPE html>
<html lang="pt">
<body>

 {% if youngest_teams %}
    <ul>
     {% for team in youngest_teams %}
         <li>{{ team.team_name }}</li>
     {% endfor %}     </ul> {% else %}
     <p>Nenhum time disponível.</p>
 {% endif %}
 </body>
 </html>
```

O que mais você pode fazer?
---------------------------

As seções anteriores mostram os principais recursos que você usará na maioria dos aplicativos Web: mapeamento de URL, views, moldes e modelos. O Django também fornece outras coisas, como:

* **Formulários (Forms)**: Os formulários HTML são usados para coletar dados do usuário para processamento no servidor. Django simplifica a criação, validação e processamento de formulários.
* **Autenticação de usuário e permissões**: Django inclui um sistema robusto de autenticção e permissão de usuário, construído com a segurança em mente.
* **Caching**: Criar conteúdo dinamicamente é muito mais pesado (e lento) computacionalmente do que exibir conteúdo estático. O Django fornece armazenamento em cache flexível para que você possa armazenar toda ou parte de uma página pronta para que ela não seja renderizada novamente, exceto quando necessário.
* **Site de administração**: O site de administração do Django é incluído por padrão quando você cria um aplicativo usando o esqueleto básico. Ele facilita o fornecimento de uma página de administração para os administradores do site criarem, editarem e exibirem quaisquer modelos de dados em seu site
* **Serializando dados**: O Django facilita a serialização e a veiculação de dados como XML ou JSON. Isso pode ser útil ap criar um serviço Web (um site que serve apenas para que dados sejam consumidos por outros aplicativos ou sites e não exibe nada por si só), ou ao criar um site no qual o código do lado do cliente lida com todas as renderizações.
Resumo
------

Parabéns, você completou o primeiro passo em sua jornada no Django! Agora você deve entender os principais benefícios do Django, um pouco sobre sua história e aproximadamente como podem ser as partes principais de um aplicativo Django. Você também deve ter aprendido algumas coisas sobre a linguagem de programação Python, incluindo a sintaxe para listas, funções e classes.

Você já viu algum código real do Django acima, mas, diferentemente do código do lado do cliente, você precisa configurar um ambiente de desenvolvimento para executá-lo. Esse é o nosso próximo passo.

* Menu: Django
* Próxima


CSS layout - Aprendendo desenvolvimento web

CSS layout
==========

Neste ponto, vimos os fundamentos do CSS, como estilizar o texto e como estilizar e manipular as caixas dentro das quais seu conteúdo se encontra. Agora é hora de ver como organizar corretamente suas caixas em relação à viewport, bem como umas às outras. Cobrimos os pré-requisitos necessários, então vamos nos aprofundar no layout CSS, examinando vários recursos como: diferentes configurações de exibição, posicionamento, ferramentas de layout modernas como flexbox e grade CSS e algumas das técnicas herdadas que você ainda pode querer saber. cerca de.

>
> **Callout:**
>
>
> #### Quer se tornar um desenvolvedor web front-end?
>
>
>
>  Reunimos um curso que inclui todas as informações essenciais que você precisa para
>  trabalhe em direção ao seu objetivo.
>
>
>
> **Primeiros passos**
>
>
>

Pré-requisitos
--------------

Antes de iniciar este módulo, você já deve:

1. Ter familiaridade básica com HTML, conforme discutido no módulo Introdução ao HTML.
2. Esteja familiarizado com os fundamentos do CSS, conforme discutido em Introdução ao CSS.
3. Entenda como estilizar caixas.

**Nota:** Se você estiver trabalhando em um computador/tablet/outro dispositivo em que não tenha a capacidade de criar seus próprios arquivos, experimente (a maioria) os exemplos de código em um programa de codificação on-line, como como JSBin ou Glitch.

Guias
-----

Esses artigos fornecerão instruções sobre as ferramentas e técnicas de layout fundamentais disponíveis em CSS. No final das lições, há uma avaliação para ajudá-lo a verificar sua compreensão dos métodos de layout ao criar uma página da web.

Introdução ao layout CSS

Este artigo irá recapitular alguns dos recursos de layout CSS que já abordamos em módulos anteriores — como valores `display` diferentes — e apresentar alguns dos conceitos que abordaremos ao longo deste módulo.

Fluxo normal

Os elementos nas páginas da Web se apresentam de acordo com o *fluxo normal* - até que façamos algo para mudar isso. Este artigo explica os fundamentos do fluxo normal como base para aprender como alterá-lo.

Flexbox

Flexbox (en-US) é um método de layout unidimensional para dispor itens em linhas ou colunas. Os itens se flexionam para preencher espaço adicional e encolhem para caber em espaços menores. Este artigo explica todos os fundamentos. Depois de estudar este guia, você pode testar suas habilidades em flexbox (en-US) para verificar sua compreensão antes de prosseguir.

Grids (en-US)

CSS Grid Layout é um sistema de layout bidimensional para a web. Ele permite que você organize o conteúdo em linhas e colunas e tem muitos recursos que facilitam a criação de layouts complexos. Este artigo fornecerá tudo o que você precisa saber para começar com o layout de página e testar suas habilidades de grade (en-US) antes de prosseguir.

Floats (en-US)

Originalmente para imagens flutuantes dentro de blocos de texto, a propriedade `float` tornou-se uma das ferramentas mais usadas para criar layouts de múltiplas colunas em páginas da web. Com o advento do Flexbox e do Grid, ele voltou ao seu propósito original, como explica este artigo.

Posicionamento (en-US)

O posicionamento permite retirar elementos do fluxo normal do layout do documento e fazer com que se comportem de maneira diferente, por exemplo, posicionando-se uns sobre os outros ou permanecendo sempre no mesmo lugar dentro da janela de visualização do navegador. Este artigo explica os diferentes valores `position` e como usá-los.

Layout de várias colunas

A especificação de layout de várias colunas fornece um método de disposição de conteúdo em colunas, como você pode ver em um jornal. Este artigo explica como usar esse recurso.

Design responsivo

À medida que tamanhos de tela mais diversos apareceram em dispositivos habilitados para a Web, surgiu o conceito de web design responsivo (RWD): um conjunto de práticas que permite que as páginas da Web alterem seu layout e aparência para se adequar a diferentes larguras de tela, resoluções etc. É uma ideia que mudou a forma como projetamos para uma web multidispositivo, e neste artigo vamos te ajudar a entender as principais técnicas que você precisa saber para dominá-la.

Guia do iniciante para consultas de mídia (en-US)

A **CSS Media Query** oferece uma maneira de aplicar CSS somente quando o navegador e o ambiente do dispositivo correspondem a uma regra que você especifica, por exemplo, "a janela de visualização é maior que 480 pixels". Consultas de mídia são uma parte fundamental do web design responsivo porque permitem criar diferentes layouts dependendo do tamanho da viewport. Eles também podem ser usados para detectar outros recursos do ambiente em que seu site está sendo executado, por exemplo, se o usuário está usando uma tela sensível ao toque em vez de um mouse. Nesta lição, você aprenderá primeiro sobre a sintaxe usada em consultas de mídia e, em seguida, as usará em um exemplo interativo que mostra como um design simples pode se tornar responsivo.

Métodos de layout legados (en-US)

Os sistemas de grade são um recurso muito comum usado em layouts CSS. Antes do **CSS Grid Layout**, eles tendiam a ser implementados usando flutuadores ou outros recursos de layout. Você primeiro imaginaria seu layout como um número definido de colunas (por exemplo, 4, 6 ou 12) e, em seguida, ajustaria suas colunas de conteúdo dentro dessas colunas imaginárias. Neste artigo, exploraremos como esses métodos antigos funcionam para que você entenda como eles eram usados se você trabalhasse em um projeto antigo.

Suporte a navegadores mais antigos (en-US)

Neste módulo, recomendamos o uso de Flexbox e Grid como os principais métodos de layout para seus projetos. No entanto, é provável que haja visitantes de um site que você desenvolver no futuro que usem navegadores mais antigos ou navegadores que não suportam os métodos que você usou. Esse sempre será o caso na web — à medida que novos recursos são desenvolvidos, diferentes navegadores priorizarão diferentes recursos. Este artigo explica como usar técnicas modernas da Web sem excluir usuários de tecnologia mais antiga.

Avaliações
----------

A avaliação a seguir testará sua compreensão dos métodos de layout CSS abordados nos guias acima.

Compreensão fundamental do layout (en-US)

Uma avaliação para testar seus conhecimentos sobre diferentes métodos de layout ao criar uma página da web.

Veja também
-----------

Exemplos de posicionamento prático (en-US)

Este artigo mostra como construir alguns exemplos do mundo real para ilustrar que tipos de coisas você pode fazer com o posicionamento.

livro de receitas de layout CSS

O livro de receitas de layout CSS visa reunir receitas para padrões de layout comuns, coisas que você pode precisar implementar em seus sites. Além de fornecer o código que você pode usar como ponto de partida em seus projetos, essas receitas destacam as diferentes maneiras pelas quais as especificações de layout podem ser usadas e as escolhas que você pode fazer como desenvolvedor.k


Construindo blocos CSS - Aprendendo desenvolvimento web

Construindo blocos CSS
======================

Este módulo continua onde Primeiros passos em CSS parou — agora que você já ganhou familiaridade com a linguagem e sua sintaxe, e já tem alguma experiência básica usando-a, é hora de mergulhar um pouco mais fundo. Este módulo analisa a conceitos de cascata e herança , todos os tipos de seletores que temos disponíveis, unidades, dimensionamentos, estilos de fundo e bordas, depuração, e muito mais.

O objetivo aqui é lhe prover com um conjunto de ferramentas para construir um código CSS competente e ajuda-lo a entender toda a teoria essencial, antes de passarmos para tópicos mais específicos como Estilização de texto e Modelo CSS.

Pré-requisitos
--------------

Antes de iniciar este módulo, você deve ter:

1. Familiaridade básica com uso de computadores, e usar a Web passivamente (por exemplo. apenas olhar, consumindo o conteúdo.)
2. Um ambiente de trabalho básico configurado conforme detalhado em Instalando software básico, e um entendimento de como criar e gerenciar arquivos, como detalhado em Lidando com arquivos.
3. Familiaridade básica com HTML, como foi discutido no módulo Introdução ao HTML.
4. Um entendimento do básico em CSS, como o mostrado no módulo Primeiros Passos com CSS.

**Nota:** Se você estiver usando um computador/tablet/outro dispositivo onde você não puder criar seus próprios arquivos, você pode tentar rodar (a maioria) os códigos de exemplo em um programa de codificação online como o JSBin ou Glitch.

Guias
-----

Este módulo contém os seguintes artigos, que cobrem a maioria das partes essenciais da linguagem CSS. Ao longo do caminho você encontrará vários exercícios para testar seu entendimento.

Cascata e Herança

O objetivo desta lição é desenvolver seu entendimento de alguns dos conceitos mais fundamentais do CSS — a cascata, especificidade e herança — que controlam como o CSS será aplicado ao HTML e como conflitos são resolvidos.

Seletores CSS

Há uma ampla variedade de seletores CSS disponíveis, permitindo uma fina precisão ao selecionar elementos para estilizar. Neste artigo e em seus sub-artigos, examinaremos os diferentes tipos em detalhes, vendo como eles funcionam. Os sub-artigos são os seguintes:

* Tipo, classe e seletores de ID
* Seletores de atributo
* Pseudo-classes e pseudo-elementos (en-US)
* Combinadores (en-US)

O modelo de caixa (Ou Box Model)

Tudo em CSS está dentro de caixas, e entender essas caixas é a chave para estar apto a criar layouts (modelos) em CSS, ou alinhar itens com outros itens. Nesta lição,trataremos mais propriamente sobre Modelo de Caixa CSS, afim de que você possa passar para tarefas de Layout mais complexas com um entendimento de como isto funciona e a terminologia relacionada a este modelo.

Planos de fundo e bordas (en-US)

Nesta lição, examinaremos algumas das coisas criativas que você pode fazer com os planos de fundo e as bordas do CSS. Desde a criação de gradientes, imagens de plano de fundo e cantos arredondados, planos de fundo e bordas são a resposta para muitas questões de estilo em CSS.

Manipulando diferentes direções de texto (en-US)

Nos últimos anos, o CSS evoluiu para oferecer melhor suporte a diferentes direções de conteúdo, incluindo o conteúdo da direita para a esquerda, mas também de cima para baixo (como o japonês) - essas diferentes direções são chamadas de modos de escrita. À medida que você progride em seu estudo e começa a trabalhar com o layout, o entendimento dos **modos de escrita** será muito útil para você; portanto, os apresentaremos neste artigo..

Transbordando conteúdo (en-US)

Nesta lição, examinaremos outro conceito importante em CSS - overflow, efeito de transbordar. O overflow é o que acontece quando há muito conteúdo para ser contido adequadamente dentro de uma "caixa". Neste guia, você aprenderá o que é e como gerenciá-lo.

Valores CSS e unidades (en-US)

Cada propriedade usada em CSS tem um valor ou um conjunto de valores que são permitidos para uma dada propriedade, veremos alguns dos valores e unidades mais comuns em uso.

Dimensionando itens em CSS (en-US)

Nas várias lições até agora, você encontrou várias maneiras de dimensionar itens em uma página da Web usando CSS. É importante entender o tamanho dos diferentes recursos do seu design e, nesta lição, resumiremos as várias maneiras pelas quais os elementos obtêm um tamanho via CSS e definiremos alguns termos de dimensionamento que ajudarão você no futuro.

Imagens, mídia, e elementos de formulário (en-US)

Nesta lição, veremos como certos elementos especiais são tratados no CSS. Imagens, outras mídias e elementos de formulário se comportam de maneira um pouco diferente em termos de sua capacidade de estilizá-los com CSS do que as caixas regulares. Compreender o que é e o que não é possível pode poupa-lo de algumas frustrações, e esta lição destacará algumas das principais coisas que você precisa saber.

Estilizando Tabelas (en-US)

Estilizar uma tabela HTML não é o trabalho mais fascinante do mundo, mas às vezes todos nós precisamos fazê-lo. Este artigo fornece um guia para melhorar a aparência das tabelas HTML, com algumas técnicas específicas de estilo de tabela destacadas.

Depurando CSS (en-US)

Às vezes, ao escrever CSS, você encontrará um problema em que seu CSS parece não estar fazendo o que você espera. Este artigo fornecerá orientações sobre como depurar um problema de CSS e mostrará como os DevTools (ferramentas de desenvolvedor) incluídos em todos os navegadores modernos podem ajudá-lo a descobrir o que está acontecendo.

Organizando seu CSS (en-US)

Ao começar a trabalhar com folhas de estilo e em projetos maiores, você descobrirá que manter um grande arquivo CSS pode ser desafiador. Neste artigo, examinaremos brevemente algumas práticas recomendadas para escrever seu CSS para facilitar a manutenção e algumas das soluções que você encontrará em uso por outras pessoas para ajudar a melhorar a capacidade de manutenção.

Avaliações
----------

Deseja testar suas habilidades de CSS? As avaliações a seguir testarão sua compreensão do CSS abordado nos guias acima.

Entendimento fundamental de CSS (en-US)

Esta avaliação testará seu entendimento da sintaxe básica, seletores, especificidade, modelo caixa, e mais.

Criando uma carta timbrada ideal (en-US)

Se você deseja causar uma boa impressão, escrever uma carta em papel timbrado bonito pode ser um bom começo. Nesta avaliação, desafiaremos você a criar um modelo online para obter essa aparência.

Caixa de estilo atraente (en-US)

Aqui você aprenderá a usar o estilo de plano de fundo e borda para criar uma caixa agradável.

Veja também
-----------

Efeitos de estilo avançados (en-US)

Este artigo funciona como uma caixa de truques, fornecendo uma introdução a alguns recursos avançados de estilo interessantes, como sombras de caixa, modos de mesclagem e filtros.


Primeiros passos com CSS - Aprendendo desenvolvimento web

Primeiros passos com CSS
========================

CSS ( Planilhas de estilo em cascata) é usada para estilizar e arranjar páginas web — por exemplo, para alterar a fonte, cor, tamanho e espaçamento do seu conteúdo, separá-lo em multiplas colunas, ou então adicionar animações e outras implementações decorativas. Esse módulo provê um começo sutil em seu caminho pelo domínio do CSS com o básico de como ele funciona, como é a aparência da sintaxe e como você pode começar a utilizá-lo para estilizar seu HTML.

Pré-requisitos
--------------

Antes de iniciar este módulo, você deve ter:

1. Familiaridade básica com o uso de computadores e utilização da internet passivamente (Ex: vendo e consumindo o conteúdo.)
2. Um ambiente de trabalho básico configurado conforme detalhado em Instalando Software Básico e um entendimento de como criar e gerenciar arquivos, conforme detalhado em Lidando com Arquivos.
3. Familiaridade básica com HTML, como discutido no módulo Introdução ao HTML.

**Nota:** Se você está trabalhando em um computador/tablet/ou outro dispostivo onde você não tem habilidade para criar seus próprios arquivos, você poderá tentar (a maioria) os exemplos de códigos em um programa online de codificação como JSBin ou Thimble.

Guias
-----

Este módulo contém os seguintes artigos, que o guiarão através de toda a teoria básica do CSS e fornecerão oportunidades para você testar algumas habilidades.

O que é CSS?

**CSS** (Cascading Style Sheets) permite que você crie páginas web com ótima aparência. Mas como isso funciona por debaixo dos panos? Este artigo explica o que é CSS, com um exemplo simples de sintaxe, e também cobre alguns termos importantes sobre a linguagem.

Iniciando com CSS

Neste artigo, pegaremos um documento HTML simples e aplicaremos CSS, aprendendo algumas coisas práticas sobre a linguagem ao longo do caminho.

Como CSS é estruturado

Agora que você tem uma idéia sobre o que é CSS e o básico sobre como usá-lo, é hora de analisar um pouco mais a fundo a estrutura da própria linguagem. Já conhecemos muitos dos conceitos discutidos aqui; você pode retornar a este para recapitular se achar confusos os conceitos posteriores.

Como CSS funciona

Aprendemos o básico do CSS, para que serve e como escrever folhas de estilo simples(Cascading Style Sheets - CSS). Neste exercício, veremos como um navegador utiliza CSS e HTML, e os transforma em uma página da web.

Usando seu novo conhecimento

Com o que aprendeu nas poucas lições anteriores, você já deve estar achando que pode formatar simples documentos de textos usando CSS, para adicionar seu próprio estilo neles. Este artigo te dará a chance de fazê-lo.

Veja também
-----------

Conhecimento Intermerdiário da Web 1: Introdução ao CSS

Um excelente curso básico da Mozilla que explora e testa muitas das habilidades mencionadas no módulo Introdução ao CSS. Aprenda sobre o estilo de elementos HTML em uma página web, seletores de CSS, atributos e valores.


Estilizando texto - Aprendendo desenvolvimento web

Estilizando texto
=================

Com o básico de CSS compreendido, o próximo passo para você se concentrar será a estilização de textos — uma das mais importantes coisas que você fará com CSS. Aqui nós olhamos para os fundamentos de estilização de texto, fontes, negritos, italicos, linha e espaço entre letras, sombreamente e outras características textuais. Completamos o módulo produrando aplicar fontes personalizadas para sua página, e estilizando listas e links.

Pré-requisites
--------------

Antes de começar este módulo, você já deverá ter familiaridade básica com HTML, como dissemos no módulos Introdução ao HTML, e estar confortável com os fundamentos de CSS, como discutido em Introdução ao CSS (en-US).

**Nota:** Se você está usando um computador/tablet/outro dispositivo onde não tem a possibilidade de criar seus próprios arquivos, você poderá treinar os códigos-exemplo em um programa de código online como JSBin, CodePen or Thimble.

Guias
-----

Este módulo contém os seguintes artigos que ensinarão você todos os fundamentos por trás da estilização de conteúdo textual HTML.

Fundamentos da estilização de texto e fontes (en-US)

Neste artigo nós passamos por todo o básico da estilização de texto/fonte, incluindo a configuração weight(negrito), family e style, configuração com forma abreviada, alinhamento textual, linha e espaçamento entre as letras.

Estilizando lista

Listas comportam-se como qualquer texto na maior parte das vezes, ma há algumas propriedades CSS específicas para lista que você precisa conhecer, e algumas boas práticas a considerar. Este artigo esclarecerá tudo.

Estilizando links (en-US)

Na estilização de links, é importante entender como fazer uso de pseudo-classes para estilizar o estado dos links efetivamente, como estilizar links para uso em recursos de interfaces diversas como menus de navegação e guias. Veremos todos esses tópicos neste artigo.

Web Fontes (en-US)

Aqui nós exploraremos Web Fontes em detalhes — isto permite que você baixe fontes personalizadas junto com sua página web, para permitir maior personalização na estilização.

Avaliação
---------

A seguinte avaliação testará seu entendimento das técnicas de estilização de texto cobertas pelo guia acima.

Estilizando a homepage de um escola comunitária

Nesta avaliação nos testeremos seu entendimento de estilização de texto fazendo com que você estilize a homepage de uma escola comunitária.


The box model - Aprendendo desenvolvimento web

The box model
=============

* Anterior  (en-US)
* Menu: Building blocks
* Próxima  (en-US)

Tudo em CSS tem um quadro em torno de si, e entender estes quadros é chave para ser capaz de criar arranjos ( layouts ) com CSS, ou para alinhar itens com outros itens. Nesta lição, olharemos de modo apropiado para o modelo de caixas do CSS ( CSS Box Model ), de forma que você possa montar arranjos mais complexos com um melhor entendimento de como ele funciona e da terminologia relacionada.

|  |  |
| --- | --- |
| Pré-requisitos: |
 Familiaridade básica em utilizar computadores, ambiente de trabalho
 básico configurado conforme detalhado emsoftware básico instalado, conhecimento básico de como
 criar e gerenciar arquivos, básico de HTML (
 Introdução ao HTML), e uma idéia de como o CSS funciona (ensinado em
 CSS primeiros passos.)
  |
| Objetivo: |
 Aprender sobre o Modelo de Caixa do CSS, o que faz o modelo de caixa e
 como trocar para um modelo alternativo.
  |

Caixas Block e Inline
---------------------

No CSS, temos dois tipos, **caixas box** e **caixas inline**, O tipo de caixa influencia diretameente em como as mesmas irao interagir com o fluxo da pagina(page flow) e com as outras caixas da pagina:

Se for uma caixa definida como block, ela tera os seguintes comportamentos:

* A caixa irá quebrar em uma nova linha.
* A caixa irá se estender na direção horizontal (inline) para preeencher todo o espaço disponível no container. Na maioria dos casos isso significa que essa caixa será tão larga quanto seu recipiente.
* As propriedades `width` e `height` serão respeitadas.
* `padding`, `margin` e `border` (en-US) farão com que outros elementos sejam empurrados para fora da caixa.

A menos que decidamos alterar o tipo de exibição para `inline`, alguns elementos como os cabeçalhos (ex: `<h1>`) e `<p>` são caixas do tipo `block` por padrão.

Se a caixa for do tipo `inline`, ela seguira os segintes comportamentos:

* Ela não quebrará em uma nova linha.
* As propriedades `width` e `height` não serão aplicadas.
* Padding vertical, margens e bordas serão aplicados, mas não farão com que outras caixas embutidades se afastem.
* Padding horizontal, margens e bordas serão aplicadas e farão com que outras caixas embutidades se afastem da caixa.

O elemento `<a>` usado em links, `<span>`, `<em>` e `<strong>` são exemplos de elementos que sao `inline` por padrão.

O tipo de caixa aplicada em um elemento é definida pela propriedade `display` como `block` ou `inline` e está relacionada ao valor **outer** do `display`.

Além disto: Tipos de exibição ( display ) internos e externos
-------------------------------------------------------------

Nesse ponto, é melhor também explicar os tipos de exibição interna ( **inner** ) e externa ( **outer** ). Como mencionado acima, as caixas em CSS têm um tipo de exibição externa, que detalha se a caixa é em bloco ou em linha.

Caixas possuem também um tipo de display *inner*, que determina como elementos dentro da caixa são posicionados. Por default, os elementos dentro de uma caixa são posicionados em um fluxo normal ( **normal flow** ), significando que eles se comportam como qualquer outro bloco e elementos inline (como explicado acima).

Podemos, no entando, alterar o tipo de exibição (display) interna usando valores `display` como `flex`. Se definirmos `display: flex;` em um elemento, o tipo de exibição externo será `block`, mas o tipo de exibição interna será alterada para `flex`. Todos os filhos diretos desta caixa se tornarão itens flexíveis e serão dispostos de acordo com as regras estabelecidas na especificação Flexbox, que você aprenderá mais tarde.

**Nota:** Para ler mais sobre valores de exibição (display) e como caixas funcionam nos layouts `block` e `inline`, dê uma olhada no guia MDN sobre Block e Inline Layout (en-US)

Quando aprender sobre CSS Layout você encontrará `flex` e vários outros valores internos que suas caixas podem ter, como por exemplo `grid` (en-US).

O layout Block e inline, no entanto, é a forma padrão de como as coisas na web se comportam. Como dissemos acima, às vezes é chamado de *normal flow*, porque sem qualquer outra instrução, nossas caixas são dispostas como blocks ou inlines.

Examples of different display types
-----------------------------------

Let's move on and have a look at some examples. Below we have three different HTML elements, all of which have an outer display type of `block`. The first is a paragraph, which has a border added in CSS. The browser renders this as a block box, so the paragraph begins on a new line, and expands to the full width available to it.

The second is a list, which is laid out using `display: flex`. This establishes flex layout for the items inside the container, however, the list itself is a block box and — like the paragraph — expands to the full container width and breaks onto a new line.

Below this, we have a block-level paragraph, inside which are two `<span>` elements. These elements would normally be `inline`, however, one of the elements has a class of block, and we have set it to `display: block`.

We can see how `inline` elements behave in this next example. The `<span>` elements in the first paragraph are inline by default and so do not force line breaks.

We also have a `<ul>` element which is set to `display: inline-flex`, creating an inline box around some flex items.

Finally, we have two paragraphs both set to `display: inline`. The inline flex container and paragraphs all run together on one line rather than breaking onto new lines as they would do if they were displaying as block-level elements.

**In the example, you can change `display: inline` to `display: block` or `display: inline-flex` to `display: flex` to toggle between these display modes.**

You will encounter things like flex layout later in these lessons; the key thing to remember for now is that changing the value of the `display` property can change whether the outer display type of a box is block or inline, which changes the way it displays alongside other elements in the layout.

In the rest of the lesson, we will concentrate on the outer display type.

What is the CSS box model?
--------------------------

The full CSS box model applies to block boxes, inline boxes only use some of the behavior defined in the box model. The model defines how the different parts of a box — margin, border, padding, and content — work together to create a box that you can see on the page. To add some additional complexity, there is a standard and an alternate box model.

### Parts of a box

Making up a block box in CSS we have the:

* **Content box**: The area where your content is displayed, which can be sized using properties like `width` and `height`.
* **Padding box**: The padding sits around the content as white space; its size can be controlled using `padding` and related properties.
* **Border box**: The border box wraps the content and any padding. Its size and style can be controlled using `border` (en-US) and related properties.
* **Margin box**: The margin is the outermost layer, wrapping the content, padding and border as whitespace between this box and other elements. Its size can be controlled using `margin` and related properties.

The below diagram shows these layers:

![Diagram of the box model](/pt-BR/docs/Learn/CSS/Building_blocks/The_box_model/box-model.png)

### The standard CSS box model

In the standard box model, if you give a box a `width` and a `height` attribute, this defines the width and height of the *content box*. Any padding and border is then added to that width and height to get the total size taken up by the box. This is shown in the image below.

If we assume that the box has the following CSS defining `width`, `height`, `margin`, `border`, and `padding`:

```css
.box {
  width: 350px;
  height: 150px;
  margin: 10px;
  padding: 25px;
  border: 5px solid black;
}
```

The space taken up by our box using the standard box model will actually be 410px (350 + 25 + 25 + 5 + 5), and the height 210px (150 + 25 + 25 + 5 + 5), as the padding and border are added to the width used for the content box.

![Showing the size of the box when the standard box model is being used.](/pt-BR/docs/Learn/CSS/Building_blocks/The_box_model/standard-box-model.png)

**Nota:** The margin is not counted towards the actual size of the box — sure, it affects the total space that the box will take up on the page, but only the space outside the box. The box's area stops at the border — it does not extend into the margin.

### The alternative CSS box model

You might think it is rather inconvenient to have to add up the border and padding to get the real size of the box, and you would be right! For this reason, CSS had an alternative box model introduced some time after the standard box model. Using this model, any width is the width of the visible box on the page, therefore the content area width is that width minus the width for the padding and border. The same CSS as used above would give the below result (width = 350px, height = 150px).

![Showing the size of the box when the alternate box model is being used.](/pt-BR/docs/Learn/CSS/Building_blocks/The_box_model/alternate-box-model.png)

By default, browsers use the standard box model. If you want to turn on the alternative model for an element you do so by setting `box-sizing: border-box` on it. By doing this you are telling the browser to take the border box as the area defined by any size you set.

```css
.box {
  box-sizing: border-box;
}
```

If you want all of your elements to use the alternative box model, and this is a common choice among developers, set the `box-sizing` property on the `<html>` element, then set all other elements to inherit that value, as seen in the snippet below. If you want to understand the thinking behind this, see the CSS Tricks article on box-sizing.

```css
html {
  box-sizing: border-box;
}
\*,
\*::before,
\*::after {
  box-sizing: inherit;
}
```

**Nota:** An interesting bit of history — Internet Explorer used to default to the alternative box model, with no mechanism available to switch.

Playing with box models
-----------------------

In the below example, you can see two boxes. Both have a class of `.box`, which gives them the same `width`, `height`, `margin`, `border`, and `padding`. The only difference is that the second box has been set to use the alternative box model.

**Can you change the size of the second box (by adding CSS to the `.alternate` class) to make it match the first box in width and height?**

**Nota:** You can find a solution for this task here.

### Use browser DevTools to view the box model

Your browser developer tools can make understanding the box model far easier. If you inspect an element in Firefox's DevTools, you can see the size of the element plus its margin, padding, and border. Inspecting an element in this way is a great way to find out if your box is really the size you think it is!

![Inspecting the box model of an element using Firefox DevTools](/pt-BR/docs/Learn/CSS/Building_blocks/The_box_model/box-model-devtools.png)

Margins, padding, and borders
-----------------------------

You've already seen the `margin`, `padding`, and `border` (en-US) properties at work in the example above. The properties used in that example are **shorthands** and allow us to set all four sides of the box at once. These shorthands also have equivalent longhand properties, which allow control over the different sides of the box individually.

Let's explore these properties in more detail.

### Margin

The margin is an invisible space around your box. It pushes other elements away from the box. Margins can have positive or negative values. Setting a negative margin on one side of your box can cause it to overlap other things on the page. Whether you are using the standard or alternative box model, the margin is always added after the size of the visible box has been calculated.

We can control all margins of an element at once using the `margin` property, or each side individually using the equivalent longhand properties:

* `margin-top`
* `margin-right` (en-US)
* `margin-bottom`
* `margin-left` (en-US)

**In the example below, try changing the margin values to see how the box is pushed around due to the margin creating or removing space (if it is a negative margin) between this element and the containing element.**

#### Margin collapsing

A key thing to understand about margins is the concept of margin collapsing. If you have two elements whose margins touch, and both margins are positive, those margins will combine to become one margin, which is the size of the largest individual margin. If one or both margins are negative, the amount of negative value will subtract from the total.

In the example below, we have two paragraphs. The top paragraph has a `margin-bottom` of 50 pixels. The second paragraph has a `margin-top` of 30 pixels. The margins have collapsed together so the actual margin between the boxes is 50 pixels and not the total of the two margins.

**You can test this by setting the `margin-top` of paragraph two to 0. The visible margin between the two paragraphs will not change — it retains the 50 pixels set in the `bottom-margin` of paragraph one. If you set it to -10px, you'll see that the overall margin becomes 40px — it subtracts from the 50px.**

There are a number of rules that dictate when margins do and do not collapse. For further information see the detailed page on mastering margin collapsing. The main thing to remember for now is that margin collapsing is a thing that happens. If you are creating space with margins and don't get the space you expect, this is probably what is happening.

### Borders

The border is drawn between the margin and the padding of a box. If you are using the standard box model, the size of the border is added to the `width` and `height` of the box. If you are using the alternative box model then the size of the border makes the content box smaller as it takes up some of that available `width` and `height`.

For styling borders, there are a large number of properties — there are four borders, and each border has a style, width and color that we might want to manipulate.

You can set the width, style, or color of all four borders at once using the `border` (en-US) property.

To set the properties of each side individually, you can use:

* `border-top` (en-US)
* `border-right` (en-US)
* `border-bottom` (en-US)
* `border-left`

To set the width, style, or color of all sides, use the following:

* `border-width` (en-US)
* `border-style` (en-US)
* `border-color` (en-US)

To set the width, style, or color of a single side, you can use one of the most granular longhand properties:

* `border-top-width` (en-US)
* `border-top-style` (en-US)
* `border-top-color` (en-US)
* `border-right-width` (en-US)
* `border-right-style` (en-US)
* `border-right-color` (en-US)
* `border-bottom-width` (en-US)
* `border-bottom-style` (en-US)
* `border-bottom-color` (en-US)
* `border-left-width` (en-US)
* `border-left-style` (en-US)
* `border-left-color` (en-US)

**In the example below we have used various shorthands and longhands to create borders. Have a play around with the different properties to check that you understand how they work. The MDN pages for the border properties give you information about the different styles of border you can choose from.**

### Padding

The padding sits between the border and the content area. Unlike margins you cannot have negative amounts of padding, so the value must be 0 or a positive value. Any background applied to your element will display behind the padding, and it is typically used to push the content away from the border.

We can control the padding on each side of an element individually using the `padding` property, or each side individually using the equivalent longhand properties:

* `padding-top` (en-US)
* `padding-right` (en-US)
* `padding-bottom` (en-US)
* `padding-left`

**If you change the values for padding on the class `.box` in the example below you can see that this changes where the text begins in relation to the box.**

**You can also change the padding on the class `.container`, which will make space between the container and the box. Padding can be changed on any element, and will make space between its border and whatever is inside the element.**

The box model and inline boxes
------------------------------

All of the above applies fully to block boxes. Some of the properties can apply to inline boxes too, such as those created by a `<span>` element.

In the example below, we have a `<span>` inside a paragraph and have applied a `width`, `height`, `margin`, `border`, and `padding` to it. You can see that the width and height are ignored. The vertical margin, padding, and border are respected but they do not change the relationship of other content to our inline box and so the padding and border overlaps other words in the paragraph. Horizontal padding, margins, and borders are respected and will cause other content to move away from the box.

Using display: inline-block
---------------------------

There is a special value of `display`, which provides a middle ground between `inline` and `block`. This is useful for situations where you do not want an item to break onto a new line, but do want it to respect `width` and `height` and avoid the overlapping seen above.

An element with `display: inline-block` does a subset of the block things we already know about:

* The `width` and `height` properties are respected.
* `padding`, `margin`, and `border` will cause other elements to be pushed away from the box.

It does not, however, break onto a new line, and will only become larger than its content if you explicitly add `width` and `height` properties.

**In this next example, we have added `display: inline-block` to our `<span>` element. Try changing this to `display: block` or removing the line completely to see the difference in display models.**

Where this can be useful is when you want to give a link to a larger hit area by adding `padding`. `<a>` is an inline element like `<span>`; you can use `display: inline-block` to allow padding to be set on it, making it easier for a user to click the link.

You see this fairly frequently in navigation bars. The navigation below is displayed in a row using flexbox and we have added padding to the `<a>` element as we want to be able to change the `background-color` when the `<a>` is hovered. The padding appears to overlap the border on the `<ul>` element. This is because the `<a>` is an inline element.

**Add `display: inline-block` to the rule with the `.links-list a` selector, and you will see how it fixes this issue by causing the padding to be respected by other elements.**

Test your skills!
-----------------

We have covered a lot in this article, but can you remember the most important information? You can find some further tests to verify that you've retained this information before you move on — see Test your skills: The Box Model.

Summary
-------

That's most of what you need to understand about the box model. You may want to return to this lesson in the future if you ever find yourself confused about how big boxes are in your layout.

In the next lesson, we will take a look at how backgrounds and borders (en-US) can be used to make your plain boxes look more interesting.

* Anterior  (en-US)
* Menu: Building blocks
* Próxima  (en-US)