Aula 82 – Loja Online – Formulário Personalizado do Modelo User
Aula 82 – Loja Online – Formulário Personalizado do Modelo User
Voltar para página principal do blog
Todas as aulas desse curso
Aula 81 Aula 83
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 82 – Loja Online – Formulário Personalizado do Modelo User
Admin
Classe UserAdmin
No código do django_ecommerce/e_commerce/accounts/admin.py, a classe UserAdmin é uma extensão da classe BaseUserAdmin fornecida pelo Django.
Ela personaliza a exibição e as opções de administração do modelo de usuário personalizado.
Define os formulários UserAdminCreationForm e UserAdminChangeForm para adicionar e alterar instâncias de usuário, respectivamente.
Define também os campos a serem exibidos no modelo usuário, como: email e se o usuário é um administrador.
Configura os campos de pesquisa e filtros para facilitar a busca e filtragem dos usuários.
Define os grupos de campos para edição de usuário e criação de usuário.
Registra o modelo de usuário personalizado, aplicando a classe UserAdmin a ele.
Classe GuestEmailAdmin
A classe GuestEmailAdmin é uma extensão da classe ModelAdmin fornecida pelo Django.
Ela personaliza a exibição e as opções de administração do modelo GuestEmail.
Configura o campo de pesquisa por email para facilitar a busca de registros de GuestEmail.
Registra o modelo GuestEmail e aplica a classe GuestEmailAdmin a ele.
django_ecommerce/e_commerce/accounts/admin.py
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from .forms import UserAdminCreationForm, UserAdminChangeForm
from .models import GuestEmail
User = get_user_model()
class UserAdmin(BaseUserAdmin):
# The forms to add and change user instances
form = UserAdminChangeForm
add_form = UserAdminCreationForm
# The fields to be used in displaying the User model.
# These override the definitions on the base UserAdmin
# that reference specific fields on auth.User.
list_display = ['email', 'admin']
list_filter = ['admin', 'staff', 'active']
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ()}),
('Permissions', {'fields': ('admin', 'staff', 'active',)}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password', 'password_2')}
),
)
search_fields = ['email']
ordering = ['email']
filter_horizontal = ()
admin.site.register(User, UserAdmin)
# Remove Group Model from admin. We're not using it.
admin.site.unregister(Group)
class GuestEmailAdmin(admin.ModelAdmin):
search_fields = ['email']
class Meta:
model = GuestEmail
admin.site.register(GuestEmail, GuestEmailAdmin)
Explicando algumas partes do código em mais detalhes.
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ()}),
('Permissions', {'fields': ('admin', 'staff', 'active',)}),
)
Nesse trecho, a variável fieldsets é uma tupla que define os grupos de campos a serem exibidos na página de administração do modelo de usuário personalizado.
- O primeiro grupo de campos tem o rótulo “None” (nenhum) e contém os campos ‘email‘ e ‘password‘.
- O segundo grupo de campos tem o rótulo “Personal info” (informações pessoais) e não contém nenhum campo. Esse grupo está vazio.
- O terceiro grupo de campos tem o rótulo “Permissions” (permissões) e contém os campos ‘admin‘, ‘staff‘ e ‘active‘.
Cada grupo de campos é uma tupla que consiste em um rótulo (opcionalmente, None) e um dicionário com a chave ‘fields’ que especifica os campos a serem exibidos nesse grupo.
Essa estrutura de grupos de campos permite organizar e agrupar os campos de informações pessoais, permissões e outros em seções distintas na página de administração, tornando-a mais clara e organizada.
Agora essa parte:
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2')}
),
)
search_fields = ['email']
ordering = ['email']
filter_horizontal = ()
add_fieldsets
É uma tupla que define a forma como os campos são exibidos ao adicionar um novo usuário através da página de administração.
Nesse caso, há apenas um grupo de campos, sem rótulo (None), e contém os campos ‘email’, ‘password1’ e ‘password2’.
Além disso, a classe CSS ‘wide‘ é aplicada ao grupo de campos para que ele seja exibido em uma largura maior.
search_fields
É uma lista que especifica os campos do modelo de usuário pelos quais é possível realizar uma busca na página de administração.
Nesse caso, apenas o campo ‘email‘ é definido como um campo de busca.
ordering
É uma lista que define a ordem em que os registros do modelo de usuário são exibidos na página de administração.
Nesse caso, a ordem é definida pelo campo ‘email‘, ou seja, os registros são ordenados alfabeticamente pelo endereço de email.
filter_horizontal
É uma tupla vazia que indica que não há campos para exibir em formato horizontal no painel de administração.
Essa configuração é usada para campos de relacionamento muitos-para-muitos, como grupos de permissões, mas neste caso não há nenhum campo desse tipo.
Ainda relativo ao código acima, a parte:
class GuestEmailAdmin(admin.ModelAdmin):
search_fields = ['email']
class Meta:
model = GuestEmail
admin.site.register(GuestEmail, GuestEmailAdmin)
search_fields é uma lista que especifica os campos do modelo GuestEmail pelos quais é possível realizar uma busca na página de administração.
Neste caso, apenas o campo ‘email‘ é definido como um campo de busca.
Isso significa que na página de administração, haverá uma caixa de pesquisa onde você pode digitar um endereço de e-mail e pesquisar por registros que correspondam a esse valor.
Meta é uma classe interna do GuestEmailAdmin que define metadados adicionais para o modelo GuestEmail.
Nesse caso, a propriedade model é definida como GuestEmail, indicando qual modelo está associado a essa classe de administração.
Essas configurações permitem que você adicione um campo de busca específico e defina o modelo ao qual essa classe de administração está associada.
Dessa forma, você pode personalizar a forma como o modelo GuestEmail é exibido e gerenciado na página de administração do Django.
Seguindo para o e_commerce/accounts/forms.py.
Forms
Classe UserAdminCreationForm
No código do django_ecommerce/e_commerce/accounts/forms.py, a classe UserAdminCreationForm é um formulário para a criação de novos usuários.
Ela herda de forms.ModelForm e é associada ao modelo de usuário personalizado.
Define os campos necessários para criar um novo usuário, incluindo uma senha repetida para confirmação.
Implementa uma verificação para garantir que as senhas sejam iguais antes de salvar o usuário.
E sobrescreve o método save para salvar a senha fornecida no formato de hash.
Classe UserAdminChangeForm
É um formulário para a atualização de usuários existentes.
Herda de forms.ModelForm e é associada ao modelo de usuário personalizado.
Substitui o campo de senha pelo campo somente leitura que exibe o hash da senha atual.
E garante que a senha inicial seja retornada independentemente do que o usuário forneça.
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 = ['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):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
class RegisterForm(forms.Form):
username = forms.CharField()
email = forms.EmailField()
password = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(label='Confirm password', widget=forms.PasswordInput)
def clean_username(self):
username = self.cleaned_data.get('username')
qs = User.objects.filter(username=username)
if qs.exists():
raise forms.ValidationError("Esse usuário já existe, escolha outro nome.")
return username
def clean_email(self):
email = self.cleaned_data.get('email')
qs = User.objects.filter(email=email)
if qs.exists():
raise forms.ValidationError("Esse email já existe, tente outro!")
return email
def clean(self):
data = self.cleaned_data
password = self.cleaned_data.get('password')
password2 = self.cleaned_data.get('password2')
if password != password2:
raise forms.ValidationError("As senhas informadas devem ser iguais!")
return data
Explicando algumas partes do código em mais detalhes.
UserAdminCreationForm
A password1 e password2 são campos de senha utilizados para inserir a senha do usuário e confirmar a senha, respectivamente.
Eles são definidos como campos forms.CharField com rótulos específicos e widgets de forms.PasswordInput para ocultar os caracteres digitados.
Meta é a classe interna usada para definir a meta-informação do formulário.
No caso desse formulário, especifica que o modelo User é o modelo base para o formulário e o campo email como o único campo a ser exibido no formulário.
O clean() é um método de validação personalizado que verifica se as duas senhas fornecidas (password1 e password2) correspondem.
Se as senhas não corresponderem, vai lançar um erro com a mensagem: “Your passwords must match“.
E o save() é o método usado para salvar o usuário no banco de dados.
Ele chama o método save() da classe base forms.ModelForm para criar uma instância do modelo User, define a senha fornecida no formato hash e salva o usuário no banco de dados.
No contexto da classe UserAdminCreationForm, o motivo de usar commit=False é permitir a manipulação da senha antes de salvar o usuário no banco de dados.
O código seguinte à chamada do método save() é responsável por definir a senha fornecida pelo usuário no formato hash e, em seguida, salvar o usuário no banco de dados somente se o parâmetro commit for True.
Dessa forma, você tem a oportunidade de processar a senha antes de salvar o usuário, garantindo que ela esteja armazenada de forma segura.
O parâmetro commit=True indica que o usuário deve ser salvo imediatamente, por isso tá assim:
user = super(UserAdminCreationForm, self).save(commit=False)
O método clean_password() é usado na classe UserAdminChangeForm para retornar o valor inicial do campo de senha.
O campo password da classe UserAdminChangeForm é definido como ReadOnlyPasswordHashField(), que exibe uma representação de hash da senha atual do usuário em vez do campo de senha original.
Portanto, o campo não é editável e não precisa ser validado.
Ao substituir o método clean_password(), o objetivo é retornar o valor inicial do campo password, ou seja, a representação de hash da senha atual para garantir que o campo não seja alterado acidentalmente quando o formulário for atualizado.
Esses métodos clean() e clean_password() são exemplos de como o Django permite personalizar a validação dos campos de um formulário de acordo com as necessidades específicas do aplicativo.
UserAdminChangeForm
O password é um campo somente leitura (ReadOnly) que exibe o valor hash da senha do usuário atual.
Ele usa a classe ReadOnlyPasswordHashField, que é um widget do Django para exibir senhas em formato hash sem permitir que sejam editadas.
A classe Meta é usada para definir a meta-informação do formulário.
Nesse caso, os campos email, password, active e admin são especificados para serem exibidos no formulário.
O método clean_password() não é realmente utilizado neste contexto.
Ele retorna o valor inicial do campo de senha (password) sem fazer nenhuma validação adicional.
Essas duas classes fornecem os formulários necessários para a criação e atualização de usuários na aplicação Django.
Elas definem os campos necessários e validações personalizadas, além de lidarem com o salvamento dos dados do usuário no banco de dados.
Na próxima aula vamos adicionar campos obrigatórios ao nosso User personalizado.