Solucionado (ver solução)
Solucionado
(ver solução)
13
respostas

Problema validado form/dados

Pessoal,

Verifiquei o seguinte case (Curso do Django modulo 11): Se nao informo algum dos campos do form (todos são obrigatorios), ele faz o redirect para uma pagina e não me valida os dados/form. Alguém pode dar um help? Agradeço. Obrigado

from django import forms
from django.contrib.auth.models import User

class RegistrarUsuarioForm(forms.Form):
    nome = forms.CharField(required=True)
    email = forms.EmailField(required=True)
    senha = forms.CharField(required=True)
    telefone = forms.CharField(required=True)
    nome_empresa = forms.CharField(required=True)

    def is_valid(self):
        valid = True
        if not super(RegistrarUsuarioForm, self).is_valid():
            self.adiciona_erro('Por favor, verifique os dados informados.')
            valid = False

        user_exists = User.objects.filter(username=self.data['nome']).exists()

        if user_exists:
            self.adiciona_erro('Usuario ja existente.')
            valid = False
        return valid

    def adiciona_erro(self, message):
        errors = self._errors.setdefault(forms.forms.NON_FIELD_ERRORS, forms.utils.ErrorList())
        errors.append(message)


from django.shortcuts import redirect
from django.shortcuts import render
from django.contrib.auth.models import User
from django.views.generic.base import View
from perfis.models import Perfil
from usuarios.forms import RegistrarUsuarioForm

class RegistrarUsuarioView(View):

    template_name = 'registrar.html'

    def get(self, request):
        return render(request, self.template_name)

    def post(self, request):
        form = RegistrarUsuarioForm(request.POST)

        if form.is_valid():
            dados_form = form.data
            #cria o usuario
            usuario = User.objects.create_user(dados_form['nome'], dados_form['email'], dados_form['senha'])
            #cria o perfil
            perfil = Perfil(nome=dados_form['nome'], 
                            email=dados_form['email'],
                            telefone=dados_form['telefone'], 
                            nome_empresa=dados_form['nome_empresa'], 
                            usuario=usuario)
            perfil.save()

            #redireciona para index
            return redirect('index')

        return render(request, self.template_name, {'form' : form})
13 respostas

Pessoal, help-me please.

Se eu preencho o campo email com um email invalido ele me manda para a index (não entra no if e printa so o 99). Não estou conseguindo entender como ele ta me mandando para a index, in pratica ele deveria ficar na pagina de registracao e me mostrar os erros etc.

def post(self, request):
        form = RegistrarUsuarioForm(request.POST)

        print('99 @@@@@@@@@@@@@@@@@@@@@@@@@@@@')    

        if form.is_valid():

            print('1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@')    

            dados_form = form.data
            usuario = User.objects.create_user(dados_form['nome'], dados_form['email'], dados_form['senha'])
            perfil = Perfil(nome=dados_form['nome'], email=dados_form['email'], telefone=dados_form['telefone'], nome_empresa=dados_form['nome_empresa'], usuario=usuario)
            perfil.save()

            print('2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@')    
            return redirect('index')

        print('3 @@@@@@@@@@@@@@@@@@@@@@@@@@@@')    
        return render(request, self.template_name, {'form' : form})

Ola Flavio.

Gostaria de receber um help, não estou conseguindo resolver e estou perdendo muito tempo por uma coisa que penso seja algum detalhe "pequeno":

Praticamente ele nao entra no if corretamente porque is_valid == False, mas o detalhe e que ele não faz o

return render(request, self.template_name, {'form' : form})

mas faz um redirect na pagina de perfis (index.html).

from django.shortcuts import redirect
from django.shortcuts import render
from django.contrib.auth.models import User
from django.views.generic.base import View
from perfis.models import Perfil
from usuarios.forms import RegistrarUsuarioForm

class RegistrarUsuarioView(View):

    template_name = 'registrar.html'

    def get(self, request):
        return render(request, self.template_name)

    def post(self, request):
        form = RegistrarUsuarioForm(request.POST)

        print('@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - form: {} - form_data: {}'.format(form.is_valid(), form.data))    

        if form.is_valid():
            dados_form = form.data
            usuario = User.objects.create_user(dados_form['nome'], dados_form['email'], dados_form['senha'])
            perfil = Perfil(nome=dados_form['nome'], email=dados_form['email'], telefone=dados_form['telefone'], nome_empresa=dados_form['nome_empresa'], usuario=usuario)
            perfil.save()
            return redirect('index')

        return render(request, self.template_name, {'form' : form})

