Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Signup

22/37
Recursos

Crearemos el Registro de usuario a partir de la clase perfil, por lo que usaremos un formulario personalizado. Definiremos un nuevo Template para el formulario. Dejaremos que el browser se encargue de las validaciones generales. Sólo validaremos en python la coincidencia entre password y confirmación del password. Incluiremos una validación con try/catch para evitar que se dupliquen usuarios con mismo nombre.

Aportes 38

Preguntas 16

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Por si a alguno le pasó que le dio un Multikey value error, les dejo la solución en Django 3.0 para los métodos de post:

username = request.POST['username']
        password = request.POST.get('passwd', True)
        passwordConfirmation = request.POST.get('passwd_confirmation', True)

Le agregue validacion de email para que no se registren emails ya usados.

def signup_view(request):
    '''Signup view'''

    if request.method == 'POST':
        email = request.POST['email']
        username = request.POST['username']
        password = request.POST['password']
        password_confirm = request.POST['password_confirm']

        # PASSWORD VALIDATION
        if password != password_confirm:
            error = 'The passwords do not match.'
            return render(request, 'users/signup.html', {'error': error})
        
        # EMAIL VALIDATION
        u = User.objects.filter(email=email)
        if u:
            error = f'There is another account using {email}'
            return render(request, 'users/signup.html', {'error': error})
        
        # USERNAME VALIDATION 
        try:
            user = User.objects.create_user(username=username, password=password)
            user.email = email
            user.save()

            profile = Profile(user=user)
            profile.save()

            login(request, user)
            return redirect('profile') # CAMBIAR >> Redireccionar a completar perfil
        except IntegrityError as ie:
            error = f'There is another account using {usermame}'
            return render(request, 'users/signup.html', {'error': error})

    return render(request, 'users/signup.html')

Al final del registro estaría mejor hacer login y redireccionar al feed, en lugar de hacer registro y después login:

def signup_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        password_confirmation = request.POST['password_confirmation']

        if password != password_confirmation:
            return render(request, 'users/signup.html', {'error': 'Password confirmation does not match'})

        try:
            user = User.objects.create_user(username=username, password=password)
        except IntegrityError as ie:
            return render(request, 'users/signup.html', {'error': 'Username is already in use'})

        user.first_name = request.POST['firstname']
        user.last_name = request.POST['lastname']
        user.email = request.POST['email']
        user.save()

        profile = Profile(user=user)
        profile.save()

        login(request, user)
        return redirect('feed')

    return render(request, 'users/signup.html')

codigo del signup

{% extends "users/base.html" %}

{% block head_content %}
<title>Platzigram sign up</title>
{% endblock %}

{% block container %}

    {% if error %}
        <p class="alert alert-danger">{{ error }}</p>
    {% endif %}

    <form action="{% url 'signup' %}" method="POST">
        {% csrf_token %}

        <div class="form-group">
            <input class="form-control" type="text" placeholder="Username" name="username" required="true" />
        </div>

        <div class="form-group">
            <input class="form-control" type="password" placeholder="Password" name="password" required="true" />
        </div>

        <div class="form-group">
            <input class="form-control" type="password" placeholder="Password confirmation" name="password_confirmation" required="true" />
        </div>

        <div class="form-group">
            <input class="form-control" type="text" placeholder="Firs namet" name="first_name" required="true" />
        </div>

        <div class="form-group">
            <input class="form-control" type="text" placeholder="Last name" name="last_name" required="true" />
        </div>

        <div class="form-group">
            <input class="form-control" type="email" placeholder="eMail address" name="email" required="true" />
        </div>

        <button class="btn btn-primary btn-block mt-5" type="submit">Register!</button>

    </form>
{% endblock %}
Hay alguna forma que yo como administrador acepte al nuevo user que se creó? Ejemplo: una persona X crea una nueva cuenta, pero no puede usarla hasta que yo la habilite

https://chrome.google.com/webstore/detail/fake-filler/bnjjngeaknajbdcgpfkgnonkmififhfo/related?hl=es

Para que llenen los formularios con datos de prueba a un click, desde el navegador

Modifiqué algo en el sign up para que en vez de hacerle redirección a que inicie sesión, de una vez entra al feed de posts

