Skip to content

App Users

Angel riera edited this page Apr 1, 2022 · 3 revisions

Registro de usuarios personalizado

creamos los modelos

models.py

from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.utils.translation import gettext_lazy as _


# administra al customuser
class CustomUserManager(BaseUserManager):
    """Define a model manager for User model with no username field."""

    def _create_user(self, email, password=None, **extra_fields):
        """Create and save a User with the given email and password."""
        if not email:
            raise ValueError("The given email must be set")
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password=None, **extra_fields):
        extra_fields.setdefault("is_staff", False)
        extra_fields.setdefault("is_superuser", False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password=None, **extra_fields):
        """Create and save a SuperUser with the given email and password."""
        extra_fields.setdefault("is_staff", True)
        extra_fields.setdefault("is_superuser", True)
        if extra_fields.get("is_staff") is not True:
            raise ValueError("Superuser must have is_staff=True.")
        if extra_fields.get("is_superuser") is not True:
            raise ValueError("Superuser must have is_superuser=True.")
        return self._create_user(email, password, **extra_fields)


# user general que se autenticará con email
class CustomUser(AbstractUser):
    username = None
    email = models.EmailField(_("email address"), unique=True)

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = []

    # necesita de un manager que lo administre para crearlo con ciertos campos
    objects = CustomUserManager()

creamos los formularios de usuario

forms.py

from django import forms
from django.contrib.auth.forms import UserCreationForm

from .models import CustomUser, Seller


class UserForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ("first_name", "last_name", "email", "password1", "password2")


class UserEditForm(forms.ModelForm):
    class Meta:
        model = CustomUser
        fields = ("first_name", "last_name", "email")

Decorador para no autentificado

decorators.py

from django.shortcuts import redirect


def unauthenticated_user(view_func):
    def wrapper_func(request, *args, **kwargs):
        if request.user.is_authenticated:
            return redirect("ecommerce:home")
        else:
            return view_func(request, *args, **kwargs)

    return wrapper_func

Creamos la veiw de registro, login, logut, y modificar usuario

# Todas las importaciones
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect, render

from ecommerce.decorators import unauthenticated_user
from ecommerce.models import Product
from users.models import Seller

from .forms import SellerForm, UserEditForm, UserForm

registro de usuario

@unauthenticated_user
def register_view(request):
    form = UserForm
    if request.method == "POST":
        form = UserForm(request.POST)
        if form.is_valid():
            user = form.save()
            login(request, user)
            useremail = form.cleaned_data.get("email")
            messages.success(request, f"{useremail} was succesfully created")
            return redirect("users:login")

    return render(request, "users/register.html", {"user_registration": form})

login de usuario

@unauthenticated_user
def login_view(request):
    if request.method == "POST":
        email = request.POST.get("email")
        password = request.POST.get("password")

        user = authenticate(request, email=email, password=password)
        if user is not None:
            login(request, user)
            return redirect("ecommerce:home")
        else:
            messages.info(request, "Email or password is incorrect.")

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

logout

def logout_view(request):
    logout(request)
    return redirect("users:login")

view user

@login_required
def user_panel(request):
    if hasattr(request.user, "seller"):
        products = Product.objects.filter(seller=request.user.seller)
        ctx = {"products": products}
        return render(request, "users/user_panel.html", ctx)
    else:
        return render(request, "users/user_panel.html")

Modificar datos de usuario

@login_required
def user_modify_view(request):
    try:
        instance_seller = Seller.objects.get(profile__id=request.user.id)
    except Seller.DoesNotExist:
        instance_seller = None
    user_form = UserEditForm(instance=request.user)
    seller_form = SellerForm(instance=instance_seller)
    if request.method == "POST":
        user_form = UserEditForm(request.POST, instance=request.user)
        seller_form = SellerForm(request.POST or None, instance=instance_seller)
        if user_form.is_valid() and seller_form.is_valid():
            custom_user = user_form.save()
            seller = seller_form.save(commit=False)
            seller.profile = custom_user
            seller.save()
            return redirect("users:user_panel")
        elif user_form.is_valid():
            user_form.save()
            return redirect("users:user_panel")

    return render(request, "users/users_edit.html", {"user_form": user_form, "seller_form": seller_form})

Registro de vendedores

models.py

class Seller(models.Model):
    profile = models.OneToOneField(CustomUser, on_delete=models.CASCADE, related_name="seller", primary_key=True)
    seller_name = models.CharField(max_length=50, unique=True)
    # is_active = models.BooleanField(default=False)

    def __str__(self):
        return f"{self.seller_name}"

forms.py

class SellerForm(forms.ModelForm):
    class Meta:
        model = Seller
        fields = ("seller_name",)

views.py

