Aula 85 – Transformando as Views: Atualizando Registro, Login e Logout
Aula 85 – Transformando as Views: Atualizando Registro, Login e Logout
Voltar para página principal do blog
Todas as aulas desse curso
Aula 84 Aula 86
Redes Sociais:
Meus links de afiliados:
Hostinger
Digital Ocean
One.com
Melhore seu NETWORKING
https://digitalinnovation.one/
Participe de comunidades de desenvolvedores:
Fiquem a vontade para me adicionar ao linkedin.
E também para me seguir no https://github.com/toticavalcanti.
Código final da aula:
https://github.com/toticavalcanti
Quer aprender python3 de graça e com certificado? Acesse então:
https://workover.com.br/python-codigo-fluente
Canais do Youtube
Toti
Lofi Music Zone Beats
Backing Track / Play-Along
Código Fluente
Putz!
Vocal Techniques and Exercises
PIX para doações
Aula 85 – Transformando as Views: Atualizando Registro, Login e Logout
Nesta aula, continuaremos nossa jornada transformando nossas Functions Based Views em Classes Based Views.
Atualizaremos as Views de registro, login e logout para seguir o padrão de Views baseadas em classe.
Para isso, vamos atualizar o django_ecommerce/e_commerce/accounts/views.py.
A parte em laranja é a View como tava, usando Function Based View, por isso está comentada.
Agora vamos usar Class Based View nas Views do Register, Login e Logout.
Atualizando a View de Registro (RegisterView)
Começamos transformando a View de registro.
Substituímos a função register_page pela classe RegisterView, utilizando a classe CreateView do Django.
Atualizando a View de Login (LoginView)
Em seguida, transformamos a View de login.
Usamos a classe FormView para criar a classe LoginView, implementando o método form_valid.
Atualizando a View de Logout (LogoutView)
Por fim, transformamos a View de logout.
Utilizamos a classe View para criar a classe LogoutView, que realiza o logout e renderiza o template.
Com essa transformação, nossas Views estão mais organizadas e seguindo o padrão de Classes Based Views do Django.
Essa mudança facilita a manutenção e o desenvolvimento futuro do nosso projeto.
django_ecommerce/e_commerce/accounts/views.py
from django.contrib.auth import authenticate, login, logout, get_user_model
from django.views.generic import CreateView, FormView, View
from django.http import HttpResponse,
from django.shortcuts import render,redirect
from django.utils.http import url_has_allowed_host_and_scheme
from .forms import LoginForm, RegisterForm, GuestForm
from .models import GuestEmail
def guest_register_view(request):
form = GuestForm(request.POST or None)
context = {
"form": form
}
next_ = request.GET.get('next')
next_post = request.POST.get('next')
redirect_path = next_ or next_post or None
if form.is_valid():
email = form.cleaned_data.get("email")
new_guest_email = GuestEmail.objects.create(email=email)
request.session['guest_email_id'] = new_guest_email.id
if url_has_allowed_host_and_scheme(redirect_path, request.get_host()):
return redirect(redirect_path)
else:
return redirect("/register/")
return redirect("/register/")
class LoginView(FormView):
form_class = LoginForm
success_url = '/' # Redireciona para a raiz do projeto
template_name = 'accounts/login.html'
def form_valid(self, form):
email = form.cleaned_data.get("email")
password = form.cleaned_data.get("password")
user = authenticate(request=self.request, username=email, password=password)
if user is not None:
login(self.request, user)
try:
del self.request.session['guest_email_id']
except:
pass
return super(LoginView, self).form_valid(form)
#def login_page(request):
# form = LoginForm(request.POST or None)
# context = {
# "form": form
# }
# next_ = request.GET.get('next')
# next_post = request.POST.get('next')
# redirect_path = next_ or next_post or None
# if form.is_valid():
# username = form.cleaned_data.get("username")
# password = form.cleaned_data.get("password")
# user = authenticate(request, username=username, password=password)
# if user is not None:
# login(request, user)
# try:
# del request.session['guest_email_id']
# except:
# pass
# if url_has_allowed_host_and_scheme( redirect_path, request.get_host() ):
# return redirect( redirect_path )
# else:
# # Redireciona para uma página de sucesso.
# return redirect("/")
# else:
# #Retorna uma mensagem de erro de 'invalid login'.
# print("Login inválido")
# return render(request, "accounts/login.html", context)
class LogoutView(View):
template_name = 'accounts/logout.html'
def get(self, request, *args, **kwargs):
context = {
"content": "Você efetuou o logout com sucesso! :)"
}
logout(request)
return render(request, self.template_name, context)
#def logout_page(request):
# context = {
# "content": "Você efetuou o logout com sucesso! :)"
# }
# logout(request)
# return render(request, "accounts/logout.html", context)
class RegisterView(CreateView):
form_class = RegisterForm
template_name = 'accounts/register.html'
success_url = '/login/'
#User = get_user_model()
#def register_page(request):
# form = RegisterForm(request.POST or None)
# context = {
# "form": form
# }
# if form.is_valid():
# form.save()
# return render(request, "accounts/register.html", context)
Faça as alterações em azul no urls.py.
As mudanças realizadas no arquivo urls.py visam atualizar as URLs para utilizar as Classes Based Views que foram criadas nas aulas anteriores.
Explicação das mudanças
Importações de Views
from accounts.views LoginView, RegisterView, LogoutView, guest_register_view
Foram adicionadas importações para as novas Classes Based Views LoginView, RegisterView e LogoutView que foram definidas anteriormente.
Substituição das URLs das Functions Based Views pelas Classes Based Views:
path('login/', LoginView.as_view(), name='login'),
path('register/', RegisterView.as_view(), name='register'),
path('logout/', LogoutView.as_view(), name='logout'),
As URLs que anteriormente eram mapeadas para as functions Based Views login_page, register_page e logout_page e foram atualizadas para utilizar as Classes Based Views correspondentes: LoginView.as_view(), RegisterView.as_view() e LogoutView.as_view().
Mantendo a Consistência
Ao substituir as URLs das Functions Based Views pelas Classes Based Views, a estrutura do código fica mais consistente e segue o padrão de nomenclatura do Django para Classes Based Views.
Isso torna o código mais organizado e facilita a manutenção e entendimento do projeto.
Com essas mudanças, o arquivo urls.py foi atualizado para utilizar as Classes Based Views no LoginView, RegisterView e LogoutView em vez das Functions Based Views originais.
Isso melhora a estrutura do código e segue as práticas recomendadas pelo Django para o desenvolvimento de Views.
django_ecommerce/e_commerce/e_commerce/urls.py
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.auth.views import LogoutView
from django.urls import path, include
from django.views.generic import TemplateView
from carts.views import cart_home, cart_detail_api_view
from accounts.views import LoginView, RegisterView, LogoutView, guest_register_view
from addresses.views import checkout_address_create_view, checkout_address_reuse_view
from .views import (home_page,
about_page,
contact_page
)
urlpatterns = [
path('', home_page, name='home'),
path('about/', about_page, name='about'),
path('contact/', contact_page, name='contact'),
path('cart/', include("carts.urls", namespace="cart")),
path('checkout/address/create/', checkout_address_create_view, name='checkout_address_create'),
path('checkout/address/reuse/', checkout_address_reuse_view, name='checkout_address_reuse'),
path('api/cart/', cart_detail_api_view, name='api-cart'),
path('login/', LoginView.as_view(), name='login'),
path('register/guest/', guest_register_view, name='guest_register'),
path('logout/', LogoutView.as_view(), name='logout'),
path('register/', RegisterView.as_view(), name='register'),
path('bootstrap/', TemplateView.as_view(template_name='bootstrap/example.html')),
path('search/', include("search.urls", namespace="search")),
path('products/', include("products.urls", namespace="products")),
path('admin/', admin.site.urls),
]
if settings.DEBUG:
urlpatterns = urlpatterns + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Comente a linha: user.active = False # send confirmation email
Troque o username para email (a parte azul no código abaixo)
django_ecommerce/e_commerce/accounts/forms.py
from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import ReadOnlyPasswordHashField
User = get_user_model()
class UserAdminCreationForm(forms.ModelForm):
"""
A form for creating new users. Includes all the required
fields, plus a repeated password.
"""
password = forms.CharField(widget=forms.PasswordInput)
password_2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ['email']
def clean(self):
'''
Verify both passwords match.
'''
cleaned_data = super().clean()
password = cleaned_data.get("password")
password_2 = cleaned_data.get("password_2")
if password is not None and password != password_2:
self.add_error("password_2", "Your passwords must match")
return cleaned_data
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserAdminCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password"])
if commit:
user.save()
return user
class UserAdminChangeForm(forms.ModelForm):
"""A form for updating users. Includes all the fields on
the user, but replaces the password field with admin's
password hash display field.
"""
password = ReadOnlyPasswordHashField()
class Meta:
model = User
fields = ['full_name', 'email', 'password', 'active', 'admin']
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
class GuestForm(forms.Form):
email = forms.EmailField()
class LoginForm(forms.Form):
email = forms.EmailField(label='Email')
password = forms.CharField(widget=forms.PasswordInput)
class RegisterForm(forms.ModelForm):
"""
A form for creating new users. Includes all the required
fields, plus a repeated password.
"""
password = forms.CharField(widget=forms.PasswordInput)
password_2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ['email']
def clean(self):
'''
Verify both passwords match.
'''
cleaned_data = super().clean()
password = cleaned_data.get("password")
password_2 = cleaned_data.get("password_2")
if password is not None and password != password_2:
self.add_error("password_2", "Your passwords must match")
return cleaned_data
def save(self, commit=True):
# Save the provided password in hashed format
user = super(RegisterForm, self).save(commit=False)
user.set_password(self.cleaned_data["password"])
# user.active = False # send confirmation email
if commit:
user.save()
return user