Back-End

21 ago, 2013

O “objeto” admin de uma app – Parte 02

Publicidade

Hoje iremos demonstrar como existem outras inúmeras configurações que podemos realizar no admin. Como faz tempo desde o último artigo, quem quiser relembrar algo, a primeira parte está aqui.

Uma dica que ficou para esse segundo artigo é configurar o admin para que a listagem dos itens seja associada ao usuário logado no sistema. Isso é muito último para sistemas com vários perfis de usuário onde cada perfil pode visualizar os itens direcionados ao perfil dele.

Para não ficar um artigo muito grande, deixarei para falar sobre outras configurações mais avançadas, como por exemplo mostrar no change_list apenas os elementos pertencentes ao usuário logado. No nosso caso, como estamos trabalhando com itens de contato, iremos limitar os contatos enviados para o usuário logado.

Então, vamos ao que interessa! Vamos começar configurando o admin para primeiro identificarmos qual o usuário que está logado no sistema. Para realizarmos essa tarefa teremos que subscrever o método queryset (não confundir com QuerySets, que é outra coisa). Esse método é do Admin e é o responsável por realizar a consulta que resulta nos itens mostrado no change_list. No caso, se não declamarmos no Admin o método queryset o comportamento será o padrão do Admin, que é mostrar todos os itens.

[python]

def queryset(self, request):
u""" Subescrevendo o queryset para retornar apenas os chamados destinados ao setor do
usuário logado e os chamados que ainda não foram atendidos. Para o SuperUser são mostrados todos os chamados.
"""
try:
qs = super(ContatoAdmin, self).queryset(request)
if request.user.is_superuser is False:
if ‘perseguidora’ in str(request.user.groups.values_list(‘name’, flat=True)).lower():
return qs
else:
usuario = Equipe(fkUserAdmin=request.user.pk).retornar_colaborador()
tipos_contato = usuario.atendimento_tipo_contato.values_list(‘pk’, flat=True)
return qs.filter(fkEmpresa=usuario.fkEmpresa).filter(tipo_contato__in=tipos_contato).filter(processado=False)
else:
return qs
except Exception, e:
pass[/python]

  • Linha 1 – Declaração dos métodos;
  • Linha 2 à 4 – Comentário do código;
  • Linha 6 – Instanciando o queryset padrão do nosso Model (no caso é o model Contato), assim poderemos realizar operações no queryset, como por exemplo aplicar um filtro, nosso objetivo.
  • Linha 7 – Aqui começa a brincadeira! O comando request.user retorna o usuário logado, e como tudo no Django/Python é objeto, ele possui vários métodos/funções. Um deles é o is_superuser, que retorna um boolean que determina se o usuário logado é super usuário ou não. Caso nosso usuário seja super usuário, iremos mostrar todos os itens sem nenhuma configuração adicional linha 15; caso não seja super user, cairemos na Linha 8.
  • Linha 8 – Fazemos aqui um outro teste para saber se o usuário logado pertence ao grupo ‘perseguidora’. Aqui utilizamos o request.user.groups que retorna os grupos aos quais o usuário logado está associado. O comando values_list(‘name’, Flat=True) fica como tarefa para vocês descobrirem o que ele faz.
  • Linha 9 – Caso o teste da linha 8  seja verdadeiro, fazemos o retorno do qs sem nenhuma configuração adicional, o que resulta na listagem de todos os itens.
  • Linha 11 à 12 – Executo aqui outras consultas para resgatar dados necessário para o filter do qs, isso está totalmente relacionado à estrutura do seu models (por isso não é objeto desse artigo).
  • Linha 13 – Aqui damos o pulo do gato: percebam que estou fazendo qs.filter(), que é aplicar um filtro ao qs (queryset) padrão, assim podemos aplicar qualquer tipo de filtro, como já sabemos fazer no models. O que fiz aqui foi justamente filtrar os chamados para a empresa X, pois o sistema é multi-empresas; depois um outro filtro que é pelo tipo de contato, resultando nos contatos direcionados apenas para o setor do usuário logado e, por fim, filtro novamente trazendo apenas os contatos ainda não atendidos.

Outro método bem interessante de falarmos é o changelist_view(). Nesse método iremos dentre várias possibilidades, determinar os campos que serão mostrados na “tabela” novamente iremos utilizar o usuário logado como fator determinante para nossa customização.

[python]

def changelist_view(self, request, extra_content=None):
u""" Alterando o changelist_view para gerenciar os campos que serão mostrados conforme
perfil do usuário logado. Sendo SuperUser será mostrado a data de envio da resposta.
"""
if request.user.is_superuser or ‘perseguidora’ in str(request.user.groups.values_list(‘name’, flat=True)).lower():
self.list_display = (‘tipo_contato’, ‘nome’, ‘email’, ‘telefone’,
‘data_recebimento’, ‘data_resposta’, ‘mostrar_status_contato’, ‘fkEmpresa’)
else:
self.list_display = (‘tipo_contato’, ‘nome’, ‘email’, ‘telefone’,
‘data_recebimento’, ‘data_resposta’, ‘fkEmpresa’)

return super(ContatoAdmin, self).changelist_view(request, extra_content)[/python]

  • Linha 5 – Novamente realizamos alguns testes para identificarmos o perfil do usuário logado, já explicado no método anterior
  • Linha 6 – O list_display determina quais os campos serão “listados” no change_list. Nesse caso, estamos determinando, via self.list_display, quais campos serão mostrados. Percebam que a linha 6 é diferente da linha 9 apenas na quantidade de itens (que são os atributos do nosso model), é só isso! Configuramos o Admin para mostrar campos conforme o perfil do usuário logado.

Com a mesma lógica podemos subescrever outros métodos, como o get_form, que é responsável por configurar o formulário de inserção/edição dos dados no Admin. Como estamos trabalhando com o Models Contato, iremos configurar conforme o perfil do usuário quais campos serão mostrados ou não.

[python]

def get_form(self, request, obj=None, **kwargs):
form = super(AtendimentoAdmin, self).get_form(request, obj, **kwargs)
if request.user.is_superuser:
return form
else:
self.fieldset = [(‘tipo_contato’, ‘nome’,
‘email’, ‘telefone’,
‘data_recebimento’,
‘data_resposta’,)]
return form[/python]

Tentei aqui mostrar alguns métodos do admin. Novamente, para não me estender muito e assim tornar cansativo a leitura do artigo, deixei para a terceira parte do Admin para falarmos sobre:

  1. TabularInline
  2. Herança de Admins
  3. raw_id_fields
  4. formfield_overrides
  5. delete_model