💻
Dicas de Django
  • Dica 1 - Django boilerplate e cookiecutter-django
  • Dica 1.1 - Django boilerplate
  • Dica 2 - Django extensions
  • Dica 3 - Django bulk_create e django-autoslug
  • Dica 4 - Django Admin personalizado
  • Dica 5 - Django Admin Date Range filter
  • Dica 6 - Geradores de senhas randômicas - uuid, hashids, secrets
  • Dica 7 - Rodando o ORM do Django no Jupyter Notebook
  • Dica 8 - Conhecendo o Django Debug Toolbar
  • Dica 9 - Escondendo suas senhas python-decouple
  • Dica 10 - Prototipagem de web design (Mockup)
  • Dica 11 - Bootstrap e Bulma + Colorlib
  • Dica 12 - Imagens: pexels e unsplash
  • Dica 13 - Cores
  • Dica 14 - Herança de Templates e Arquivos estáticos
  • Dica 15 - Busca por data no frontend
  • Dica 16 - Filtros com django-filter
  • Dica 17 - Criando comandos personalizados
  • Dica 18 - bulk_create e bulk_update
  • Dica 19 - Criando Issues por linha de comando com a api do github
  • Dica 20 - api github e click
  • Dica 21 - Criando issues por linha de comando com gitlab cli
  • 022-criando-issues-por-linha-de-comando-com-bitbucket-cli
  • Dica 23 - Diferença entre JSON dump, dumps, load e loads
  • Dica 24 - Barra de progresso
  • Dica 25 - Rodando Shell script dentro do Python
  • Dica 26 - Rodando Python dentro do Shell script
  • Dica 27 - Retornando os nomes dos campos do model
  • Dica 28 - Admin: Usando short description
  • Dica 29 - Django Admin: Criando actions no Admin
  • Dica 30 - Django Admin: Editando direto na listview do Admin
  • Dica 31 - Django Admin: Pegando usuário logado no Admin
  • Dica 32 - Django Admin: Sobreescrevendo os templates do Admin
  • Dica 33 - Github cli
  • Dica 34 - Django: custom template tags
  • Dica 35 - Django: passando usuário logado no formulário
  • Dica 36 - Django: visualizando seus modelos com graph models
  • Dica 37 - Faker
  • Dica 38 - Django: Paginação + Filtros
  • Dica 39 - Django Admin: display decorator (Django 3.2+)
  • Dica 40 - Formulários: date, datetime, duration e templatetags de data
  • Dica 41 - django-seed
  • Dica 42 - Custom context processors
  • Dica 43 - django-admin-rangefilter
  • Dica 44 - Django: F() expression
  • Dica 45 - DRF: Scaffold django apis - Django REST framework
  • Dica 46 - DRF: drf-yasg - Yet another Swagger generator
  • Dica 47 - DRF: djoser - Django REST framework
  • Dica 48 - DRF: Reset de Senha com djoser - Django REST framework
  • Dica 49 - DRF: Autenticação via JWT com djoser - Django REST framework
  • Dica 50 - DRF: Django CORS headers
  • Dica 51 - DRF: paginação
  • Dica 52 - DRF: django-filter
  • Dica 53 - DRF: Criando subrota com action
  • 54-django-extensions-mais-comandos
  • Dica 55 - Rodando Django em https localmente com runserver_plus
  • Dica 56 - Django inlineformset_factory + HTMX
  • Dica 57 - Criando API com Django SEM DRF
  • Dica 58 - Rodando PostgreSQL com Docker + Portainer + pgAdmin + Django local para desenvolvimento
  • Dica 59 - Django: Busca por palavras acentuadas ou sem acento
  • Dica 60 - Django: Adicionando atributos extras no formulário
  • Dica 01 - Criando Issues com API do Github (Linux)
  • Dica 02 - Usando http.server
  • Dica 03 - Criando um template com Bulma CSS
  • Dica 04 - Criando um template com Tailwind CSS
  • Dica 05 - htmx simples
  • Dica 06 - Criando o projeto Django
  • Dica 07 - PostgreSQL, pgAdmin e MailHog com docker-compose
  • Dica 08 - Aplicando isort e autopep8
  • Dica 09 - Aplicando djhtml
  • Dica 10 - Criando Makefile
  • Dica 11 - Criando Landpage de produtos
  • 072-012-fale-co-nosco-form-email
  • Dica 13 - Dashboard com Django e Tailwind CSS
  • Dica 14 - Django Custom User com e-mail
  • Dica 15 - Login com e-mail no Django
  • Dica 16 - Logout
  • Dica 17 - Cadastro de Usuários no Django
  • Dica 18 - Esqueci a senha
  • Dica 19.1 - Modelagem - OneToMany - Um pra Muitos - ForeignKey - Chave Estrangeira
  • Dica 19.2 - Modelagem - OneToOne - Um pra Um
  • Dica 19.3 - Modelagem - ManyToMany - Muitos pra Muitos
  • Dica 19.4 - Modelagem - Abstract Inheritance - Herança Abstrata
  • Dica 19.5 - Modelagem - Multi-table Inheritance - Herança Multi-tabela
  • Dica 19.6 - Modelagem - Proxy Model
  • Dica 19.7 - Modelagem - Resumo
  • Dica 20 - Templates
  • Dica 21 - Tentativas de Login
  • Dica 22 - Validação
  • Dica 23 - CRUD de produtos
  • Dica 24 - Alpine.js e Django
  • 091-25-dica-queryset
  • Dica 26 - Paginação e Breadcrumb
  • Dica 27 - Signals
  • Dica 28 - Gerando dados aleatórios com Faker - faker-commerce
  • Dica 29 - Importando CSV
  • 096-30-import-csv-inmemoryuploadedfile
  • Dica 31 - Importando CSV com Pandas
  • Dica 32 - Importando CSV com Dask
  • Dica 33 - Importando XLSX com OpenPyXL
  • 100-34-export-csv
  • Dica 35 - Exportando XLSX mais rápido com pyexcelerate
  • Dica 36 - Exportando CSV e XLSX pelo front no projeto
  • Novidades do Django 5.1
  • Django Router
  • 105-django-52
