Django SearchField
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 )