Aula 14 – Curso de Django
Criando uma primeira aplicação com Django e mysql
Criação da interface pública – “views”.
https://docs.djangoproject.com/pt-br/1.11/intro/tutorial03/
Visão Geral
- Uma view é um “tipo” de página Web da sua aplicação Django, que em geral serve a uma função específica e tem um template específico. Por exemplo, em uma aplicação de blog, você deve ter as seguintes views:
- Página inicial do blog – exibe os artigos mais recentes.
- Página de “detalhes” – página de vínculo estático, a página do artigo em si.
- Página de arquivo por ano – exibe todos os artigos de todos os meses em determinado ano.
- Página de arquivo por mês – exibe todos os artigos por dia em determinado mês.
- Página de arquivo por dia – exibe todos os artigos de um determinado dia.
- Ação de comentários – controla o envio de comentários para um artigo.
Em nossa aplicação de enquetes, nós teremos as seguintes views:
- Página de “índice” de enquetes – exibe as enquetes mais recente.
- Página de “detalhes” da Question – exibe o texto da questão, sem resultados, mas com um formulário para votar
- Página de “resultados” de perguntas – exibe os resultados de uma pergunta em particular.
- Ação de voto – gerencia a votação para uma escolha em uma enquete específica.
No Django, páginas web e outros conteúdos são entregues por views.
Cada view é representada por uma simples função Python(ou metodos, no caso das views baseadas em classes).
O django irá escolher uma view examinando a URL que foi requisitada (para ser preciso, a parte da URL depois do nome de domínio).
Você já deve ter visto urls na internet desse tipo: “ME2/Sites/dirmod.aspsid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B”.
Você ficará satisfeito em saber que o Django permite padrões de URL muito mais elegantes do que isso.
Um padrão de URL é simplesmente a formatação geral de uma URL – por exemplo: /newsarchive/<year>/<month>/.
Para ir de uma URL para uma view, O Django usa o que é conhecido como ‘URLconfs’.
Uma URLconf mapeia padrões de URL (descritas com expressões regulares) para views.
Antes de escrever as views, modifique o mysite/urls para que fique assim:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls)
]
Veja que incluímos o urls da pasta polls aqui no urls da pasta mysite.
Agora vamos adicionar algumas views em polls/views.py.
Crie então o polls/views.py
A view index() mostra as últimas 5 “poll questions” do sistema, separada por vírgulas, de acordo com sua data de publicação.
polls/views.py
from django.http import HttpResponse
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
output = ', '.join([q.question_text for q in latest_question_list])
return HttpResponse(output)
def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id)
def results(request, question_id):
response = "You're looking at the results of question %s."
return HttpResponse(response % question_id)
def vote(request, question_id):
return HttpResponse("You're voting on question %s." % question_id)
Ligue as views dentro do módulo polls.urls adicionando as seguintes chamadas:
polls/urls.py
from django.urls import path
from . import views
urlpatterns = [
# ex: /polls/
path('', views.index, name='index'),
# ex: /polls/5/
path('/', views.detail, name='detail'),
# ex: /polls/5/results/
path('/results/', views.results, name='results'),
# ex: /polls/5/vote/
path('/vote/', views.vote, name='vote'),
]
- /polls/34/ executa o método detail() e mostra o ID que você informou na URL.
- “/polls/34/results/” e “/polls/34/vote/” – vai mostrar a pagina resultados e a pagina de votação.
Obs. Se preferir a implementação antiga usando url() com regex ao invés de path() coloque no /polls/urls.py o conteúdo abaixo:
from django.conf.urls import url
from . import views
urlpatterns = [
# ex: /polls/
url(r'^$', views.index, name='index'),
# ex: /polls/5/
url(r'^(?P[0-9]+)/$', views.detail, name='detail'),
# ex: /polls/5/results/
url(r'^(?P[0-9]+)/results/$', views.results, name='results'),
# ex: /polls/5/vote/
url(r'^(?P[0-9]+)/vote/$', views.vote, name='vote'),
]
A nova funçao django.urls.path() permite uma sintaxe de roteamento de URL mais simples e mais legível. Por exemplo, nas versões anteriores do Django:
url(r’^articles/(?P<year>[0-9]{4})/$’, views.year_archive),
pode agora ser escrito como:
path(‘articles/<int:year>/’, views.year_archive),
Com a função url(), quando alguém requisita uma página do seu site – vamos dizer, “/polls/34”, o Django irá carregar o módulo Python mysite.urls porque este está sendo apontado pela definição ROOT_URLCONF.
Ele encontra a variável denominada urlpatterns e atravessa as expressões regulares seguindo a ordem.
Depois de encontrar uma combinação no ‘^polls/’, ele corta o texto que combina (“polls/”) e envia a parte remanescente – “34/” – para o URLconf do ‘polls.urls’ para processamento posterior.
Lá ele encontra a r’^(?P<question_id>[0-9]+)/$’, resultando em uma chamada para a “view” detail() como esta:
detail(request=<HttpRequest object>, question_id=’34’)
A parte question_id=’34’ vem de (?P<question_id>[0-9]+).
Usando parênteses em torno de um padrão “captura-se” o texto que casa com esse padrão e envia ele como um argumento da função;
?P<question_id> define o nome que será usado para identificar o padrão casado;
[0-9]+ é a expressão regular para casar uma sequência de dígitos (ex., um número)
Como os padrões de URL são expressões regulares, realmente não há limites para o que você possa fazer com elas. E também não é necessário adicionar extensão na URL como .html – a menos que você queira, neste caso você pode fazer algo como:
url(r’^polls/latest\.html$’, views.index),
Mas não faça isso, isto não é funcional.
Quando o vídeo dessa aula foi gravado, a jeito como se fazia o roteamento de urls era usando url().
Agora, pela documentação oficial, é melhor e mais simples usar a funcão path() ao invés de url().
Escreva views que façam algo
Cada view é responsável por fazer uma de duas coisas: retornar um objeto HttpResponse contendo o conteúdo para a página requisitada, ou levantar uma exceção como Http404.
Sua view pode ler registros do banco de dados, ou não.
Ela pode usar um sistema de templates como o do Django – ou outro sistema de templates Python de terceiros – ou não.
Pode gerar um arquivo PDF, uma saída em XML, criar um arquivo ZIP sob demanda, qualquer coisa que você quiser, usando qualquer biblioteca Python que você queira.
Tudo que o Django espera é que a view retorne um HttpResponse, ou uma exceção.
Por ser mais conveniente, vamos usar a própria API de banco de dados do Django, a qual vimos na parte 2 do Tutorial.
Há um problema aqui, o design da página esta codificado na view. Se você quiser mudar a forma de apresentação de sua página, você terá de editar este código diretamente em Python. Então, vamos usar o sistema de templates do Django para separar o design do código Python:
Primeiro, crie um diretório chamado templates em seu diretório polls.
O Django irá procurar por templates lá.
A sua configuração de projeto TEMPLATES descreve como o Django vai carregar e renderizar templates.
O arquivo de configuração padrão usa o backend DjangoTemplates do qual a opção APP_DIRS é configurada como True. Por convenção DjangoTemplates procura por um subdiretório “templates” em cada uma das INSTALLED_APPS.
Dentro do diretório templates que acabou de criar, crie outro diretório polls, e dentro crie um arquivo chamado index.html. Em outras palavras, seu template deve estar em polls/templates/polls/index.html. Devido a forma como o carregador de templates app_directories funciona como descrito acima, você pode referenciar este template dentro do Django simplesmente como polls/index.html.
Namespacing de template
Agora nós podemos ser capazes de avançar com a colocação dos nossos modelos diretamente em polls/templates (em vez de criar outro subdiretório poll), que na verdade seria uma má ideia.
Django irá escolher o primeiro template que encontra cujo nome corresponde, se você tivesse um template com o mesmo nome em uma aplicação diferente, o Django seria incapaz de distinguir entre eles, por isso, precisamos apontar o Django no caminho certo, e a maneira mais fácil de fazer isso é usar namespacing, ou seja, colocar esses templates dentro de outro diretório nomeado para a aplicação em si.
Ponha o seguinte código neste template:
polls/templates/polls/index.html
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
Agora vamos atualizar nossa view index em polls/views.py para usar o template:
polls/views.py
from django.http import HttpResponse
from django.template import loader
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = {
'latest_question_list': latest_question_list,
}
return HttpResponse(template.render(context, request))
Esse código carrega o template chamado polls/index.html e passa um contexto para ele. O contexto é um dicionário mapeando nomes de variáveis para objetos Python.
Carregue a página apontando seu navegador para “/polls/”, e você deve ver uma lista contendo a questão “What’s up” do Tutorial 2. O link aponta para página de detalhes das perguntas.
Um atalho: render()
É um estilo muito comum carregar um template, preenchê-lo com um contexto e retornar um objeto HttpResponse com o resultado do template renderizado. O Django fornece este atalho. Aqui esta toda a view index() reescrita:
polls/views.py
from django.shortcuts import render
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'polls/index.html', context)
Note que uma vez que você tenha feito isto em todas as views, nós não vamos mais precisar importar loader e HttpResponse (você vai querer manter HttpResponse se você ainda tiver os métodos criados para detail, results e vote).
A função render() recebe o nome do template como primeiro argumento e um dicionário opcional como segundo argumento. Ele retorna um objeto HttpResponse do template informado renderizado com o contexto determinado.
Boa tarde, esta com erro:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/polls/34
Using the URLconf defined in mysite_project.urls, Django tried these URL patterns, in this order:
polls/ [name=’index’]
polls/ [name=’detail’]
polls/ results/ [name=’results’]
polls/ vote/ [name=’vote’]
admin/
The current path, polls/34, didn’t match any of these.
You’re seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
Olá Maria, tudo bem?
Foi legal você ter comentado, eu refiz essa aula, tinha alguns códigos errados, acho que agora você não terá problemas. Peço que refaça essa aula copiando os códigos para ver se continua a dá problema ou não.
Qualquer coisa entre em contato novamente.
\o/ 😉
Toti
Mano sua aulas são muito boas, parabens.
eu encontrei um erro na hora de chamar a view pelo id, pesquisei a dom=cumentação e vi que o seu código esta faltando parte, acontece com todos os programadores(kkkk), vou colocar aqui em baixo.
from django.urls import path
from . import views
urlpatterns = [
# ex: /polls/
path(”, views.index, name=’index’),
# ex: /polls/5/
path(‘/’, views.detail, name=’detail’),
# ex: /polls/5/results/
path(‘/results/’, views.results, name=’results’),
# ex: /polls/5/vote/
path(‘/vote/’, views.vote, name=’vote’),
]
estã faltando o
# ex: /polls/5/
path(‘/’, views.detail, name=’detail’),
Espero ter ajudado, mas no geral está muito bom.
Valeu Júlio, o erro foi só no código no github. Vou corrigir.
🙂 abraço.
Corrigido! ;), \o/