Django

Django Forms: inserindo dados

31 de janeiro de 2019

Django Forms: inserindo dados

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.

django forms insert capa

Projeto em andamento

Antes de iniciar é bom entender que este é um projeto em andamento, você pode fazer comigo do zero começando por aqui:

  1. Instalando Django 2 e criando um projeto;

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!

create post django

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:

link para form

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!

Subscribe
Notify of
guest
10 Comentários
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
renato de souza

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

Battisti
Thiago Dantas

Muito bom o material!

Battisti

valeu Thiago!

rodrigo

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… Read more »

Battisti

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.

Ulisses

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).

Marcio Guillardi

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

Antonio Freitas

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.

Battisti

opa Antonio, não tenho esse tipo de conteúdo não, foi mal =(

10
0
Would love your thoughts, please comment.x
()
x