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.

Para baixar o código como está até agora, acesse o meu github no link abaixo: https://github.com/toticavalcanti/django_course/tree/views

AULA  13

AULA  15

Todas as Aulas da App Polls

Página Principal

Obrigado

Até a próxima