Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Autenticação Básica.

Na aula o professor mostra como autenticação com o super usuário, teria como fazer uma rota para a criação de usuários, salvando esses usuários no banco de dados e posteriormente para realizar as requisições será necessário realizar o login usando usuário e senha ? Como fazer isso ?

2 respostas

Oii Matheus, como você está?

É possível sim. Essa vai ser uma resposta longa hahahaha Mas vou fazer passo a passo com você explicando o porquê de cada procedimento e deixando algumas referências da documentação, tá bom? E se ficar alguma dúvida no meio do caminho, fique a vontade para perguntar =) Vamos lá:

O primeiro passo é criarmos um modelo responsável por guardar os dados do cadastro do usuário. Sendo assim, no arquivo models.py do nosso app de escola iremos criar uma classe Usuario para modelar quais dados o cadastro deve ter. Veja como fica em código:

from django.contrib.auth.models import AbstractUser

class Usuario(AbstractUser):
    username = models.CharField(max_length=50)
    password = models.CharField(max_length=8)
    email = models.EmailField(max_length=254, unique=True, error_messages={'unique': "O email cadastrado já existe."})
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)

    USERNAME_FIELD = 'email'

Observe que na classe acima, diferente do que vimos no curso onde herdávamos de models.Model, agora estamos herdando de AbstractUser. Mas o que essa classe AbstractUser significa? Essa classe é um modelo padrão de usuários do django que já possui alguns campos e métodos dispostos para que possamos usar relacionados a Users e por isso, os nomes dos campos estão em inglês, pois esses nomes são da nossa classe mãe, a AbstractUser. Você ver pode mais detalhes a respeito da implementação interna dessa classe neste link da documentação do github do Django.

Nessa classe, também implementamos o campo e-mail como único e além disso, personalizamos uma mensagem de erro para quando algum usuário tentar cadastrar algum e-mail que já existe. Outros atributos foram o is_staff e is_superuser, o primeiro se refere a possibilidade do usuário acessar o admin, já o segundo é para marcar se o usuário será ou não um super usuário, ou seja, terá acesso ao admin e todas suas operações. Quanto ao campo USERNAME_FIELD é para dizermos que no momento de efetuarmos o login utilizaremos o email.

De posse da classe criada, precisamos voltar na pasta do nosso projeto(setup) e ir até o arquivo settings.py(no finalzinho dele) e adicionar o seguinte trecho:

AUTH_USER_MODEL = "escola.Usuario"

Esse trecho é responsável por mostrar ao Django qual modelo ele terá que usar para representar um usuário, nesse caso, esse modelo se encontra no app escola e a classe se chama Usuario.

Além disso, precisamos registrar esse nosso modelo no admin.py do app de escola. Veja como fica em código:

from escola.models import Usuario
from django.contrib.auth.admin import UserAdmin

admin.site.register(Usuario, UserAdmin)
solução!

Quanto a serialização dos dados(serializers.py), utilizaremos o código abaixo:


class UsuarioSerializer(serializers.ModelSerializer):

    password = serializers.CharField(
        style={'input_type': 'password'},
        write_only=True,
        label="Senha"
    )

    password_confirm = serializers.CharField(
        style={'input_type': 'password'},
        write_only=True,
        label="Confirme a senha"
    )

    is_staff = serializers.BooleanField(
        label="Membro da Equipe",
        help_text="Indica que usuário consegue acessar o site de administração."
    )

    is_superuser = serializers.BooleanField(
        label="SuperUsuário",
        help_text="Indica que este usuário tem todas as permissões sem atribuí-las explicitamente."
    )

    class Meta:
        model = Usuario
        fields = ('username','email', 'password', 'password_confirm', 'is_staff', 'is_superuser')
        extra_kwargs = {'password': {'write_only': True}}

    def save(self):
        conta = Usuario(
            email=self.validated_data['email'], 
            username=self.validated_data['username'],
            is_staff=self.validated_data['is_staff'],
            is_superuser=self.validated_data['is_superuser']
        )
        password = self.validated_data['password']
        password_confirm = self.validated_data['password_confirm']

        if password != password_confirm:
            raise serializers.ValidationError({'password': 'As senhas não são iguais.'})
        conta.set_password(password)
        conta.save()
        return conta

Com esse código, estamos pegando os dados do nosso modelo e após isso, antes de salvar o usuário verificamos se os campos de senha são iguais. E caso seja, salvamos o usuário e em caso contrário, lançamos uma exceção. O validated_data serve para que possamos verificar se a entrada que o usuário digitou é válida, como herdamos da classe AbstractUser ela internamente já possui esses métodos de validação. Os campos de senha foram definidos apenas como campo de escrita write_only, pois não queremos ler dados desse campo.

Agora, no arquivo views.py, iremos construir o nosso modelo de listagem e o viewset de usuários:

from escola.models import Usuario

class UsuariosViewSet(viewsets.ModelViewSet):
    queryset = Usuario.objects.all()
    serializer_class = UsuarioSerializer

class ListaUsuarios(generics.ListAPIView):

    def get_queryset(self):
        queryset = Usuario.objects.all()
        return queryset
    serializer_class = UsuarioSerializer

Por fim, vamos ao arquivo urls.py do nosso projeto(setup) e adicionaremos uma rota para cadastrar o usuário:

from escola.views import ListaUsuarios, UsuariosViewSet

router = routers.DefaultRouter()
router.register('cadastrar_usuario', UsuariosViewSet, basename='Cadastrar Usuário')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
    path('cadastrar_usuario/', ListaUsuarios.as_view())
]

Antes de testar é necessário excluir o arquivo db.sqlite3 e pasta de migrações. Após a exclusão, refaça as migrations:

python manage.py makemigrations
python manage.py migrate

Caso todas as migrações tenham sido feitas, execute o servidor:

python manage.py runserver

Como resultado deverá ver a rota de cadastro de usuário na página principal:

Imgur

E ao clicar nessa rota http://localhost:8000/cadastrar_usuario/, será apresentado o formulário para cadastro de usuário:

Imgur

Como as rotas para cadastro de aluno, cursos ou matrículas possuem autenticação, ao clicar em uma dessas rotas será pedido as credenciais, basta colocar o e-mail cadastrado e a senha que conseguirá realizar as operações do crud.

Qualquer dúvida estou por aqui, tá bom?

Abraços e bons estudos!

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software