Powered by GitBook
On this page

Was this helpful?

Dica 17 - Cadastro de Usuários no Django

PreviousDica 16 - LogoutNextDica 18 - Esqueci a senha

Last updated 2 years ago

Was this helpful?

Importante: remova a \ no meio das tags.

Vamos editar os arquivos:

  • accounts/templates/registration/registration_form.html

  • accounts/templates/registration/password_reset_confirm.html

  • accounts/templates/registration/password_reset_complete.html

  • accounts/forms.py

  • accounts/services.py

  • accounts/tokens.py

  • accounts/urls.py

  • accounts/views.py

Edite login.html

<a href="{\% url 'signup' %}" class="text-teal-500 hover:underline">Criar conta</a>
touch backend/accounts/templates/registration/registration_form.html
<!-- registration_form.html -->
{\% extends "base_login.html" %}

{\% block content %}
  <main class="bg-gray-50">

    <div class="mx-auto md:h-screen flex flex-col justify-center items-center px-6 pt-8 pt:mt-0">
      <a href="https://demo.themesberg.com/windster/" class="text-2xl font-semibold flex justify-center items-center mb-8 lg:mb-10">
        <img src="https://demo.themesberg.com/windster/images/logo.svg" class="h-10 mr-4" alt="Windster Logo">
        <span class="self-center text-2xl font-bold whitespace-nowrap">Dicas de Django</span>
      </a>
      <!-- Card -->
      <div class="bg-white shadow rounded-lg md:mt-0 w-full sm:max-w-screen-sm xl:p-0">
        <div class="p-6 sm:p-8 lg:p-16 space-y-8">
          <h2 class="text-2xl lg:text-3xl font-bold text-gray-900">
            Crie sua conta
          </h2>
          <form class="mt-8 space-y-6" action="." method="POST">
            {\% csrf_token %}
            <div>
              <label for="id_first_name" class="text-sm font-medium text-gray-900 block mb-2">Nome</label>
              <input
                id="id_first_name"
                type="text"
                name="first_name"
                class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-cyan-600 focus:border-cyan-600 block w-full p-2.5"
                placeholder="Primeiro Nome"
                required
              >
            </div>
            <div>
              <label for="id_last_name" class="text-sm font-medium text-gray-900 block mb-2">Sobrenome</label>
              <input
                id="id_last_name"
                type="text"
                name="last_name"
                class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-cyan-600 focus:border-cyan-600 block w-full p-2.5"
                placeholder="Sobrenome"
                required
              >
            </div>
            <div>
              <label for="id_email" class="text-sm font-medium text-gray-900 block mb-2">E-mail</label>
              <input
                id="id_email"
                type="email"
                name="email"
                class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-cyan-600 focus:border-cyan-600 block w-full p-2.5"
                placeholder="nome@example.com"
                required
              >
            </div>
            <!-- <div>
              <label for="id_password1" class="text-sm font-medium text-gray-900 block mb-2">Senha</label>
              <input
                id="id_password1"
                type="password"
                name="password1"
                placeholder="••••••••"
                class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-cyan-600 focus:border-cyan-600 block w-full p-2.5"
                required
              >
            </div>
            <div>
              <label for="id_password2" class="text-sm font-medium text-gray-900 block mb-2">Confirmação da Senha</label>
              <input
                id="id_password2"
                type="password"
                name="password2"
                placeholder="••••••••"
                class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-cyan-600 focus:border-cyan-600 block w-full p-2.5"
                required
              >
            </div> -->
            <div class="flex items-start">
              <div class="flex items-center h-5">
                <input
                  id="remember"
                  type="checkbox"
                  name="remember"
                  aria-describedby="remember"
                  class="bg-gray-50 border-gray-300 focus:ring-3 focus:ring-cyan-200 h-4 w-4 rounded"
                >
              </div>
              <div class="text-sm ml-3">
                <label for="remember" class="font-medium text-gray-900">Eu aceito os <a href="#" class="text-teal-500 hover:underline">Termos e Condições</a></label>
              </div>
            </div>
            <button type="submit" class="text-white bg-cyan-600 hover:bg-cyan-700 focus:ring-4 focus:ring-cyan-200 font-medium rounded-lg text-base px-5 py-3 w-full sm:w-auto text-center">Salvar</button>
            <div class="text-sm font-medium text-gray-500">
              Você já tem uma conta? <a href="{\% url 'login' %}" class="text-teal-500 hover:underline">Login</a>
            </div>
          </form>
        </div>
      </div>
    </div>
  </main>

