Resumo : neste tutorial, você aprenderá como criar um formulário de login do Django que permite aos usuários fazer login usando um nome de usuário e senha.
Este tutorial começa onde o tutorial Django Delete Form parou.
Criar uma nova aplicação
Primeiro, crie um novo aplicativo chamado users
executando o startapp
comando:
django-admin startapp users
O diretório do projeto ficará assim:
├── blog
├── db.sqlite3
├── manage.py
├── mysite
├── static
├── templates
└── users
Linguagem de código: texto simples ( texto simples )
Segundo, registre o users
aplicativo nos aplicativos instalados do settings.py
projeto:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# local
'blog.apps.BlogConfig',
'users.apps.UsersConfig'
]
Linguagem de código: Python ( python )
Terceiro, crie um novo urls.py
arquivo dentro do users
aplicativo com o seguinte código:
from django.urls import path
from . import views
urlpatterns = []
Linguagem de código: Python ( python )
Por fim, inclua o urls.py
da users
aplicação no urls.py
do projeto usando a include()
função:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('blog.urls')),
path('',include('users.urls'))
]
Linguagem de código: Python ( python )
Crie um formulário de login
Primeiro, crie uma URL de login no urls.py
aplicativo users
:
from django.urls import path
from . import views
urlpatterns = [
path('login/', views.sign_in, name='login'),
]
Linguagem de código: Python ( python )
Segundo, crie um forms.py
arquivo na users
aplicação e defina o LoginForm
que herda da Form
classe:
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(max_length=65)
password = forms.CharField(max_length=65, widget=forms.PasswordInput)
Linguagem de código: Python ( python )
O LoginForm
possui dois campos nome de usuário e senha.
Terceiro, crie a sign_in()
função no views.py
arquivo da users
aplicação para renderizar o login.html
template:
from django.shortcuts import render
from .forms import LoginForm
def sign_in(request):
if request.method == 'GET':
form = LoginForm()
return render(request, 'users/login.html', {'form': form})
Linguagem de código: Python ( python )
Quarto, crie o templates/users
diretório dentro da users
aplicação:
mkdir templates
cd templates
mkdir users
Linguagem de código: texto simples ( texto simples )
Quinto, crie o login.html
modelo dentro do templates/users
diretório que estende o base.html
modelo:
{% extends 'base.html' %}
{% block content %}
<form method="POST" novalidate>
{% csrf_token %}
<h2>Login</h2>
{{form.as_p}}
<input type="submit" value="Login" />
</form>
{% endblock content%}
Linguagem de código: HTML, XML ( xml )
Sexto, abra o URL de login e você verá o formulário de login:
http://127.0.0.1:8000/login
Linguagem de código: texto simples ( texto simples )
Se você inserir um nome de usuário/senha e clicar no botão Login, receberá um erro porque ainda não adicionamos o código que trata a solicitação HTTP POST.
Sétimo, modifique a sign_in()
função para lidar com o processo de login:
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth import login, authenticate
from .forms import LoginForm
def sign_in(request):
if request.method == 'GET':
form = LoginForm()
return render(request,'users/login.html', {'form': form})
elif request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(request,username=username,password=password)
if user:
login(request, user)
messages.success(request,f'Hi {username.title()}, welcome back!')
return redirect('posts')
# form is not valid or user is not authenticated
messages.error(request,f'Invalid username or password')
return render(request,'users/login.html',{'form': form})
Linguagem de código: Python ( python )
Como funciona.
Primeiro, importe a função authenticate
e login
do django.contrib.auth
módulo:
from django.contrib.auth import login, authenticate
Linguagem de código: Python ( python )
A authenticate()
função verifica um nome de usuário e senha. Se o nome de usuário e a senha forem válidos, ele retornará uma instância de User
classe ou None
não.
A login()
função faz login de um usuário. Tecnicamente, ela cria um ID de sessão no servidor e o envia de volta ao navegador na forma de um cookie.
Na solicitação subsequente, o navegador envia o ID da sessão de volta ao servidor web, o Django combina o valor do cookie com o ID da sessão e cria o User
objeto.
Segundo, verifique o nome de usuário e a senha usando a authenticate()
função se o formulário for válido:
user = authenticate(request, username=username, password=password)
Linguagem de código: Python ( python )
Terceiro, faça login do usuário, crie uma mensagem flash e redirecione o usuário para a posts
URL se o nome de usuário e a senha forem válidos:
if user:
login(request, user)
messages.success(request,f'Hi {user.username.title()}, welcome back!')
return redirect('posts')
Linguagem de código: Python ( python )
Caso contrário, crie uma mensagem de erro flash e redirecione o usuário de volta à página de login:
messages.error(request,f'Invalid username or password')
return render(request,'users/login.html')
Linguagem de código: Python ( python )
Se você inserir um nome de usuário sem senha e clicar no botão Login, receberá a seguinte mensagem de erro:
No entanto, se você inserir o nome de usuário/senha corretos, você será redirecionado para a página da lista de postagens com uma mensagem de boas-vindas:
Adicionar um formulário de logout
Primeiro, defina uma rota para desconectar um usuário:
from django.urls import path
from . import views
urlpatterns = [
path('login/', views.sign_in, name='login'),
path('logout/', views.sign_out, name='logout'),
]
Linguagem de código: JavaScript ( javascript )
Segundo, defina a sign_out()
função no views.py
arquivo que trata da rota de logout:
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth import login, authenticate, logout
from .forms import LoginForm
def sign_in(request):
if request.method == 'GET':
form = LoginForm()
return render(request,'users/login.html', {'form': form})
elif request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password=form.cleaned_data['password']
user = authenticate(request,username=username,password=password)
if user:
login(request, user)
messages.success(request,f'Hi {username.title()}, welcome back!')
return redirect('posts')
# either form not valid or user is not authenticated
messages.error(request,f'Invalid username or password')
return render(request,'users/login.html',{'form': form})
def sign_out(request):
logout(request)
messages.success(request,f'You have been logged out.')
return redirect('login')
Linguagem de código: Python ( python )
Se você fizer login e acessar a página de login, ainda verá o formulário de login. Portanto, é melhor redirecionar o usuário logado para a lista de postagens se o usuário acessar a página de login.
Terceiro, modifique a sign_in()
função no views.py
aplicativo users
:
def sign_in(request):
if request.method == 'GET':
if request.user.is_authenticated:
return redirect('posts')
form = LoginForm()
return render(request,'users/login.html', {'form': form})
elif request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password=form.cleaned_data['password']
user = authenticate(request,username=username,password=password)
if user:
login(request, user)
messages.success(request,f'Hi {username.title()}, welcome back!')
return redirect('posts')
# either form not valid or user is not authenticated
messages.error(request,f'Invalid username or password')
return render(request,'users/login.html',{'form': form})
Linguagem de código: PHP ( php )
O request.user.is_authenticated
retorno True
se um usuário estiver logado ou False
não.
Quarto, modifique o base.html
modelo para incluir o link de logout se o usuário estiver autenticado e o link de login caso contrário:
{%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' %}" />
<script src="{% static 'js/app.js' %}" defer></script>
<title>My Site</title>
</head>
<body>
<header>
{%if request.user.is_authenticated %}
<span>Hi {{ request.user.username | title }}</span>
<a href="{% url 'logout' %}">Logout</a>
{%else%}
<a href="{% url 'login' %}">Login</a>
{%endif%}
</header>
<main>
{% if messages %}
<div class="messages">
{% for message in messages %}
<div class="alert {% if message.tags %}alert-{{ message.tags }}"{% endif %}>
{{ message }}
</div>
{% endfor %}
</div>
{% endif %}
{%block content%}
{%endblock content%}
</main>
</body>
</html>
Linguagem de código: HTML, XML ( xml )
Se você acessar o site, verá o link de login:
Ao clicar no link de login, a página de login será aberta:
Se você inserir o nome de usuário e a senha válidos e fazer login, verá uma mensagem de boas-vindas, bem como o link de logout:
Se você clicar no link de logout, ele será redirecionado para a página de login:
Ocultando os links de edição e exclusão na lista de postagens
Se um usuário estiver logado, o arquivo request.user.is_authenticated
é True
. Portanto, você pode usar este objeto para mostrar e ocultar elementos da página, esteja o usuário logado ou não.
Por exemplo, o seguinte oculta os links de edição e exclusão no blog/home.html
modelo se o usuário estiver autenticado:
{% extends 'base.html' %}
{% block content %}
<h1>My Posts</h1>
{% for post in posts %}
<h2>{{ post.title }}</h2>
<small>Published on {{ post.published_at | date:"M d, Y" }} by {{ post.author | title}}</small>
<p>{{ post.content }}</p>
{% if request.user.is_authenticated %}
<p>
<a href="{% url 'post-edit' post.id %}">Edit</a>
<a href="{% url 'post-delete' post.id%}">Delete</a>
</p>
{% endif %}
{% endfor %}
{% endblock content %}
Linguagem de código: HTML, XML ( xml )
Protegendo as páginas protegidas
Normalmente, você deve permitir que usuários autenticados acessem as páginas de criação, atualização e exclusão de postagens. Para fazer isso você pode usar login_required
o decorador do Django.
Se uma função de visualização tiver o login_required
decorador e um usuário não autenticado tentar executá-la, o Django redirecionará o usuário para a página de login.
Protegeremos as funções de criação, atualização e exclusão de postagem usando o login_required
decorador.
Primeiro, defina o URL de login settings.py
no URL de login:
LOGIN_URL = 'login'
Linguagem de código: JavaScript ( javascript )
Se você não fizer isso, o Django irá redirecionar para a URL de login padrão que accounts/login/
não é users/login
a que definimos neste projeto.
Segundo, modifique o views.py
aplicativo blog
adicionando o @login_required
decorador às funções create_post
, edit_post
e :delete_post
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .models import Post
from .forms import PostForm
@login_required
def delete_post(request, id):
post = get_object_or_404(Post, pk=id)
context = {'post': post}
if request.method == 'GET':
return render(request, 'blog/post_confirm_delete.html', context)
elif request.method == 'POST':
post.delete()
messages.success(request, 'The post has been deleted successfully.')
return redirect('posts')
@login_required
def edit_post(request, id):
post = get_object_or_404(Post, id=id)
if request.method == 'GET':
context = {'form': PostForm(instance=post), 'id': id}
return render(request, 'blog/post_form.html', context)
elif request.method == 'POST':
form = PostForm(request.POST, instance=post)
if form.is_valid():
form.save()
messages.success(
request, 'The post has been updated successfully.')
return redirect('posts')
else:
messages.error(request, 'Please correct the following errors:')
return render(request, 'blog/post_form.html', {'form': form})
@login_required
def create_post(request):
if request.method == 'GET':
context = {'form': PostForm()}
return render(request, 'blog/post_form.html', context)
elif request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
form.save()
messages.success(
request, 'The post has been created successfully.')
return redirect('posts')
else:
messages.error(request, 'Please correct the following errors:')
return render(request, 'blog/post_form.html', {'form': form})
def home(request):
posts = Post.objects.all()
context = {'posts': posts}
return render(request, 'blog/home.html', context)
def about(request):
return render(request, 'blog/about.html')
Linguagem de código: JavaScript ( javascript )
Se você abrir o URL de criação, atualização ou exclusão, por exemplo:
http://127.0.0.1/post/create
Linguagem de código: JavaScript ( javascript )
Ele será redirecionado para a página de login.
Baixe o código fonte do Projeto Django
Resumo
- Use
authenticate()
a função para verificar um usuário por nome de usuário e senha. - Use
login()
a função para fazer login de um usuário. - Use
logout()
a função para desconectar um usuário. - Use
request.user.is_authenticated
para verificar se o usuário atual está autenticado. - Decorador de usuário
@login_required
para proteger páginas de usuários não autenticados.