Neste artigo veremos como adicionar registros ao banco de dados por meio do recurso de formulários do framework Django de forma simples e rápida.
Projeto em andamento
Antes de iniciar é bom entender que este é um projeto em andamento, você pode fazer comigo do zero começando por aqui:
O código de todo o conteúdo está disponível aqui!
obs: esta é a parte 11
Fala galera, tudo certo? Espero que sim 😀
Agora veremos como inserir, atualizar e deletar dados do nosso banco através do front-end da aplicação.
Assim não dependeremos mais da área administrativa.
E mais uma vez o Django faz seu papel muito bem, abstraindo várias responsabilidades e tornando a criação de form mamão com açucar, vamos lá?
Criando arquivos forms.py
E a nossa primeira tarefa é criar um arquivo chamado forms.py dentro do nosso app blog.
Veja como fica a árvore de arquivos:
Este arquivo concentrará todos os forms, mas não o template em si, e sim os campos que queremos passar para o template.
E tudo por meio do model que criamos antes, ou seja, de forma fácil escolhemos o que o usuário deve preencher para criar o registro.
Deixe o arquivo forms.py desta maneira:
from django.forms import ModelForm from .models import Post
class PostForm(ModelForm): class Meta: model = Post fields = ['title', 'slug', 'body', 'author', 'status']
Importamos o nosso model Post, que é a base do formulário
Ou seja, o usuário deve preencher os campos que o nosso model possui
Assim criamos a classe PostForm, que posteriormente será importada na view para que possamos utilizar os campos escolhidos na variável fields
Então campos como created_at e updated_at do nosso model, não vão aparecer para o usuário, pois nós não selecionamos eles em fields
Ficou com dúvidas sobre os models? Veja este post.
Criando a URL
Como já sabemos, o usuário deve acessar uma URL que lá estará o form.
Então vamos abrir o arquivo urls.py de blog, e adicionar a rota que levará a criação do post.
Deixe a variável urlpatterns desta maneira:
urlpatterns = [ path('', views.post_list, name='post_list'), path('<slug:slug>', views.post_detail, name='post_detail'), path('criar/', views.post_create, name='post_create'), path('sobre-nos/', views.about, name='about'), path('contato/', views.contact, name='contact'), ]
Perceba que a única mudança, foi a adição da url post_create.
Criando a view
Agora devemos criar a view, para podermos escolher um template e o usuário enfim poder adicionar um post
Primeiro vamos importar o form e mais alguns recursos, na área de imports de views.py do app blog, deixe os imports dessa forma:
from django.shortcuts import render, get_object_or_404, redirect from django.contrib.auth.decorators import login_required from django.http import HttpResponse from django.core.paginator import Paginator from .models import Post from .forms import PostForm
Agora vamos ver o que foi importado:
- redirect: para ajudar a mudar de página com o sucesso do formulário, neste caso em específico porém pode ser utilizado para qualquer redirecionamento;
- login_required: com este decorator podemos limitar uma view apenas para usuários autenticados;
- PostForm: importando o form, poderemos enviar ele para o template, esta é a maneira mais fácil de trabalhar com forms no Django;
Agora vamos criar a função post_create, que fica da seguinte maneira:
@login_required def post_create(request): form = PostForm() if(request.method == 'POST'): form = PostForm(request.POST) if(form.is_valid()): post_title = form.cleaned_data['title'] post_slug = form.cleaned_data['slug'] post_body = form.cleaned_data['body'] post_author = form.cleaned_data['author'] post_status = form.cleaned_data['status'] new_post = Post(title=post_title, slug=post_slug, body=post_body, author=post_author, status=post_status) new_post.save() return redirect('blog:post_list') elif(request.method == 'GET'): return render(request, 'blog/add_post.html', {'form': form})
Provavelmente o metodo mais complicado e extenso que já escrevemos nos tutoriais, vamos quebrá-lo em partes…
Primeiro criamos uma variável com o form, que vai servir para caso da requisição ser um GET, ou seja, o formulário não é enviado
Então o usuário verá um formulário em branco para preencher o novo post
Depois temos um if e um elif, que verificam o request, se for POST ele procede para a inserção do post no banco de dados
No caso de GET, como explicado acima, o usuário vê o form apenas
Depois importamos o form também, porém agora com os dados do POST, os dados enviados na requisição
Checamos se todos os dados enviados são válidos, com is_valid(), e prosseguimos criando um objeto com todos os dados enviados e previamente limpso com cleaned_data
O atributo cleaned_data normaliza os valores enviados, ou seja, faz que com que os enviados sejam sempre consistentes e do tipo informado no model em questão
Para enfim salvar no banco com o método save()
Não podemos esquecer do @login_required, como só usuários que fazem parte da administração podem adicionar posts geralmente, vamos fazer essa medida de segurança no nosso projeto
Ou seja, você precisa estar autenticado para acessar a URL de criação!
E se você ficou com dúvidas, tenho um post dedicado a views, veja aqui!
Criando o template
Agora temos que criar o template para enfim finalizar todo o ciclo
Na pasta de templates do app blog, crie o arquivo add_post.hmtl com o seguinte conteúdo:
{% extends 'blog/base.html' %} {% block title %}Adicionar um post{% endblock %} {% block content %} <div class="container"> <h1>Adicionar um post</h1> <div> <form action="." method="POST"> {% csrf_token %} {{ form.as_p }} <input type="submit" class="btn btn-default" value="Criar"> </form> </div> </div> {% endblock %}
Nada de novo por aqui, estendemos o arquivo base para pegar o template do projeto
Depois criamos um form com método POST para envio dos dados
E utilizamos o metodo as_p para o formulário ser diposto em blocos no template
Também utilizamos o csrf_field, conforme explicado aqui, para deixar a requisição segura e criamos um input de envio
Testando formulário
Enfim chegou a hora!
Coloque o servidor para rodar com:
python manage.py runserver
Vá ao endereço:
http://localhost:8000/criar/
Obs: você precisa estar autenticado!
Este form deve ter aparecido para você, agora tente adicionar alguns posts e veja os mesmos na lista, a home do projeto.
Está pronto!
Inserindo botão de adicionar post para administradores
Mais um detalhe que pode ser útil para o projeto, adicionar um link para os usuários conseguirem adicionar um post rapidamente
Por isso vamos fazer essa modificação no base.html
Onde há uma verificação de usuário logado (if user.is_authenticated), deixe assim:
{% if user.is_authenticated %} <p class="logged-in-p"> Olá {{ user.username }} seja bem vindo, o que deseja fazer hoje? <span class="sair"><a href="{% url 'logout' %}">Sair</a></span> </p> <div class="submenu-auth"> <span><a href="{% url 'blog:post_create' %}">Adicionar post</a></span> </div> {% endif %}
Agora você deve ter esse link na barra de navegação, veja:
Conclusão
O nosso primeiro passo foi criar o arquivos forms.py, e vimos que nele podemos criar um formulário baseado nos nossos models
Isso ajuda muito porque abstraímos o trabalho de lidar com o front-end campo a campo
Depois criamos a url e a view, onde importamos alguns recursos essencials como: login_required, redirect e o próprio form
Na view ainda criamos a função que com um if e elif retornará ou o formulário para preencher ou a requisição para o banco
Por fim adicionamos o template que comportará o formulário e também um botão na navbar dos usuários para eles terem um atalho para adicionar novos posts
Confira também o nosso canal do Youtube com muito conteúdo sobre programação, clicando aqui.
Pessoal, agradeço a todos por lerem até o fim, se possível compartilhem com os amigos interessados em Django e se inscrevam na nossa lista de e-mail para não perder as novidades.
Caso haja alguma dúvida ou crítica, comentem abaixo que responderei assim que possível, obrigado!
Olá, interessante o conteúdo parabéns pelo trabalho, uma duvida, como eu aplico um bootstrap nesse tipo de formulário, eu utilizei o form do django mas não consigo estilizar o formulário criado pelo django.
Desde já agradeço
opa Renato, tem um post sobre isso:
https://www.horadecodar.com.br/2019/02/26/utilizando-django-bootstrap-form/
Muito bom o material!
valeu Thiago!
Matheus, será que você consegue me ajudar, estou aprendendo django e me deparei com a seguinte situação, tenho um form que preciso apresentar um campo protegido na tela (o usuário tem que ver sem poder alterar), verifiquei que utilizando disable funciona da maneira que desejo, ou seja, ele esta apresentando na tela com o conteúdo inicial que passei protegido, porém um realizar um POST desse form o valor não é retornando gerando um keyerror no momento da inclusão na tabela. Verifiquei que tem também o readonly, porém ao tentar utilizar o campo não aparece para o usuário, será que consegue… Leia mais »
opa Rodrigo, cara eu nessas situações uso o readonly, acredito que tenha algum problema no CSS do seu projeto, pelo fato dele não aparecer na tela.
Olá a todos! Como eu faria para ter dois botões funcionando no mesmo template? Um pra pesquisar dados de outro banco (já configurado e funcionando para obter dados) e depois outro botão para salva esses mesmos dados no segundo banco de dados (já possui o modelo, ou seja, a tabela já foi criado).
Corrigir: add_post.hmtl(?): “Na pasta de templates do app blog, crie o arquivo add_post.hmtl com o seguinte conteúdo:”
Não que faça muita diferença… mas…
Abraços
E aí Matheus, primeiramente gostaria de agradecê-lo pelo conteúdo q tens compartilhado, de excelente qualidade.
Por acaso vc tem algo q oriente a fazer vários inserts (registros) a partir de um unico “form”. Por exemplo, cada linha dentro do form, será um registro no banco.
desde já agradeço a atenção.
opa Antonio, não tenho esse tipo de conteúdo não, foi mal =(