Oi Melo, Deixa eu ver se entendi.

Você diz que ele não entra dentro do if form.is_valid(), ainda assim ele teria que fazer o return render... porque esta fora do bloco do if. Certo? Mas você diz que ele não faz.

Já verificou a indentação do seu código, verificando se o return render... não esta no bloco do if?

Oi Flavio. Isso mesmo, ele deve executar o return render..., mas não sei como ele corretamente não inseri no banco os dados mas me manda (faz o redirect para a index).

Ja organizei e reorganizei toda essa classe varias vezes , mas continua no mesmo jeito. Se eu cadastro os dados preenchendo todo o form ele entra no if (inseri os dados etc e faz o redirect index etc correttamente). Abs,

Sua última resposta não ficou clara mim. Não entendi isso

"mas não sei como ele corretamente não inseri no banco os dados mas me manda".

Bom, resumindo o que entendi. Você tem campo obrigatório, mas ele esta te direcionando para index.html e não para o form. Certo?

Então, você precisa postar o código do HTML no qual você indicou a validação via atributo. Se estiver algo errado lá, ele não vai validar. Se estiver escrito errado ou se não foi colocado nos campos. Isso porque seu validador extrai as informações os inputs enviados.

É a hipótese de não estar funcionando, dá uma checada lá. Aliás, não pode mudar os names dos campos, viu.

Outra coisa, você esta usando a versão do Django 1.7.4 indicada logo no início do curso? Se esta usando algo novo, pode ser que tenham mudado e não ficamos sabendo.

Oi Flavio. Estou usando a versão do curso (django 1.7.4) Entao, ele nao valida os dados do form mas faz o redirect para a index.html

Segue o form/html:

{% extends "base_usuario.html" %}

{% block body %}

    <form class="form-signin" action="{% url 'registrar' %}" method="post">

        {% csrf_token %}

        <h2 class="form-signin-heading">Crie seu usuário</h2>
        <input type="text" id="id_email" name="email" class="form-control" placeholder="Email *" value="{{form.email.value}}" required autofocus>
        <input type="text" id="id_nome" name="nome" class="form-control" placeholder="Nome *" value="{{form.nome.value}}" required >
        <input type="password" id="id_senha" name="senha" class="form-control" placeholder="Senha *" value="{{form.senha.value}}" required>

        <hr/>
        <input type="text" id="id_telefone" name="telefone" class="form-control" placeholder="Telefone" value="{{form.telefone.value}}">
        <input type="text" id="id_nome_empresa" name="nome_empresa" class="form-control" placeholder="Empresa" value="{{form.nome_empresa.value}}">

        <hr/>
        <button class="btn btn-lg btn-primary btn-block" type="submit" value="Login">Registrar</button>

        <a href="{% url 'login' %}">Login</a>

        <!-- if novo aqui ERRORS -->
        <hr/>
        {% if form.erros %}

            <div class="alert alert-danger">
                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                {{form.non_field_errors}}
            </div>

        {% endif %}
        <!-- fim if novo -->
    </form>

{% endblock %}

Codigo do form.py

from django import forms
from django.contrib.auth.models import User

class RegistrarUsuarioForm(forms.Form):
    nome = forms.CharField(required=True)
    email = forms.EmailField(required=True)
    senha = forms.CharField(required=True)
    telefone = forms.CharField(required=True)
    nome_empresa = forms.CharField(required=True)

    def is_valid(self):
        valid = True
        if not super(RegistrarUsuarioForm, self).is_valid():
            self.adiciona_erro('Por favor, verifique os dados informados.')
            valid = False

        user_exists = User.objects.filter(username=self.data['nome']).exists()

        if user_exists:
            self.adiciona_erro('Usuario ja existente.')
            valid = False

        return valid

    def adiciona_erro(self, message):
        erros = self._errors.setdefault(forms.forms.NON_FIELD_ERRORS, forms.utils.ErrorList())
        erros.append(message)

Flavio,

Era algum problema na identacao de alguma linha etc, recriei a classe e consegui fazer funcionar.

Agora ela fica no form mas não me faz ver os erros do form. Vc pode dar uma olhada no html? ta um pouco confuso erros com errors :D

Agradeço seu help. Obrigado. Abs

Tem que verificar seu método adiciona_erros depois das últimas mudanças. É ele quem disponibiliza a mensagem de erro para o form.

Oi Flavio.

