Resumo : neste tutorial, você aprenderá como implementar um perfil de usuário em aplicações Django.
Este tutorial começa onde o tutorial de redefinição de senha do Django parou.
Um perfil de usuário consiste em configurações e informações associadas a um usuário. Neste tutorial, você aprenderá como permitir que usuários atualizem seus perfis em aplicações Django.
Instalando o pacote de travesseiros
Como trataremos de imagens, precisamos instalar o pillow
pacote usando o seguinte pip
comando:
pip install Pillow
Linguagem de código: Python ( python )
Configurando o diretório para armazenar as imagens enviadas
Primeiro, crie um media
diretório no projeto:
mkdir media
Linguagem de código: Python ( python )
Em segundo lugar, adicione o MEDIA_ROOT
e MEDIA_URL
ao settings.py
do projeto:
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'
Linguagem de código: Python ( python )
Especifica
o diretório que armazena a imagem carregada. Especifica MEDIA_ROOT
MEDIA_URL
o URL que exibe os arquivos de imagem do
diretório.MEDIA_ROOT
Terceiro, adicione a URL que fornece os arquivos de mídia ao urls.py
projeto da seguinte maneira:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('todo.urls')),
path('',include('users.urls'))
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
Linguagem de código: Python ( python )
Se DEBUG
estiver True
no settings.py
arquivo, o aplicativo Django servirá os arquivos de mídia de MEDIA_URL
.
Criando um modelo de perfil
Modifique o models.py
do users
aplicativo e defina o Profile
modelo da seguinte forma:
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
avatar = models.ImageField(
default='avatar.jpg', # default avatar
upload_to='profile_avatars' # dir to store the image
)
def __str__(self):
return f'{self.user.username} Profile'
def save(self, *args, **kwargs):
# save the profile first
super().save(*args, **kwargs)
# resize the image
img = Image.open(self.avatar.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
# create a thumbnail
img.thumbnail(output_size)
# overwrite the larger image
img.save(self.avatar.path)
Linguagem de código: Python ( python )
Como funciona.
Primeiro, defina o Profile
modelo que herda da Model
classe:
class Profile(models.Model):
Linguagem de código: CSS ( css )
Segundo, cada usuário possui um perfil e cada perfil pertence a um usuário. Portanto, a relação entre o User
modelo e o Profile
modelo é um para um.
Para definir o relacionamento um-para-um , você usa OneToOneField
:
user = models.OneToOneField(User, on_delete=models.CASCADE)
Linguagem de código: Python ( python )
Se a User
for excluído, o Profile
associado a User
também será excluído. Isso indica no on_delete=models.CASCADE
parâmetro do OneToOneField()
.
Terceiro, defina o avatar
campo que contém o avatar do usuário:
avatar = models.ImageField(
default='avatar.jpg', # default avatar
upload_to='profile_avatars' # dir to store the image
)
Linguagem de código: Python ( python )
Se os usuários não carregaram avatares, o padrão é avatar.jpg
file. Além disso, especificamos o diretório ( profile_avatars
) que armazenará os avatares carregados.
Observe que você pode adicionar mais campos ao Profile
modelo, como endereços, interesses, etc., se necessário.
Quarto, baixe o avatar.jpg
arquivo e copie-o para o media
diretório do projeto:
Quinto, defina o __str__()
método que retorna uma representação em string do Profile
modelo:
def __str__(self):
return f'{self.user.username} Profile'
Linguagem de código: Python ( python )
Sexto, defina o save()
método que salva o perfil no banco de dados, cria uma miniatura do avatar e o armazena no diretório especificado:
def save(self, *args, **kwargs):
# save the profile first
super().save(*args, **kwargs)
# resize the image
img = Image.open(self.avatar.path)
if img.height > 150 or img.width > 150:
output_size = (150, 150)
# create a thumbnail
img.thumbnail(output_size)
# overwrite the large image
img.save(self.avatar.path)
Linguagem de código: Python ( python )
Sétimo, cadastre o Perfil no admin.py
para que possamos gerenciar o perfil na página de administração:
from django.contrib import admin
from .models import Profile
admin.site.register(Profile)
Linguagem de código: Python ( python )
Aplicando as migrações
Primeiro, faça migrações executando o makemigrations
comando:
python manage.py makemigrations
Linguagem de código: Python ( python )
Saída:
Migrations for 'users':
users\migrations\0001_initial.py
- Create model Profile
Linguagem de código: Python ( python )
Segundo, aplique as migrações:
python manage.py migrate
Linguagem de código: Python ( python )
Saída:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, todo, users
Running migrations:
Applying users.0001_initial... OK
Linguagem de código: Python ( python )
Criando a visualização MeuPerfil
Defina uma MyProfile
visualização baseada em classe no views.py
arquivo:
from django.views import View
# ...
class MyProfile(LoginRequiredMixin, View):
def get(self, request):
user_form = UserUpdateForm(instance=request.user)
profile_form = ProfileUpdateForm(instance=request.user.profile)
context = {
'user_form': user_form,
'profile_form': profile_form
}
return render(request, 'users/profile.html', context)
def post(self,request):
user_form = UserUpdateForm(
request.POST,
instance=request.user
)
profile_form = ProfileUpdateForm(
request.POST,
request.FILES,
instance=request.user.profile
)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
messages.success(request,'Your profile has been updated successfully')
return redirect('profile')
else:
context = {
'user_form': user_form,
'profile_form': profile_form
}
messages.error(request,'Error updating you profile')
return render(request, 'users/profile.html', context)
Linguagem de código: Python ( python )
Primeiro, importe a View
classe de django.views
:
from django.views import View
Linguagem de código: Python ( python )
Segundo, defina
a classe que herda da MyView
View
classe. A
classe possui os métodos MyView
get()
e post()
que correspondem aos métodos HTTP GET
e POST
.
Ao usar a View
classe, você não precisa ter ramificações if-else dentro de uma função de visualização para determinar se o método HTTP é GET ou POST.
No get()
método da MyProfile
classe, criamos os objetos UserUpdateForm
e ProfileUpdateForm
e os passamos para o profile.html
template.
No post()
método, também criamos os objetos UserUpdateForm
and ProfileUpdateForm
, mas passamos dados adicionais de request.POST
and request.FILES
.
Quando ambos os formulários são válidos, nós os salvamos no banco de dados, criamos uma mensagem flash e redirecionamos o usuário de volta para a página de perfil.
Se um dos formulários não for válido, criamos uma mensagem de erro e redirecionamos o usuário de volta à página de perfil e renderizamos novamente o modelo.
Criando modelo profile.html
Crie profile.html
no templates/users
diretório que estende o base.html
modelo:
{% extends 'base.html' %}
{% block content %}
<div class="center">
<form method="POST" enctype="multipart/form-data" class="card">
{% csrf_token %}
{% if user.profile %}
<img src="{{user.profile.avatar.url}}" alt="{{ user.username }}" class="avatar" accept=".jpg,.jpeg,.png"/>
{% endif %}
<h2 class="text-center">{{ user.username | title }}</h2>
<p class="text-center"><a href="mailto:{{user.email}}">{{user.email}}</a></p>
<hr>
<label for="email">Email Address:</label>
<input type="email" id="email" name="email" value="{{user.email}}" />
<label for="avatar">Avatar:</label>
<input type="file" name="avatar" id="avatar">
<button type="submit" class="btn btn-primary full-width">Update Profile</button>
</form>
</div>
{% endblock content %}
Linguagem de código: Python ( python )
Criando um perfil manualmente
Primeiro, faça login no site de administração usando a conta de superusuário, você verá Profiles
abaixo do Users
aplicativo:
Segundo, clique no botão Adicionar perfil para criar um novo perfil para o usuário existente:
Terceiro, adicione um novo perfil para o usuário John e clique no botão Salvar:
O Django mostrará que o perfil do usuário John foi adicionado com sucesso.
Se você fizer login como John e abrir a página de perfil http://127.0.0.1:8000/profile/
, verá a seguinte página:
Neste formulário você pode atualizar um perfil alterando o endereço de e-mail e enviando um novo avatar.
Incluir o URL do perfil no cabeçalho
Modifique o base.html
modelo para adicionar o URL do perfil ao cabeçalho:
{%load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{% static 'css/style.css' %}" />
<title>Todo List</title>
</head>
<body>
<header class="header">
<div class="container">
<a href="{%url 'home'%}" class="logo">Todo</a>
<nav class="nav">
<a href="{%url 'home'%}"><i class="bi bi-house-fill"></i> Home</a>
{% if request.user.is_authenticated %}
<a href="{% url 'tasks' %}"><i class="bi bi-list-task"></i> My Tasks</a>
<a href="{% url 'task-create' %}"><i class="bi bi-plus-circle"></i> Create Task</a>
<a href="{% url 'profile' %}" title="Update my profile">Hi {{request.user | title}}</a>
<a href="{% url 'logout' %}" class="btn btn-outline">Logout</a>
{% else %}
<a href="{% url 'login' %}" class="btn btn-outline">Login</a>
<a href="{% url 'register' %}" class="btn btn-primary">Join Now</a>
{% endif %}
</nav>
</div>
</header>
<main>
<div class="container">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{message.tags}}">
{{message}}
</div>
{% endfor %}
{% endif %}
{%block content %}
{%endblock content%}
</div>
</main>
<footer class="footer">
<div class="container">
<p>© Copyright {% now "Y" %} by <a href="https://tutorials.acervolima.com">Python Tutorial</a></p>
</div>
</footer>
</body>
</html>
Linguagem de código: HTML, XML ( xml )
Criando perfil automaticamente
Se você fizer login como Jane
e acessar a página de perfil, receberá o seguinte erro:
A razão é que não criamos o perfil do usuário Jane
. Para corrigir esse problema, devemos criar um perfil assim que o usuário se registrar com sucesso. Para implementar isso, usaremos algo chamado sinais no Django.
Primeiro, crie signals.py
um arquivo no users
aplicativo com o seguinte código:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()
Linguagem de código: Python ( python )
Neste signals.py
arquivo:
- A
create_profile()
função cria um novo perfil apósUser
a criação de um objeto. - A
save_profile()
função atualiza o perfil depois que umUser
objeto é salvo.
O @receiver
decorador conecta o post_save
evento do User
modelo a cada função.
Segundo, importe sinais para o apps.py
arquivo do users
aplicativo:
from django.apps import AppConfig
class UsersConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'users'
def ready(self):
import users.signals
Linguagem de código: Python ( python )
No apps.py
aplicativo users
, importamos o signals.py
método ready da UsersConfig
classe.
Terceiro, registre um novo usuário e verifique o perfil:
Você pode baixar o código-fonte completo do perfil de usuário do Django aqui .
Resumo
- Use o sinal Django para criar um perfil para um usuário automaticamente.