Django Wars [Parte 06]: Criando um perfil de jogador

O Django Wars foi idealizado e desenvolvido no Django 1.4. Algumas funcionalidades aqui descritas podem não funcionar ou funcionar de forma diferente em outras versões do Django

Quando criamos o formulário de cadastro do usuário, estavamos criando um usuário padrão do Django.
Claro que poderíamos criar o nosso próprio formulário de cadastro e login, modelo de usuário, sessão persistente de usuário logado e afins, mas é muito trabalho para algo que já vem pronto.
Surge então um problema: o usuário Django possui apenas informações de login, não possui atributos que queremos nos nossos jogadores como, por exemplo, a quantidade de dinheiro em banco.

De acordo com a documentação de como guardar campos extras no usuário Django, precisaremos criar um modelo com os campos que queremos, além de utilizar um relacionamento OneToOne entre nosso modelo e o modelo de usuário do Django.
Para facilitar, vou criar uma app chamada players onde definirei o modelo do usuário.

python manage.py startapp player

Dentro desta app modificarei o arquivo models.py com o modelo de usuário que desejo implementar.

from django.db import models
#importamos o modelo de usuario do Django para "extende-lo"
from django.contrib.auth.models import User


# Create your models here.
class Player(models.Model):
    #fazendo o relacionamento entre o usuario Django e o player
    #Docs: https://docs.djangoproject.com/en/1.4/topics/auth/#storing-additional-information-about-users
    user = models.OneToOneField(User)
    
    #campos que definem o player do jogo
    carteira = models.FloatField(default=0) #dinheiro na mao
    banco = models.FloatField(default=0) #dinheiro no banco
    
    ataque = models.PositiveSmallIntegerField(default=10)
    defesa = models.PositiveSmallIntegerField(default=10)
    vida = models.PositiveSmallIntegerField(default=10)
    energia = models.PositiveSmallIntegerField(default=20) #energia para fazer roubos
    raiva = models.PositiveSmallIntegerField(default=5) #raiiva para atacar outros players
    
    hp = models.PositiveIntegerField(default=100) #hp = vida * 10
    energia_atual = models.PositiveIntegerField(default=20)
    raiva_atual = models.PositiveIntegerField(default=5)
    
    nivel = models.PositiveSmallIntegerField(default=1)
    experiencia = models.PositiveIntegerField(default=0)
    
    hp_update = models.DateTimeField(auto_now_add=True) # 1 de hp a cada 2 minutos
    energia_update = models.DateTimeField(auto_now_add=True) # 1 de energia a cada minuto
    raiva_update = models.DateTimeField(auto_now_add=True) # 1 de raiva a cada 5 minutos

Assim, para cada usuário no banco, teremos um Player no banco.
Um relacionamento “um para um”.

Devemos lembrar que, no nosso formulário de criação de usuário, ele cria um usuario da biblioteca de apoio Django.
Lá, não escrevemos nenhuma informação de que deve-se criar o Player sempre que se criar um user.
É ai que entra o Django Signals.
O Django monitora os sinais que algumas ações emitem, entre elas a ação de criar um usuário.
O que queremos é fazer com que sempre que o Django criar um usuário, ele aproveite e crie um Player.
Para isso, precisaremos colocar mais algumas linhas de código no models.py

#inclua essa linha no 'cabeçalho' do seu código
from django.db.models.signals import post_save
#importa a função que detecta sinais de 'save', enviados ao salvar um modelo


# funcao que cria o player toda vez que um usuario for criado pelo Django.contrib.auth
def cria_user_player(sender, instance, created, **kwargs):
    if created:
        Player.objects.create(user=instance)

#configurando o signal que detecta quando um usuario é criado
#ao detectar, executa a funcao acima (cria_user_payer) para termos o
# "perfil" do jogador ligado ao usuario
# vide documentacao: https://docs.djangoproject.com/en/1.4/topics/auth/#storing-additional-information-about-users
post_save.connect(cria_user_player, sender=User) # USER = importado na linha 3

Por fim, vamos fazer uma última alteração.
Vamos informar ao Django que, apesar de ainda desejarmos todas as facilidades de cadastro e login de usuários que ele fornece, quando um usuário se logar, não queremos ter um objeto do tipo user na mão, que é o padrão.
Quando o usuário logar, desejamos ter um objeto Player, que contém todas as informações de perfil de jogador, que acabamos de descrever no models.py, além de apontar para as informações de usuário, que é o objeto user.
E isso é molesa.

Basta ir no arquivo settings.py do seu projeto e ADICIONAR a linha:

# configurando o usuario do django para ser
# o usuario definido pelo projeto e nao o usuario
# padrao do Django.contrib.auth
AUTH_PROFILE_MODULE = 'nomeDAapp.nomeDOmodel'

Você vai apontar a variável AUTH_PROFILE_MODULE para o modelo de usuário que você criou na app dentro dele.
Note que não colocamos o models dentro do caminho que leva até o modelo de usuário.

O código fonte atual do projeto pode ser visto aqui:
https://github.com/frenetic/django-wars

2 thoughts on “Django Wars [Parte 06]: Criando um perfil de jogador

  1. Preciso fazer isso, armazenar campos extras no User do django, segui a documentação e o que você tem aqui tb, excelente tutorial, mas nem a documentação e nem lugar nenhum na internet mundial, pelo menos que eu tenha encontrado, mostra como renderizar esses forms, como trabalho com eles no forms.py e depois como persisto ambos no views.py? Se puder ajudar agradeço bastante.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *