Arquivo de December, 2008

Reaproveitando a inteface do Admin do Django

Postado por Rafael Sierra em 16/12/2008

Finalmente o Django pra mim atingiu a perfeição, depois da minha surpresa com o {{ block.super }}, agora foi a vez de eu realizar um sonho meu: Aproveitar as interfaces maravilhosas de administração do Django.

Sempre é um verdadeiro pé no saco ter que ficar escrevendo código que você sabe que ta pronto, e mais sacal ainda quando o código ta a apenas "../../" de você, mas agora é um trabalho a menos que eu tenho :D (especialmente considerando a minha "super habilidade" com CSS).

Agora vamos ao que interessa, o conhecimento necessário pra fazer isso funcionar levou cerca de 4 horas pra ser adiquirido, foram 4 horas engolindo e reengolindo código do Django, mas no final resultou em uma view como a seguinte (ignorem os imports desnecessários):

 
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.utils.text import ugettext_lazy as _
from django.contrib.auth.decorators import login_required
from mysearch.profiles.models import Profile
from mysearch.profiles.admin import ProfileAdmin
from django.contrib import admin
from django.contrib.admin.views.main import ChangeList
 
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
 
@login_required
def index(request):
    admin_model = admin.site._registry[Profile]
    admin_model.admin_site.root_path = request.path
    cl = ChangeList(
        request,
        Profile,
        ProfileAdmin.list_display,
        ProfileAdmin.list_display_links,
        ProfileAdmin.list_filter,
        ProfileAdmin.date_hierarchy,
        ProfileAdmin.search_fields,
        ProfileAdmin.list_select_related,
        ProfileAdmin.list_per_page,
        admin_model)
    cl.query_set = cl.query_set.filter(user=request.user)
    cl.get_results(request)
 
    context = {
        'title': cl.title,
        'is_popup': cl.is_popup,
        'cl': cl,
        'has_add_permission': admin_model.has_add_permission(request),
        'root_path': admin_model.admin_site.root_path,
        'app_label': _('Profile'),
    }
 
    return render_to_response('admin/change_list.html',
        context, context_instance=RequestContext(request))
 

Vamos as explicações agora. Primeiramente, pra que isso funcione é preciso que seu model tenha sido registrado no Admin do Django, no meu caso o model utilizado foi esse chamado Profile.

Depois disso é criado um objeto do tipo `django.contrib.admin.views.main.ChangeList`, infelizmente todos os parametros devem ser passados, e essa foi a parte que mais me decepcionou, uma vez que todos os atributos poderiam ser resgatados com base no último argumento, ou simplesmente pedindo a classe que define o model, mas tudo bem, é um pequeno preço a se pagar pelo beneficio.

Após criar a variável `cl`, vem o ponto que meu deu maior dor de cabeça: Filtrar o que eu quero que apareca para o usuário. Nesse caso eu precisava que o usuário tivesse acesso apenas ao próprio conteudo, e pra isso adicionei o `.filter(user=request.user)`, porém, isso não basta, é preciso chamar a função `cl.get_results(request)` pra que ele possa atualizar a lista de resultados que vai ser usada

A váriavel `context`, neste caso, é usada pelo template `admin/change_list.html`, sinta-se a vontade para copiar o template da pasta do Django e colocar na sua pra editar.

Por fim, basta retornar o template que vai pegar o resultado e imprimir na tela pro seu usuário que será muito feliz :D

Observações
O template `admin/change_list.html` não imprime a tabela propriamente dia, ela utiliza uma tag (não documentada no site) chamada `result_list`, essa tag recebe um objeto do tipo `ChangeList` que é o nosso `cl`.

Você ainda vai precisa escrever uma view (ou aproveitar a do Admin) para fazer o handle quando o usuário clicar no objeto, mas essa é a parte fácil :P

Acessando `block` tags parentes em templates Django

Postado por Rafael Sierra em 16/12/2008

Se tem algo que eu admiro muito no sistema de templates do Django, é a tag block, eu acho ela realmente f#!$ pra ca#@!&.

Só que recemente eu descobri algo nela que se eu estivesse em um ato sexual teria resultado em um fork(), que é a possibilidade de acessar o conteúdo antigo da tag antes dela ser sobrescrevida por você.

É extremamente simples, vamos pegar como exemplo o seguinte template `base.html`:

 
<html>
    <head><title>{% block title%}Meu site dahora{% endblock %}</html>
    <body>{% block content %}{% endblock %}
</html>
 

A parte legal fica por conta do bloco title. Até então, sempre que eu quizesse colocar "Meu site dahora | Home" no titulo, eu teria que fazer assim em um template filho:

 
{% extends "base.html" %}
{% block title %}Meu site dahora | Home{% endblock %}
 

O problema óbvio nesse caso, é que se um dia eu resolver trocar o titulo pra "O Jardineiro é Jesus", então eu vo ter que editar todo template que extende o template `base.html` pra arrumar isso.

Eis então que surge a solução

 
{% extends "base.html" %}
{% block title %}{{block.super}} | Home{% endblock %}
 

:D Simples e funcional. VIDA LONGA AO DJANGO!

Oracle – Consultas com “Accent Insensitive”

Postado por Rafael Monteiro em 4/12/2008

Estava precisando fazer uma consulta que não levasse em conta acentos digitados pelo usuário no filtro da pesquisa, nem a capitalização (case).

Eis que após alguma pesquisa cheguei à seguinte solução:

WHERE
TRANSLATE(UPPER(campo),'ÁÇÉÍÓÚÀÈÌÒÙÂÊÎÔÛÃÕËÜ','ACEIOUAEIOUAEIOUAOEU')
LIKE
TRANSLATE(UPPER('%parametro%'),'ÁÇÉÍÓÚÀÈÌÒÙÂÊÎÔÛÃÕËÜ',
'ACEIOUAEIOUAEIOUAOEU')

 

Dependendo da complexidade da consulta, pode ser mais interessante a utilização do conceito de Full Text Search, mas para uma consulta mais 'simples', o exposto acima supre a necessidade.

Av. Conselheiro Nébias, 368A, Cj. 413
Vila Mathias - Santos - SP
Telefone: (13) 3345-4580

© 2008 - 2009 Stiod. Todos os direitos reservados.