Aula 04 – Loja Virtual – Ecommerce – Django – Form

Aula 04 – Loja Virtual – Ecommerce – Django – Form

Loja Virtual – Ecommerce – Django – Form

Como criar um form django?

Primeiro vamos criar um form para a página de contato usando html puro, um form bruto digamos assim, um formulário em hard code.

Depois iremos refatorar os códigos para utilizar a biblioteca forms do python e transformar nosso formulário django, em um formulário robusto e profissional.

Pessoal, antes de prosseguir, quero deixar esse link para quem quiser investir em um curso de Java completo para web, achei bem honesto. 😉

Loja virtual com Django

Loja virtual com Django

Voltar para página principal do blog

Todas as aulas desse curso

Aula 03                Aula 05

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

Curta a página do Código Fluente no Facebook
https://www.facebook.com/Codigofluente-338485370069035/

Vou deixar meu link de referidos na digitalocean pra vocês.

Quem se cadastrar por esse link, ganha $100.00 dólares de crédito na digitalocean:

Digital Ocean

Esse outro link é da one.com:

One.com

Bem, prosseguindo com nosso curso.

Na aula 03 deixamos o src/templates/contact/view.html  assim:

<!doctype html>
<html lang="en">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

        <title>Código Fluente Ecommerce!</title>
    </head>
    <body>
        <div class='text-center'>
            <h1>{{ title }}</h1>
            <h2>{{ content }}</h2>
            <h2>Tá funcionando perfeitamente!!!</h2>
        </div>
        <!-- Optional JavaScript -->
        <!-- jQuery first, then Popper.js, then Bootstrap JS -->
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
    </body>
</html>

{% csrf_token %} e a class form control

Vamos modificá-lo para ficar assim, observe no código acima (antiga versão) e no abaixo (a versão nova com o formulário) o que mudou.

O que está marcado em cores no código abaixo foi o que mudou.

<!doctype html>
<html lang="en">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

        <title>Formulário de contato</title>
    </head>
    <body>
        <div class='text-center'>
            <h1>{{ title }}</h1>
        </div>
   <div class='container'>
            <div class='row'>
                <div class='col'>
                    <p>{{ content }}</p>
                    <div class='col-sm-6 col-12'>
                    <form method='POST'> {% csrf_token %}
                        <input type='text' class='form-control' name='fullname 'placeholder='Digite seu nome completo'>
                        <input type='email' class='form-control' name='email' placeholder='Digite seu email'>
                        <textarea name='content' class='form-control' placeholder='Digite seu texto aqui'></textarea>
                        <button type='submit' class='btn btn-default'>Enviar</button>
                    </form>
                    </div>
                </div>
            </div>
        </div>
        <!-- Optional JavaScript -->
        <!-- jQuery first, then Popper.js, then Bootstrap JS -->
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
    </body>
</html>

Método HTTP usado

O método usado no form foi o POST, pois quero mandar as informações digitadas no formulário para o backend, ou seja, quero salvar no banco.

{% csrf_token %}

O {% csrf_token %} é uma proteção Cross Site Request Forgery, que é um tipo de ataque malicioso a um site, onde comandos não autorizados são transmitidos através de um usuário em quem o site confia.

Diferente do cross-site scripting (XSS), que explora a confiança de um usuário em um site, o CSRF explora a confiança que um site tem no navegador do usuário.

Caso não use o {% csrf_token %} no form, na hora que você tentar enviar o formulário, será mostrado a seguinte mensagem de erro:

CSRF verification failed. Request aborted

Faça uma modificação, apenas para teste mesmo, no arquivo src/e_commerce/views.py

As mudanças estão em laranja no código abaixo:


from django.http import HttpResponse
from django.shortcuts import render
def home_page(request):
    context = {
        "title": "Página principal",
        "content": "Bem-vindo a página principal"
    }
    return render(request, "home_page.html", context)

def about_page(request):
    context = {
        "title": "Página sobre",
        "content": "Bem-vindo a página sobre"
    }
    return render(request, "about/view.html", context)

