Exemplo em Django – parte 4

django-4_abertura

Na terceira parte o “Agenda de Eventos” foi (mais ou menos) concluído com a inclusão das opções para visualizar todos os eventos cadastrados, em um determinado dia e a visualização individual deles através da correspondente edição dos gabaritos, visões e rotas necessários para tudo funcionar corretamente.

Porém, as tarefas de inserção, edição e remoção dos eventos somente estão disponíveis a partir da interface de administração do Django, o que será corrigido nesta parte… 🙂

Antes de começar…

As alterações já foram submetidas no repositório no GitHub, então basta usar git pull para atualizar a cópia local e pegá-las. Outra coisa, em virtude da já citada “indisposição” do WordPress com código HTML nas publicações farei referência aos arquivos e, quando for o caso, usarei alguns trechos nas explicações.

ATENÇÃO : Para visualizar os arquivos do repositório na versão em que eles são citados aqui use git checkout parte-4 e git checkout master para voltar à última versão.

(re)Colocando o menu

django-4_menu

O menu já fazia parte tanto do exemplo de Bootstrap 4 que copiei me inspirei para o modelo de HTML usado na criação dos gabaritos. Ou seja, ele estava lá e só foi recolocado dentro de volta ao arquivo “./events/templates/navbar.html”.

Está acessível através do botão no “menu de hambúrguer” no lado direito da barra de navegação e exibe as seguintes opções:

  • Eventos de hoje — Vai para a listagem dos eventos do dia, utilizando {% ‘agenda-events-day’ today.year today.month today.day %}, a data é recuperada dentro de ‘today’;
  • Todos os eventos —  Vai para a relação de todos os eventos, usando {% url ‘agenda-events-all’ %}, e
  • Administração — Vai para a interface de administração do Django.

Também foi incluída uma breve descrição sobre o programa.

Formulários

O Django tem um  componente próprio para a criação de formulários que se encarrega da tarefa (quase sempre ingrata) de montá-los, tratá-los e validá-los. Sua sintaxe é bastante parecida com a que é utilizada na definição do modelo:

from django import forms

class EventForm(forms.Form):
    date = forms.DateField()
    event = forms.CharField(max_length=80)
    ...

Também é possível criar um formulário fazendo referência direta a um modelo já existente, o que foi feito no arquivo “./events/forms.py” para definir EventForm:

from django import forms
from .models import Event

class EventForm(forms.ModelForm):
    class Meta:
        model = Event
        fields = ['date', 'event', 'priority']

A definição do modelo e atributos a utilizar é feita na classe Meta.

Gabaritos dos formulários

No “Agenda de Eventos” preferi não utilizar os recurso de criação automática de formulários, optando pela edição manual do HTML na criação de janelas modais do Bootstrap nos arquivos “./events/template/new.html” e “./events/template/edit.html” — ambas inseridas a partir de um outro gabarito, o “./templates/footer.html”.

Além dos campos para a inserção/edição dos eventos elas uma caixa de seleção com as opções já populadas a partir do conteúdo de ‘priorities’ (lembrando que é usado também para “colorir” os eventos):

{% for value, priority in priorities %}
    ... value="{{ value }}"... {{ priority }} ...
{% endfor %}

Aliás, isto poderia ser feito com uma só janela modal mas preferi não aumentar a complexidade do projeto.

Uma pitada de JavaScript jQuery…

Para transferir os dados de um evento para a janela de edição são usadas funções do jQuery para copiar os valores do evento disponíveis no próprio DOM (data e descrição do evento) ou codificadas no Id do elemento — veja a linha 26 do arquivo “./template/day.html”.

Novas visões

Assim como o modelo, o formulário também precisa ser carregado no arquivo “./events/views.py”:

from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.timezone import localdate
from django.views.defaults import bad_request, server_error
from .models import Event
from .forms import EventForm
...

Aproveitando a oportunidade para incluir os métodos get_object_or_404() e redirect() no arquivo. O primeiro funciona como o método get() do ORM com a diferença de redireciona automaticamente para a página de “não encontrado” (404) caso a consulta não obtenha um resultado válido. O outro, como o nome já indica, redireciona para uma determinada visão.

Também foram incluídas as visões para o tratamento de eventuais erros que possam acontecer.

Novo evento

Na visão a inserção de um novo evento é realizada pelo método new():

def new(request):
    form = EventForm(request.POST)
    if form.is_valid():
        form.save(commit=True)
        (year, month, day) = tuple(
        split_date(request.POST['date']))
        return redirect('agenda-events-day',
                        year=year, month=month, day=day)
    else:
        return bad_request(request, None, 'ops_400.html')

O conteúdo enviado pelo formulário de “Novo” é inserido em EventForm, assim é possível utilizar os métodos do objeto para validá-los através de is_valid(), daí armazená-lo e exibir o dia deste evento. Em caso contrário, isto é dados inválidos no formulário, é exibida a página de erro 400 (requisição inválida).

O split_date() é uma invenção minha para pegar uma data qualquer e separá-la numa tupla para ano, mês e dia que usada a todo instante com ‘agenda-events-day’.

Remoção do evento

A remoção de um evento é executada na visão pelo delete():

def delete(request, id: int):
    event = get_object_or_404(Event, id=id)
    (year, month, day) = tuple(
        split_date('{:%Y-%m-%d}'.format(event.date)))
    if event.delete():
        return redirect('agenda-events-day',
                        year=year, month=month, day=day)
    else:
        return server_errror(reqest, 'ops_500.html')

Aqui o método get_object_or_404() é usado para verificar se o evento realmente existe antes de tentar apagá-lo. Caso não exista, é exibida a página de erro 404 e caso algo estranho aconteça durante a remoção é exibida a página de erro 500 (erro interno).

Alteração do evento

E por último a alteração de um evento com o método edit():

def edit(request):
    form = EventForm(request.POST)
    if form.is_valid():
        event = get_object_or_404(Event, id=request.POST['id'])
        event.date = form.cleaned_data['date']
        event.event = form.cleaned_data['event']
        event.priority = form.cleaned_data['priority']
        event.save()
        (year, month, day) = tuple(
            split_date('{:%Y-%m-%d}'.format(event.date)))
        return redirect('agenda-events-day',
                    year=year, month=month, day=day)
    else:
        return bad_request(request, None, 'ops_400.html')

Ele usa tanto os objetos de formulário (‘form’) como de modelo (‘event’), no primeiro  os dados são validados antes de serem substituídos no evento pré existente. Por último ele exibe a página relativa à nova data do evento ou alguma das respectivas páginas de erro.

Fim desta parte

django-4_inicial

Além das visões responsáveis pela edição do conteúdo também foi criada uma para servir de página principal da aplicação, por enquanto ela não tem muita informação mas isto ficará para a próxima parte, assim como também dar alguma finalidade para a visualização de um evento específico que, aparentemente, ficou sem função agora.

Até!

Anúncios

Um comentário sobre “Exemplo em Django – parte 4

  1. Pingback: Exemplo em Django – parte 5 | giovannireisnunes

Os comentários estão desativados.