Igor Sobreira

Mensagens para os usuários no Django

Ultimamente tenho usado muito a aplicação de autenticação do Django. Mas não estava muito satisfeito com o sistema de mensagens para os usuários que é oferecido. Na verdade a intenção é ser realmente bem simples, vejamos um exemplo:

def alterar_foto(request):
    # executa o código da view aqui....
    request.user.message_set.create(message=u'Foto alterada')
    return render_to_response('usuarios/dados.html',
                              context_instance=RequestContext(request))

Foi adicionado uma mensagem para o usuário, assim podemos criar uma fila das últimas ações executadas pelo mesmo. Só que o método para acessar essas mensagens é o get_and_delete_messages():

mensagens = user.get_and_delete_messages()

e no template, assumido que esteja usando RequestContext, ficaria assim:

<ul>
{% for message in messages %}
    <li>{{ message }}</li>
{% endfor %}
</ul>

pois o RequestContext define no template a variável messages, que são as mensagens do usuário logado. Mas como o próprio nome do método já diz, quando as mensagen são acessadas, elas são removidas. Eu não gostei muito disso, pelo fato de o usuário só poder ver as últimas ações uma única vez, além de que não tem um campo de data no model Message, pra mostrar o dia e hora daquela ação.

Daí decidi reinventar a roda, e fazer um sisteminha de mensagens com essas características. Eu fiz as mensagens acopladas a um perfil que eu criei pra o usuário do django, e não vou detalhar como se criar um perfil para seu User, veja mais aqui(lá no final do capítulo) e aqui.

Bem, basicamente é esse model:

class Action(models.Model):
    user = models.ForeignKey(UserProfile)
    action = models.CharField(max_length=200)
    pub_date = models.DateTimeField(auto_now_add=True)

def __unicode__(self):
    return self.action

class Meta:
    ordering = (&#39;-pub_date&#39;,)
    db_table = &#39;auth_user_profile_action&#39;</code></pre></figure>

Onde a classe UserProfile, é minha classe que extende o User da aplicação contrib.auth do Django. Daí eu adicionei um método na classe UserProfile:

from django.contrib.auth.models import User

class UserProfile(models.Model): # meus campos extras user = models.ForeignKey(User, unique=True)

# mais alguns método aqui, como o __unicode__, a class Meta, class Admin, etc

def keep_actions(self, maximum=10):
    actions = self.action_set.count()
    if actions &gt; maximum:
        extras = self.action_set.all()[maximum:actions]
        for extra in extras:
            extra.delete()</code></pre></figure>

A intenção é a seguinte: sempre ter um número máximo de 'ultimas ações' do usuário, então esse método keep_settings() recebe um parâmatro opcional(valor default é 10), que vai ser o número máximo de ações que ele vai permitir na tabela. É mais um método pra "limpar" as ações antigas.

Um exemplo de uso:

def adicionar_foto(request):
    # codigo normal da view...
    profile = request.user.get_profile()
    profile.action_set.create(action=u'Foto adicionada')
    profile.keep_actions()
    profile.save()
    # termina a view normalmente....

Aí eu adiciono uma ação relacionada com meu usuário, e o método keep_settings() vai garantir que terá no máximo 10 "ultimas ações", caso tenha mais de 10, ele remove as mais antigas e deixa apenas as 10 mais recentes.

E no template ficaria assim:

<ul>
{% for action in request.user.get_profile.action_set.all %}
    <li>{{ action.pub_date|date:'d/m/Y H:i' }} - {{ action }}</li>
{% endfor %}
</ul>

Assim eu mostro a hora que a ação foi executada e deixo sempre um histórico de 10 ou mais últimas ações. Pra deletar todas poderia chamar o método keep_actions(0) passando zero como parâmetro.

blog comments powered by Disqus

My name is Igor Sobreira and is my website. I'm a software developer working at Real Geeks. I currently live in Hawaii doing the two things that I like most: windsurfing and writing software.

See more about me and get in touch.