{\% endblock content %}

Edite accounts/forms.py

# accounts/forms.py
from django import forms

from backend.accounts.models import User


class CustomUserForm(forms.ModelForm):
    first_name = forms.CharField(
        label='Nome',
        max_length=150,
    )
    last_name = forms.CharField(
        label='Sobrenome',
        max_length=150,
    )
    email = forms.EmailField(
        label='E-mail',
    )

    class Meta:
        model = User
        fields = (
            'first_name',
            'last_name',
            'email',
        )

Edite accounts/services.py

# accounts/services.py
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode

from .tokens import account_activation_token


def send_mail_to_user(request, user):
    current_site = get_current_site(request)
    use_https = request.is_secure()
    subject = 'Ative sua conta.'
    message = render_to_string('email/account_activation_email.html', {
        'user': user,
        'protocol': 'https' if use_https else 'http',
        'domain': current_site.domain,
        'uid': urlsafe_base64_encode(force_bytes(user.pk)),
        'token': account_activation_token.make_token(user),
    })
    user.email_user(subject, message)

Edite accounts/tokens.py

# accounts/tokens.py
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from six import text_type


class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
    def _make_hash_value(self, user, timestamp):
        return (
            text_type(user.pk) + text_type(timestamp) + text_type(user.email)
        )


account_activation_token = AccountActivationTokenGenerator()

Edite accounts/urls.py

# accounts/urls.py
from django.contrib.auth.views import LoginView, LogoutView
from django.urls import path

from backend.accounts import views as v

urlpatterns = [
    path('login/', LoginView.as_view(), name='login'),  # noqa E501
    path('logout/', LogoutView.as_view(), name='logout'),  # noqa E501
    path('register/', v.signup, name='signup'),  # noqa E501
    path('reset/<uidb64>/<token>/', v.MyPasswordResetConfirm.as_view(), name='password_reset_confirm'),  # noqa E501
    path('reset/done/', v.MyPasswordResetComplete.as_view(), name='password_reset_complete'),  # noqa E501
]
pip install django-widget-tweaks
pip freeze | grep django-widget-tweaks >> requirements.txt

Em settings.py

INSTALLED_APPS = [
    ...
    # apps de terceiros
    'widget_tweaks',
]

Edite accounts/templates/registration/password_reset_confirm.html

<!-- password_reset_confirm.html -->
{\% extends "base_login.html" %}
{\% load widget_tweaks %}

