16. Models, templates e views - AndersonBatalha/tango_with_django GitHub Wiki
-
Após criar os modelos e o script de população do banco de dados, é necessário interligar os models, templates e views para gerar conteúdo dinâmico.
-
No arquivo
views.pyimporte os modelos a serem utilizadosfrom rango.models import Category -
Na view, crie as consultas para obter os dados que irão ser apresentados
-
Passe os dados como contexto para o template
def index(request): category_list = Category.objects.order_by('-likes')[:5] print('Categorias: ', category_list, len(category_list)) context_dict = {'categories': category_list} return render(request, 'rango/index.html', context=context_dict)-
category_listretorna as categorias cadastradas no banco de dados -
Category.objects.order_by: retorna o resultado ordenando pelo número de likes -
'-likes': o sinal de - indica ordenação decrescente -
[:5]limita em 5 o número de registros -
context_dictrepresenta o dicionário com o resultado da consulta (category_list), que será passado para o template - A função
render()recebe como parâmetros a requisição (request), o template (index.html), e o contexto (context_dict)
-
-
Crie ou modifique o template para exibir os dados do contexto
<!DOCTYPE html> <html> {% load staticfiles %} <head> <title>Rango</title> </head> <body> <h1>Rango says...</h1> <div> hey there partner! <br /><br /> </div> <div> {% if categories %} <ul> {% for category in categories %} <li>{{ category.name }} - {{ category.likes }} likes</li> {% endfor %} </ul> {% else %} <h4>Não existem categorias cadastradas.</h4> {% endif %} </div> <div> <a href="/rango/about/">About</a><br /> <br> <img width="400px" height="400px" src="{% static 'images/rango.jpg' %}" alt="Picture of Rango"/> </div> </body> </html>- Todos os comandos entre
{% %}são específicos da linguagem de templates do Django - O código acima verifica se a variável categories existe, e então percorre a lista, exibindo o nome e o número de likes para cada categoria. Se não existem categorias, uma mensagem é exibida.
- Todos os comandos entre
-
Mapeie a URL para a view (no arquivo
urls.py)url(r'^$', views.index, name='index'),
-
-
Criando a página de detalhes
-
O próximo passo é listar as páginas que pertencem a cada categoria.
-
O principal problema está nas URLs. Podemos criar uma URL do tipo
rango/category/1, mas não é possível saber o nome da categoria apenas pelo id. -
Para resolver este problema, o ideal é criar URLs limpas. Por exemplo:
rango/category/pythontorna melhor a usabilidade e acessibilidade do site para os usuários -
O Django fornece a função slugify para substituir espaços em branco em hifens. Exemplo: "Django Tutorial" para "django-tutorial". Não é recomendado criar URLs com espaços, por questões de segurança.
-
Atualizando os modelos. Modifique a classe
Categoryemmodels.pye adicione um camposlugdo tipoSlugField. Além disso, adicione um métodosave(), que irá atualizar o valor da variável slug toda vez que uma categoria for inserida no banco de dados.class Category(models.Model): name = models.CharField(max_length=128, unique=True) views = models.IntegerField(default=0) likes = models.IntegerField(default=0) slug = models.SlugField() def save(self, *args, **kwargs): self.slug = slugify(self.name) super(Category, self).save(*args, **kwargs) class Meta: verbose_name_plural = 'categories' def __str__(self): return self.name -
Realize as migrações (migrate e makemigrations) e execute o script de população novamente
-
Para exibir as páginas associadas a uma categoria, é necessário:
-
Importar o model Page em
views.pyfrom rango.models import Page -
Criar uma view
show_category()def show_category(request, category_name_slug): context_dict = {} try: category = Category.objects.get(slug=category_name_slug) pages = Page.objects.filter(category=category) context_dict['pages'] = pages context_dict['category'] = category except Category.DoesNotExist: context_dict['category'] = None context_dict['pages'] = None return render(request, 'rango/category.html', context_dict) -
Criar um template em
templates/rango/category.html<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Rango</title> </head> <body> <div> {% if category %} <h1>{{ category.name }}</h1> {% if pages %} <ul> {% for page in pages %} <li><a href="{{ page.url }}">{{ page.title }}</a></li> {% endfor %} </ul> {% else %} <strong><h4>Não existem páginas relacionadas a esta categoria</h4></strong> {% endif %} {% else %} <h3>Não existe essa categoria</h3> {% endif %} </div> </body> </html> -
Atualizar a view index() e o template index.html para exibir os links para exibir a lista de páginas
-
-