Resumo : neste tutorial, você aprenderá como usar a FormView
classe Django para criar um formulário de registro para o aplicativo Todo.
Este tutorial começa onde o tutorial Django LoginView parou.
A classe Django FormView
permite criar uma visualização que exibe um formulário. Usaremos a FormView
classe para criar um formulário de registro para o Todo App .
Criando um formulário de inscrição
Crie form.spy
um arquivo no users
aplicativo e defina a RegisterForm
classe da seguinte forma:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class RegisterForm(UserCreationForm):
email = forms.EmailField(max_length=254)
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2', )
Linguagem de código: Python ( python )
O RegisterForm
usa o User
modelo e exibe os campos nome de usuário, email, senha1 e senha2.
Definindo uma classe RegisterView
Defina a RegisterView
classe views.py
do users.py
aplicativo:
from django.urls import reverse_lazy
from django.views.generic.edit import FormView
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login
from django.contrib.auth.models import User
from .forms import RegisterForm
class RegisterView(FormView):
template_name = 'users/register.html'
form_class = RegisterForm
redirect_authenticated_user = True
success_url = reverse_lazy('tasks')
def form_valid(self, form):
user = form.save()
if user:
login(self.request, user)
return super(RegisterView, self).form_valid(form)
Linguagem de código: Python ( python )
A classe RegisterView herda da classe FormView e possui os seguintes atributos e métodos:
template_name
especifica o nome do modelo para renderizar o formulário de inscrição.form_class
especifica o formulário (RegisterForm
) usado no modelo.redirect_authenticated_user
é definido como True para redirecionar o usuário depois de autenticado.success_url
especifica o URL a ser redirecionado assim que o usuário se inscrever com sucesso. Neste exemplo, ele redireciona o usuário para a lista de tarefas.form_valid()
O método é chamado assim que o formulário é enviado com sucesso. Neste exemplo, salvamos oUser
modelo e logamos o usuário automaticamente.
Definindo a rota de registro
Defina uma rota que mapeie a URL de registro register/
com o resultado do as_view()
método da RegisterView
classe no urls.py
app users
:
from django.urls import path
from django.contrib.auth.views import LogoutView
from .views import MyLoginView, RegisterView
urlpatterns = [
path('login/', MyLoginView.as_view(),name='login'),
path('logout/', LogoutView.as_view(next_page='login'),name='logout'),
path('register/', RegisterView.as_view(),name='register'),
]
Linguagem de código: Python ( python )
Crie um modelo de registro
Crie um register.html
no templates/users
diretório do users
aplicativo com o seguinte código:
{%extends 'base.html'%}
{%block content%}
<div class="center">
<form method="post" novaldiate class="card">
{% csrf_token %}
<h2 class="text-center">Create your account</h2>
{% for field in form %}
{{ field.label_tag }}
{{ field }}
{% if field.errors %}
<small class="error">{{ field.errors|striptags }}</small>
{% endif %}
{% endfor %}
<input type="submit" value="Register" class="btn btn-primary full-width">
<hr>
<p class="text-center">Already have an account? <a href="{% url 'login'%}">Login Here</a></p>
</form>
</div>
{%endblock content%}
Linguagem de código: HTML, XML ( xml )
O formulário em users/register.html
é a RegisterForm
classe que definimos no forms.py
arquivo.
Adicionando link de registro ao login e navegação
Modifique o login.html
modelo adicionando o link de registro:
{%extends 'base.html'%}
{%block content%}
<div class="center">
<form method="post" class="card" novalidate>
{% csrf_token %}
<h2 class="text-center">Log in to your account</h2>
{% for field in form %}
{{ field.label_tag }}
{{ field }}
{% if field.errors %}
<small>{{ field.errors|striptags }}</small>
{% endif %}
{% endfor %}
<input type="submit" value="Login" class="btn btn-primary full-width">
<hr>
<p class="text-center">Forgot your password <a href="#">Reset Password</a></p>
<p class="text-center">Don't have a account? <a href="{%url 'register'%}">Join Now</a></p>
</form>
</div>
{%endblock content%}
Linguagem de código: HTML, XML ( xml )
Além disso, modifique o base.html
modelo adicionando o link de registro à navegação e à página inicial:
{%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="#">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 )
home.html
{%extends 'base.html'%}
{%load static %}
{%block content%}
<section class="feature">
<div class="feature-content">
<h1>Todo</h1>
<p>Todo helps you more focus, either work or play.</p>
<a class="btn btn-primary cta" href="{% url 'register' %}">Get Started</a>
</div>
<img src="{%static 'images/feature.jpg'%}" alt="" class="feature-image">
</section>
{%endblock content%}
Linguagem de código: HTML, XML ( xml )
Se você abrir o URL de registro:
http://127.0.0.1:8000/register/
Linguagem de código: Python ( python )
você verá o formulário de registro:
Depois de registrado com sucesso, você fará login automaticamente:
No entanto, temos um problema. Jane pode visualizar, atualizar e excluir tarefas de outros usuários.
Para corrigir isso, você precisa filtrar as tarefas que pertencem ao usuário atualmente logado em todas as classes adicionando os get_queryset()
métodos às classes TaskList
, TaskDetail
, TaskCreate
, TaskUpdate
, TaskDelete
.
from django.shortcuts import render
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from .models import Task
class TaskList(LoginRequiredMixin, ListView):
model = Task
context_object_name = 'tasks'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['tasks'] = context['tasks'].filter(user=self.request.user)
return context
class TaskDetail(LoginRequiredMixin, DetailView):
model = Task
context_object_name = 'task'
def get_queryset(self):
base_qs = super(TaskDetail, self).get_queryset()
return base_qs.filter(user=self.request.user)
class TaskUpdate(LoginRequiredMixin, UpdateView):
model = Task
fields = ['title','description','completed']
success_url = reverse_lazy('tasks')
def form_valid(self, form):
messages.success(self.request, "The task was updated successfully.")
return super(TaskUpdate,self).form_valid(form)
def get_queryset(self):
base_qs = super(TaskUpdate, self).get_queryset()
return base_qs.filter(user=self.request.user)
class TaskDelete(LoginRequiredMixin, DeleteView):
model = Task
context_object_name = 'task'
success_url = reverse_lazy('tasks')
def form_valid(self, form):
messages.success(self.request, "The task was deleted successfully.")
return super(TaskDelete,self).form_valid(form)
def get_queryset(self):
base_qs = super(TaskDelete, self).get_queryset()
return base_qs.filter(user=self.request.user)
Linguagem de código: Python ( python )
Agora, se você fizer login como Jane, verá uma lista de tarefas vazia:
Se você criar uma nova tarefa, verá apenas essa tarefa na lista de tarefas:
Se você tentar acessar as tarefas de John enquanto estiver fazendo login como Jane, receberá um erro 404 como este:
Você pode baixar o código completo aqui.
Resumo
- Use Django
FormView
para criar uma view que exibe um formulário.