{\% block content %}
  <main class="bg-gray-50">
    <div class="mx-auto md:h-screen flex flex-col justify-center items-center px-6 pt-8 pt:mt-0">
      <a href="https://demo.themesberg.com/windster/" class="text-2xl font-semibold flex justify-center items-center mb-8 lg:mb-10">
        <img src="https://demo.themesberg.com/windster/images/logo.svg" class="h-10 mr-4" alt="Windster Logo">
        <span class="self-center text-2xl font-bold whitespace-nowrap">Dicas de Django</span>
      </a>
      <!-- Card -->
      <div class="bg-white shadow rounded-lg md:mt-0 w-full sm:max-w-screen-sm xl:p-0">
        <div class="p-6 sm:p-8 lg:p-16 space-y-8">
          <h2 class="text-2xl lg:text-3xl font-bold text-gray-900">
            Trocar senha
          </h2>
          <p class="text-sm font-medium text-gray-500">Digite sua nova senha.</p>
          {\% if validlink %}
            <form class="mt-8 space-y-6" action="." method="POST">
              {\% csrf_token %}
              {\% for field in form.visible_fields %}
                <div>
                  <label class="text-sm font-medium text-gray-900 block mb-2">{{ field.label }}</label>
                  {\% render_field field class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-cyan-600 focus:border-cyan-600 block w-full p-2.5" %}
                </div>
                <span class="text-sm font-medium text-gray-500">{{ field.help_text }}</span>
                {\% for error in field.errors %}
                  <span class="text-red-500">{{ error }}</span> <br>
                {\% endfor %}
              {\% endfor %}
              <button type="submit" class="text-white bg-cyan-600 hover:bg-cyan-700 focus:ring-4 focus:ring-cyan-200 font-medium rounded-lg text-base px-5 py-3 w-full sm:w-auto text-center">Trocar senha</button>
              <div class="text-sm font-medium text-gray-500">
                Você já tem uma conta? <a href="{\% url 'login' %}" class="text-teal-500 hover:underline">Login</a>
              </div>
            </form>
          {\% else %}
            <p>O link para a recuperação de senha era inválido, possivelmente porque já foi utilizado. Por favor, solicite uma nova recuperação de senha.</p>
          {\% endif %}
        </div>
      </div>
    </div>
  </main>
{\% endblock content %}

Edite accounts/templates/registration/password_reset_complete.html

<!-- password_reset_complete.html -->
{\% extends "base_login.html" %}

{\% block content %}
  <main class="bg-gray-50">
    <div class="mx-auto md:h-screen flex flex-col justify-center items-center px-6 pt-8 pt:mt-0">
      <a href="https://demo.themesberg.com/windster/" class="text-2xl font-semibold flex justify-center items-center mb-8 lg:mb-10">
        <img src="https://demo.themesberg.com/windster/images/logo.svg" class="h-10 mr-4" alt="Windster Logo">
        <span class="self-center text-2xl font-bold whitespace-nowrap">Dicas de Django</span>
      </a>
      <!-- Card -->
      <div class="bg-white shadow rounded-lg md:mt-0 w-full sm:max-w-screen-sm xl:p-0">
        <div class="p-6 sm:p-8 lg:p-16 space-y-8">
          <h2 class="text-2xl lg:text-3xl font-bold text-gray-900">
            Deu tudo certo!
          </h2>
          <p class="text-sm font-medium text-gray-500">
            Sua senha foi definida. Você pode prosseguir e se <a class="text-sm font-medium text-cyan-600 hover:bg-gray-100 rounded-lg" href="{\% url 'login' %}">autenticar</a> agora.
          </p>
        </div>
      </div>
    </div>
  </main>
{\% endblock content %}

Edite accounts/views.py

# accounts/views.py
from django.contrib.auth.views import (
    PasswordResetCompleteView,
    PasswordResetConfirmView
)
from django.shortcuts import redirect, render

from backend.accounts.services import send_mail_to_user

from .forms import CustomUserForm


def signup(request):
    '''
    Cadastra Usuário.
    '''
    template_name = 'registration/registration_form.html'
    form = CustomUserForm(request.POST or None)

    if request.method == 'POST':
        if form.is_valid():
            user = form.save()
            send_mail_to_user(request=request, user=user)
            return redirect('login')

    return render(request, template_name)


class MyPasswordResetConfirm(PasswordResetConfirmView):
    '''
    Requer password_reset_confirm.html
    '''

    def form_valid(self, form):
        self.user.is_active = True
        self.user.save()
        return super(MyPasswordResetConfirm, self).form_valid(form)


class MyPasswordResetComplete(PasswordResetCompleteView):
    '''
    Requer password_reset_complete.html
    '''
    ...

Instale .

https://docs.djangoproject.com/en/4.1/topics/auth/default/#django.contrib.auth.views.PasswordResetConfirmView
https://docs.djangoproject.com/en/4.1/topics/auth/default/#django.contrib.auth.views.PasswordResetCompleteView
django-widget-tweaks