Personalizando o modelo de usuário do Django
Tags: django, python, model, user
Published: 2023-12-02 16:37:50

_Quer usar o seu próprio modelo de usuário na autenticação do Django? Vem comigo que eu te ensino em 4 passos simples!_

---

O Django é uma ferramenta bastante útil para acelerar o processo de desenvolvimento de software pois já entrega diversas funcionalidades comuns — entre elas, um sistema de autenticação com um modelo próprio de usuário, que será o foco das próximas linhas.

Se você está desenvolvendo um projeto nesse framework e seus models incluem uma classe de usuário que não é nativa dele, ela não será lida automaticamente como um modelo para autenticação de usuário.

O que acontece é que, ao implementar a autenticação para usuários por meio da função helper `create_user()`, o Django cria uma tabela própria de usuários, ignorando o modelo e as características que você definiu no arquivo `models.py`. Isso pode ser um problema quando o modelo de usuário da sua aplicação tem atributos específicos ou, ainda, é referenciado por Foreign Keys (FK) em outros modelos.

## AbstractUser e AbstractBaseUser

Para resolver isso, precisamos criar um modelo personalizado baseado no modelo padrão do Django e existem duas maneiras de fazer isso: estendendo `AbstractUser` ou `AbstractBaseUser`.

Escolhendo `AbstractUser`, você estenderá uma classe que inclui recursos normalmente utilizados em modelos de usuário. Isso inclui campos como `username`, `password`, `email`, `first_name` e `last_name`, além de [outros atributos e métodos](https://docs.djangoproject.com/en/4.2/ref/contrib/auth/#user-model) para funcionalidades comuns relacionadas à manipulação de usuários.

Enquanto isso, `AbstractBaseUser` fornece apenas o mínimo necessário para um modelo de usuário. Não inclui os campos citados anteriormente e é mais adequada quando você deseja ter controle total sobre o modelo de usuário, permitindo que você defina seus próprios campos. 

Nesse último caso, como é especificado pela [documentação](https://docs.djangoproject.com/en/4.2/topics/auth/customizing/#specifying-a-custom-user-model) do framework, você também precisa definir o campo de nome de usuário (usado como login) e os campos obrigatórios do modelo por conta própria.

## Executando o passo a passo

Nesse caso, vamos escolher `AbstractUser` pois é uma classe mais completa e já fornece, entre outros, os campos de nome de usuário e senha.

### Passo 1: crie o novo modelo de usuário

No arquivo `models.py`, faça o seguinte:

```python
from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    bio = models.CharField(max_length=128, null=True)
    # Adicione características personalizadas conforme necessário
```

Observe que não é necessário incluir campos básicos de login, como nome de usuário, e-mail e senha, pois eles já estão presentes em `AbstractUser`. Além disso, por padrão, o Django não trata o campo de e-mail como único na tabela, portanto, se desejar que isso seja feito, especifique isso na definição do `CustomUser`:

```python
email = models.EmailField(unique=True, null=False)
```

Depois da definição, use `CustomUser` como FK onde for necessário nos outros modelos. Por exemplo:

```python
class Post(models.Model):
    author = models.ForeignKey(CustomUser, on_delete=models.CASCADE, null=False)
```

### Passo 2: atualize as configurações do projeto

No arquivo `settings.py`, certifique-se de que a aplicação faça parte do projeto:

```python
INSTALLED_APPS = [
    'app',
]
```

Informe também que o modelo de autenticação que deve ser utilizado pelo Django agora é o seu modelo customizado:

```python
AUTH_USER_MODEL = 'app.CustomUser'
```

Nos dois casos, lembre-se de alterar `app` pelo nome da sua aplicação.

### Passo 3: personalize a interface administrativa

No arquivo `admin.py`, importe e registre os novos modelos e, se desejar, utilize `list_display` para definir quais campos do modelo serão exibidos no painel de administração do Django:

```python
from django.contrib.auth.admin import UserAdmin
from .models import CustomUser

class CustomUserAdmin(UserAdmin):
    list_display = (
        'id', 'email', 'username', 'bio', 'created_at', 'is_staff'
    )

admin.site.register(CustomUser, CustomUserAdmin)
```

Se não quiser personalizar a exibição com o `list_display`, use a palavra reservada `pass` no lugar. O painel administrativo exibirá a tabela de usuários com os campos padrão do `AbstractUser`. Isso não influenciará nos atributos do model, é apenas um ajuste para a exibição dos registros.

### Passo 4: aplique as mudanças no banco de dados

Finalmente, execute os comandos `makemigrations` e `migrate` para aplicar as modificações ao banco de dados:

```bash
$ python manage.py makemigrations app
$ python manage.py migrate
```

E claro, mais uma vez, lembre-se de alterar `app` pelo nome da sua aplicação.

Depois de seguir esse passo a passo, você poderá utilizar o sistema de autenticação do Django ao mesmo tempo em que mantém as características específicas do seu modelo de usuário.

E aí, gostou? Se liga aí que em breve tem mais post ;)