O metodo esta exatamente como no exercício do curso:

    def adiciona_erro(self, message):
        erros = self._errors.setdefault(forms.forms.NON_FIELD_ERRORS, forms.utils.ErrorList())
        erros.append(message)

        print('*********************** message: {} '.format(message))

Result print:

4/Jun/2017 18:48:56] "GET /static/styles/main.css HTTP/1.1" 200 982 [04/Jun/2017 18:48:57] "GET /registrar/ HTTP/1.1" 200 1533 * message: Por favor, verifique os dados informados. [04/Jun/2017 18:49:15] "POST /registrar/ HTTP/1.1" 200 1549

HTML

{% extends "base_usuario.html" %}

{% block body %}

    <form class="form-signin" action="{% url 'registrar' %}" method="post">

        {% csrf_token %}

        <h2 class="form-signin-heading">Crie seu usuário</h2>
        <input type="text" id="id_email" name="email" class="form-control" placeholder="Email *" value="{{form.email.value}}" required autofocus>
        <input type="text" id="id_nome" name="nome" class="form-control" placeholder="Nome *" value="{{form.nome.value}}" required >
        <input type="password" id="id_senha" name="senha" class="form-control" placeholder="Senha *" value="{{form.senha.value}}" required>

        <hr/>
        <input type="text" id="id_telefone" name="telefone" class="form-control" placeholder="Telefone" value="{{form.telefone.value}}">
        <input type="text" id="id_nome_empresa" name="nome_empresa" class="form-control" placeholder="Empresa" value="{{form.nome_empresa.value}}">

        <hr/>
        <button class="btn btn-lg btn-primary btn-block" type="submit" value="Login">Registrar</button>

        <a href="{% url 'login' %}">Login</a>

        <!-- if novo aqui ERRORS -->
        <hr/>
        {% if form.erros %}

            <div class="alert alert-danger">
                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                {{form.non_field_erros}}
            </div>

        {% endif %}
        <!-- fim if novo -->
    </form>

{% endblock %}
solução!

Flavio,

Consegui alterando todos os erros X errors:

    def adiciona_erro(self, message):
        errors = self._errors.setdefault(forms.forms.NON_FIELD_ERRORS, forms.utils.ErrorList())
        errors.append(message)

HTML:
{% if form.errors %}

            <div class="alert alert-danger">
                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                {{form.non_field_errors}}
            </div>

        {% endif %}

Pessoal, bom dia. Nesta validação, tentei inserir um usuário que já existe. Até ai tudo bem, conseguir até dar um print na mensagem que informa que o usuário já existe.

Ocorre que estou tendo o erro abaixo:

AttributeError at /registrar/
'NoneType' object has no attribute 'setdefault'
Request Method:    POST
Request URL:    http://localhost:8082/registrar/
Django Version:    1.7.4
Exception Type:    AttributeError
Exception Value:    
'NoneType' object has no attribute 'setdefault'
Exception Location:    C:\Projetos\safepass\usuarios\forms.py in adiciona_erro, line 36
Python Executable:    C:\Python27\python.exe

A linha 36, do forms.py é essa:

        errors = self._errors.setdefault(forms.forms.NON_FIELD_ERRORS, forms.utils.ErrorList())

Segue o forms.py todo:

# -*- coding: utf-8 -*-
from django import forms
from django.contrib.auth.models import User

class RegistrarUsuarioForm(forms.Form):

    ds_login = forms.CharField(required = True)
    cpf_cgc = forms.CharField(required = True)
    nome_razao = forms.CharField(required = True)
    senha = forms.CharField(required = True)
    email = forms.EmailField(required = True)
    telefone = forms.CharField(required = False)
    site = forms.CharField(required = False)

    def is_valid(self):

        valid = True

        if not super(RegistrarUsuarioForm, self).is_valid:
            self.adiciona_erro('Por favor, verifique os dados informados!')
            valid = False

        usuario_existe = User.objects.filter(username=self.data['ds_login']).exists()

        if usuario_existe:
            nome_usuario_existe = self.data['ds_login']
            msg_usuario_existe = "Usuario ja existente: %s " %(nome_usuario_existe)  
            print(msg_usuario_existe)
            self.adiciona_erro(msg_usuario_existe)
            valid = False 

        return valid

    def adiciona_erro(self, message):
        errors = self._errors.setdefault(forms.forms.NON_FIELD_ERRORS, forms.utils.ErrorList())
        errors.append(message)

Se puderem me dar um help! Grato,

Trevisolli