<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Paivatulio's Blog</title>
	<atom:link href="http://paivatulio.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://paivatulio.wordpress.com</link>
	<description>Desenvolvimento Web, Django, Python etc.</description>
	<lastBuildDate>Thu, 16 Apr 2009 22:33:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='paivatulio.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Paivatulio's Blog</title>
		<link>http://paivatulio.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://paivatulio.wordpress.com/osd.xml" title="Paivatulio&#039;s Blog" />
	<atom:link rel='hub' href='http://paivatulio.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Django SearchField</title>
		<link>http://paivatulio.wordpress.com/2008/12/01/django-searchfield/</link>
		<comments>http://paivatulio.wordpress.com/2008/12/01/django-searchfield/#comments</comments>
		<pubDate>Mon, 01 Dec 2008 16:08:13 +0000</pubDate>
		<dc:creator>paivatulio</dc:creator>
				<category><![CDATA[django]]></category>
		<category><![CDATA[acentuação]]></category>
		<category><![CDATA[banco de dados]]></category>

		<guid isPermaLink="false">http://paivatulio.wordpress.com/?p=14</guid>
		<description><![CDATA[Há muito tempo &#8220;manter um blog&#8221; estava na minha &#8220;To Do List&#8221; e os colegas da lista de discussão django-brasil me deram o &#8220;empurrão&#8221; 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 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paivatulio.wordpress.com&amp;blog=5374294&amp;post=14&amp;subd=paivatulio&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Há muito tempo &#8220;manter um blog&#8221; estava na minha &#8220;To Do List&#8221; e os colegas da lista de discussão <a href="http://groups.google.com/group/django-brasil" target="_blank">django-brasil</a> me deram o &#8220;empurrão&#8221; que eu precisava.</p>
<p>Depois de participar da <a title="thread" href="http://groups.google.com/group/django-brasil/browse_thread/thread/60f9afde5984cb74/982da8bffc312a98#982da8bffc312a98" target="_blank">thread</a> 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 <a href="http://ramalho.org/" target="_blank">Luciano Ramalho</a>. Agradeço aqui aos dois camaradas.</p>
<h3>Por Que SearchField?</h3>
<p>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 <strong>to_ascii</strong>, que é uma adaptação do <a href="http://www.pythonbrasil.com.br/moin.cgi/RemovedorDeAcentos" target="_blank">removedor de acentos</a>. Assim, podemos ter uma comparação de &#8220;strings&#8221; no banco de dados considerando os valores de várias colunas e sem considerar os acentos.</p>
<h3>Como Usar</h3>
<p>O SearchField tem um atributo obrigatório: <strong>field_names</strong>, que é uma lista com os nomes dos campos que se deseja indexar.</p>
<h4>Declaração da classe de modelo</h4>
<p><pre class="brush: python;">
class Test(models.Model):
    text = models.TextField()
    another_text = models.TextField()
    search_text = SearchField(field_names=['text', 'another_text'])
</pre></p>
<h4>Integrando com o Site de Administração do Django</h4>
<p>Para utilizar o SearchField no Site de Administração basta forçar que o valor da busca seja convertido com a função <strong>to_ascii</strong>. Segue abaixo o código do arquivo &#8220;admin.py&#8221;:</p>
<p><pre class="brush: python;">
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)
</pre></p>
<h3>Função to_ascii</h3>
<p><pre class="brush: python;">
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')
</pre></p>
<h3>SearchField</h3>
<p><pre class="brush: python;">
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)
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/paivatulio.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/paivatulio.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/paivatulio.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/paivatulio.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/paivatulio.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/paivatulio.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/paivatulio.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/paivatulio.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/paivatulio.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/paivatulio.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/paivatulio.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/paivatulio.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/paivatulio.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/paivatulio.wordpress.com/14/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paivatulio.wordpress.com&amp;blog=5374294&amp;post=14&amp;subd=paivatulio&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://paivatulio.wordpress.com/2008/12/01/django-searchfield/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/64fc51618800bf231a93ec537c2aef37?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paivatulio</media:title>
		</media:content>
	</item>
	</channel>
</rss>