def signup(request):
    """Sign up view."""
    if request.method == 'POST':
        username = request.POST['username']
        passwd = request.POST['passwd']
        passwd_confirmation = request.POST['passwd_confirmation']
        
        if passwd != passwd_confirmation:
            return render(
                request,
                'users/signup.html',
                {'error': 'Password confirmation does not match'}
            )
        
        try:
            user = User.objects.create_user(
                username=username,
                password=passwd,
            )
        except IntegrityError:
            return render(
                request,
                'users/signup.html',
                {'error': 'Username is already in use'}
            )
            
        user.first_name = request.POST['first_name']
        user.last_name = request.POST['last_name']
        user.email = request.POST['email']
        user.save()
        
        profile = Profile(user=user)
        profile.save()
        
        # return redirect('login')
        login(request, user)
        return redirect('feed')
    return render(request, 'users/signup.html')

hice el signup un tanto diferente, con verificador de username y email.

def signup_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        password_confirmation = request.POST['password_confirmation']
        email = request.POST['email']

        if password != password_confirmation:
            return render(request, 'users/signup.html', {'error': "Passwords does'nt match"})
        
        if User.objects.filter(username=username).exists():
            return render(request, 'users/signup.html', {'error': "Username is already exists."})

        if User.objects.filter(email=email).exists():
            return render(request, 'users/signup.html', {'error': "Email is already registered."})

        user = User.objects.create_user(username=username, password=password, email=email)

        user.first_name = request.POST['first_name'] 
        user.last_name = request.POST['last_name'] 
        user.save()

        profile = Profile(user=user)
        profile.save()

        login(request, user)
        return redirect('feed')

    return render(request, 'users/signup.html')

Siguiendo los comentarios y sugerencias de varios agregue al modelo de User el campo unique para email, para que no puedan haber emails repetidos:

User._meta.get_field('email')._unique = True

Luego agregue el email en create_user para que valide el email unico al crearse el usuario antes de registrarlo en la BD e hice un if en el try para validar si el IntegrityError fuera generado por el username o por el email y devolver el correspondiente error:

def signup_view(request):
    if request.method == "POST":
        password = request.POST["password"]
        password_confirmation = request.POST["password_confirmation"]
        if password != password_confirmation:
            return render(request, 'users/signup.html', { "error": "Password confirmation does not match "})
        
        username = request.POST["username"]
        email = request.POST["email"]

        try:
            user = User.objects.create_user(username=username, password=password, email=email)
        except IntegrityError as e:
            if e.args[0] == 'UNIQUE constraint failed: auth_user.email':
                return render(request, 'users/signup.html', { "error": "Email is already in use"})
            else:
                return render(request, 'users/signup.html', { "error": "Username is already in use"})

        user.first_name = request.POST["first_name"]
        user.last_name = request.POST["last_name"]
        user.save()

        profile = Profile(user=user)
        profile.save()

Por ultimo no use redirect(“login”), sino que renderice el template de login pasandole como contexto mensaje de success si el usuario fue creado con exito para que lo muestre en el html:

return render(request, 'users/login.html', { "success": "User created successfully"})

codigo del view

"""Users views."""
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect

# Exceptions
from django.db.utils import IntegrityError

# Models
from django.contrib.auth.models import User
from users.models import Profile

# Create your views here.

def login_view(request):
    """Login view."""
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user:
            login(request, user)
            return redirect('feed')
        else:
            return render(request, 'users/login.html', {'error': 'Ivanlid username and password'})
    return render(request, 'users/login.html')


def signup(request):
    """Sign up view."""
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        password_confirmation = request.POST['password_confirmation']

        if password != password_confirmation:
            return render(request, 'users/signup.html', {'error': 'Password confirmation does not match'})

        try:
            user = User.objects.create_user(username=username, password=password)
        except IntegrityError:
            return render(request, 'users/signup.html', {'error': 'Username is already in use'})

        user.first_name = request.POST['first_name']
        user.last_name = request.POST['last_name']
        user.email = request.POST['email']
        user.save()

        profile = Profile(user=user)
        profile.save()

        return render(request, 'users/login.html')

    return render(request, 'users/signup.html')

@login_required
def logout_view(request):
    """Logout view."""
    logout(request)
    return redirect('login')

Para : Platzi Team

El día de ayer envíe un a pregunta en cuanto a que no me sale correctamente la pantalla centrada el username, password y Sign In , también no se despliega el icono de instagram.

El anterior problema lo tengo desde el video 19 de “Templates y archivos estáticos”.

Por lo cual pido apoyo al equipo Platzi Team, ya que no he obtenido respuesta para solucionar lo anterior, siendo importante ya que estoy por iniciar el video 22 "Signup"
no quiero completar el curso con estos detalles importantes sin solucionar !!!