def contact_page(request):
    context = {
        "title": "Página de contato",
        "content": "Bem-vindo a página de contato"
    }
    if request.method == "POST":
        print(request.POST)
    return render(request, "contact/view.html", context)

Teste vendo o print no shell

Insira um nome e email, depois clique em enviar e veja no shell onde o servidor tá rodando, o resultado dos prints das linhas que estão em laranja no código acima.

O formulário da forma como está, não valida nenhum campo e não lança nenhum erro ao preencher o formulário de forma errada, por isso, a melhor forma no django para fazer um formulário é usando a biblioteca forms do django.

forms.py

Primeiro crie o arquivo src/e_commerce/forms.py e insira esse conteúdo:

from django import forms

class ContactForm(forms.Form):
    fullname = forms.CharField()
    email = forms.EmailField()
    content = forms.CharField()

Utilizando o form da biblioteca do django

Vamos modificar novamente src/templates/contact/view.html, o que mudou tá em laranja no código abaixo.

Onde foi trocado o formulário html normal, hard code, pelo context {{ form }} utilizando a biblioteca forms do django.

<!doctype html>
<html lang="en">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

        <title>Formulário de contato</title>
    </head>
    <body>
        <div class='text-center'>
            <h1>{{ title }}</h1>
        </div>
        <div class='container'>
            <div class='row'>
                <div class='col'>
                    <p>{{ content }}</p
                    <div class='col-sm-6 col-12'>
                    <form method='POST'> {% csrf_token %}
                        {{ form }}
                        <button type='submit' class='btn btn-default'>Enviar</button>
                    </form>
                    </div>
                </div>
            </div>
        </div>
        <!-- Optional JavaScript -->
        <!-- jQuery first, then Popper.js, then Bootstrap JS -->
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
    </body>
</html

E em src/e_commerce/views.py importe ContactForm, instancie um contact form e crie o contact form como variável de contexto.

As mudanças estão em laranja no código abaixo:


from django.http import HttpResponse
from django.shortcuts import render

from .forms import ContactForm
def home_page(request): context = { "title": "Página principal", "content": "Bem-vindo a página principal" } return render(request, "home_page.html", context) def about_page(request): context = { "title": "Página sobre", "content": "Bem-vindo a página sobre" } return render(request, "about/view.html", context) def contact_page(request):
contact_form = ContactForm(request.POST or None) context = {
"title": "Página de contato", "content": "Bem-vindo a página de contato",
"form": contact_form } if request.method == "POST": print(request.POST) return render(request, "contact/view.html", context)

Com o servidor rodando, veja como está o formulário: 127.0.0.1:8000/contact/

Modifique o arquivo src/e_commerce/forms.py para utilizar widgets personalizados.

Para maiores detalhes sobre Customizing widget instances, acesse:

https://docs.djangoproject.com/en/2.1/ref/forms/widgets/#customizing-widget-instances

O que tá em laranja no código abaixo é o que tá formatando os campos do form com o Customizing widget instances

from django import forms

class ContactForm(forms.Form):
    full_name = forms.CharField(
        widget=forms.TextInput(
            attrs={
                    "class": "form-control", 
                    "placeholder": "Seu nome completo"
                }
            )
        )
    email     = forms.EmailField(
        widget=forms.EmailInput(
            attrs={
                    "class": "form-control", 
                    "placeholder": "Digite seu email"
                }
            )
        )
    content   = forms.CharField(
        widget=forms.Textarea(
            attrs={
                    "class": "form-control", 
                    "placeholder": "Digite sua mensagem"
                }
            )
)

Modifique o arquivo src/e_commerce/forms.py para customizar as mensagens de campo obrigatório.

from django import forms

class ContactForm(forms.Form):
    nome_completo = forms.CharField(
error_messages={'required': 'Obrigatório o preenchimento do nome'}, widget=forms.TextInput( attrs={ "class": "form-control", "placeholder": "Seu nome completo" } ) ) email = forms.EmailField(
error_messages={'invalid': 'Digite um email válido!'}, widget=forms.EmailInput( attrs={ "class": "form-control", "placeholder": "Digite seu email" } ) ) mensagem = forms.CharField(
error_messages={'required': 'É obrigatório o preenchimento do campo mensagem!'}, widget=forms.Textarea( attrs={ "class": "form-control", "placeholder": "Digite sua mensagem" } ) )

