<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2spanishfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>AxiaCore</title>
	
	<link>http://axiacore.com</link>
	<description>Tenemos poderes magicos...</description>
	<lastBuildDate>Tue, 10 Apr 2012 23:35:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/AxiaCore" /><feedburner:info uri="axiacore" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><image><link>http://axiacore.com</link><url>http://axiacore.com/images/axiacore/axiabanner.png</url><title>AxiaCore</title></image><feedburner:emailServiceId>AxiaCore</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FAxiaCore" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FAxiaCore" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://add.my.yahoo.com/content?lg=es&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2FAxiaCore" src="http://eur.i1.yimg.com/eur.yimg.com/i/es/my/addto1.gif">Subscribe with My Yahoo!</feedburner:feedFlare><item>
		<title>Generando hojas de cálculo flexibles con Python</title>
		<link>http://feedproxy.google.com/~r/AxiaCore/~3/v6-EZ8s1-Ik/</link>
		<comments>http://axiacore.com/2012/04/generando-hojas-de-calculo-flexibles-con-python/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 23:33:14 +0000</pubDate>
		<dc:creator>andres.quiroga</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://axiacore.com/?p=2308</guid>
		<description><![CDATA[A diario nos encontramos con la necesidad de que nuestros proyectos soporten la generación de informes ordenados, con buena presentación y fácilmente legibles por los usuarios. Ya sea un informe de gastos, un informe de facturación,  una tabla que nos permita visualizar los datos de nuestros contactos o un informe de movimientos y solicitudes mensuales en nuestro [...]]]></description>
			<content:encoded><![CDATA[<p>A diario nos encontramos con la necesidad de que nuestros proyectos soporten la generación de informes ordenados, con buena presentación y fácilmente legibles por los usuarios. Ya sea un informe de gastos, un informe de facturación,  una tabla que nos permita visualizar los datos de nuestros contactos o un informe de movimientos y solicitudes mensuales en nuestro sitio web, una hoja de cálculo es la mejor opción a la hora de tener un informe entendible y flexible para el usuario.</p>
<p>xlwt es una librería de python creada por John Machin, que permite generar hojas de cálculo flexibles. compatibles con Office, OpenOffice, Calc, Gnumeric y con total soporte para Unicode, y a la vez permite personalizar los archivos generados. En este articulo enumeraremos algunas de las herramientas que nos brinda xlwt e iremos paso a paso, detallando el código para obtener un informe final con  nuestras preferencias de personalización.</p>
<p><strong>1. GENERANDO LIBRO</strong></p>
<p>La clase WorkBook() nos permite asignar a una variable las características de un archivo xls. Todo libro o archivo xls debe contar con al menos una hoja de cálculo. Las hojas de cálculo se crean por medio del método  <em>add_sheet(&#8216;nombre_de_la_hoja&#8217;)</em>. A continuación, se describe el código básico para generar un libro de trabajo llamado <em>first_book.xls</em>, con dos hojas de calculo vacías<em>(first_sheet y second_sheet).</em></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> Workbook
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> first_book<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># Workbook asing</span>
    first_book=Workbook<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Sheets definition</span>
    first_book.<span style="color: black;">add_sheet</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_sheet'</span><span style="color: black;">&#41;</span>
    first_book.<span style="color: black;">add_sheet</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'second_sheet'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Saving file</span>
    first_book.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_book.xls'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Para manipular las distintas hojas de cálculo y así definir los contenidos deseados para cada una de ellas, asignamos variables a estas, de la siguiente forma:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> Workbook
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> first_book<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># Workbook asing</span>
    first_book=Workbook<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Sheets definition</span>
    ws1 = first_book.<span style="color: black;">add_sheet</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_sheet'</span><span style="color: black;">&#41;</span>
    ws2 = first_book.<span style="color: black;">add_sheet</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'second_sheet'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Saving file</span>
    first_book.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_book.xls'</span><span style="color: black;">&#41;</span></pre></div></div>

<p><strong>2. IMPRIMIENDO DATOS</strong></p>
<p>Las hojas de cálculo cuentan con el método <em>write</em>, que nos permite introducir contenido en las celdas. Los parámetros que recibe son la posición (celda) y contenido. La posición se introduce de la forma (fila, columna), empezando por la posición (0, 0), equivalente en nuestra hoja a la celda A1.</p>
<p>En la siguiente modificación a nuestra función, se introduce, en la hoja de trabajo <em>first_sheet, </em>en la posición A1, el texto <em>&#8220;Content 1, sheet 1&#8243;, </em>y en la posición B1, el texto <em>&#8220;Content 2, sheet 1&#8243;</em>. De la misma forma, en la hoja de cálculo <em>second_sheet,</em> se introduce, en la posición A2, el texto <em>&#8220;Content 1, sheet 2</em>&#8220;, y en la posición B2, el texto<em> &#8221;Content 2, sheet 2&#8243;</em>.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> Workbook
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> first_book<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># Workbook asing</span>
    first_book=Workbook<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Sheets definition</span>
    ws1 = first_book.<span style="color: black;">add_sheet</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_sheet'</span><span style="color: black;">&#41;</span>
    ws2 = first_book.<span style="color: black;">add_sheet</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'second_sheet'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># content per sheets</span>
    ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>, <span style="color: #483d8b;">'Content 1, sheet 1'</span><span style="color: black;">&#41;</span>
    ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'Content 2, sheet 1'</span><span style="color: black;">&#41;</span>
    ws2.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">0</span>, <span style="color: #483d8b;">'Content 1, sheet 2'</span><span style="color: black;">&#41;</span>
    ws2.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'Content 2, sheet 2'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Saving file</span>
    first_book.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_book.xls'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Pero introducir uno a uno el contenido de cada una de las celdas resultaría ser el proceso mas ineficiente posible a la hora de generar un informe xls. Por tal razón, utilizaremos los bucles de python para imprimir estos contenidos de forma automática.<br />
Ahora generaremos una sola hoja de cálculo, en la cual imprimiremos una tabla que relaciona <em>nombre</em> y <em>edad</em> de una sería de personas que se han definido previamente en un diccionario llamado <em>ages</em>.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> Workbook
&nbsp;
ages=<span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'Peter'</span>: <span style="color: #ff4500;">20</span>,
        <span style="color: #483d8b;">'Karen'</span>: <span style="color: #ff4500;">19</span>,
        <span style="color: #483d8b;">'Jessie'</span>: <span style="color: #ff4500;">43</span>,
        <span style="color: #483d8b;">'Leonard'</span>: <span style="color: #ff4500;">56</span>,
        <span style="color: #483d8b;">'Robert'</span>: <span style="color: #ff4500;">30</span>,
        <span style="color: #483d8b;">'Nina'</span>: <span style="color: #ff4500;">23</span>,
    <span style="color: black;">&#125;</span>
&nbsp;
number_of_elements = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>ages<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> first_book<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    first_book=Workbook<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Sheet definition</span>
    ws1 = first_book.<span style="color: black;">add_sheet</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_sheet'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Header definition</span>
    ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>, <span style="color: #483d8b;">'Name'</span><span style="color: black;">&#41;</span>
    ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'Years old'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Represents the first row in the iteration</span>
    i = <span style="color: #ff4500;">1</span> 
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> name, years <span style="color: #ff7700;font-weight:bold;">in</span> ages.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span>i, <span style="color: #ff4500;">0</span>, name<span style="color: black;">&#41;</span>
        ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span>i, <span style="color: #ff4500;">1</span>, years<span style="color: black;">&#41;</span>
        i += <span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> i == number_of_elements+<span style="color: #ff4500;">1</span>: <span style="color: #808080; font-style: italic;"># For display the latest element</span>
            <span style="color: #ff7700;font-weight:bold;">break</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Saving file</span>
    first_book.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_book.xls'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Primero definimos el <em>header</em> de la tabla. Asignamos como contenido a la celda A1 (posición 0, 0) el texto &#8220;<em>Name&#8221;, </em>y a la celda B1 (posición 0, 1) el texto <em>&#8220;Years old&#8221;</em>. A continuación definimos la variable <em>i, </em>que representa el número de la fila desde la cual vamos a empezar a imprimir la información de las personas de nuestro diccionario. En este caso, como la fila 1 se encuentra ocupada con el <em>header</em> de la tabla, debemos empezar a introducir los datos desde la fila 2, es decir, desde la posición (1, #-columna).</p>
<p>Con un bucle <em>for </em>en el que iteramos el diccionario <em>ages</em>, introducimos de forma ordenada los datos de las personas en nuestra tabla. Por cada ciclo aumentamos el valor de <em>i</em> en 1, y de esta forma imprimimos los datos de cada persona del diccionario en una fila distinta.<br />
Previamente habíamos definido la variable number_of_elements, asignándole como valor el número equivalente a la cantidad de elementos del diccionario <em>ages</em>. Esta variable es de gran importancia en este ejemplo, ya que es la clave para salir del bucle y evitar errores de sobre-escritura en las celdas de nuestro archivo first_book.xls.</p>
<p>Rompemos el bucle cuando la variable <em>i </em>sea igual a <em>number_of_elements + 1</em>.¿Porque?&#8230; La cantidad de elementos en nuestro diccionario es 6 y el valor inicial de la variable <em>i</em> es 1. Por lo tanto, si rompemos el bucle cuando la variable <em>i</em> sea igual a 6, solo estaríamos repitiendo el ciclo 5 veces, es decir, perderíamos el último elemento de nuestro diccionario.</p>
<p><strong>3. PERSONALIZANDO LA PRESENTACIÓN</strong></p>
<p>haciendo uso de las clases Font, XFStyle y Borders, podemos añadir preferencias de visualización para nuestras celdas y sus contenidos. A continuación se muestra como personalizar nuestra hoja de cálculo mediante el uso de solo unas pocas de las muchas opciones que brinda xlwt.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> Workbook
<span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> Font
<span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> XFStyle
<span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> Borders
&nbsp;
ages=<span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'Peter'</span>: <span style="color: #ff4500;">20</span>,
        <span style="color: #483d8b;">'Karen'</span>: <span style="color: #ff4500;">19</span>,
        <span style="color: #483d8b;">'Jessie'</span>: <span style="color: #ff4500;">43</span>,
        <span style="color: #483d8b;">'Leonard'</span>: <span style="color: #ff4500;">56</span>,
        <span style="color: #483d8b;">'Robert'</span>: <span style="color: #ff4500;">30</span>,
        <span style="color: #483d8b;">'Nina'</span>: <span style="color: #ff4500;">23</span>,
    <span style="color: black;">&#125;</span>
&nbsp;
number_of_elements = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>ages<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> first_book<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    first_book=Workbook<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Sheet definition</span>
    ws1 = first_book.<span style="color: black;">add_sheet</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_sheet'</span><span style="color: black;">&#41;</span>
&nbsp;
    header_font = Font<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    body_font = Font<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Header font preferences</span>
    header_font.<span style="color: black;">name</span> = <span style="color: #483d8b;">'Times New Roman'</span>
    header_font.<span style="color: black;">height</span> = <span style="color: #ff4500;">20</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">15</span>
    header_font.<span style="color: black;">bold</span> = <span style="color: #008000;">True</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Body font preferences</span>
    body_font.<span style="color: black;">name</span> = <span style="color: #483d8b;">'Arial'</span>
    body_font.<span style="color: black;">italic</span> = <span style="color: #008000;">True</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Header Cells style definition</span>
    header_style = XFStyle<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    header_style.<span style="color: black;">font</span> = header_font 
&nbsp;
    borders = Borders<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    borders.<span style="color: black;">left</span> = <span style="color: #ff4500;">1</span>
    borders.<span style="color: black;">right</span> = <span style="color: #ff4500;">1</span>
    borders.<span style="color: black;">top</span> = <span style="color: #ff4500;">1</span>
    borders.<span style="color: black;">bottom</span> = <span style="color: #ff4500;">1</span>
    header_style.<span style="color: black;">borders</span> = borders
&nbsp;
    <span style="color: #808080; font-style: italic;"># body cell name style definition</span>
    body_style = XFStyle<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    body_style.<span style="color: black;">font</span> = body_font 
&nbsp;
    <span style="color: #808080; font-style: italic;"># Header definition</span>
    ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>, <span style="color: #483d8b;">'Name'</span>, header_style <span style="color: black;">&#41;</span>
    ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'Years old'</span>, header_style <span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Represents the first row in the iteration</span>
    i = <span style="color: #ff4500;">1</span> 
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> name, years <span style="color: #ff7700;font-weight:bold;">in</span> ages.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span>i, <span style="color: #ff4500;">0</span>, name, body_style<span style="color: black;">&#41;</span>
        ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span>i, <span style="color: #ff4500;">1</span>, years<span style="color: black;">&#41;</span>
        i += <span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> i == number_of_elements+<span style="color: #ff4500;">1</span>: <span style="color: #808080; font-style: italic;"># For display the latest element</span>
            <span style="color: #ff7700;font-weight:bold;">break</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Saving file</span>
    first_book.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_book.xls'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>El parámetro <em>height </em>que representa el tamaño de la fuente, se debe incluir multiplicado por un factor de 20. Es decir, si el tamaño de fuente deseado es 15, entonces se debe incluir el valor 300, o si el tamaño deseado es 20, entonces se debe introducir el valor 400.</p>
<p>Una vez definidas nuestras preferencias de personalización, el resultado se envía como el tercer parámetro en el constructor de la celda. Así, en este caso, para las celdas del <em>header</em> enviamos el parámetro <em>header_style</em>, y para las celdas que contienen los nombres de nuestro diccionario enviamos el parámetro <em>body_style</em></p>
<p><strong>4. COMBINANDO CELDAS</strong></p>
<p>Otra funcionalidad muy común a la hora de trabajar con hojas de cálculo, es la posibilidad de combinar celdas. <em>xlwt </em>permite hacer esto de una forma muy simple. A continuación, insertaremos una imagen en el encabezado de la tabla. Para hacer esto, combinaremos una serie de celdas. La forma de hacerlo es <em>sheet_name.write_merge(fila_inicial, fila_final, columna_inicial, columna_final,)</em>. Así, se combinarán las celdas comprendidas en el rango indicado. En este caso, combinaremos las celdas comprendidas entre la posición A1 a la B11.  El rango de celdas combinadas y el ancho de las columnas los ajustamos según el tamañ de la imagén a insertar (Este ejemplo esta ajustado para una imagen de <em>273&#215;180 px</em> ). Este cambio implica mover nuestros datos tantas filas hacia abajo como filas se combinaron para el encabezado. Así, las celdas del <em>header, (Name y years old)</em>, se deben ubicar en la fila 12. Nuestra función <em>first_book</em> quedará de la siguiente manera:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> first_book<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    first_book=Workbook<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Sheet definition</span>
    ws1 = first_book.<span style="color: black;">add_sheet</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_sheet'</span><span style="color: black;">&#41;</span>
&nbsp;
    header_font = Font<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    body_font = Font<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Header font preferences</span>
    header_font.<span style="color: black;">name</span> = <span style="color: #483d8b;">'Times New Roman'</span>
    header_font.<span style="color: black;">height</span> = <span style="color: #ff4500;">20</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">15</span>
    header_font.<span style="color: black;">bold</span> = <span style="color: #008000;">True</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Body font preferences</span>
    body_font.<span style="color: black;">name</span> = <span style="color: #483d8b;">'Arial'</span>
    body_font.<span style="color: black;">italic</span> = <span style="color: #008000;">True</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Header Cells style definition</span>
    header_style = XFStyle<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    header_style.<span style="color: black;">font</span> = header_font 
&nbsp;
    borders = Borders<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    borders.<span style="color: black;">left</span> = <span style="color: #ff4500;">1</span>
    borders.<span style="color: black;">right</span> = <span style="color: #ff4500;">1</span>
    borders.<span style="color: black;">top</span> = <span style="color: #ff4500;">1</span>
    borders.<span style="color: black;">bottom</span> = <span style="color: #ff4500;">1</span>
    header_style.<span style="color: black;">borders</span> = borders
&nbsp;
    <span style="color: #808080; font-style: italic;"># body cell name style definition</span>
    body_style = XFStyle<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    body_style.<span style="color: black;">font</span> = body_font 
&nbsp;
    <span style="color: #808080; font-style: italic;"># Header definition</span>
    ws1.<span style="color: black;">write_merge</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">10</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</span>,<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># # Adjust columns width acording to the image size</span>
&nbsp;
    ws1.<span style="color: black;">col</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>.<span style="color: black;">width</span> = <span style="color: #ff4500;">8</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">625</span>
    ws1.<span style="color: black;">col</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>.<span style="color: black;">width</span> = <span style="color: #ff4500;">8</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">625</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Insert image</span>
    ws1.<span style="color: black;">insert_bitmap</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'logo.bmp'</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
    ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">11</span>, <span style="color: #ff4500;">0</span>, <span style="color: #483d8b;">'Name'</span>, header_style <span style="color: black;">&#41;</span>
    ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">11</span>, <span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'Years old'</span>, header_style <span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Represents the first row in the iteration</span>
    i = <span style="color: #ff4500;">12</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> name, years <span style="color: #ff7700;font-weight:bold;">in</span> ages.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span>i, <span style="color: #ff4500;">0</span>, name, body_style<span style="color: black;">&#41;</span>
        ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span>i, <span style="color: #ff4500;">1</span>, years<span style="color: black;">&#41;</span>
        i += <span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> i == number_of_elements+<span style="color: #ff4500;">12</span>: <span style="color: #808080; font-style: italic;"># For display the latest element</span>
            <span style="color: #ff7700;font-weight:bold;">break</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Saving file</span>
    first_book.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_book.xls'</span><span style="color: black;">&#41;</span></pre></div></div>

<p><strong>5. INSERTANDO FORMULAS</strong></p>
<p>Ahora, introduciremos el código para implementar una formula que calcule la suma total de las edades de las personas en nuestra tabla. Debemos exportar la clase &#8220;<em>Formula&#8221;</em> y definir las celdas que se van a operar.</p>
<p>En este caso, se muestra el código para explicar el funcionamiento de las formulas en xlwt, aunque en realidad sería mas sencillo hacer el cálculo en nuestro código y enviar el resultado como parámetro de contenido a una celda determinada. Se deben introducir las celdas a operar por su posición en el formato como se identifican las celdas en los archivos xls (ej:A1, B1).<br />
El código quedaría como sigue:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> Workbook
<span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> Font
<span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> XFStyle
<span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> Borders
<span style="color: #ff7700;font-weight:bold;">from</span> xlwt impor Formula
&nbsp;
ages=<span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'Peter'</span>: <span style="color: #ff4500;">20</span>,
        <span style="color: #483d8b;">'Karen'</span>: <span style="color: #ff4500;">19</span>,
        <span style="color: #483d8b;">'Jessie'</span>: <span style="color: #ff4500;">43</span>,
        <span style="color: #483d8b;">'Leonard'</span>: <span style="color: #ff4500;">56</span>,
        <span style="color: #483d8b;">'Robert'</span>: <span style="color: #ff4500;">30</span>,
        <span style="color: #483d8b;">'Nina'</span>: <span style="color: #ff4500;">23</span>,
    <span style="color: black;">&#125;</span>
&nbsp;
number_of_elements = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>ages<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> first_book<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    first_book=Workbook<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Sheet definition</span>
    ws1 = first_book.<span style="color: black;">add_sheet</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_sheet'</span><span style="color: black;">&#41;</span>
&nbsp;
    header_font = Font<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    body_font = Font<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Header font preferences</span>
    header_font.<span style="color: black;">name</span> = <span style="color: #483d8b;">'Times New Roman'</span>
    header_font.<span style="color: black;">height</span> = <span style="color: #ff4500;">20</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">15</span>
    header_font.<span style="color: black;">bold</span> = <span style="color: #008000;">True</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Body font preferences</span>
    body_font.<span style="color: black;">name</span> = <span style="color: #483d8b;">'Arial'</span>
    body_font.<span style="color: black;">italic</span> = <span style="color: #008000;">True</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Header Cells style definition</span>
    header_style = XFStyle<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    header_style.<span style="color: black;">font</span> = header_font 
&nbsp;
    borders = Borders<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    borders.<span style="color: black;">left</span> = <span style="color: #ff4500;">1</span>
    borders.<span style="color: black;">right</span> = <span style="color: #ff4500;">1</span>
    borders.<span style="color: black;">top</span> = <span style="color: #ff4500;">1</span>
    borders.<span style="color: black;">bottom</span> = <span style="color: #ff4500;">1</span>
    header_style.<span style="color: black;">borders</span> = borders
&nbsp;
    <span style="color: #808080; font-style: italic;"># body cell name style definition</span>
    body_style = XFStyle<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    body_style.<span style="color: black;">font</span> = body_font 
&nbsp;
    <span style="color: #808080; font-style: italic;"># Header definition</span>
    ws1.<span style="color: black;">write_merge</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">10</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</span>,<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># # Adjust columns width acording to the image size</span>
&nbsp;
    ws1.<span style="color: black;">col</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>.<span style="color: black;">width</span> = <span style="color: #ff4500;">8</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">625</span>
    ws1.<span style="color: black;">col</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>.<span style="color: black;">width</span> = <span style="color: #ff4500;">8</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">625</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Insert image</span>
    ws1.<span style="color: black;">insert_bitmap</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'logo.bmp'</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
    ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">11</span>, <span style="color: #ff4500;">0</span>, <span style="color: #483d8b;">'Name'</span>, header_style <span style="color: black;">&#41;</span>
    ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">11</span>, <span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'Years old'</span>, header_style <span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Represents the first row in the iteration</span>
    i = <span style="color: #ff4500;">12</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> name, years <span style="color: #ff7700;font-weight:bold;">in</span> ages.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span>i, <span style="color: #ff4500;">0</span>, name, body_style<span style="color: black;">&#41;</span>
        ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span>i, <span style="color: #ff4500;">1</span>, years<span style="color: black;">&#41;</span>
        i += <span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> i == number_of_elements+<span style="color: #ff4500;">12</span>: <span style="color: #808080; font-style: italic;"># For display the latest element</span>
            <span style="color: #ff7700;font-weight:bold;">break</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Total cell style</span>
    total_font = Font<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    total_font.<span style="color: black;">bold</span> = <span style="color: #008000;">True</span>
    total_style = XFStyle<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    total_style.<span style="color: black;">font</span> = total_font 
&nbsp;
    ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span>i, <span style="color: #ff4500;">0</span>, <span style="color: #483d8b;">'Total'</span>, total_style<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Formula</span>
    ws1.<span style="color: black;">write</span><span style="color: black;">&#40;</span>i, <span style="color: #ff4500;">1</span>, Formula<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SUM(B13:B18)&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Saving file</span>
    first_book.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'first_book.xls'</span><span style="color: black;">&#41;</span></pre></div></div>

<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AxiaCore?a=v6-EZ8s1-Ik:4c1Vt0ySA-k:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=v6-EZ8s1-Ik:4c1Vt0ySA-k:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/AxiaCore?i=v6-EZ8s1-Ik:4c1Vt0ySA-k:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=v6-EZ8s1-Ik:4c1Vt0ySA-k:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=v6-EZ8s1-Ik:4c1Vt0ySA-k:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AxiaCore/~4/v6-EZ8s1-Ik" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://axiacore.com/2012/04/generando-hojas-de-calculo-flexibles-con-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://axiacore.com/2012/04/generando-hojas-de-calculo-flexibles-con-python/</feedburner:origLink></item>
		<item>
		<title>Write beautiful software</title>
		<link>http://feedproxy.google.com/~r/AxiaCore/~3/OvYlyfGPnjk/</link>
		<comments>http://axiacore.com/2012/03/write-beautiful-software/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 01:56:35 +0000</pubDate>
		<dc:creator>Camilo Nova</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://axiacore.com/?p=2258</guid>
		<description><![CDATA[You are an artist. Your laptop is your brush. Incidentally, your brush is emblazoned with a small, white, glowing piece of fruit, because you are an artist. You care about the design of things. You sweat the details. You carefully paint each leaf on the juniper bush. We, too, are artists. We write lots of [...]]]></description>
			<content:encoded><![CDATA[<p>You are an artist. Your laptop is your brush. Incidentally, your brush is emblazoned with a small, white, glowing piece of fruit, because you are an artist. You care about the design of things. You sweat the details. You carefully paint each leaf on the juniper bush.<br />
We, too, are artists.</p>
<p>We write lots of code in Python because it&#8217;s beautifully succinct. It lets us get things done, minimizing the time it takes to craft our ideas into reality.</p>
<p>We also write lots of code in Objective-C because of the beautiful user interfaces we can create with it. We want to make software that literally responds to your every touch.</p>
<p>Unlike a great painting, truly great software can not be made alone.</p>
<p>&#8230;</p>
<p>seen on the web</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AxiaCore?a=OvYlyfGPnjk:XJHvgk2esfs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=OvYlyfGPnjk:XJHvgk2esfs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/AxiaCore?i=OvYlyfGPnjk:XJHvgk2esfs:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=OvYlyfGPnjk:XJHvgk2esfs:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=OvYlyfGPnjk:XJHvgk2esfs:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AxiaCore/~4/OvYlyfGPnjk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://axiacore.com/2012/03/write-beautiful-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://axiacore.com/2012/03/write-beautiful-software/</feedburner:origLink></item>
		<item>
		<title>Rol de los fondos en el diseño web sensible (Responsive design)</title>
		<link>http://feedproxy.google.com/~r/AxiaCore/~3/WoZRc3Y9XPQ/</link>
		<comments>http://axiacore.com/2012/02/rol-de-los-fondos-en-el-diseno-web-sencible-responsive-design/#comments</comments>
		<pubDate>Fri, 24 Feb 2012 19:39:35 +0000</pubDate>
		<dc:creator>daniel.osorio</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[background]]></category>
		<category><![CDATA[diseño sensible]]></category>
		<category><![CDATA[Ipad]]></category>
		<category><![CDATA[Responsive design]]></category>

		<guid isPermaLink="false">http://axiacore.com/?p=2262</guid>
		<description><![CDATA[Es una verdad, el fondo es una tortura a menos de que sea un patrón o se trabaje para un solo dispositivo, pero en este momento, con las variadas resoluciones de pantalla y los diferentes dispositivos móviles, los usuarios quieren ser sorprendidos con algo diferente y el fondo es un punto muy importante que puede [...]]]></description>
			<content:encoded><![CDATA[<p>Es una verdad, el fondo es una tortura a menos de que sea un patrón o se trabaje para un solo dispositivo, pero en este momento, con las variadas resoluciones de pantalla y los diferentes dispositivos móviles, los usuarios quieren ser sorprendidos con algo diferente y el fondo es un punto muy importante que puede marcar la diferencia.</p>
<p><a href="http://axiacore.com/wp-content/uploads/2012/02/img_12.jpg" rel="lightbox[2262]" title="Rol de los fondos en el diseño web sensible (Responsive design)"><img class="alignnone size-full wp-image-2264" style="border: solid 4ps #ccc" src="http://axiacore.com/wp-content/uploads/2012/02/img_12.jpg" alt="" width="500" height="374" /></a></p>
<p>Ahora bien, sucede se tiene un fondo como el de la imagen anterior, la línea básica de estilo es:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&nbsp;
body {
    background-image: url(bg_body.png);
}</pre></div></div>

<p>.. y este es el resultado :<br />
<a href="http://axiacore.com/wp-content/uploads/2012/02/img_21.jpg" rel="lightbox[2262]" title="Rol de los fondos en el diseño web sensible (Responsive design)"><img class="alignnone  wp-image-2266" src="http://axiacore.com/wp-content/uploads/2012/02/img_21.jpg" alt="" width="499" height="290" /></a></p>
<p>Bueno en realidad no es lo que se espera, y si&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&nbsp;
body {
    background-image: url(bg_body.png);
    background-repeat: no-repeat;
    background-position: left top;
}</pre></div></div>

<p><a href="http://axiacore.com/wp-content/uploads/2012/02/img_3.png" rel="lightbox[2262]" title="Rol de los fondos en el diseño web sensible (Responsive design)"><img class="alignnone size-full wp-image-2267" src="http://axiacore.com/wp-content/uploads/2012/02/img_3.png" alt="" width="500" height="291" /></a></p>
<p>Parece que ese resultado tampoco es el requerido y seguro no va a descrestar al usuario, entonces se debe comenzar a pensar en soluciones como: hacer el fondo más grande o ajustes en algún programa de edición de imágenes, pero eso no siempre es muy conveniente, hay que tener varias cosas en cuenta como: el peso del archivo o la pixelación en caso de que sea un archivo demasiado pequeño.</p>
<p>La solución Bienvenido css3 <img src='http://axiacore.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Los nuevos atributos de css en su tercera versión y el diseño de sitios web sensibles traen la solución casi definitiva a este problema.</p>
<p>Bien a hacer lo básico:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&nbsp;
body {
    background-image: url(bg_body.png);
    background-repeat: no-repeat;
    -moz-background-size: cover;
    -webkit-background-size: cover;
    background-size: cover;
}</pre></div></div>

<p>El resultado :</p>
<p><a href="http://axiacore.com/wp-content/uploads/2012/02/img_4.png" rel="lightbox[2262]" title="Rol de los fondos en el diseño web sensible (Responsive design)"><img class="alignnone size-full wp-image-2269" src="http://axiacore.com/wp-content/uploads/2012/02/img_4.png" alt="" width="500" height="291" /></a></p>
<p>El peso de la imagen es el mismo al igual que su tamaño en pixeles, pero ahora esta cubriendo el área total del body.<br />
El background-size cover es una propiedad css3 que se ajusta al tamaño del contenedor sin necesidad de un alto o ancho especificado,  para cualquier resolución de pantalla.<br />
Listo ahora el fondo se auto ajusta a nuestras pantallas problemas resuelto . o no?</p>
<p>Bueno sucede que surge otro reto, dispositivos móviles,</p>
<p><a href="http://axiacore.com/wp-content/uploads/2012/02/img_5.png" rel="lightbox[2262]" title="Rol de los fondos en el diseño web sensible (Responsive design)"><img class="alignnone size-full wp-image-2270" src="http://axiacore.com/wp-content/uploads/2012/02/img_5.png" alt="" width="300" height="385" /></a></p>
<p>Tomemos como referencia el iPad, el cual sirve como punto de partida para comenzar un proyecto que soporte responsive design. Las propiedades que se utilizan anteriormente solucionan muy bien los problemas que se generan en una pantalla de PC o un portátil sin tener que modificar las imágenes, pero ese tipo de pantallas no responden a la variación de ángulo (modos landscape o portrait). La imagen anterior muestra, haciendo uso de las propiedades mencionadas anteriormente, cómo responde un dispositivo como iPad, comportamiento muy similar en otros<br />
dispositivos. Solución css3 y diseño sensible junto a la propiedad media query:</p>
<p>Hagamos el avanzado:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&nbsp;
@media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px) {
    body {
	background-image: url(bg_body.png);
	-moz-background-size: auto;
	-webkit-background-size: auto;
	background-size: auto;
    }
}</pre></div></div>

<p><a href="http://axiacore.com/wp-content/uploads/2012/02/img_6.png" rel="lightbox[2262]" title="Rol de los fondos en el diseño web sensible (Responsive design)"><img class="alignnone size-full wp-image-2271" src="http://axiacore.com/wp-content/uploads/2012/02/img_6.png" alt="" width="300" height="383" /></a></p>
<p>El media query reconoce el tamaño del dispositivo en el cual se renderiza el sitio y toma los tamaños definidos en el css para mostrar los atributos únicamente donde el tamaño o la posición se cumplan.</p>
<p>Este fue un tip ajustado para un fondo, pero las posibilidades de los media query permiten ajustar cualquier elemento del DOM, en un próximo post mostraremos otras posibilidades de esta poderosa herramienta. </p>
<p>Bueno para finalizar dejamos un listado de media query que hasta ahora se utilizan en cuanto a diseño sensible para los dispositivos más comunes:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">/* Smartphones (portrait and landscape) ----------- */
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) {
/* Styles */
}
&nbsp;
/* Smartphones (landscape) ----------- */
@media only screen and (min-width : 321px) {
/* Styles */
}
&nbsp;
/* Smartphones (portrait) ----------- */
@media only screen and (max-width : 320px) {
/* Styles */
}
&nbsp;
/* iPads (portrait and landscape) ----------- */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) {
/* Styles */
}
&nbsp;
/* iPads (landscape) ----------- */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) {
/* Styles */
}
&nbsp;
/* iPads (portrait) ----------- */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) {
/* Styles */
}
/* Ordenadores de escritorio y portatiles ----------- */
@media only screen and (min-width : 1224px) {
/* Styles */
}
/* Large screens ----------- */
@media only screen and (min-width : 1824px) {
/* Styles */
}
/* iPhone 4 and high pixel ratio devices ----------- */
@media
only screen and (-webkit-min-device-pixel-ratio : 1.5),
only screen and (min-device-pixel-ratio : 1.5) {
/* Styles */
}</pre></div></div>

<p>Compatibilidad: IE9+ &#8211; Ffox 3+ &#8211; Chrome &#8211; Safari 2+</p>
<p>Enlaces relacionados:</p>
<ul>
<li><a href="http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size&amp;preval=cover">w3schools</a></li>
<li><a href="http://www.quirksmode.org/css/background.html">quirksmode</a></li>
<li><a href="http://css-tricks.com/perfect-full-page-background-image/">css-tricks</a></li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AxiaCore?a=WoZRc3Y9XPQ:YUAZmIfVU4o:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=WoZRc3Y9XPQ:YUAZmIfVU4o:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/AxiaCore?i=WoZRc3Y9XPQ:YUAZmIfVU4o:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=WoZRc3Y9XPQ:YUAZmIfVU4o:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=WoZRc3Y9XPQ:YUAZmIfVU4o:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AxiaCore/~4/WoZRc3Y9XPQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://axiacore.com/2012/02/rol-de-los-fondos-en-el-diseno-web-sencible-responsive-design/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://axiacore.com/2012/02/rol-de-los-fondos-en-el-diseno-web-sencible-responsive-design/</feedburner:origLink></item>
		<item>
		<title>Tu sitio en Django puede tener una herramienta de búsqueda útil en poco tiempo</title>
		<link>http://feedproxy.google.com/~r/AxiaCore/~3/eJRUYtLetzc/</link>
		<comments>http://axiacore.com/2012/02/tu-sitio-en-django-puede-tener-una-herramienta-de-busqueda-util-en-poco-tiempo/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 23:05:11 +0000</pubDate>
		<dc:creator>andres.cardenas</dc:creator>
				<category><![CDATA[Desarrollo]]></category>

		<guid isPermaLink="false">http://axiacore.com/?p=2235</guid>
		<description><![CDATA[(english version) Cuando tienes un sitio Django y no quieres torturar tu base de datos con búsquedas, pero quieres ofrecer a tus usuarios la posibilidad de tener una buena herramienta de búsqueda, puedes echarle un vistazo a haystack, esto es un motor de búsqueda configurable donde puedes tomar backends tales como xapian, solr y whoosh, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://axiacore.com/2012/02/tu-sitio-en-django-puede-tener-una-herramienta-de-busqueda-util-en-poco-tiempo/">(english version)</a></p>
<p>Cuando tienes un sitio Django y no quieres torturar tu base de datos con búsquedas, pero quieres ofrecer a tus usuarios la posibilidad de tener una buena herramienta de búsqueda, puedes echarle un vistazo a <a href="http://haystacksearch.org/">haystack</a>, esto es un motor de búsqueda configurable donde puedes tomar backends tales como <a href="http://xapian.org/">xapian</a>, <a href="http://lucene.apache.org/solr/">solr</a> y <a href="http://whoosh.ca/">whoosh</a>, entre otros. Si tienes buen hardware ve por solr, si no esperas muchas visitas, ve por whoosh, pero seguramente encontraras a xapian realmente bueno. Nosotros también preferimos xapian.</p>
<p>Espera, ya tienes una base de datos relacional, ahora estas añadiendo una base de datos documental, así en tu siguiente reunión geek podrías hablar fluidamente sobre esto; nota que tendrás una segunda base de datos especializada para búsquedas, así el proceso es más o menos así: añades o actualizas un registro en tu base de datos original, el sistema añade o actualiza un registro en la base de datos documental, el “índice” se actualiza y las búsquedas se efectúan solo en la base de datos documental dejando que tu base de datos relacional haga las cosas que tienen que ver con el la lógica del sitio sin sobrecargarla con solicitudes de las búsquedas de los usuarios.</p>
<p>Asumimos que estas trabajando con virtualenv, si no lo estas usando, <a href="http://www.saltycrane.com/blog/2009/05/notes-using-pip-and-virtualenv-django/">ve por el</a> primero <img src='http://axiacore.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , si estas usando Debian o Ubuntu, puedes seguir esa guía, en otros sabores o sistemas operativos debería funcionar, pero necesitarás trabajar en esto por ti mismo o actualizar a alguno de los sistemas operativos recomendados que usamos aquí. Asumimos que tienes python 2.7, si no, la técnica de copiar/pegar no funcionaría directamente.</p>
<h2>Obteniendo las herramientas</h2>
<p>En tu maquina instala xapian</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> python-xapian</pre></div></div>

<p>Asumiendo que tu virtualenv se llama <strong>tr</strong>,<strong> </strong>el siguiente script deberia funcionar ajustando tus variables acorde a tu instalación.</p>
<div id="gist-1793995" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nb">export </span><span class="nv">MYENV</span><span class="o">=</span>~/.virtualenvs/tr</div><div class='line' id='LC2'><span class="nb">export </span><span class="nv">LOCALPYTHON</span><span class="o">=</span>/usr/lib/python2.7</div><div class='line' id='LC3'>ln -s <span class="nv">$LOCALPYTHON</span>/dist-packages/xapian/__init__.py <span class="nv">$MYENV</span>/lib/python2.7/site-packages/xapian.py</div><div class='line' id='LC4'>ln -s <span class="nv">$LOCALPYTHON</span>/dist-packages/xapian/_xapian.so <span class="nv">$MYENV</span>/lib/python2.7/site-packages/</div><div class='line' id='LC5'><span class="k">if</span> <span class="o">[</span> ! -f <span class="nv">$MYENV</span>/lib/python2.7/site-packages/haystack/backends/xapian_backend.py <span class="o">]</span> </div><div class='line' id='LC6'><span class="k">then </span></div><div class='line' id='LC7'><span class="k">  </span>ln -s <span class="nv">$MYENV</span>/lib/python2.7/site-packages/xapian_backend.py <span class="nv">$MYENV</span>/lib/python2.7/site-packages/haystack/backends/</div><div class='line' id='LC8'><span class="k">fi</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1793995/a90b29840958d5b0d812d3fdb633241b41e09680/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1793995#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1793995">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<h2>Interconectando Django con haystack</h2>
<p>Añade a tu archivo <strong>requirements.txt</strong> las siguietes líneas. Si te preguntas que hace requierements.txt, échale un vistazo a <a href="http://www.saltycrane.com/blog/2009/05/notes-using-pip-and-virtualenv-django/">virtualenv</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">xapian-haystack==1.1.5beta
django-haystack==1.2.6
<span style="color: #007800;">translitcodec</span>==<span style="color: #000000;">0.2</span></pre></div></div>

<p>Como de costumbre, ejecutas</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">pip <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #660033;">-U</span> requirements.txt</pre></div></div>

<p>En tu <strong>setting.py</strong> añades <strong>&#8216;haystack&#8217;</strong>,</p>
<p>Y configuras las siguientes variables en tu settings.py , asegúrate de colocar tales variables ANTES de la configuración de las aplicaciones:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">HAYSTACK_SITECONF = <span style="color: #483d8b;">'rt.search_sites'</span>
HAYSTACK_SEARCH_ENGINE = <span style="color: #483d8b;">'xapian'</span>
HAYSTACK_XAPIAN_PATH = <span style="color: #483d8b;">'/var/lib/rtsearch/rtindex'</span></pre></div></div>

<p>donde <strong>rt</strong> es tu proyecto, tienes un archivo <strong>search_sites.py</strong> en el interior,  más tarde comentaremos acerca de esto, y tienes el directorio <strong>/var/lib/rtsearch/rtindex</strong> con los permisos apropiados (www-data:www-data o todo lo que el usuario ejecuta en servidor web con el virtualenv).</p>
<h2>Encender tu sitio django con haystack</h2>
<p>Recuerdas que hablamos sobre la base de datos documental? en haystack hay un archivo <strong>search_indexes.py</strong> que es muy parecido a <strong>models.py</strong>, ahí especificamos como recogemos elementos de la base de datos relacional que se deben buscar, con este archivo haystack sabe qué debe comparar con lo que es buscado, en otras palabras, el índice se genera con este archivo, así, cuando alguien busque, la base documental se emplea y no tu base de datos relacional. En haystack hay un archivo donde queda la información que será usada para la búsqueda, es una plantilla, y puedes personalizar tu pagina de resultados y los aspectos usuales en los que estés interesado cuando ofrezcas una herramienta de búsqueda. Hay tres archivos importantes:  autodiscover, search_indexes.py, la plantilla y la configuraron de urls, y como un bono te mostraremos una aproximación que no tiene en cuenta los acentos.</p>
<p>Todavía estas leyendo? Iremos a el índice, esto esta en <strong>search_indexes.py</strong>, para motivarnos:</p>
<div id="gist-1793858" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">from</span> <span class="nn">haystack.indexes</span> <span class="kn">import</span> <span class="n">RealTimeSearchIndex</span></div><div class='line' id='LC2'><span class="kn">from</span> <span class="nn">haystack.indexes</span> <span class="kn">import</span> <span class="n">CharField</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'><span class="kn">from</span> <span class="nn">haystack.indexes</span> <span class="kn">import</span> <span class="n">RealTimeSearchIndex</span></div><div class='line' id='LC5'><span class="kn">from</span> <span class="nn">haystack.indexes</span> <span class="kn">import</span> <span class="n">CharField</span></div><div class='line' id='LC6'><span class="kn">from</span> <span class="nn">haystack.indexes</span> <span class="kn">import</span> <span class="n">MultiValueField</span></div><div class='line' id='LC7'><span class="kn">from</span> <span class="nn">haystack</span> <span class="kn">import</span> <span class="n">site</span></div><div class='line' id='LC8'><span class="kn">from</span> <span class="nn">apps.informationgathering.models</span> <span class="kn">import</span> <span class="n">RR</span></div><div class='line' id='LC9'><br/></div><div class='line' id='LC10'><br/></div><div class='line' id='LC11'><span class="k">class</span> <span class="nc">RRIndex</span><span class="p">(</span><span class="n">RealTimeSearchIndex</span><span class="p">):</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="sd">&quot;&quot;&quot;Index preparation, in production, when there is high write traffic</span></div><div class='line' id='LC13'><span class="sd">    we have to make sure we are using QueueSearchIndex and updating the index</span></div><div class='line' id='LC14'><span class="sd">    in a timely way</span></div><div class='line' id='LC15'><span class="sd">    &quot;&quot;&quot;</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">text</span> <span class="o">=</span> <span class="n">CharField</span><span class="p">(</span><span class="n">document</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">use_template</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span></div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">assignednumber</span> <span class="o">=</span> <span class="n">CharField</span><span class="p">(</span><span class="n">model_attr</span><span class="o">=</span><span class="s">&#39;assignednumber&#39;</span><span class="p">)</span></div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">people</span> <span class="o">=</span> <span class="n">MultiValueField</span><span class="p">()</span></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">territory</span> <span class="o">=</span> <span class="n">CharField</span><span class="p">()</span></div><div class='line' id='LC20'><br/></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">prepare_people</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">inst</span><span class="p">):</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="p">[</span><span class="n">o</span><span class="o">.</span><span class="n">indexsearch</span><span class="p">()</span> <span class="k">for</span> <span class="n">o</span> <span class="ow">in</span> <span class="n">inst</span><span class="o">.</span><span class="n">relatedpeople</span><span class="o">.</span><span class="n">all</span><span class="p">()]</span></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">prepare_territory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">inst</span><span class="p">):</span></div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="n">inst</span><span class="o">.</span><span class="n">territory_for_restitutionrequest_set</span><span class="o">.</span><span class="n">count</span><span class="p">()</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">:</span></div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">inst</span><span class="o">.</span><span class="n">territory_for_restitutionrequest_set</span><span class="o">.</span><span class="n">all</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">name</span></div><div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="s">&quot;&quot;</span></div><div class='line' id='LC28'><br/></div><div class='line' id='LC29'><span class="n">site</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">RR</span><span class="p">,</span><span class="n">RRIndex</span><span class="p">)</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1793858/9a50342d7a812bdcc8db17bfe47bae7845df6f27/search_indexes.py" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1793858#file_search_indexes.py" style="float:right;margin-right:10px;color:#666">search_indexes.py</a>
            <a href="https://gist.github.com/1793858">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>Hay tres formas para actualizar el índice, en tiempo real, en lote o en una cola, para este ejemplo usaremos tiempo real, te sugerimos emplear el método de colas en un sitio en producción, este archivo se asemeja a models.py, estamos definiendo los campos que estamos usando para el índice en nuestras búsquedas, la mas sencilla es <strong>assignednumber</strong>, mapeando directamente a un campo de el modelo RR, para hacerte la vida más fácil incluímos un <strong>ManyToManyField</strong> representado por <strong>people</strong> donde definimos un método llamado <strong>indexsearch()</strong> que será usado como índice, por otra parte estamos mostrando en territorio una posible <strong>ForeignKey</strong> que puede ser nula donde estamos indexando por el campo <strong>name</strong>, y finalmente describimos el campo de texto que tiene el atributo <strong>use_template</strong> con el valor <strong>True</strong>, esto es de especial interés porque somos capaces de definir en una plantilla otros campos y aspectos usando el lenguaje de plantillas para iterar y seguir las relaciones para hacer que el índice esté un poco más completo. El siguiente código te muestra una plantilla ejemplo, esta plantilla deberías ubicarla en <strong>templates/search/indexes/informationgathering/restitutionrequest_text.txt</strong></p>
<div id="gist-1794205" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>{{ object.assignednumber }}</div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'>{{ object.holderrightenterprise.nit }}</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'>{{ object.territory }}</div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>{{ object.people }}</div><div class='line' id='LC8'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1794205/dc56221ff2ff7b51dc2c5071b779fbb9d00cbd26/restitutionrequest_text.txt" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1794205#file_restitutionrequest_text.txt" style="float:right;margin-right:10px;color:#666">restitutionrequest_text.txt</a>
            <a href="https://gist.github.com/1794205">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>Finalmente cuando definas tu índice, asegúrate de registrarlo con el modelo, a la interfaz de administración.</p>
<p>Puedes activar tu url con algo como</p>
<div id="gist-1794231" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">from</span> <span class="nn">haystack.views</span> <span class="kn">import</span> <span class="n">SearchView</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="o">.</span></div><div class='line' id='LC4'><span class="o">.</span></div><div class='line' id='LC5'><span class="o">.</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'><span class="n">urlpatterns</span> <span class="o">+=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;haystack.views&#39;</span><span class="p">,</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">url</span><span class="p">(</span><span class="s">r&#39;^$&#39;</span><span class="p">,</span> <span class="n">SearchView</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;haystack_search&#39;</span><span class="p">),</span></div><div class='line' id='LC9'><span class="p">)</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1794231/3da0142caf53528ba338ff47ba7511714f54510c/urls.py" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1794231#file_urls.py" style="float:right;margin-right:10px;color:#666">urls.py</a>
            <a href="https://gist.github.com/1794231">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<h2>Reconstruyendo el indice</h2>
<p>si por cualquier razón necesitas reconstruir tu indice, tu shell django tiene ahora rebuild_index, asi puedes usar</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>manage.py rebuild_index</pre></div></div>

<p>En caso de ser necesario</p>
<h2>Usando acentos</h2>
<p>Dado que nosotros (AxiaCore) estamos en un país donde se habla español, necesitamos el control/evitar acentos, así ofrecemos urls complementarias, un formulario y un template.</p>
<p>A continuación un formulario sencillo usando <strong>translitcodec</strong>, si, viste esto antes en requierements.txt.</p>
<div id="gist-1794257" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">from</span> <span class="nn">haystack.forms</span> <span class="kn">import</span> <span class="n">SearchForm</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="o">.</span></div><div class='line' id='LC4'><span class="o">.</span></div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="k">class</span> <span class="nc">RtSearchForm</span><span class="p">(</span><span class="n">SearchForm</span><span class="p">):</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">search</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="s">&#39;cleaned_data&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s">&#39;q&#39;</span><span class="p">]:</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="bp">self</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s">&#39;q&#39;</span><span class="p">]</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s">&#39;q&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;translit/one/ascii&#39;</span><span class="p">,</span> <span class="s">&#39;replace&#39;</span><span class="p">)</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">sqs</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">RtSearchForm</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">search</span><span class="p">()</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">sqs</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1794257/ab045ca896496bfe59baa315faf92a99d602da36/forms.py" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1794257#file_forms.py" style="float:right;margin-right:10px;color:#666">forms.py</a>
            <a href="https://gist.github.com/1794257">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>y puedes personalizar tus resultados usando tus propias plantillas, al mostrar los resultados de la busqueda, deberias colocarlo en <strong>templates/search/search.html</strong></p>
<div id="gist-1794257" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">from</span> <span class="nn">haystack.forms</span> <span class="kn">import</span> <span class="n">SearchForm</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="o">.</span></div><div class='line' id='LC4'><span class="o">.</span></div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="k">class</span> <span class="nc">RtSearchForm</span><span class="p">(</span><span class="n">SearchForm</span><span class="p">):</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">search</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="s">&#39;cleaned_data&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s">&#39;q&#39;</span><span class="p">]:</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="bp">self</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s">&#39;q&#39;</span><span class="p">]</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s">&#39;q&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;translit/one/ascii&#39;</span><span class="p">,</span> <span class="s">&#39;replace&#39;</span><span class="p">)</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">sqs</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">RtSearchForm</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">search</span><span class="p">()</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">sqs</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1794257/ab045ca896496bfe59baa315faf92a99d602da36/forms.py" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1794257#file_forms.py" style="float:right;margin-right:10px;color:#666">forms.py</a>
            <a href="https://gist.github.com/1794257">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>Finalmente tu urls.py deberían verse como</p>
<div id="gist-1794220" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">from</span> <span class="nn">haystack.views</span> <span class="kn">import</span> <span class="n">SearchView</span></div><div class='line' id='LC2'><span class="kn">from</span> <span class="nn">django.contrib.auth.decorators</span> <span class="kn">import</span> <span class="n">login_required</span></div><div class='line' id='LC3'><span class="kn">from</span> <span class="nn">apps.informationgathering.forms</span> <span class="kn">import</span> <span class="n">RtSearchForm</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="o">.</span></div><div class='line' id='LC6'><span class="o">.</span></div><div class='line' id='LC7'><span class="o">.</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'><span class="n">urlpatterns</span> <span class="o">+=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;haystack.views&#39;</span><span class="p">,</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">url</span><span class="p">(</span><span class="s">r&#39;^$&#39;</span><span class="p">,</span> <span class="n">login_required</span><span class="p">(</span><span class="n">SearchView</span><span class="p">(</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">form_class</span><span class="o">=</span><span class="n">RtSearchForm</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">)),</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;haystack_search&#39;</span><span class="p">),</span></div><div class='line' id='LC13'><span class="p">)</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1794220/83dd2688c2ba584deb99463ce7244efa615a91d7/urls.py" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1794220#file_urls.py" style="float:right;margin-right:10px;color:#666">urls.py</a>
            <a href="https://gist.github.com/1794220">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<h2>Referencias</h2>
<ul>
<li><a title="Django for all" href="http://djangoproject.com">django</a></li>
<li><a title="Search for Django" href="http://haystacksearch.org">haystack</a></li>
<li><a title="Your Search in C++" href="http://xapian.org">xapian</a></li>
<li><a title="xapian haystack interface" href="https://github.com/notanumber/xapian-haystack">xapian-haystack</a></li>
<li><a href="http://tartarus.org/james/diary/2009/10/20/simple-search-for-django-using-haystack-and-xapian">another blog entry</a></li>
</ul>
<h2>Mas por hacer</h2>
<p>Si, <a title="Documentación en inglés de haystack" href="http://django-haystack.readthedocs.org/en/latest/index.html">puedes</a> conectar tu propio backend, puedes hacer búsquedas parciales y cosas avanzadas que tu documento favorito de la base de datos pueda hacer.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AxiaCore?a=eJRUYtLetzc:CavIXD9KBoo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=eJRUYtLetzc:CavIXD9KBoo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/AxiaCore?i=eJRUYtLetzc:CavIXD9KBoo:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=eJRUYtLetzc:CavIXD9KBoo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=eJRUYtLetzc:CavIXD9KBoo:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AxiaCore/~4/eJRUYtLetzc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://axiacore.com/2012/02/tu-sitio-en-django-puede-tener-una-herramienta-de-busqueda-util-en-poco-tiempo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://axiacore.com/2012/02/tu-sitio-en-django-puede-tener-una-herramienta-de-busqueda-util-en-poco-tiempo/</feedburner:origLink></item>
		<item>
		<title>Your Django site can have a useful search tool in no time</title>
		<link>http://feedproxy.google.com/~r/AxiaCore/~3/8l9OzOUG3fo/</link>
		<comments>http://axiacore.com/2012/02/your-django-site-can-have-a-useful-search-tool-in-no-time/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 22:45:55 +0000</pubDate>
		<dc:creator>igor</dc:creator>
				<category><![CDATA[Desarrollo]]></category>

		<guid isPermaLink="false">http://axiacore.com/?p=2217</guid>
		<description><![CDATA[When you have a Django site and you don&#8217;t want to torture your database with searches, but you want to offer your users the possibility of having a nice search tool, you could take a look at haystack, this is a configurable search engine where you can pick backends such as xapian, solr and whoosh, [...]]]></description>
			<content:encoded><![CDATA[<p>When you have a Django site and you don&#8217;t want to torture your database with searches, but you want to offer your users the possibility of having a nice search tool, you could take a look at <a title="haystack search" href="http://haystacksearch.org/" target="_blank">haystack</a>, this is a configurable search engine where you can pick backends such as <a title="Xapian search" href="http://xapian.org" target="_blank">xapian</a>, <a title="Solr" href="http://lucene.apache.org/solr/" target="_blank">solr</a> and <a title="Whoosh" href="http://whoosh.ca" target="_blank">whoosh</a>, among others.  If you have plenty of hardware go for solr, if you don&#8217;t expect so many visits go for whoosh, but for sure you will find xapian really cool. We prefer xapian too.</p>
<p>Wait, you have already a relational database, now you are adding a document database, so in your next geek party you would be able to speak fluently about it; note that you will have a second database specialized for searches, so the process is like this : you add or update a record to your original database, the system adds or updates a record to the document database, the &#8220;index&#8221; can be updated and the searches go only in the document database letting your relational database do the things it has to do in your deploy and not overwhelming it with the user search requests.</p>
<p>We assume you are working with a virtualenv, if you are not already using it, <a title="Virtualenv + pip rocks" href="http://www.saltycrane.com/blog/2009/05/notes-using-pip-and-virtualenv-django/" target="_blank">go for it</a> first <img src='http://axiacore.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  , if you are using Debian or Ubuntu, you can follow this guide straightforward, other flavors or oses should work, but you will need to work on it by yourself or upgrade to the recommended Oses we use here.  We assume you have python 2.7, if not, the copy/paste technique won&#8217;t work directly.</p>
<h2>Getting the tools</h2>
<p>in your host install xapian</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> python-xapian</pre></div></div>

<p>Assuming your virtualenv is called <strong>tr</strong>, the following script should work tweaking your vars according to your installation</p>
<div id="gist-1793995" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nb">export </span><span class="nv">MYENV</span><span class="o">=</span>~/.virtualenvs/tr</div><div class='line' id='LC2'><span class="nb">export </span><span class="nv">LOCALPYTHON</span><span class="o">=</span>/usr/lib/python2.7</div><div class='line' id='LC3'>ln -s <span class="nv">$LOCALPYTHON</span>/dist-packages/xapian/__init__.py <span class="nv">$MYENV</span>/lib/python2.7/site-packages/xapian.py</div><div class='line' id='LC4'>ln -s <span class="nv">$LOCALPYTHON</span>/dist-packages/xapian/_xapian.so <span class="nv">$MYENV</span>/lib/python2.7/site-packages/</div><div class='line' id='LC5'><span class="k">if</span> <span class="o">[</span> ! -f <span class="nv">$MYENV</span>/lib/python2.7/site-packages/haystack/backends/xapian_backend.py <span class="o">]</span> </div><div class='line' id='LC6'><span class="k">then </span></div><div class='line' id='LC7'><span class="k">  </span>ln -s <span class="nv">$MYENV</span>/lib/python2.7/site-packages/xapian_backend.py <span class="nv">$MYENV</span>/lib/python2.7/site-packages/haystack/backends/</div><div class='line' id='LC8'><span class="k">fi</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1793995/a90b29840958d5b0d812d3fdb633241b41e09680/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1793995#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1793995">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<h2>Interfacing Django with haystack</h2>
<p>Complement your <strong>requirements.txt</strong> with the following lines. If you are wondering what does requirements.txt is about, take a look at <a href="http://www.saltycrane.com/blog/2009/05/notes-using-pip-and-virtualenv-django/" target="_blank">virtualenv</a></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">xapian-haystack==1.1.5beta
django-haystack==1.2.6
<span style="color: #007800;">translitcodec</span>==<span style="color: #000000;">0.2</span></pre></div></div>

<p>As usual, run your</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">pip <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #660033;">-r</span> requirements.txt</pre></div></div>

<p>In your <strong>settings.py</strong> add <strong>&#8216;haystack&#8217;</strong> ,</p>
<p>And configure the following variables in your settings.py, make sure you have this variables defined BEFORE the apps configuration:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">HAYSTACK_SITECONF = <span style="color: #483d8b;">'rt.search_sites'</span>
HAYSTACK_SEARCH_ENGINE = <span style="color: #483d8b;">'xapian'</span>
HAYSTACK_XAPIAN_PATH = <span style="color: #483d8b;">'/var/lib/rtsearch/rtindex'</span></pre></div></div>

<p>where <strong>rt </strong>is your project, you have a <strong>search_sites.py</strong> file inside it, more on this later, and you have the directory <strong>/var/lib/rtsearch/rtindex </strong>with the proper permissions (www-data:www-data or whatever user runs the webserver with the virtualenv).</p>
<h2>Powering your django site with haystack</h2>
<p>Do you recall we talked about a document database?  in haystack there is a file <strong>search_indexes.py</strong> that looks familiar to <strong>models.py</strong>, there we specify how we pick elements from the relational database to be searched, so with this file haystack knows what would be used to compare versus the searched thing, in other words, with this file the index is generated, so when someone searches, the document database is hit, but not your relational database.  In haystack there is a file where we can drop the information that will be used for the search, it&#8217;s a template and certainly you can customize your results page and the usual aspects you are interested when offering a search tool.  you will take a look at three files, the autodiscover, the search_indexes.py, the template and the configured urls, and as a bonus we will show you an approximation to search no matter if your users have accents or not.</p>
<p>Still reading? We&#8217;ll go for the index, this is a <strong>search_indexes.py</strong>, just for motivation we have the following:</p>
<div id="gist-1793858" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">from</span> <span class="nn">haystack.indexes</span> <span class="kn">import</span> <span class="n">RealTimeSearchIndex</span></div><div class='line' id='LC2'><span class="kn">from</span> <span class="nn">haystack.indexes</span> <span class="kn">import</span> <span class="n">CharField</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'><span class="kn">from</span> <span class="nn">haystack.indexes</span> <span class="kn">import</span> <span class="n">RealTimeSearchIndex</span></div><div class='line' id='LC5'><span class="kn">from</span> <span class="nn">haystack.indexes</span> <span class="kn">import</span> <span class="n">CharField</span></div><div class='line' id='LC6'><span class="kn">from</span> <span class="nn">haystack.indexes</span> <span class="kn">import</span> <span class="n">MultiValueField</span></div><div class='line' id='LC7'><span class="kn">from</span> <span class="nn">haystack</span> <span class="kn">import</span> <span class="n">site</span></div><div class='line' id='LC8'><span class="kn">from</span> <span class="nn">apps.informationgathering.models</span> <span class="kn">import</span> <span class="n">RR</span></div><div class='line' id='LC9'><br/></div><div class='line' id='LC10'><br/></div><div class='line' id='LC11'><span class="k">class</span> <span class="nc">RRIndex</span><span class="p">(</span><span class="n">RealTimeSearchIndex</span><span class="p">):</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="sd">&quot;&quot;&quot;Index preparation, in production, when there is high write traffic</span></div><div class='line' id='LC13'><span class="sd">    we have to make sure we are using QueueSearchIndex and updating the index</span></div><div class='line' id='LC14'><span class="sd">    in a timely way</span></div><div class='line' id='LC15'><span class="sd">    &quot;&quot;&quot;</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">text</span> <span class="o">=</span> <span class="n">CharField</span><span class="p">(</span><span class="n">document</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">use_template</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span></div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">assignednumber</span> <span class="o">=</span> <span class="n">CharField</span><span class="p">(</span><span class="n">model_attr</span><span class="o">=</span><span class="s">&#39;assignednumber&#39;</span><span class="p">)</span></div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">people</span> <span class="o">=</span> <span class="n">MultiValueField</span><span class="p">()</span></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">territory</span> <span class="o">=</span> <span class="n">CharField</span><span class="p">()</span></div><div class='line' id='LC20'><br/></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">prepare_people</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">inst</span><span class="p">):</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="p">[</span><span class="n">o</span><span class="o">.</span><span class="n">indexsearch</span><span class="p">()</span> <span class="k">for</span> <span class="n">o</span> <span class="ow">in</span> <span class="n">inst</span><span class="o">.</span><span class="n">relatedpeople</span><span class="o">.</span><span class="n">all</span><span class="p">()]</span></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">prepare_territory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">inst</span><span class="p">):</span></div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="n">inst</span><span class="o">.</span><span class="n">territory_for_restitutionrequest_set</span><span class="o">.</span><span class="n">count</span><span class="p">()</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">:</span></div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">inst</span><span class="o">.</span><span class="n">territory_for_restitutionrequest_set</span><span class="o">.</span><span class="n">all</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">name</span></div><div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="s">&quot;&quot;</span></div><div class='line' id='LC28'><br/></div><div class='line' id='LC29'><span class="n">site</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">RR</span><span class="p">,</span><span class="n">RRIndex</span><span class="p">)</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1793858/9a50342d7a812bdcc8db17bfe47bae7845df6f27/search_indexes.py" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1793858#file_search_indexes.py" style="float:right;margin-right:10px;color:#666">search_indexes.py</a>
            <a href="https://gist.github.com/1793858">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>There are three ways to update the index, in real time, in batch and in a queue, for this sample we used realtime, you are warned to use queue on a production site, this file resembles models.py , we are defining the fields we are using to index our searches, the easiest one is <strong>assignednumber</strong> , mapping directly to a field of the model <strong>RR</strong>, for the sake of make yor life easier we considered a <strong>ManyToManyField</strong> represented by <strong>people</strong> where we defined a method called <strong>indexsearch()</strong> that will be used to index, in the other hand we are showing in territory a possible <strong>ForeignKey</strong> that can be nullable where we are indexing by the field <strong>name</strong>, and finally we describe the field text that has the attribute <strong>use_template</strong> set to <strong>True</strong>, this is special interest because we are able to define in a template many other fields and aspects using the template language to iterate and follow relations in order to make our index a little bit more complete.  The following code shows you a sample template, this template should be located at <strong>templates/search/indexes/informationgathering/restitutionrequest_text.txt</strong></p>
<div id="gist-1794205" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>{{ object.assignednumber }}</div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'>{{ object.holderrightenterprise.nit }}</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'>{{ object.territory }}</div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>{{ object.people }}</div><div class='line' id='LC8'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1794205/dc56221ff2ff7b51dc2c5071b779fbb9d00cbd26/restitutionrequest_text.txt" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1794205#file_restitutionrequest_text.txt" style="float:right;margin-right:10px;color:#666">restitutionrequest_text.txt</a>
            <a href="https://gist.github.com/1794205">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>Finally when you define your index, make sure you register it for the model, ala admin interface.</p>
<p>You can activate your url with something like</p>
<div id="gist-1794231" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">from</span> <span class="nn">haystack.views</span> <span class="kn">import</span> <span class="n">SearchView</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="o">.</span></div><div class='line' id='LC4'><span class="o">.</span></div><div class='line' id='LC5'><span class="o">.</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'><span class="n">urlpatterns</span> <span class="o">+=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;haystack.views&#39;</span><span class="p">,</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">url</span><span class="p">(</span><span class="s">r&#39;^$&#39;</span><span class="p">,</span> <span class="n">SearchView</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;haystack_search&#39;</span><span class="p">),</span></div><div class='line' id='LC9'><span class="p">)</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1794231/3da0142caf53528ba338ff47ba7511714f54510c/urls.py" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1794231#file_urls.py" style="float:right;margin-right:10px;color:#666">urls.py</a>
            <a href="https://gist.github.com/1794231">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<h2>Rebuilding the index</h2>
<p>If for any reason you need to rebuild your index, your django shell has now rebuild_index , so you can use</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>manage.py rebuild_index</pre></div></div>

<p>If necessary</p>
<h2>Using accents</h2>
<p>Because we(Axiacore) are in spoken spanish country we need to control/avoid accents, so we offer a urls complement, a form and a template.</p>
<p>Follows a sample form using <strong>translitcodec</strong>, yes, you saw it earlier in requirements.txt.</p>
<div id="gist-1794257" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">from</span> <span class="nn">haystack.forms</span> <span class="kn">import</span> <span class="n">SearchForm</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="o">.</span></div><div class='line' id='LC4'><span class="o">.</span></div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="k">class</span> <span class="nc">RtSearchForm</span><span class="p">(</span><span class="n">SearchForm</span><span class="p">):</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">search</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="s">&#39;cleaned_data&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s">&#39;q&#39;</span><span class="p">]:</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="bp">self</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s">&#39;q&#39;</span><span class="p">]</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s">&#39;q&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;translit/one/ascii&#39;</span><span class="p">,</span> <span class="s">&#39;replace&#39;</span><span class="p">)</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">sqs</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">RtSearchForm</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">search</span><span class="p">()</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">sqs</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1794257/ab045ca896496bfe59baa315faf92a99d602da36/forms.py" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1794257#file_forms.py" style="float:right;margin-right:10px;color:#666">forms.py</a>
            <a href="https://gist.github.com/1794257">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>and you can customize your result using your own template to show the results of the search, it should be located at templates/search/search.html</p>
<div id="gist-1794276" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>{% extends &quot;layout/base.html&quot; %}</div><div class='line' id='LC2'><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;entry&quot;</span><span class="nt">&gt;</span></div><div class='line' id='LC3'>{% block body %}</div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;register_init&quot;</span><span class="nt">&gt;</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;add_new&quot;</span><span class="nt">&gt;</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/recolecta/nuevo&quot;</span><span class="nt">&gt;</span>Nueva Solicitud de Inscripción en el Registro<span class="nt">&lt;/a&gt;</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;/div&gt;</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;form</span> <span class="na">method=</span><span class="s">&quot;get&quot;</span> <span class="na">action=</span><span class="s">&quot;.&quot;</span><span class="nt">&gt;</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ form.as_p }}</div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;submit&quot;</span> <span class="na">value=</span><span class="s">&quot;Buscar&quot;</span><span class="nt">&gt;</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;/form&gt;</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% if query %}</div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;h3&gt;</span>Resultados<span class="nt">&lt;/h3&gt;</span></div><div class='line' id='LC14'><br/></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% for result in page.object_list %}</div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;p&gt;</span></div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/recolecta/1/{{ result.object.id }}&quot;</span><span class="nt">&gt;</span>{{ result.object.assignednumber }}<span class="nt">&lt;/a&gt;</span>: {{ result.object }}</div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% empty %}</div><div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;p&gt;</span>No se encontraron resultados.<span class="nt">&lt;/p&gt;</span></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% endfor %}</div><div class='line' id='LC22'><br/></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% if page.has_previous or page.has_next %}</div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;div&gt;</span></div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% if page.has_previous %}<span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;?q={{ query }}&amp;amp;page={{ page.previous_page_number }}&quot;</span><span class="nt">&gt;</span>{% endif %}<span class="ni">&amp;laquo;</span> Previous{% if page.has_previous %}<span class="nt">&lt;/a&gt;</span>{% endif %}</div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|</div><div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% if page.has_next %}<span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;?q={{ query }}&amp;amp;page={{ page.next_page_number }}&quot;</span><span class="nt">&gt;</span>{% endif %}Next <span class="ni">&amp;raquo;</span>{% if page.has_next %}<span class="nt">&lt;/a&gt;</span>{% endif %}</div><div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;/div&gt;</span></div><div class='line' id='LC29'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% endif %}</div><div class='line' id='LC30'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% else %}</div><div class='line' id='LC31'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{# Show some example queries to run, maybe query syntax, something else? #}</div><div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% endif %}    </div><div class='line' id='LC33'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nt">&lt;/div&gt;</span></div><div class='line' id='LC34'>{% endblock %}</div><div class='line' id='LC35'><span class="nt">&lt;/div&gt;</span></div><div class='line' id='LC36'>{% block search %}</div><div class='line' id='LC37'>{% endblock %}</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1794276/3d7044e7418a066dde69d7d2b1751e408f31f26d/search.html" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1794276#file_search.html" style="float:right;margin-right:10px;color:#666">search.html</a>
            <a href="https://gist.github.com/1794276">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>Finally your urls.py could look something like</p>
<div id="gist-1794220" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">from</span> <span class="nn">haystack.views</span> <span class="kn">import</span> <span class="n">SearchView</span></div><div class='line' id='LC2'><span class="kn">from</span> <span class="nn">django.contrib.auth.decorators</span> <span class="kn">import</span> <span class="n">login_required</span></div><div class='line' id='LC3'><span class="kn">from</span> <span class="nn">apps.informationgathering.forms</span> <span class="kn">import</span> <span class="n">RtSearchForm</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="o">.</span></div><div class='line' id='LC6'><span class="o">.</span></div><div class='line' id='LC7'><span class="o">.</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'><span class="n">urlpatterns</span> <span class="o">+=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;haystack.views&#39;</span><span class="p">,</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">url</span><span class="p">(</span><span class="s">r&#39;^$&#39;</span><span class="p">,</span> <span class="n">login_required</span><span class="p">(</span><span class="n">SearchView</span><span class="p">(</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">form_class</span><span class="o">=</span><span class="n">RtSearchForm</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">)),</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;haystack_search&#39;</span><span class="p">),</span></div><div class='line' id='LC13'><span class="p">)</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1794220/83dd2688c2ba584deb99463ce7244efa615a91d7/urls.py" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1794220#file_urls.py" style="float:right;margin-right:10px;color:#666">urls.py</a>
            <a href="https://gist.github.com/1794220">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<h2>References</h2>
<ul>
<li><a title="Django for all" href="http://djangoproject.com">django</a></li>
<li><a title="Search for Django" href="http://haystacksearch.org">haystack</a></li>
<li><a title="Your Search in C++" href="http://xapian.org">xapian</a></li>
<li><a title="xapian haystack interface" href="https://github.com/notanumber/xapian-haystack">xapian-haystack</a></li>
<li><a href="http://tartarus.org/james/diary/2009/10/20/simple-search-for-django-using-haystack-and-xapian">another blog entry</a></li>
</ul>
<h2> More to be done</h2>
<p>Yes, <a title="Documentation for Haystack" href="http://django-haystack.readthedocs.org/en/latest/index.html">you can</a> plug your own backend, you can make partial searches and the advanced things that your favourite document database can do.</p>
<p><a title="Versión en español" href="http://axiacore.com/2012/02/your-django-site-can-have-a-useful-search-tool-in-no-time/">Traducción de Andrés Cárdenas Versión en español</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AxiaCore?a=8l9OzOUG3fo:spaSdE-wEaM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=8l9OzOUG3fo:spaSdE-wEaM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/AxiaCore?i=8l9OzOUG3fo:spaSdE-wEaM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=8l9OzOUG3fo:spaSdE-wEaM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=8l9OzOUG3fo:spaSdE-wEaM:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AxiaCore/~4/8l9OzOUG3fo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://axiacore.com/2012/02/your-django-site-can-have-a-useful-search-tool-in-no-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://axiacore.com/2012/02/your-django-site-can-have-a-useful-search-tool-in-no-time/</feedburner:origLink></item>
		<item>
		<title>Instalación de PIL en OSX Lion</title>
		<link>http://feedproxy.google.com/~r/AxiaCore/~3/FTlyacvjHxk/</link>
		<comments>http://axiacore.com/2011/12/instalacion-de-pil-en-osx-lion/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 22:43:30 +0000</pubDate>
		<dc:creator>Camilo Nova</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[OSX]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://axiacore.com/?p=2189</guid>
		<description><![CDATA[PIL es una libreria necesaria para el manejo de imagenes en python, trabajando en entornos virtuales es necesario instalarla con el soporte necesario para tipos de archivos como jpeg y png. PIL al ser compilado intenta obtener las librerías necesarias desde el sistema y para eso es necesario instalarlas, en el caso de OSX lion [...]]]></description>
			<content:encoded><![CDATA[<p>PIL es una libreria necesaria para el manejo de imagenes en python, trabajando en entornos virtuales es necesario instalarla con el soporte necesario para tipos de archivos como jpeg y png.</p>
<p>PIL al ser compilado intenta obtener las librerías necesarias desde el sistema y para eso es necesario instalarlas, en el caso de OSX lion solo hace falta la libreria para los archivos jpeg, las demás ya vienen pre-instaladas.</p>
<p>Haciendo uso de homebrew:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">brew <span style="color: #c20cb9; font-weight: bold;">install</span> jpeg</pre></td></tr></table></div>

<p>Tendremos la libreria faltante, así cuando instalemos PIL tendremos pleno soporte:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">pip <span style="color: #c20cb9; font-weight: bold;">install</span> pil
...
    <span style="color: #660033;">---</span> TKINTER support available
    <span style="color: #660033;">---</span> JPEG support available
    <span style="color: #660033;">---</span> ZLIB <span style="color: #7a0874; font-weight: bold;">&#40;</span>PNG<span style="color: #000000; font-weight: bold;">/</span>ZIP<span style="color: #7a0874; font-weight: bold;">&#41;</span> support available</pre></td></tr></table></div>

<p>Espero les sea de ayuda.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AxiaCore?a=FTlyacvjHxk:iEFLLozRA-o:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=FTlyacvjHxk:iEFLLozRA-o:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/AxiaCore?i=FTlyacvjHxk:iEFLLozRA-o:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=FTlyacvjHxk:iEFLLozRA-o:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=FTlyacvjHxk:iEFLLozRA-o:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AxiaCore/~4/FTlyacvjHxk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://axiacore.com/2011/12/instalacion-de-pil-en-osx-lion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://axiacore.com/2011/12/instalacion-de-pil-en-osx-lion/</feedburner:origLink></item>
		<item>
		<title>Preparados para la certificación ISO 9001</title>
		<link>http://feedproxy.google.com/~r/AxiaCore/~3/bZbzdogpgfs/</link>
		<comments>http://axiacore.com/2011/12/preparados-para-la-certificacion-iso-9001/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 14:44:05 +0000</pubDate>
		<dc:creator>Camilo Nova</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[AxiaCore]]></category>

		<guid isPermaLink="false">http://axiacore.com/?p=2135</guid>
		<description><![CDATA[Desde hace algunos meses venimos trabajando arduamente en definir todos nuestros procesos para aspirar a obtener la certificación de calidad ISO 9001, ha sido un esfuerzo importante por parte de toda la empresa, el cual estamos seguros que será bien recibido por nuestros clientes.]]></description>
			<content:encoded><![CDATA[<p>Desde hace algunos meses venimos trabajando arduamente en definir todos nuestros procesos para aspirar a obtener la certificación de calidad ISO 9001, ha sido un esfuerzo importante por parte de toda la empresa, el cual estamos seguros que será bien recibido por nuestros clientes.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AxiaCore?a=bZbzdogpgfs:8bV31w-KC-4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=bZbzdogpgfs:8bV31w-KC-4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/AxiaCore?i=bZbzdogpgfs:8bV31w-KC-4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=bZbzdogpgfs:8bV31w-KC-4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=bZbzdogpgfs:8bV31w-KC-4:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AxiaCore/~4/bZbzdogpgfs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://axiacore.com/2011/12/preparados-para-la-certificacion-iso-9001/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://axiacore.com/2011/12/preparados-para-la-certificacion-iso-9001/</feedburner:origLink></item>
		<item>
		<title>Llegamos a un millón!</title>
		<link>http://feedproxy.google.com/~r/AxiaCore/~3/b7_E8R3oNAE/</link>
		<comments>http://axiacore.com/2011/11/llegamos-a-un-millon/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 15:29:48 +0000</pubDate>
		<dc:creator>Nayla Gandur</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[AxiaCore]]></category>

		<guid isPermaLink="false">http://axiacore.com/?p=2132</guid>
		<description><![CDATA[Hemos llegado a un millón de visitas en las páginas servidas por nuestros proyectos, esperamos seguir creciendo y llegar a gran cantidad de personas con nuestros servicios!!!!]]></description>
			<content:encoded><![CDATA[<p>Hemos llegado a un millón de visitas en las páginas servidas por nuestros proyectos, esperamos seguir creciendo y llegar a gran cantidad de personas con nuestros servicios!!!!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AxiaCore?a=b7_E8R3oNAE:QZlR-IbV4ns:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=b7_E8R3oNAE:QZlR-IbV4ns:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/AxiaCore?i=b7_E8R3oNAE:QZlR-IbV4ns:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=b7_E8R3oNAE:QZlR-IbV4ns:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=b7_E8R3oNAE:QZlR-IbV4ns:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AxiaCore/~4/b7_E8R3oNAE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://axiacore.com/2011/11/llegamos-a-un-millon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://axiacore.com/2011/11/llegamos-a-un-millon/</feedburner:origLink></item>
		<item>
		<title>Capturando excepciones en Symfony 1.4</title>
		<link>http://feedproxy.google.com/~r/AxiaCore/~3/0TzqxfvTZ0Q/</link>
		<comments>http://axiacore.com/2011/10/capturando-excepciones-en-symfony-1-4/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 17:28:49 +0000</pubDate>
		<dc:creator>Juan Pablo Romero Bernal</dc:creator>
				<category><![CDATA[Desarrollo]]></category>

		<guid isPermaLink="false">http://axiacore.com/?p=2125</guid>
		<description><![CDATA[Gracias al componente sfEventDispatcher que se encuentra integrado en Symfony 1.x (desde la versión 1.2)  es posible capturar eventos (a manera de hooks) de forma muy sencilla. Voy a explicar rápidamente como podemos capturar eventos asociados a excepciones que regularmente implican errores cuyo código de salida es 500. Primero que todo, Symfony incluye una serie [...]]]></description>
			<content:encoded><![CDATA[<p>Gracias al componente sfEventDispatcher que se encuentra integrado en Symfony 1.x (desde la versión 1.2)  es posible capturar eventos (a manera de hooks) de forma muy sencilla. Voy a explicar rápidamente como podemos capturar eventos asociados a excepciones que regularmente implican errores cuyo código de salida es 500.</p>
<p>Primero que todo, Symfony incluye una serie de eventos (<a href="http://www.symfony-project.org/gentle-introduction/1_4/en/17-Extending-Symfony">lista completa</a>) genéricos que notifican varias tareas comúnes como: procesamiento de formularios y filtros, ejecución de tareas, etc. Para este caso particular, vamos a centrarnos en el evento: <strong>application.throw_exception</strong> el cual es notificado cuando se captura una excepción (por ejemplo de tipo sfFileException). Para poder capturar este evento, lo que debemos hacer es establecer un observador que se encargue de capturar el evento y procesarlo. Para ello simplemente agregamos en la clase de configuración del proyecto (o de la aplicación):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> miAplicacionConfiguration <span style="color: #000000; font-weight: bold;">extends</span> sfApplicationConfiguration
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dispatcher</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">connect</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'application.throw_exception'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'MiClaseObservador'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'metodoObservador'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Cada vez que ocurra una excepción, el método metodoObservador de la clase MiClaseObservador será llamado, cuyo parámetro será un objeto sfEvent. A continuación la implementación de la clase y el método:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> MiClaseObservador 
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> metodoObservador<span style="color: #009900;">&#40;</span>sfEvent <span style="color: #000088;">$event</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$mailer</span> <span style="color: #339933;">=</span> sfContext<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;;</span>getMailer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// Se obtiene la instancia del objeto que notifica el error, un ejemplar de una clase que extiende la clase</span>
        <span style="color: #666666; font-style: italic;">// Exception de PHP</span>
	<span style="color: #000088;">$subject</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$event</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSubject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$message</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$subject</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$subject</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getTraceAsString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$mailer</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">composeAndSend</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'info@example.com'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'developers@example.com'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'An error has been occurred'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>El código anterior envía un correo electrónico notificando del error, muy útil para entornos de prueba. El mensaje incluye el mensaje de error y el trace. Esperamos sea de utilidad.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AxiaCore?a=0TzqxfvTZ0Q:gFtesiYDx2g:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=0TzqxfvTZ0Q:gFtesiYDx2g:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/AxiaCore?i=0TzqxfvTZ0Q:gFtesiYDx2g:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=0TzqxfvTZ0Q:gFtesiYDx2g:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=0TzqxfvTZ0Q:gFtesiYDx2g:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AxiaCore/~4/0TzqxfvTZ0Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://axiacore.com/2011/10/capturando-excepciones-en-symfony-1-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://axiacore.com/2011/10/capturando-excepciones-en-symfony-1-4/</feedburner:origLink></item>
		<item>
		<title>Portal EmiConecta</title>
		<link>http://feedproxy.google.com/~r/AxiaCore/~3/cHh2ZwkE_0A/</link>
		<comments>http://axiacore.com/2011/10/portal-emiconecta/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 16:59:52 +0000</pubDate>
		<dc:creator>Nayla Gandur</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://axiacore.com/?p=2121</guid>
		<description><![CDATA[AxiaCore ha finalizado otro de sus proyectos, el Portal Web de EmiConecta para Colombia y Uruguay. Para nosotros es un orgullo poder participar en el desarrollo de Portales para empresas de gran reconocimiento a nivel nacional e internacional]]></description>
			<content:encoded><![CDATA[<p>AxiaCore ha finalizado otro de sus proyectos, el Portal Web de EmiConecta para Colombia y Uruguay. Para nosotros es un orgullo poder participar en el desarrollo de Portales para empresas de gran reconocimiento a nivel nacional e internacional</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AxiaCore?a=cHh2ZwkE_0A:qwgnqwvpBOg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=cHh2ZwkE_0A:qwgnqwvpBOg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/AxiaCore?i=cHh2ZwkE_0A:qwgnqwvpBOg:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=cHh2ZwkE_0A:qwgnqwvpBOg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AxiaCore?a=cHh2ZwkE_0A:qwgnqwvpBOg:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/AxiaCore?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AxiaCore/~4/cHh2ZwkE_0A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://axiacore.com/2011/10/portal-emiconecta/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://axiacore.com/2011/10/portal-emiconecta/</feedburner:origLink></item>
	</channel>
</rss>