@login_required
def seller_register(request):
    """ registro disponible para clientes, debe estar registrado en la plataforma para acceder a este registro"""
    """ hay que preveer de que alguien ya registrado como vendedor no se pueda volver a entrar a este registro"""
    seller_form = SellerForm()
    if request.method == "POST":
        seller_form = SellerForm(request.POST)
        if seller_form.is_valid():
            seller = seller_form.save(commit=False)
            seller.profile = request.user
            seller.save()
            return redirect("ecommerce:home")

    return render(request, "users/seller_register.html", {"seller_form": seller_form})

registro de urls

from django.urls import path

from . import views

app_name = "users"

urlpatterns = [
    path("register/", views.register_view, name="register"),
    path("login/", views.login_view, name="login"),
    path("logout/", views.logout_view, name="logout"),
    path("seller_register/", views.seller_register, name="seller_register"),
    path("user_panel/", views.user_panel, name="user_panel"),
    path("user_edit/", views.user_modify_view, name="user_edit"),
]

uso de urls y formularios

login

<form method="post" action="" class="px-20 pt-12 w-full flex-col space-y-6">
			{% csrf_token %}
			<div class="flex flex-col ">
				<label for="input_email" class="text-left text-red-800">Email*</label>
				<input type="text" name="email"
					class="leading-none focus:outline-none border-b-2 hover:border-b-3 border-red-700">
			</div>

			<div class="flex  flex-col  ">
				<label for="password" class="text-left text-red-800">Password</label>
				<input type="password" name="password"
					class="leading-none focus:outline-none border-b-2 hover:border-b-3 border-red-700">

			</div>
			{% if user_registration.errors %}
			<div class="text-center text-red-700 mt-4">
				{{ user_registration.errors }}
			</div>
			{% endif %}

			<div class="mt-16 pt-16 flex justify-center">
				<input type="submit" class="w-full  w-2/3 px-20 py-3 border border-red-500" value="Login">
			</div>
		</form>

register

		<form id="form" method="post" action="" class="px-20 pt-12 w-full flex-col space-y-6">
			{% csrf_token %}
			<div class="flex flex-col ">
				<label for="name" class="text-left text-red-800">First Name*</label>
				{{ user_registration.first_name }}
			</div>

			<div class="flex flex-col ">
				<label for="Last" class="text-left text-red-800">Last Name*</label>
				{{ user_registration.last_name }}

			</div>
			<div class="flex flex-col ">
				<label for="input_email" class="text-left text-red-800">Email*</label>
				{{ user_registration.email }}

			</div>
			<div class="flex  flex-col  ">
				<label for="password" class="text-left text-red-800">Enter password...</label>
				{{ user_registration.password1 }}

			</div>
			<div class="flex  flex-col  ">
				<label for="password" class="text-left text-red-800">Re-enter Password...</label>
				{{ user_registration.password2 }}

				{% if user_registration.errors %}

				<div class="text-center text-red-700 mt-4">

					{{ user_registration.errors }}
				</div>
				{% endif %}

			</div>
			<div class="mt-16 pt-16 flex justify-center">
				<input type="submit" class="w-full  w-2/3 px-20 py-3 border border-red-500" value="Register">
			</div>



		</form>

<script>
	/* Because i didnt set placeholder values in forms.py they will be set here using vanilla Javascript
//We start indexing at one because CSRF_token is considered and input field 
*/

	//Query All input fields
	var form_fields = document.getElementById('form')
	for (var field in form_fields) {
		form_fields[field].className += 'leading-none focus:outline-none border-b-2 hover:border-b-3 border-red-700'
	}
</script>

urls

   <div class="flex flex-col-reverse  justify-end ml-4">

                        {% if request.user.is_authenticated %}
                        <a href="{% url 'users:user_panel' %}" class="flex mt-2">
                            <img class="m-1 inline-block h-5 w-5 rounded-full ring-2 ring-white"
                                src="https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png"
                                alt="">
                            <p class="text-right font-bold">

                                {{ request.user.first_name }}
                            </p>
                        </a>


                        <div>

                            <a class="whitespace-nowrap text-base  text-gray-500 hover:text-gray-900"
                                href="{% url 'users:logout' %}">
                                Logout
                            </a>
                            {% else %}
                            <div>
                                <a class=" whitespace-nowrap text-base  text-gray-500 hover:text-gray-900"
                                    href="{% url 'users:login' %}">
                                    login
                                </a>
                                {% endif %}
                                <a class="ml-2 whitespace-nowrap text-base  text-red-800 hover:text-gray-900"
                                    href="{% url 'shopping_cart:home' %}"> Cart ( 0 )
                                </a>
                            </div>

                        </div>

                    </div>