Faça um teste, digite um nome, email e qualquer texto e clique em enviar. Olhe no shell e veja os prints com os dados digitados.

Vamos modificar novamente o src/e_commerce/views.py

As mudanças estão em laranja no código abaixo:


from django.http import HttpResponse
from django.shortcuts import render

from .forms import ContactForm def home_page(request): context = { "title": "Página principal", "content": "Bem-vindo a página principal" } return render(request, "home_page.html", context) def about_page(request): context = { "title": "Página sobre", "content": "Bem-vindo a página sobre" } return render(request, "about/view.html", context) def contact_page(request):
contact_form = ContactForm(request.POST or None) context = { "title": "Página de contato", "content": "Bem-vindo a página de contato"
"form": contact_form }
if contact_form.is_valid():
print(contact_form.cleaned_data) #if request.method == "POST": #print(request.POST) #print(request.POST.get('Nome_Completo')) #print(request.POST.get('email')) #print(request.POST.get('Mensagem')) return render(request, "contact/view.html", context)

Bora colocar uma  validação de email no src/e_commerce/forms.py só pra testar?

Vamos supor que o email tenha que ser necessariamente do gmail para ser aceito.

Então vamos refatorar o código, veja abaixo em laranja.

from django import forms

class ContactForm(forms.Form):
    full_name = forms.CharField(
        widget=forms.TextInput(
            attrs={
                    "class": "form-control", 
                    "placeholder": "Seu nome completo"
                }
            )
        )
    email     = forms.EmailField(
        widget=forms.EmailInput(
            attrs={
                    "class": "form-control", 
                    "placeholder": "Digite seu email"
                }
            )
        )
    content   = forms.CharField(
        widget=forms.Textarea(
            attrs={
                    "class": "form-control", 
                    "placeholder": "Digite sua mensagem"
                }
            )
        )
    def clean_email(self):
        email = self.cleaned_data.get("email")
        if not "gmail.com" in email:
            raise forms.ValidationError("O Email deve ser do gmail.com")
        return email

Agora faça um teste tentando cadastrar um email que não seja gmail e veja o que acontece.

Com isso encerramos mais essa aula.

Aula 03                Aula 05

Todas as aulas desse curso

Voltar para página principal do blog

Curta a página do Código Fluente no Facebook
https://www.facebook.com/Codigofluente-338485370069035/

Vou deixar meu link de referidos na digitalocean pra vocês.

Quem se cadastrar por esse link, ganha $100.00 dólares de crédito na digitalocean:

Digital Ocean

Esse outro link é da one.com:

One.com

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

Obrigado, até a próxima e bons estudos. 😉

About The Author
-

7 Comentários

  • Erisvaldo Carvalho
    Reply

    Estou acompanhando sua série de vídeos, estou gostando do conteúdo, parabéns pela iniciativa em dividir seu conhecimento! Acho que vou demorar um pouco para concluir porque estou estou repetindo 21 vezes cada implementação pra fixar melhor o conteúdo.

    • toticavalcanti
      Reply

      Que bom que o conteúdo tem te ajudado Erisvaldo.
      Sucesso e bons estudos. \o/ 😉

  • Wesley
    Reply

    a parte de validação do gmail não funcionou comigo

    • toticavalcanti
      Reply

      Fala Wesley, blz?
      Qual mensagem de erro que tá dando?

    • Gustavo
      Reply

      No meu está funcionando de boa. Veja se não é indentação.

  • joao
    Reply

    Boa noite, na parte do error_messages, a pagina continua mostrando a mensagem de erro padrão do django.

    • toticavalcanti
      Reply

      Opa João, blz?
      O que diz exatamente a mensagem de erro?
      Se quiser uma solução rápida, clona a branch dessa aula e roda pra vê se funciona.
      Outra opção é copiar o código do meu github, colar no arquivo que tá dando erro, e vê as diferenças.
      Dá uma checada nas identações, não pode misturar espaços, com tab, ou é só tab, ou só espaços.
      Vlw
      \o/

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>