Atte.

Anibal

Para los que les sale multiples errores, yo tuve que mezclar mucho de muchos comentarios. Principalmente gracias a Diego Casillas Duarte y franciscoyorlano.
Mi codigo es este, espero a alguien lo salve

En users/views.py

from django.contrib.auth.models import User
from users.models import Profile
from django.db import IntegrityError


def signup_view(request):
    '''Signup view'''

    if request.method == 'POST':
        email = request.POST['email']
        username = request.POST['username']
        password = request.POST.get('passwd', True)
        password_confirm = request.POST.get('passwd_confirmation', True)

        # PASSWORD VALIDATION
        if password != password_confirm:
            error = 'The passwords do not match.'
            return render(request, 'users/signup.html', {'error': error})
        
        # EMAIL VALIDATION
        u = User.objects.filter(email=email)
        if u:
            error = f'There is another account using {email}'
            return render(request, 'users/signup.html', {'error': error})
        
        # USERNAME VALIDATION 
        try:
            user = User.objects.create_user(username=username, password=password)
            user.email = email
            user.save()

            profile = Profile(user=user)
            profile.save()

            login(request, user)
            return redirect('profile') # CAMBIAR >> Redireccionar a completar perfil
        except IntegrityError as ie:
            error = f'There is another account using {username}'
            return render(request, 'users/signup.html', {'error': error})

    return render(request, 'users/signup.html')


@login_required
def logout_view(request):
    """Logout a user"""

    logout(request)
    return redirect('login')

En platzigram/urls.py

urlpatterns = [
    path('users/signup', users_views.signup_view, name='signup'),
] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)

Y luego en el template es idéntico al del profe. Mucha suerte!

Buenas día, tengo un detalle…al usar los mismos códigos presentados en la clase me surge error UNIQUE constraint failed: auth_user.username…por lo que me marcar integrity error a pesar de que el usuario se acaba de crear y teniendo la excepción integrity error programada. Versión de django == 3.1, python == 3.8, OS == windows 10
![](url C:\Users\Lenovo\Desktop\EliasCAmovil\EliasCA\BROXIA Intelligence\integrity error.png)
![](url C:\Users\Lenovo\Desktop\signup.png)

Una vez el usuario se registro, pueden hacerle login asi:

...
login(request,user)
return redirect('feed')

De esta manera no tiene que llenar todos sus datos de nuevo en login ya que es tedioso

Pienso que en una futura actualización de este curso y en muchos otros que sean de introducción sería bueno que mantuvieran este enfoque de ir de la mano con la documentación, es lo más valioso que tiene este curso a nivel pedagógico.

Si se modifica un registro de la base de datos, a través de un objeto, recuerda utilizar save()

Como es de esperarse, es dentro de nuestra vista, que hacemos todas las validaciones, para ingresar los datos de un usuario.

Nota: Jamás confiar en las validaciones que hace el frontend.

Dentro de nuestro input, es mejor poner un requiered="True", además de ser consistentes con nuestros nombres.

Cada vez que se cree un usuario, se crea un perfil, debio al modelo Proxy que pusimos en la clase Profile.

I did my signup view this way, to prevent repeat code unnecessarily

def signup(request):
    if request.method == 'POST':
        fields = (
            'username',
            'passwd',
            'passwd_confirmation',
            'first_name',
            'last_name',
            'email',
        )
        error = {}
        user_data = dict((key, request.POST[key]) for key in fields)
        if user_data['passwd'] != user_data['passwd_confirmation']:
            error = {'error': 'Password confirmation doesn\'t match'}
        else:
            try:
                user = User.objects.create_user(username=user_data['username'], password=user_data['passwd'])
                user.first_name = user_data['first_name']
                user.last_name = user_data['last_name']
                user.email = user_data['email']

                user_profile = Profile(user=user)
                user_profile.save()
                return redirect('login')
            except IntegrityError as ex:
                error = {'error': "Username already taken!"}


    return render(request, 'users/signup.html', error)

Hola, soy de los tantos que no entienden nada de lo que esta haciendo en los archivos html, mas que nada cuando usa bootstrap.
Es para preocuparme? Un puesto de trabajo en el que pidan django tambien requiere saber el nivel del profesor en frontend? O de eso se encargaria un frontend y yo solamente debo saber integrarlo mediante vistas y logica?

perfecto muchas gracias pablo

