Django SearchField

Posted on December 1, 2008. Filed under: django | Tags: , , |

Há muito tempo “manter um blog” estava na minha “To Do List” e os colegas da lista de discussão django-brasil me deram o “empurrão” que eu precisava.

Depois de participar da thread na lista, decidi que o SearchField seria o assunto do meu primeiro post. Portanto, esse post é uma consequência da thread iniciada por Diego Martins e da super dica e ajuda de Luciano Ramalho. Agradeço aqui aos dois camaradas.

Por Que SearchField?

A idéia do SearchField é armazenar dados num formato útil para buscas, de forma a indexar valores de vários atributos num só atributo. Além disso, o valor indexado tem os caracteres não-ascii substituídos por seus correspondentes na tabela ascii através da função to_ascii, que é uma adaptação do removedor de acentos. Assim, podemos ter uma comparação de “strings” no banco de dados considerando os valores de várias colunas e sem considerar os acentos.

Como Usar

O SearchField tem um atributo obrigatório: field_names, que é uma lista com os nomes dos campos que se deseja indexar.

Declaração da classe de modelo

class Test(models.Model):
    text = models.TextField()
    another_text = models.TextField()
    search_text = SearchField(field_names=['text', 'another_text'])

Integrando com o Site de Administração do Django

Para utilizar o SearchField no Site de Administração basta forçar que o valor da busca seja convertido com a função to_ascii. Segue abaixo o código do arquivo “admin.py”:

from django.contrib import admin

def queryset_ascii(self, request):
    if 'q' in request.GET:
        request.GET._mutable = True
        request.GET['q'] = to_ascii(request.GET['q'])
    return admin.ModelAdmin.queryset(self, request)

class TestAdmin(admin.ModelAdmin):
    list_display = ['text', 'another_text', 'search_text']
    search_fields = ['search_text']
    queryset = queryset_ascii

admin.site.register(Test, TestAdmin)

Função to_ascii

from unicodedata import normalize

def to_ascii(txt, codif='utf-8'):
    if not isinstance(txt, basestring):
        txt = unicode(txt)
    if isinstance(txt, unicode):
        txt = txt.encode('utf-8')
    return normalize('NFKD', txt.decode(codif)).encode('ASCII','ignore')

SearchField

from django.db import models

class SearchField(models.TextField):
    def pre_save(self, model_instance, add):
        search_text = []
        for field_name in self.field_names:
            val = unicode(to_ascii(getattr(model_instance, field_name)))
            search_text.append(val)
        value = u' '.join(search_text)
        setattr(model_instance, self.name, value)
        return value
    def __init__(self, field_names, *args, **kwargs):
        self.field_names = field_names
        kwargs['editable'] = False
        super(self.__class__, self).__init__(*args, **kwargs)


Read Full Post | Make a Comment ( 2 so far )

Recently on Paivatulio’s Blog...

Not Found

Sorry, but you are looking for something that isn't here.

Liked it here?
Why not try sites on the blogroll...

Follow

Get every new post delivered to your Inbox.