<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>En borrador permanente &#187; Django</title>
	<atom:link href="http://www.juanjoconti.com.ar/categoria/aprendiendo-python/django/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.juanjoconti.com.ar</link>
	<description>el blog de Juanjo Conti - abstracto, lúdico y digital</description>
	<lastBuildDate>Tue, 07 Feb 2012 16:20:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Algunos problemas y soluciones al levantar bases de datos legacy con Django</title>
		<link>http://www.juanjoconti.com.ar/2010/10/27/algunos-problemas-y-soluciones-al-levantar-bases-de-datos-legacy-con-django/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=algunos-problemas-y-soluciones-al-levantar-bases-de-datos-legacy-con-django</link>
		<comments>http://www.juanjoconti.com.ar/2010/10/27/algunos-problemas-y-soluciones-al-levantar-bases-de-datos-legacy-con-django/#comments</comments>
		<pubDate>Wed, 27 Oct 2010 02:28:54 +0000</pubDate>
		<dc:creator>Juanjo</dc:creator>
				<category><![CDATA[Aprendiendo Python]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[legacy db]]></category>

		<guid isPermaLink="false">http://www.juanjoconti.com.ar/?p=2889</guid>
		<description><![CDATA[Con Django podemos levantar una base de datos legacy en lugar de definir nuestro modelo de datos y arrancar una aplicación desde cero. No es necesariamente una base de datos vieja, sino una base de datos heredada de otro sistema; &#8230; <a href="http://www.juanjoconti.com.ar/2010/10/27/algunos-problemas-y-soluciones-al-levantar-bases-de-datos-legacy-con-django/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://docs.djangoproject.com/en/dev/howto/legacy-databases/" target="_blank">Con Django</a> podemos levantar una <a href="http://stackoverflow.com/questions/939465/what-does-the-term-legacy-database-mean" target="_blank">base de datos <em>legacy</em></a> en lugar de definir nuestro modelo de datos y arrancar una aplicación desde cero. No es necesariamente una base de datos vieja, sino una base de datos heredada de otro sistema; puede ser de un sistema anterior que se está reemplazando o incluso de otro sistema que queremos usar de forma paralela.</p>
<p>Luego de configurar nuestra base de datos y ejecutar:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">python manage.<span style="color: black;">py</span> inspectdb <span style="color: #66cc66;">&gt;</span> models.<span style="color: black;">py</span></pre></div></div>

<p>obtenemos una definición de modelos basada en en las tablas de la base de datos. Lo siguiente es ver si anda.</p>
<p>Lo más probable es que obtengamos un <a href="http://docs.python.org/library/exceptions.html#exceptions.NameError" target="_blank">NameError</a>. Esto pasa cuando en la definición de alguno de los modelos se hace referencia a otro modelo aún no definido! La solución indicada es empezar a reordernar los modelos, pero una forma más fácil es cambiar los nombres por strings. Un ejemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">jefe = models.<span style="color: black;">ForeingKey</span><span style="color: black;">&#40;</span>Empleado<span style="color: black;">&#41;</span></pre></div></div>

<p>por</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">jefe = models.<span style="color: black;">ForeingKey</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Empleado'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Otra queja que nos puede hacer Django es que tengamos atributos llamados <strong>id</strong> que no sean <em>primary key</em>. Solución: les cambiamos el nombre.</p>
<p>Eventualmente vamos a necesitar habilitar la aplicación <a href="http://docs.djangoproject.com/en/dev/ref/contrib/admin/" target="_blank"><strong>admin</strong></a> (ya que estamos usando Django para levantar datos, nada mejor que usar su ABM estrella para ahorrarnos mucho trbajo). Los pasos para hacer con éxito son:</p>
<ol>
<li>Habilitar la aplicaccion admin en <code>settings.py</code>.</li>
<li>Ejecutar <code>syncdb</code> para que se creen las tablas de esta aplicación.</li>
<li>Agregar los modelos de la base de datos heredada al archivo <code>admin.py</code> de la aplicación.</li>
</ol>
<p>Por supuesto, si los nuevos modelos son cientos, es bastante engorroso hacer esto a mano. Les paso un hack; así luce mi <code>admin.py</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span> <span style="color: #ff7700;font-weight:bold;">import</span> admin
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">db</span>.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> base
<span style="color: #ff7700;font-weight:bold;">from</span> my_app.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> k,v <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">locals</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>v, base.<span style="color: black;">ModelBase</span><span style="color: black;">&#41;</span>:
        admin.<span style="color: #dc143c;">site</span>.<span style="color: black;">register</span><span style="color: black;">&#40;</span>v<span style="color: black;">&#41;</span></pre></div></div>

<p>Tip final. Si obtenemos un error de este tipo:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">OperationalError at <span style="color: #000000; font-weight: bold;">/</span>admin<span style="color: #000000; font-weight: bold;">/</span>mango<span style="color: #000000; font-weight: bold;">/</span>datapointusers<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1054</span>, <span style="color: #ff0000;">&quot;Unknown column 'dataPointUsers.id' in 'field list'&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>es por que alguna de las tablas levantadas no tenía una columna que sea clave primaria. Django necesita esto para poder distinguir los objetos entre si. Para cada tabla dónde tengamos este problema, podemos ejecutar el siguiente comando SQL para agregarle una columna llamada id; clave primaria y auto numérico.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`dataPointUsers`</span> <span style="color: #993333; font-weight: bold;">ADD</span> <span style="color: #ff0000;">`id`</span> <span style="color: #993333; font-weight: bold;">INT</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>;</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.juanjoconti.com.ar/2010/10/27/algunos-problemas-y-soluciones-al-levantar-bases-de-datos-legacy-con-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>El hosting para Django más barato</title>
		<link>http://www.juanjoconti.com.ar/2010/08/20/el-hosting-para-django-mas-barato/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=el-hosting-para-django-mas-barato</link>
		<comments>http://www.juanjoconti.com.ar/2010/08/20/el-hosting-para-django-mas-barato/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 15:40:23 +0000</pubDate>
		<dc:creator>Juanjo</dc:creator>
				<category><![CDATA[Aprendiendo Python]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[AlwaysData.com]]></category>
		<category><![CDATA[hosting]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.juanjoconti.com.ar/?p=2690</guid>
		<description><![CDATA[Hace un tiempo recomendé Webfaction como el mejor hosting para Django (debe aún serlo). Pero algunas veces no queremos el mejor, con el más barato nos alcanza Tal vez son un adolecente aprendiendo a programar, o simplemente rata. Para un &#8230; <a href="http://www.juanjoconti.com.ar/2010/08/20/el-hosting-para-django-mas-barato/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Hace un tiempo <a href="http://www.juanjoconti.com.ar/2008/11/24/el-mejor-hosting-para-django/" target="_blank">recomendé Webfaction</a> como el mejor hosting para Django (debe aún serlo). Pero algunas veces no queremos el mejor, con el más barato nos alcanza <img src='http://www.juanjoconti.com.ar/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Tal vez son un adolecente aprendiendo a programar, o simplemente rata. Para un programador PHP es bastante fácil encontrar un hosting en Internet que le de un servicio gratuito, subir sus cosas y mostrarlas al mundo. Cuando programás en Django&#8230; es más difícil.</p>
<p>Hasta hoy; les paso el dato: <a href="http://www.alwaysdata.com/" target="_blank">AlwaysData.com</a></p>
<p><em><strong>Hosting Django gratuito. </strong></em></p>
<p>Tengo 2 cuentas funcionando muy bien. Y no se asusten por que está en francés (eso me detuvo la primer vez que lo vi); luego de sacar la cuenta tenés acceso al panel de administración que está en muchos idiomas; incluyendo español. Tenés para elegir distintas versiones de Python y Djando, MySQL o PosgreSQL, acceso SHELL, FTP y WebDAV. Qué más querés?</p>
<p>También podés tener PHP o Ruby on Rails.</p>
<p>Espero les sirva.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juanjoconti.com.ar/2010/08/20/el-hosting-para-django-mas-barato/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>os.path en el settings.py de Django para mayor comodidad</title>
		<link>http://www.juanjoconti.com.ar/2010/03/03/os-path-en-el-settings-py-de-django-para-mayor-comodidad/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=os-path-en-el-settings-py-de-django-para-mayor-comodidad</link>
		<comments>http://www.juanjoconti.com.ar/2010/03/03/os-path-en-el-settings-py-de-django-para-mayor-comodidad/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 04:45:16 +0000</pubDate>
		<dc:creator>Juanjo</dc:creator>
				<category><![CDATA[Aprendiendo Python]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Siempre se aprende algo]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.juanjoconti.com.ar/?p=2164</guid>
		<description><![CDATA[En el archivo de configuración settings.py de un proyecto Django, por lo general tenemos que setear variables como MEDIA_ROOT o STATIC_DOC_ROOT. Su contenido en una instalación Windows suele ser algo como: 'C:\Windows\camino\hasta\mi\projecto'. Y en Linux: '/home/usuario/camino/a/mi/proyecto'. El problema surge cuando &#8230; <a href="http://www.juanjoconti.com.ar/2010/03/03/os-path-en-el-settings-py-de-django-para-mayor-comodidad/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>En el archivo de configuración <code>settings.py</code> de un proyecto Django, por lo general tenemos que setear variables como <code>MEDIA_ROOT</code> o <code>STATIC_DOC_ROOT.</code> Su contenido en una instalación Windows suele ser algo como: <code>'C:\Windows\camino\hasta\mi\projecto'</code>. Y en Linux:<code> '/home/usuario/camino/a/mi/proyecto'</code>. El problema surge cuando el proyecto es desarrollado en varias máquinas a la vez, y con distintos sistemas operativos. Más aún, si hacemos lo anterior, seguramente versionaremos el proyecto y con él, al archivo de configuración. No sería raro que tras una actualización, el archivo se actualice con los valores que puso algún compañero de trabajo.</p>
<p>Mi solución es definir primero una variable para el proyecto:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">PROJECT_PATH = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">abspath</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span><span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Luego podemos usarla para definir el path absoluto a la carpeta con archivos de media:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">MEDIA_ROOT = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>PROJECT_PATH, <span style="color: #483d8b;">'media'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>nuestros templates:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">TEMPLATE_DIRS = <span style="color: black;">&#40;</span>
<span style="color: #808080; font-style: italic;"># Put strings here, like &quot;/home/html/django_templates&quot; or &quot;C:/www/django/templates&quot;.</span>
<span style="color: #808080; font-style: italic;"># Always use forward slashes, even on Windows.</span>
<span style="color: #808080; font-style: italic;"># Don't forget to use absolute paths, not relative paths.</span>
<span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>PROJECT_PATH, <span style="color: #483d8b;">'templates'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#41;</span></pre></div></div>

<p>o cualquier otra variable de configuración que requiere una ruta de directorios.</p>
<p>Con esta solución podemos cambiar el proyecto de carpeta, disco o computadora y seguirá funcionando.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juanjoconti.com.ar/2010/03/03/os-path-en-el-settings-py-de-django-para-mayor-comodidad/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Django Middleware</title>
		<link>http://www.juanjoconti.com.ar/2009/08/15/django-middleware/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=django-middleware</link>
		<comments>http://www.juanjoconti.com.ar/2009/08/15/django-middleware/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 14:37:06 +0000</pubDate>
		<dc:creator>Juanjo</dc:creator>
				<category><![CDATA[Aprendiendo Python]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.juanjoconti.com.ar/?p=1737</guid>
		<description><![CDATA[Mientras estudié el tema para hacer un experimento, traduje el 80% de la documentación oficial. La dejo aquí más algunos condimentos personales. Middleware Es un sub framework que permite modificaciones al sistema de procesamiento de request/response de Django. Es un &#8230; <a href="http://www.juanjoconti.com.ar/2009/08/15/django-middleware/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Mientras estudié el tema para hacer un experimento, traduje el 80% de la <a href="http://docs.djangoproject.com/en/dev/topics/http/middleware/" target="_blank">documentación oficial</a>. La dejo aquí más algunos condimentos personales.</p>
<h2>Middleware</h2>
<p>Es un sub framework que permite modificaciones al sistema de procesamiento de request/response de Django. Es un sistema de plugins liviano y de bajo nivel que permite alterar globalmente las entradas y salidas de Django.</p>
<p>Cada componente middleware es responsable de hacer alguna función específica.</p>
<h3>Activar componentes middleware</h3>
<p>Para hacerlo, añadirlo a la lista MIDDLEWARE_CLASSES en la configuración de Django (settings.py). En esta lista, cada componente se representa por un string: el camino completo al nombre de la clase. Por ejemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">MIDDLEWARE_CLASSES = <span style="color: black;">&#40;</span>
<span style="color: #483d8b;">'django.middleware.common.CommonMiddleware'</span>,
<span style="color: #483d8b;">'django.contrib.sessions.middleware.SessionMiddleware'</span>,
<span style="color: #483d8b;">'django.contrib.auth.middleware.AuthenticationMiddleware'</span>,
<span style="color: black;">&#41;</span></pre></div></div>

<p>En el tratamiento de requests y la generación de responses, existen dos faces:</p>
<p>1) Fase Request (se llama a los métodos process_request() y process_view())<br />
2) Fase Response (se llama a los métodos process_response() y process_exception())</p>
<p>En la primera, las clases son aplicadas desde la primera a la última, según el orden de la lista mencionada. En la segunda fase, se aplican en orden inverso; podemos pensarlo como una cebolla:</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-1740" title="middleware" src="http://www.juanjoconti.com.ar/wp-content/uploads/2009/08/middleware.png" alt="middleware" width="502" height="417" /></p>
<p>Una instalación de Django puede funcionar sin ningún middleware, pero esto no es recomendado.</p>
<h3>Para escribir middleware propios</h3>
<p>Cada componente es una clase Python, que no tiene que extender a ninguna clase en particular y debe definir uno o más de los siguientes métodos.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">process_request<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, request<span style="color: black;">&#41;</span></pre></div></div>

<p>request es un objeto HttpRequest. El método es llamada por cada request, antes de que Django decida que vista ejecutar.</p>
<p>Debe retornar None o un objeto HttpResponse. Si retorna None, Django seguirá procesando el request, ejecutando los otros middlewares y luego la vista apropiada. Si retorna un objeto HttpResponse, Django no hará nada más, solo retornar ese objeto.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">process_view<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, request, view_func, view_args, view_kwargs<span style="color: black;">&#41;</span></pre></div></div>

<p>request es un objeto HttpRequest. view_func es la función Python que Django está por usar. (Es el objeto function, no el nombre de la función en un string). view_args es un alista de argumentos posicionales que serán pasados a la vista. Y view_kwargs es un diccionario de argumentos de palagra clave que serán pasados a la vista. Ni view_args ni view_kwargs incluye al primer argumento de la vista (request).</p>
<p>process_view() es llamado antes de que Django ejecute la vista. Debe retornar None o un objeto HttpResponse. Si retorna None, Django seguirá procesando el request, ejecutando otros process_view() y luego la vista apropiada. Si retorna un objeto HttpResponse, Django no hará nada más, solo retornar ese objeto.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">process_response<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, request, response<span style="color: black;">&#41;</span></pre></div></div>

<p>request es un objeto HttpRequest. response es un objeto HttpResponse retornado por una vista de Django.</p>
<p>process_response() debe retornar un objeto HttpResponse. Puede altener el objeto response dado o puede crear uno nuevo.</p>
<p>A diferencia de proces_request() y process_view(), este siempre es ejecutado.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">process_exception<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, request, exception<span style="color: black;">&#41;</span></pre></div></div>

<p>request es un objeto HttpRequest. exception es un objeto Exception lanzado por la vista.</p>
<p>Django llama a process_exception() cuando la vista lanza una excepción. process_exception() debe retornar None o un objeto HttpResponse. Si retorna un objeto HttpResponse, la respuesta es devuelta al navegador. De lo contrario, el sistema por defecto para manejo de excepciones entra en acción.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #0000cd;">__init__</span></pre></div></div>

<p>Por lo general estas clases no tienen estado; simplemente contienen a los anteriores métodos. Se puede usar el método __init__ pero se debe tener en cuenta que Django inicializa estas clases sin argumentos y que el método __init__ es llamado solo una vez, cuando el servidor web arranca.</p>
<h2>Experimento</h2>
<p>Con lo anterior en mente, me quedaron algunas dudas al respecto:</p>
<ul>
<li>si modifico los argumentos de view_func en process_view y retorno None, ¿estos son pasados modificados a la vista?</li>
<li>si lo anterior es falso, puedo lograr el mismo efecto haciendo:

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> process_view<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>,request, view_func, view_args, view_kwargs<span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># modificar request, view_args y view_kwargs</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> view_func<span style="color: black;">&#40;</span>request, view_args, view_kwargs<span style="color: black;">&#41;</span></pre></div></div>

<p>?</li>
<li>¿puedo definir process_response de tal forma que examine response?</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.juanjoconti.com.ar/2009/08/15/django-middleware/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>URLs elegantes con Django</title>
		<link>http://www.juanjoconti.com.ar/2009/05/04/urls-elegantes-con-django/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=urls-elegantes-con-django</link>
		<comments>http://www.juanjoconti.com.ar/2009/05/04/urls-elegantes-con-django/#comments</comments>
		<pubDate>Mon, 04 May 2009 10:00:17 +0000</pubDate>
		<dc:creator>Juanjo</dc:creator>
				<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://www.juanjoconti.com.ar/?p=808</guid>
		<description><![CDATA[Este texto es parte del informe de nuestro proyecto final de carrera, lo publico en forma separada aquí por que tiene valor propio y puede convencer a más de un programador PHP de probar Django. Las URLs elegantes son la &#8230; <a href="http://www.juanjoconti.com.ar/2009/05/04/urls-elegantes-con-django/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>Este texto es parte del informe de nuestro  proyecto final de carrera, lo publico en forma separada aquí por que tiene valor propio y puede convencer a más de un programador PHP de probar Django. Las URLs elegantes son la forma natural de las URL en Django.</em></p>
<h3>Manejo de URLs</h3>
<p">Tener URLs elegantes y limpias es un requisito común para aplicaciones web modernas. Django provee un mecanismo de manejo de URLs basado en expresiones regulares que asocia una expresión regular a una vista.</p>
<p>Para diseñar las URLs de una aplicación Django, se construye una especie de tabla que mapea patrones de URL a funciones Python a ejecutar (vistas). Con esto se logra que las URLs estén desacopladas del resto de la aplicación.</p>
<p">El siguiente es un ejemplo de una entrada de esa tabla:</p>
<p><code>(r'^index/$', index)</code></p>
<p>Suponiendo que la aplicación web está corriendo en el servidor con nombre localhost, cuando alguien acceda a http://localhost/index/ se ejecutará la vista ‘index’.</p>
<p>El siguiente es un ejemplo un poco más complejo:</p>
<p><code>(r'^cliente/datos/(\d+)/$', cliente_datos)</code></p>
<p>En el patrón de la URL se utilizan paréntesis para capturar una parte de la misma y poder accederla luego como parámetros en la vista. La expresión encerrada entre paréntesis se denomina grupo y son propias de las expresiones regulares en Python. Así, siempre que se acceda a, por ejemplo, http://localhost/cliente/datos/1/ o http://localhost/cliente/datos/100/ se ejecutará la vista cliente_datos y recibirá como parámetro el número correspondiente.</p>
<p>Algo similar sucede en el siguiente ejemplo:</p>
<p><code>(r'^inmueble/fotos/(\d+)/eliminar/(\d+)/$', eliminar_foto)</code></p>
<p>Con la diferencia de que ahora la vista recibe dos parámetros, en este caso particular el primero corresponde a un identificador de inmueble y el segundo a un identificador de foto.</p>
<p>Las expresiones regulares en Python soportan también lo que se denomina grupos nombrados. Esto permite obtener un grupo por su nombre. Si escribimos una especificación de URL como la siguiente:</p>
<p><code>(r'^inmueble/fotos/(?P&lt;inmueble&gt;\d+)/eliminar/(?P&lt;foto&gt;\d+)/$', eliminar_foto)</code></p>
<p>la vista será llamada utilizando parámetros nombrados. Esto tiene la ventaja de que si cambia el orden de los parámetros en la URL, la vista seguirá funcionando sin que se necesite redefinirla.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juanjoconti.com.ar/2009/05/04/urls-elegantes-con-django/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>FPDF en Django</title>
		<link>http://www.juanjoconti.com.ar/2009/03/27/fpdf-en-django/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=fpdf-en-django</link>
		<comments>http://www.juanjoconti.com.ar/2009/03/27/fpdf-en-django/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 18:53:01 +0000</pubDate>
		<dc:creator>Juanjo</dc:creator>
				<category><![CDATA[Aprendiendo Python]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[fpdf]]></category>

		<guid isPermaLink="false">http://www.juanjoconti.com.ar/?p=1336</guid>
		<description><![CDATA[Si intentás usar FPDF en Django hay algunas cosas que necesitás saber: (ya sabés qué) FPDF está originalmente escrita en PHP y permite generar documentos PDF sin usar PDFLib (C). (ya sabés qué) hay más de un port de esta &#8230; <a href="http://www.juanjoconti.com.ar/2009/03/27/fpdf-en-django/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Si intentás usar FPDF en Django hay algunas cosas que necesitás saber:</p>
<ul>
<li>(ya sabés qué) <a href="http://www.fpdf.org/">FPDF</a> está originalmente escrita en PHP y permite generar documentos PDF sin usar PDFLib (C).</li>
<li>(ya sabés qué) hay más de un port de esta librería a Python. Todos son incompletos.</li>
<li>Usá este <a href="http://www.nsis.com.ar/svn/pyfpdf/" target="_blank">http://www.nsis.com.ar/svn/pyfpdf/</a> (parcheado en Argentina para utilizar unicode).</li>
<li>FPDF <a href="http://www.fpdf.org/en/FAQ.php#q7">trabaja con la codificación ISO-8859-1</a>.</li>
<li>Mi código fuente Django usa la cotificación UTF-8 y en los documentos resultantes aparecían caracteres raros en lugar de vocales con tilde o eñes.</li>
<li>Lo soluciné haciendo una modificacicón en el método Output:</li>
</ul>
<p><code>self.buffer = buffer.encode('iso-8859-1')</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.juanjoconti.com.ar/2009/03/27/fpdf-en-django/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>El mejor hosting para Django</title>
		<link>http://www.juanjoconti.com.ar/2008/11/24/el-mejor-hosting-para-django/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=el-mejor-hosting-para-django</link>
		<comments>http://www.juanjoconti.com.ar/2008/11/24/el-mejor-hosting-para-django/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 20:25:51 +0000</pubDate>
		<dc:creator>Juanjo</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[hosting]]></category>

		<guid isPermaLink="false">http://www.juanjoconti.com.ar/?p=874</guid>
		<description><![CDATA[Según DjangoFriendly, el mejor hosting para Django es Webfaction. Yo lo vengo probando por un mes y estoy muy satisfecho.]]></description>
			<content:encoded><![CDATA[<p>Según <a href="http://djangofriendly.com/">DjangoFriendly</a>, el mejor hosting para Django es <a href="http://www.webfaction.com?affiliate=zafiro">Webfaction</a>. Yo lo vengo probando por un mes y estoy muy satisfecho.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juanjoconti.com.ar/2008/11/24/el-mejor-hosting-para-django/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>SQL Debug en Django</title>
		<link>http://www.juanjoconti.com.ar/2008/11/02/sql-debug-en-django/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-debug-en-django</link>
		<comments>http://www.juanjoconti.com.ar/2008/11/02/sql-debug-en-django/#comments</comments>
		<pubDate>Sun, 02 Nov 2008 23:50:50 +0000</pubDate>
		<dc:creator>Juanjo</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.juanjoconti.com.ar/?p=825</guid>
		<description><![CDATA[¿Cómo saber en Django qué sentencias SQL se están ejecutando detrás de su ORM? Según la FAQ, podemos hacerlo de esta forma: Make sure your Django DEBUG setting is set to True. Then, just do this: &#62;&#62;&#62; from django.db import &#8230; <a href="http://www.juanjoconti.com.ar/2008/11/02/sql-debug-en-django/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>¿Cómo saber en Django <strong>qué</strong> sentencias SQL se están ejecutando detrás de su ORM? Según la <a href="http://docs.djangoproject.com/en/dev/faq/models/#how-can-i-see-the-raw-sql-queries-django-is-running">FAQ</a>, podemos hacerlo de esta forma:</p>
<blockquote><p>
Make sure your Django DEBUG setting is set to True. Then, just do this:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">db</span> <span style="color: #ff7700;font-weight:bold;">import</span> connection
<span style="color: #66cc66;">&gt;&gt;&gt;</span> connection.<span style="color: black;">queries</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'sql'</span>: <span style="color: #483d8b;">'SELECT polls_polls.id,polls_polls.question,polls_polls.pub_date FROM polls_polls'</span>,
<span style="color: #483d8b;">'time'</span>: <span style="color: #483d8b;">'0.002'</span><span style="color: black;">&#125;</span><span style="color: black;">&#93;</span></pre></div></div>

<p>connection.queries is only available if DEBUG is True. It&#8217;s a list of dictionaries in order of query execution. Each dictionary has the following:</p>
<p>&#8220;sql&#8220; &#8212; The raw SQL statement<br />
&#8220;time&#8220; &#8212; How long the statement took to execute, in seconds.</p>
<p>connection.queries includes all SQL statements &#8212; INSERTs, UPDATES, SELECTs, etc. Each time your app hits the database, the query will be recorded.
</p></blockquote>
<p>Cada vez que se realiza una nueva petición, esa variable es sobre escrita con las consultas que se ejecutaron en la vista asociada. La forma de verlas es accediendo a <code>connection.queries</code> en cada vista de nuestro interés. Para facilitar esta tarea y no tener código intrusivo, escribí un decorador:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">db</span> <span style="color: #ff7700;font-weight:bold;">import</span> connection
<span style="color: #ff7700;font-weight:bold;">def</span> sql_debug<span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'
    Decorador útil para inspeccionar las sentencias SQL que se ejecutan en
    cada request.
    '</span><span style="color: #483d8b;">''</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> inner<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
        r = f<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> d <span style="color: #ff7700;font-weight:bold;">in</span> connection.<span style="color: black;">queries</span>:
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;time: %s<span style="color: #000099; font-weight: bold;">\n</span> sql:%s<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>d<span style="color: black;">&#91;</span><span style="color: #483d8b;">'time'</span><span style="color: black;">&#93;</span>, d<span style="color: black;">&#91;</span><span style="color: #483d8b;">'sql'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> r
    <span style="color: #ff7700;font-weight:bold;">return</span> inner</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.juanjoconti.com.ar/2008/11/02/sql-debug-en-django/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Diagrama de capas de Django</title>
		<link>http://www.juanjoconti.com.ar/2008/10/30/diagrama-de-capas-de-django/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=diagrama-de-capas-de-django</link>
		<comments>http://www.juanjoconti.com.ar/2008/10/30/diagrama-de-capas-de-django/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 15:50:42 +0000</pubDate>
		<dc:creator>Juanjo</dc:creator>
				<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://www.juanjoconti.com.ar/?p=811</guid>
		<description><![CDATA[¿Cuál sería un diagrama de capas correcto para representar una instalación de Django? Ensayé el siguiente gráfico; es para una instalación en particular, pero se puede cambiar GNU/Linux por Sistema Operativo, PostgreSQL por Base de Datos y Apache por Servidor &#8230; <a href="http://www.juanjoconti.com.ar/2008/10/30/diagrama-de-capas-de-django/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>¿Cuál sería un diagrama de capas correcto para representar una instalación de Django? Ensayé el siguiente gráfico; es para una instalación en particular, pero se puede cambiar GNU/Linux por Sistema Operativo, PostgreSQL por Base de Datos y Apache por Servidor Web para hacerlo más genérico:</p>
<p><a href="http://www.juanjoconti.com.ar/wp-content/uploads/2008/10/g2210.png"><img class="aligncenter size-medium wp-image-812" title="g2210" src="http://www.juanjoconti.com.ar/wp-content/uploads/2008/10/g2210.png" alt="" /></a></p>
<p>La idea detrás de un diagrama de capas es expresar que los componentes de una capa le brindan servicios a los de la capa superior mediante alguna interfaz.<br />
¿Mejores ideas? ¿Conviene otro tipo de diagrama?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juanjoconti.com.ar/2008/10/30/diagrama-de-capas-de-django/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Generar diagramas de clases a partir de modelos de Django</title>
		<link>http://www.juanjoconti.com.ar/2008/10/23/generar-diagramas-de-clases-a-partir-de-modelos-de-django/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=generar-diagramas-de-clases-a-partir-de-modelos-de-django</link>
		<comments>http://www.juanjoconti.com.ar/2008/10/23/generar-diagramas-de-clases-a-partir-de-modelos-de-django/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 02:33:56 +0000</pubDate>
		<dc:creator>Juanjo</dc:creator>
				<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://www.juanjoconti.com.ar/?p=760</guid>
		<description><![CDATA[La siguiente es la mejor forma que encontré de tomar todos los archivos models.py de las aplicaciones que componen un proyecto Django y generar un diagrama de clases completo, listo para exportar cómo imagen. Utilizo un comando incluido en django-command-extensions. &#8230; <a href="http://www.juanjoconti.com.ar/2008/10/23/generar-diagramas-de-clases-a-partir-de-modelos-de-django/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>La siguiente es la mejor forma que encontré de tomar todos los archivos models.py de las aplicaciones que componen un proyecto Django y generar un diagrama de clases completo, listo para exportar cómo imagen. Utilizo un comando incluido en <a href="http://code.google.com/p/django-command-extensions/">django-command-extensions</a>.<br />
<span id="more-760"></span></p>
<h2>Obtener e instalar django-extensions</h2>
<p>Para Django 1.0 hay que bajar la última versión del svn:<br />
<code><br />
svn checkout http://django-command-extensions.googlecode.com/svn/trunk/ django-command-extensions<br />
</code><br />
E instalarlo ejecutando el script de instalación:<br />
<code><br />
cd django-command-extensions<br />
sudo python setup.py install<br />
</code><br />
Podemos probar si se instaló correctamente abriendo una consola Python y ejecutando:<br />
<code><br />
&gt;&gt;&gt; import django_extensions<br />
</code><br />
Para que este disponible en nuestro proyecto debemos agregar la aplicación a <code>settings.py</code>:<br />
<code><br />
INSTALLED_APPS = (<br />
...<br />
'django_extensions'<br />
)<br />
</code><br />
Cuando ejecutemos:<br />
<code><br />
python manage.py help<br />
</code><br />
veremos una lista de los nuevos comandos disponibles.</p>
<h2>Generar archivo .dot</h2>
<p>Uno de ellos es graph_models el cual nos permitirá generar un archivo en formato .dot:<br />
<code><br />
python manage.py graph_models -a &gt; mi_proyecto.dot<br />
</code></p>
<h2>Generar archivo .png</h2>
<p>O una imagen png:<br />
<code><br />
python manage.py graph_models -a -g -o mi_proyecto.png<br />
</code><br />
Para que el anterior comando funcione, necesitamos tener instalado <a href="https://networkx.lanl.gov/wiki/pygraphviz/">pygraphviz</a>. En mi Ubuntu no tenía el paquete python-pygraphviz por lo que tuve que bajarlo desde su página web. Para instalarlo requiere tener instalados los paquetes graphviz y graphviz-dev.</p>
<h2>Ejemplo</h2>
<p>El siguiente comando genera el diagrama de clases para auth, la popular aplicación que viene con Django y sirve como ejemplo de cómo generar el diagrama para solo una aplicación del proyecto:<br />
<code><br />
python manage.py graph_models auth -g -o mi_proyecto_auth.png<br />
</code><br />
<a href="http://www.juanjoconti.com.ar/wp-content/uploads/2008/10/mi_proyecto_auth.png"><img class="aligncenter size-full wp-image-766" title="mi_proyecto_auth" src="http://www.juanjoconti.com.ar/wp-content/uploads/2008/10/mi_proyecto_auth.png" alt="" width="475" height="880" /></a></p>
<h2>Nota</h2>
<p>Les recomiendo bajar la versión de pygraphviz empaquetada de Cheeseshop en lugar de la del svn, ya que con esta el comando de django-extensions lanza una excepción. Correguí el programa, <a href="http://code.google.com/p/django-command-extensions/issues/detail?id=66">abrí un ticket y envié un parche</a>. Para cuando leas esto probablemente ya se haya incorporado a trunk.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juanjoconti.com.ar/2008/10/23/generar-diagramas-de-clases-a-partir-de-modelos-de-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