Asi deje mi metodo porque puede ser un poco como primero creo usuarios y contraseña y luego instancio los otros campos.

def signup(request):
""“Sign up view.”""
if request.method == ‘POST’:
username = request.POST[‘username’]
passwd = request.POST[‘passwd’]
passwd_confirmation = request.POST[‘passwd_confirmation’]

    if passwd != passwd_confirmation:
        return render(request, 'users/signup.html', {'error': 'Password confirmation does not match'})
    first_name = request.POST['first_name']
    last_name = request.POST['last_name']
    email = request.POST['email']
    try:
        user = User.objects.create_user(username=username, password=passwd,first_name=first_name,last_name=last_name,email=email)
    except IntegrityError:
        return render(request, 'users/signup.html', {'error': 'Username is already in user'})


    profile = Profile(user=user)
    profile.save()

    return redirect('login')

return render(request, 'users/signup.html')

View para signup

Haciendo las pruebas me sale este error cuando intento guardar a un usuario con el mismo username

En lugar del IntegrityError… ¿Por qué será?. Cuando coloco todos los datos correctos no me da ningún problema.

Este es mi método signup

Cómo se debe hacer un request desde una aplicacion en React con el token de login? es decir , como desde una aplicación en React ouede decire al servidor de Django que ya hice login y tengo cierto scope?

def create_account(request):
    """Create account user"""
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        password_confirmation = request.POST['password_confirmation']
        first_name = request.POST['first_name']
        last_name = request.POST['last_name']
        email = request.POST['email']

        if password != password_confirmation:
            return render(request, 'users/create_account.html', {'error': 'Password confirmation does not match'})

        try:
            user = User.objects.create_user(
                username=username, password=password, first_name=first_name, last_name=last_name, email=email)
        except IntegrityError:
            return render(request, 'users/create_account.html', {'error': 'Username ir already in user'})

        website = request.POST['website']
        phone_number = request.POST['phone_number']
        biography = request.POST['biography']

        profile = Profiles.objects.create(
            user=user, website=website, phone_number=phone_number, biography=biography)

        return redirect('login')

    return render(request, 'users/create_account.html')```

¿Alguien sabe cómo puedo hacer para guardar en MAYÚSUCLAS los datos recibidos de un form?

Intenté modificando el estilo en html pero, no funcionó XD, alguien sabe algo?

¿Porqué se empecinan en mostrar herramientas de backend implementadas en frontend???
el curso que stoy tomando dice “backend con django” y ya hasta aprendí html y css. No se pasen. Si dice backend. hagan backend…

Uno de los mejores profesores y cursos que hay…

Excelente clase les comparto este tutorial acerca de autentificacion de usuarios esta perfecto para complementar con esta clase:

formulario del signup.html

{% extends 'users/base.html' %}
{% block head_content %}
    <title>PlatziGram sign in</title>
{% endblock %}
{% block container %}
    <form action="{% url "signup" %}" method="POST">
        {% csrf_token %}
        <div class="form-group">
            <input class="form-control" type="text" placeholder="Username" name="name" required="true">
        </div>
        <div class="form-group">
            <input class="form-control" type="password" placeholder="Password" name="password" required="true">
        </div>
        <div class="form-group">
            <input class="form-control" type="password" placeholder="Password confirmation" name="password_confirmation" required="true">
        </div>
        <div class="form-group">
            <input class="form-control" type="text" placeholder="First name" name="first_name" required="true">
        </div>
        <div class="form-group">
            <input class="form-control" type="text" placeholder="Last name" name="last_name" required="true">
        </div>
        <div class="form-group">
            <input class="form-control" type="email" placeholder="Email" name="email" required="true">
        </div>
        <button class="btn btn-primary btn-block mt-5" type="submit"> Sign in!</button>
    </form>
{% endblock

Crearemos el Registro de usuario a partir de la clase perfil, por lo que usaremos un formulario personalizado. Definiremos un nuevo Template para el formulario. Dejaremos que el browser se encargue de las validaciones generales. Sólo validaremos en python la coincidencia entre password y confirmación del password. Incluiremos una validación con try/catch para evitar que se dupliquen usuarios con mismo nombre.

Muy buen ejercicio

Para poder agregar un botón al Login para acceder al SignUp pueden agregar esto en el archivo: [users/login.html]
(afuera del <form>)

<button class="btn btn-primary btn-block mt-5" onclick="location.href = '{% url "signup" %}'">Sign Up!</button>
```html

jejeje, funciona!