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

<channel>
	<title>Maestros del Web</title>
	<atom:link href="http://www.maestrosdelweb.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.maestrosdelweb.com</link>
	<description>Un espacio para los entusiastas del web</description>
	<lastBuildDate>Tue, 22 May 2012 19:23:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Khan Academy, una plataforma de educación virtual invirtiendo en ladrillo</title>
		<link>http://www.maestrosdelweb.com/editorial/khan-academy-educacion-virtual/</link>
		<comments>http://www.maestrosdelweb.com/editorial/khan-academy-educacion-virtual/#comments</comments>
		<pubDate>Tue, 22 May 2012 19:21:57 +0000</pubDate>
		<dc:creator>Christian Van Der Henst S.</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[educacion virtual]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[khan academy]]></category>
		<category><![CDATA[plataforma]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24621</guid>
		<description><![CDATA[En serio, ¿por qué invirten en ladrillos? ¿van a dar diplomas? ¿alquilarán birretes? permítanme explicar más y dar un poco de contexto para quienes aún no conocen la historia de Khan Academy y su creador Salman Khan. Un hombre en Boston jugaba a la bolsa de valores exitosamente, pero un día se le presentó un [...]]]></description>
			<content:encoded><![CDATA[<p>En serio, ¿por qué invirten en ladrillos? ¿van a dar diplomas? ¿alquilarán birretes? permítanme explicar más y dar un poco de contexto para quienes aún no conocen la historia de Khan Academy y su creador Salman Khan.</p>
<p>Un hombre en Boston jugaba a la bolsa de valores exitosamente, pero un día se le presentó un gran desafío: enseñarle algebra a sus sobrinos. Como todos nos imaginamos, la forma más eficiente para lograrlo, era contando una historia mientras dibujaba en una pizarra digital y lo compartía en youtube. Así es, el mismo youtube donde vos y yo hemos perdido tanto el tiempo viendo memes y videos musicales.</p>
<p>Con el tiempo, <a href="http://www.khanacademy.org/" title="Khan Academy">Khan Academy</a> en su canal de youtube ha reproducido más de 151 millones de lecciones en vídeos que te enseñan desde álgebra, finanzas, historia y tecnología. La fundación Bill &amp; Melinda Gates junto a otros notables inversionistas les dieron suficiente dinero para que intenten cambiar el mundo educándolo mejor. Han recibido aportes de más de 7 millones de dólares a la fecha. Les recomiendo la charla de <a href="http://www.ted.com/talks/salman_khan_let_s_use_video_to_reinvent_education.html" title="Salman Khan en Ted">Salman Khan en Ted</a> que nos cuenta más del proyecto.</p>
<p style="text-align:center"><img src="http://www.maestrosdelweb.com/images/2012/05/khan-academy.jpg" alt="Khan Academy" title="Khan Academy" width="700" height="215" class="alignnone size-full wp-image-24882" /></p>
<h3>Javascript como base de la plataforma</h3>
<p>Uno de los héroes que se unió a este cometido es <a href="http://ejohn.org/" title="John Resig">John Resig</a>. Si no sabes quién es, digamos que el ayudó a crear el framework de jQuery, del que seguramente has copy&amp;pasteado más de algún código para ponerle alguna funcionalidad al frontend de tu sitio web. Resig, <a href="http://ejohn.org/blog/khan-exercise-rewrite/" title="Khan Excercise Rewrite">se dedica a crear tecnología para esta universidad del futuro</a>. Me pregunto si este esfuerzo logrará erradicar la fórmula que BlackBoard (como software propietario) y Moodle (como software libre) han implementado en miles de centros universitarios. Centros que venden una educación virtual que sigue sin cambiar el mundo.  Y otro punto importante del apoyo de Resig es que está impulsando desde Khan que <a href="http://ejohn.org/blog/javascript-as-a-first-language/" title="Javascript sea el primer lenguaje que aprenden muchos estudiantes a programar">Javascript sea el primer lenguaje que aprenden muchos estudiantes a programar</a>.</p>
<p>Khan Academy va a seguir generando y curando contenido, está desarrollando una plataforma para organizar e impartir mucho mejor sus cursos y además tendrá muy pronto parqueos, sanitarios y cafetería. El mundo de la educación virtual convierte en tangible un espacio donde están comprometidos a enseñar. La marca y el financimiento que ha obtenido le da suficiente fuerza para luchar sola aunque siempre quedamos inquietos de las posibles alianzas con otras universidades.</p>
<p><a href="http://www.khanacademy.org/#browse" title="Catálogo de Khan Academy">Sumergirse en Khan Academy</a> es una experiencia recomendada para los que nos gusta repasar finanzas y algo de álgebra en el tiempo libre.  El proyecto se ha ganado <a href="http://larryferlazzo.edublogs.org/2011/11/20/the-best-posts-about-the-khan-academy/" title="detractores de Khan Academy">bastantes detractores</a> que cuestionan si realmente es el modelo revolucionario que todos esperamos, pero son palabras, no propuestas.  Envidia la dicen por mi tierra. </p>
<h3>¿La educación es un negocio de bienes raices?</h3>
<p>Al inicio de este post cuestionaba sobre la razón de los ladrillos que están comprando para construir un campus físico.  Cuando mueves muchos millones hay que justificar el plan y muchos de los asesores pueden tener más conocimiento sobre cómo generar conceptos universitarios ya reconocidos que transformar desde un catálogo de vídeos y nuevas platormas que funcionen online.  Si solo fuera un proyecto virtual tal vez la valuación no fuera tan alta, quizá solo haría falta seguir ganando de publicidad de las impresiones de los videos.</p>
<p>Sigo sin entender las razones por las que Khan Academy tendrá una universidad física, en mi cabeza sigue sin necesitarla, pero espero que cuando la llegue a visitar, que en lugar de estatuas y monumentos de científicos y notables personajes de la historia, que la estatua en la entrada sea de los sobrinos de Khan. Son los verdaderos heroes de esta nueva universidad. </p>
<p>- En un próximo artículo de esta <a href="http://www.maestrosdelweb.com/editorial/re-definiendo-educacion-virtual/" title="Re-definiendo lo que conocemos como Educación Virtual">serie de educación virtual</a>, hablaremos de Codecademy. Nos leemos mañana. </p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/cvander-72.jpg" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Christian Van Der Henst S.</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/khan-academy-educacion-virtual/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/khan-academy-educacion-virtual/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/khan-academy-educacion-virtual/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/khan-academy-150x150.jpg" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/khan-academy.jpg" medium="image">
			<media:title type="html">Khan Academy</media:title>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/khan-academy-150x150.jpg" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/cvander-72.jpg" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Curso Django: Las vistas</title>
		<link>http://www.maestrosdelweb.com/editorial/curso-django-las-vistas/</link>
		<comments>http://www.maestrosdelweb.com/editorial/curso-django-las-vistas/#comments</comments>
		<pubDate>Mon, 21 May 2012 12:12:38 +0000</pubDate>
		<dc:creator>Sergio Infante Montero</dc:creator>
				<category><![CDATA[django]]></category>
		<category><![CDATA[Editorial]]></category>
		<category><![CDATA[curso django]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[las vistas]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24755</guid>
		<description><![CDATA[Esta semana nos toca ver el tema de vistas, no se olviden que si este es el primer artículo que leen sobre Django en Maestros del Web, deben revisar la guía por completo, incluyendo los comentarios, donde se solucionaron muchas dudas, es necesario para que comprendan los ejemplos y aprendan fácilmente Django. Vistas Un función [...]]]></description>
			<content:encoded><![CDATA[<p>Esta semana nos toca ver el tema de vistas, no se olviden que si este es el primer artículo que leen sobre Django en Maestros del Web, deben revisar la <a href="http://www.maestrosdelweb.com/guias/#guias-django" title="Curso Django">guía por completo</a>, incluyendo los comentarios, donde se solucionaron muchas dudas, es necesario para que  comprendan los ejemplos y aprendan fácilmente Django.</p>
<h2>Vistas</h2>
<p>Un función de vista o una vista, <em>como es conocida generalmente</em>, es una función en Python que hace una solicitud Web y devuelve una respuesta Web, esta respuesta puede ser el contenido de una página, un error 404, una imagen, un documento XML, entre muchas cosas más. </p>
<p>La vista contiene toda la lógica necesaria para devolver una respuesta, todas estas respuestas se encuentran en un único archivo y este archivo se llama: <strong>views.py</strong>, que se encuentra dentro de cada aplicación de Django.</p>
<h3>Las consultas y las vistas</h3>
<p>En el <a href="http://www.maestrosdelweb.com/editorial/curso-django-el-shell-de-django/">capítulo anterior</a>, jugamos con algunas consultas, estas consultas son parte fundamental de las vistas, permiten elegir que tipo de contenido se visualizará. <a href="http://www.maestrosdelweb.com/editorial/curso-django-el-shell-de-django/" title="Consultas Django en Maestros del Web">Revisa y practica</a>, si no lo hiciste, para poder obtener mejores resultados.</p>
<h3>Las plantillas y las vistas</h3>
<p>Las plantillas son muy importantes, permiten acomodar el resultado que devuelve la vista. Django tiene un estupendo motor de plantillas que permite separar eficientemente la presentación, de la lógica de programación, esta semana trabajaremos con algunas plantillas simples para no causar confusión.</p>
<h2>Proyecto de ejemplo: las vistas</h2>
<p>Para esta semana debemos tener en cuenta que nuestros modelos almacenados en models.py dentro de la aplicación principal, quedaron así:</p>
<div id="attachment_24793" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-models-recetario.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-models-recetario-450x200.png" alt="models.py recetario" width="450" height="200" class="size-medium wp-image-24793" /></a><p class="wp-caption-text">models.py recetario</p></div>
<p>Rellenamos algunos datos para poder tener resultados:</p>
<div id="attachment_24796" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-admin-dashboard00.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-admin-dashboard00-450x302.png" alt="Django admin dashboard" width="450" height="302" class="size-medium wp-image-24796" /></a><p class="wp-caption-text">Django admin dashboard</p></div>
<div id="attachment_24795" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-add-user-recetario.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-add-user-recetario-450x245.png" alt="Django admin, agregar usuarios" width="450" height="245" class="size-medium wp-image-24795" /></a><p class="wp-caption-text">Django admin, agregar usuarios</p></div>
<div id="attachment_24807" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-recetas-recetario.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-recetas-recetario-450x214.png" alt="Django admin, agregar recetas" width="450" height="214" class="size-medium wp-image-24807" /></a><p class="wp-caption-text">Django admin, agregar recetas</p></div>
<p>Con estos datos empezaremos a hacer algunas vistas para nuestro proyecto. Empezaremos con las importaciones necesarias, que son estas:</p>
<div id="attachment_24812" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-views-import.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-views-import-450x45.png" alt="Django views.py import" width="450" height="45" class="size-medium wp-image-24812" /></a><p class="wp-caption-text">Django views.py import</p></div>
<p>La primera de ellas es porque necesitamos los modelos, la segunda línea para poder usar los datos del modelo usuario, la tercera línea es la respuesta más simple (HttpResponse), la cuarta importa: render_to_response (para las plantillas) y get_object_or_404 (para lanzar un error 404, de no encontrar ningún valor almacenado) y la quinta línea importa el RequestContext (en este caso para poder usar la ruta de las imágenes almacenadas previamente en la carpeta carga y referenciadas por la url media).</p>
<p>Ahora pasemos a ver donde usamos específicamente cada uno de estos componentes.</p>
<h3 id='sobre'>Vista: sobre</h3>
<p>Esta vista es un ejemplo muy simple del uso de HttpResponse, está devolviendo el contenido HTML:</p>
<div id="attachment_24815" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-views-sobre.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-views-sobre-450x54.png" alt="vista sobre" width="450" height="54" class="size-medium wp-image-24815" /></a><p class="wp-caption-text">vista sobre</p></div>
<div class='tipexperto'>
<h4>Nota:</h4>
<div class='tipcont'>Vamos a modificar <strong>urls.py</strong>, reescribir casi por completo, si eres impaciente y quieres ver como queda al final urls.py o no entiendes muy bien como hacerlo, <a href="#urlspy">puedes echarle un vistazo</a></div>
</div>
<p>Debemos tener en cuenta que siempre debemos acompañar una vista de su configuración en urls.py, así que en este archivo debemos tener esta línea: (ubicada dentro de patterns)</p>
<div class="codigo">
<pre>url(r'^sobre/$','principal.views.sobre'),</pre>
</div>
<p>Lanzamos nuestro servidor de desarrollo:(como todas las semanas)</p>
<div class="codigo">
<pre>python manage.py runserver</pre>
</div>
<p>Y vamos a la dirección:<br />
<a href="http://127.0.0.1:8000/sobre/" target="_blank">http://127.0.0.1:8000/sobre/</a></p>
<div id="attachment_24805" class="wp-caption aligncenter" style="width: 415px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-recetario-sobre.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-recetario-sobre.png" alt="vista sobre en el navegador" width="405" height="186" class="size-full wp-image-24805" /></a><p class="wp-caption-text">vista sobre en el navegador</p></div>
<h3>Vista: Inicio</h3>
<div id="attachment_24813" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-views-inicio.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-views-inicio-450x49.png" alt="vista inicio" width="450" height="49" class="size-medium wp-image-24813" /></a><p class="wp-caption-text">vista inicio</p></div>
<p>La vista inicio, hace una consulta de todas las recetas y las almacena en una variable llamada recetas (también), es aquí donde es apropiado usar render_to_response para poder indicarle que vamos a usar la plantilla inicio.html, y que le pasaremos en un diccionario (concepto de python), el resultado de la consulta.</p>
<p>La plantilla <strong>inicio.html</strong> debemos crearla en la carpeta &#8216;plantillas&#8217; que se encuentra en &#8216;recetario&#8217; (creada previamente en capítulos anteriores), su contenido debe ser similar al siguiente:</p>
<div id="attachment_24797" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-inicio-html.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-inicio-html-450x280.png" alt="inicio.html" width="450" height="280" class="size-medium wp-image-24797" /></a><p class="wp-caption-text">inicio.html</p></div>
<p>Veremos unos símbolos {% %} que por no deben distraernos, así que no entraré en detalles al respecto, pueden intuir de que trata, pero prefiero no confundirlos y dejarlos para la próxima semana. </p>
<p>Ahora igual que el ejemplo anterior debemos agregar la siguiente línea en nuestra configuración de las url en <strong>urls.py</strong>:</p>
<div class="codigo">
<pre>url(r'^$','principal.views.inicio'),</pre>
</div>
<p>Nuestro servidor debe estar funcionando y podemos ingresar a la siguiente dirección:</p>
<p><a href="http://127.0.0.1:8000/" target="_blank">http://127.0.0.1:8000/</a></p>
<div id="attachment_24800" class="wp-caption aligncenter" style="width: 378px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-recetario-index.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-recetario-index.png" alt="inicio.html" width="368" height="342" class="size-full wp-image-24800" /></a><p class="wp-caption-text">inicio.html</p></div>
<h3>Vista: usuarios</h3>
<p>Esta vista saca los datos de los usuarios registrados, y las recetas registradas. Y repite el mismo procedimiento de la vista anterior.</p>
<div id="attachment_24816" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-views-usuarios.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-views-usuarios-450x45.png" alt="vista usuarios" width="450" height="45" class="size-medium wp-image-24816" /></a><p class="wp-caption-text">vista usuarios</p></div>
<p>La plantilla <strong>usuarios.html</strong> debe ser creada en la carpeta plantillas y debe tener un contenido similar al siguiente:</p>
<div id="attachment_24809" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-usuarios-html.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-usuarios-html-450x377.png" alt="usuarios.html" width="450" height="377" class="size-medium wp-image-24809" /></a><p class="wp-caption-text">usuarios.html</p></div>
<p>En esta plantilla se estan juntando a los usuarios y sus respectivas recetas, agregamos la siguiente regla al <strong>urls.py</strong>:</p>
<div class="codigo">
<pre>url(r'^usuarios/$','principal.views.usuarios'),</pre>
</div>
<p>para ver el resultado (servidor corriendo), debemos entrar a:</p>
<p><a href="http://127.0.0.1:8000/usuarios/" target="_blank">http://127.0.0.1:8000/usuarios/</a></p>
<div id="attachment_24799" class="wp-caption aligncenter" style="width: 440px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-recetario-colaboradores.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-recetario-colaboradores.png" alt="Resultado de la vista usuarios" width="430" height="325" class="size-full wp-image-24799" /></a><p class="wp-caption-text">Resultado de la vista usuarios</p></div>
<h3>Vista: lista_recetas</h3>
<div id="attachment_24814" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-views-lista-recetas.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-views-lista-recetas-450x29.png" alt="vista lista_recetas" width="450" height="29" class="size-medium wp-image-24814" /></a><p class="wp-caption-text">vista lista_recetas</p></div>
<p>Esta vista, se diferencia de las anteriores por el uso de context_instance=RequestContext(request), usada para indicarle a la plantilla el parámetro {{MEDIA_URL}} que referencia a la ruta de las imágenes, la plantilla <strong>recetas.html</strong>, debe quedar así:</p>
<div id="attachment_24806" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-recetas-html.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-recetas-html-450x343.png" alt="Resultado de la vista lista_recetas" width="450" height="343" class="size-medium wp-image-24806" /></a><p class="wp-caption-text">Resultado de la vista lista_recetas</p></div>
<p>La línea en <strong>urls.py</strong> debe ser así:</p>
<div class="codigo">
<pre>url(r'^recetas/$','principal.views.lista_recetas'),</pre>
</div>
<p>Y se deben visualizar los resultados en:</p>
<p><a href="http://127.0.0.1:8000/recetas/" target="_blank">http://127.0.0.1:8000/recetas/</a></p>
<div id="attachment_24804" class="wp-caption aligncenter" style="width: 319px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-recetario-recetas.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-recetario-recetas-309x450.png" alt="Resultado de la vista lista_recetas" width="309" height="450" class="size-medium wp-image-24804" /></a><p class="wp-caption-text">Resultado de la vista lista_recetas</p></div>
<h3>Vista: detalle_receta</h3>
<div id="attachment_24811" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-views-detalle-receta.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-views-detalle-receta-450x31.png" alt="vista detalle_receta" width="450" height="31" class="size-medium wp-image-24811" /></a><p class="wp-caption-text">vista detalle_receta</p></div>
<p>Esta vista recibe un parametro mas: id_receta, que le sirve para hacer una consulta del detalle de esa receta (corresponde a su llave primaria) y usa <strong>get_object_or_404(Receta, pk=id_receta)</strong>, para obtener un objeto o un error 404 en caso de no encontrar resultado alguno. </p>
<p>Con este resultado, se realiza una consulta para obtener sus comentarios. La plantilla <strong>receta.html</strong>, quedará así:</p>
<div id="attachment_24798" class="wp-caption aligncenter" style="width: 444px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-receta-html.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-receta-html-434x450.png" alt="receta.html" width="434" height="450" class="size-medium wp-image-24798" /></a><p class="wp-caption-text">receta.html</p></div>
<p>La línea en <strong>urls.py</strong> debe ser así: (notar las expresiones regulares en python)</p>
<div class="codigo">
<pre>url(r'^receta/(?P&lt;id_receta&gt;\d+)$','principal.views.detalle_receta'),</pre>
</div>
<p>Y se deben visualizar los resultados al darle clic en los enlaces a recetas en:</p>
<p><a href="http://127.0.0.1:8000/recetas/" target="_blank">http://127.0.0.1:8000/recetas/</a></p>
<div id="attachment_24802" class="wp-caption aligncenter" style="width: 335px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-recetario-receta-huevo-frito.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-recetario-receta-huevo-frito-325x450.png" alt="receta: huevito frito" width="325" height="450" class="size-medium wp-image-24802" /></a><p class="wp-caption-text">receta: huevito frito</p></div>
<div id="attachment_24801" class="wp-caption aligncenter" style="width: 335px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-recetario-receta-agua-hervida.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-recetario-receta-agua-hervida-325x450.png" alt="receta: agua hervida" width="325" height="450" class="size-medium wp-image-24801" /></a><p class="wp-caption-text">receta: agua hervida</p></div>
<div id="attachment_24803" class="wp-caption aligncenter" style="width: 335px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-recetario-receta-limonada.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-recetario-receta-limonada-325x450.png" alt="receta: limonada" width="325" height="450" class="size-medium wp-image-24803" /></a><p class="wp-caption-text">receta: limonada</p></div>
<h3>Archivo final: views.py</h3>
<p>Al final de todo, <strong>views.py</strong> debe quedar de esta manera:</p>
<div id="attachment_24810" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-views.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-views-450x210.png" alt="views.py" width="450" height="210" class="size-medium wp-image-24810" /></a><p class="wp-caption-text">views.py</p></div>
<h3 id='urlspy'>Archivo: urls.py</h3>
<p>El archivo <strong>urls.py</strong>, permite tener unas urls limpias, para nuestro ejemplo este debe quedar de la siguiente manera: (si fuiste impaciente, <a href="#sobre">regresa a la vista: sobre <img src='http://www.maestrosdelweb.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </a> )</p>
<div id="attachment_24808" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-urls-py.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-urls-py-450x234.png" alt="urls.py" width="450" height="234" class="size-medium wp-image-24808" /></a><p class="wp-caption-text">urls.py</p></div>
<p>Para finalizar, si se perdieron con alguna línea o si desean corroborar que todo va bien, pueden estar pendientes del <a href="http://neosergio.github.com/recetario_mdw/" title="Recetario Django en Maestros del Web">repositorio del proyecto</a>. </p>
<p>La próxima semana veremos el tema de las plantillas con un poco más de detalle, practiquen haciendo sus propias vistas, usando las consultas que aprendieron en el capítulo anterior y complementen lo aprendido con <a href="https://docs.djangoproject.com/en/dev/topics/http/views/" title="Views en Django">un vistazo a la documentación oficial</a>, que nunca esta demás. Que tengan buen inicio de semana <img src='http://www.maestrosdelweb.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<hr /><p style="height: 64px;"><img alt='Sergio Infante Montero' src='http://1.gravatar.com/avatar/3ca2b43e8aedb28a82fdca67e28281a1?s=64&amp;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&amp;r=G' class='avatar avatar-64 photo' height='64' width='64' style="float:left;padding:0 5px" /> <strong>Sergio Infante Montero</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/curso-django-las-vistas/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/curso-django-las-vistas/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/curso-django-las-vistas/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-models-recetario-150x150.png" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-models-recetario.png" medium="image">
			<media:title type="html">models.py recetario</media:title>
			<media:description type="html">models.py recetario</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-models-recetario-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-admin-dashboard00.png" medium="image">
			<media:title type="html">Django admin dashboard</media:title>
			<media:description type="html">Django admin dashboard</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-admin-dashboard00-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-add-user-recetario.png" medium="image">
			<media:title type="html">Django admin, agregar usuarios</media:title>
			<media:description type="html">Django admin, agregar usuarios</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-add-user-recetario-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-recetas-recetario.png" medium="image">
			<media:title type="html">Django admin, agregar recetas</media:title>
			<media:description type="html">Django admin, agregar recetas</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-recetas-recetario-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-views-import.png" medium="image">
			<media:title type="html">Django views.py import</media:title>
			<media:description type="html">Django views.py import</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-views-import-150x56.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-views-sobre.png" medium="image">
			<media:title type="html">vista sobre</media:title>
			<media:description type="html">vista sobre</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-views-sobre-150x64.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-sobre.png" medium="image">
			<media:title type="html">vista sobre en el navegador</media:title>
			<media:description type="html">vista sobre en el navegador</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-sobre-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-views-inicio.png" medium="image">
			<media:title type="html">vista inicio</media:title>
			<media:description type="html">vista inicio</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-views-inicio-150x57.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-inicio-html.png" medium="image">
			<media:title type="html">inicio.html</media:title>
			<media:description type="html">inicio.html</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-inicio-html-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-index.png" medium="image">
			<media:title type="html">inicio.html</media:title>
			<media:description type="html">inicio.html</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-index-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-views-usuarios.png" medium="image">
			<media:title type="html">vista usuarios</media:title>
			<media:description type="html">vista usuarios</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-views-usuarios-150x70.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-usuarios-html.png" medium="image">
			<media:title type="html">usuarios.html</media:title>
			<media:description type="html">usuarios.html</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-usuarios-html-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-colaboradores.png" medium="image">
			<media:title type="html">Resultado de la vista usuarios</media:title>
			<media:description type="html">Resultado de la vista usuarios</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-colaboradores-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-views-lista-recetas.png" medium="image">
			<media:title type="html">vista lista_recetas</media:title>
			<media:description type="html">vista lista_recetas</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-views-lista-recetas-150x56.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-recetas-html.png" medium="image">
			<media:title type="html">Resultado de la vista lista_recetas</media:title>
			<media:description type="html">Resultado de la vista lista_recetas</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-recetas-html-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-recetas.png" medium="image">
			<media:title type="html">Resultado de la vista lista_recetas</media:title>
			<media:description type="html">Resultado de la vista lista_recetas</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-recetas-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-views-detalle-receta.png" medium="image">
			<media:title type="html">vista detalle_receta</media:title>
			<media:description type="html">vista detalle_receta</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-views-detalle-receta-150x71.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-receta-html.png" medium="image">
			<media:title type="html">receta.html</media:title>
			<media:description type="html">receta.html</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-receta-html-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-receta-huevo-frito.png" medium="image">
			<media:title type="html">receta: huevito frito</media:title>
			<media:description type="html">receta: huevito frito</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-receta-huevo-frito-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-receta-agua-hervida.png" medium="image">
			<media:title type="html">receta: agua hervida</media:title>
			<media:description type="html">receta: agua hervida</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-receta-agua-hervida-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-receta-limonada.png" medium="image">
			<media:title type="html">receta: limonada</media:title>
			<media:description type="html">receta: limonada</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-recetario-receta-limonada-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-views.png" medium="image">
			<media:title type="html">views.py</media:title>
			<media:description type="html">views.py</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-views-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-urls-py.png" medium="image">
			<media:title type="html">urls.py</media:title>
			<media:description type="html">urls.py</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-urls-py-150x150.png" />
		</media:content>
		<media:content url="http://1.gravatar.com/avatar/3ca2b43e8aedb28a82fdca67e28281a1?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" medium="image">
			<media:title type="html">Sergio Infante Montero</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Re-definiendo lo que conocemos de educación virtual</title>
		<link>http://www.maestrosdelweb.com/editorial/re-definiendo-educacion-virtual/</link>
		<comments>http://www.maestrosdelweb.com/editorial/re-definiendo-educacion-virtual/#comments</comments>
		<pubDate>Mon, 21 May 2012 07:14:08 +0000</pubDate>
		<dc:creator>Christian Van Der Henst S.</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[educacion virtual]]></category>
		<category><![CDATA[elearning]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24619</guid>
		<description><![CDATA[Hace 10 años deambulaba por los pasillos de la universidad, entre fotocopias, libros de algún profesor, acceso a internet limitado o nulo durante el examen. Era una época donde me hacían aprender contabilidad sin usar excel, no soñaba en compartir documentos en alguna nube y mis apuntes en clase aún utilizaban la tecnología de la [...]]]></description>
			<content:encoded><![CDATA[<p>Hace 10 años deambulaba por los pasillos de la universidad, entre fotocopias, libros de algún profesor, acceso a internet limitado o nulo durante el examen. Era una época donde me hacían aprender contabilidad sin usar excel, no soñaba en compartir documentos en alguna nube y mis apuntes en clase aún utilizaban la tecnología de la tinta y el papel.</p>
<p>Durante ese tiempo, quedé enamorado con la idea de tener un rol en las aulas. Desde muy joven me asigné un nombre que siempre me ha costado llevar en la espalda: Maestros&#8230; ¿<a href="http://www.maestrosdelweb.com/guias/#maestrosdelweb">Maestro del Web</a>? Yo estaba aprendiendo, sigo aprendiendo; enseñar y compartir es una excusa para hacer la tarea. No hay mejor alumno que el que tiene que aprender a la fuerza con el deadline y compromiso de que va a compartir algún tema en clase.</p>
<p>La educación virtual se definió como el uso de las TIC´s en el modelo de aprendizaje que se acopla al tiempo y necesidad del estudiante. Esa educación adquirida en la experiencia y cursos que se imparten fuera del salón de clases, pero que el profesor puede ser un tutor que utiliza el internet como plataforma para impartir conocimiento.</p>
<p>Sin embargo, la educación virtual se ha utilizado falsamente en la batalla por expandir la base de usuarios de centros universitarios y lamentablemente, también para vender una experiencia más pasiva de educación con libertad de horarios, espacios y agenda. La educación virtual es visto como uno de los espacios donde menos se compromete el alumno a estudiar, concretar resultados, aprender un tema y finalmente generar un cambio en el mundo.</p>
<h3>Re-definiendo Educación Virtual</h3>
<p>Hoy estamos intentando re-definir la educación virtual desde muchos frentes. Universidades tan populares en el mundo como <a href="http://www.stanford.edu/">Stanford</a>, <a href="http://www.harvard.edu/">Harvard</a>, <a href="http://www.yale.edu/">Yale</a>, <a href="http://www.cornell.edu/">Cornell</a>, <a href="http://web.mit.edu/">MIT</a> y demás, están en la apuesta. Queremos entender qué paso con <a href="http://www.ox.ac.uk/">Oxford</a>, <a href="http://www.cam.ac.uk/">Cambridge</a>, <a href="http://www.itesm.edu/wps/portal?WCM_GLOBAL_CONTEXT=">Tec de Monterrey</a>, <a href="http://campusvirtual.ub.edu/">UBVirtual</a>, <a href="http://www.palermo.edu/">Palermo</a>, etc. Más importante aún, en el entorno web surgieron otros nombres en poco tiempo: <a href="http://www.khanacademy.org/">Khan Academy</a>, <a href="http://www.codecademy.com/">Codecademy</a>, <a href="http://udacity.com/">Udacity</a> o <a href="https://www.coursera.org/">Coursera</a>.</p>
<p>¿Saben quiénes están también en la lista sin que muchos se den cuenta? Youtube (y por ende Google), Facebook, Wikipedia, Facebook, LinkedIn (hey, ahora tienen a Slideshare) y nuestras comunidades: <a href="http://www.forosdelweb.com/">Foros del Web</a> y <a href="http://cristalab.com/">Cristalab</a>, también están allí desde hace años.</p>
<p>Re-definamos la educación y lo que pasa en Internet, porque cualquier servicio, espacio digital, comunidad o red social puede potenciarse como plataforma para educar a los demás. Puede utilizarse para educar y mercadearse, sin que el capitalismo de esta estrategia sea mal visto hasta por los más izquierdosos del planeta.</p>
<p>A lo largo de este año, voy a compartir con ustedes un análisis de los servicios, las plataformas, las estrategias y los miles de proyectos que hacen que el llamado mundo de la &#8220;Educación Virtual&#8221; demuestre sus verdaderos colores, esos donde no tenemos aún nada claro, pero muchos estamos invirtiendo tiempo en descubrir o re-descubrir.</p>
<h3>¿Te interesa la educación virtual?</h3>
<p>Si participas en esta industria, si te apasiona el tema, charlemos. Estamos en la búsqueda de ampliar nuestro equipo, estamos en busca de alianzas, queremos críticas sinceras.</p>
<p>Si el mundo digital modificó por completo, sin vuelta atrás, el mundo de la música, el vídeo, el entretenimiento y lo sigue haciendo con el comercio y la creación de empresas de servicios. La educación sigue esperando su momento de gloria, donde esa misma materia digital transmite profesiones universales sin importar las distancias de los grandes maestros e investigadores. Espero me acompañen en la aventura.</p>
<p>En un próximo capítulo de la serie <a href="http://www.maestrosdelweb.com/editorial/khan-academy-educacion-virtual/">exploraremos a Khan Academy</a>. </p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/cvander-72.jpg" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Christian Van Der Henst S.</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/re-definiendo-educacion-virtual/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/re-definiendo-educacion-virtual/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/re-definiendo-educacion-virtual/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/wp-content/authors/cvander-72.jpg" />
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/cvander-72.jpg" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Es viernes: Mejorando.la/conferencia ¿Centroamérica?</title>
		<link>http://www.maestrosdelweb.com/editorial/mejorando-laconferencia-centroamerica/</link>
		<comments>http://www.maestrosdelweb.com/editorial/mejorando-laconferencia-centroamerica/#comments</comments>
		<pubDate>Fri, 18 May 2012 18:09:28 +0000</pubDate>
		<dc:creator>Stephanie Falla Aroche</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Productividad]]></category>
		<category><![CDATA[cursos]]></category>
		<category><![CDATA[es viernes!]]></category>
		<category><![CDATA[evento]]></category>
		<category><![CDATA[mejorandola]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24727</guid>
		<description><![CDATA[Hace unos días comenté en mi cuenta en Twitter (@stephaniefalla) que con el equipo de mejorando.la estábamos contemplando realizar el evento mejorando.la/conferencia que ha tenido mucho éxito en Latinoamérica; hemos transmitido desde sedes como México, Colombia y Chile. Nuestros cursos se han llevado a cabo en México, Costa Rica, Perú, Colombia, Argentina, Chile y próximamente [...]]]></description>
			<content:encoded><![CDATA[<p>Hace unos días comenté en mi cuenta en Twitter (@stephaniefalla) que con el equipo de <a href="http://mejorando.la">mejorando.la</a> estábamos contemplando realizar el evento <a href="http://mejorando.la/conferencia">mejorando.la/conferencia</a> que ha tenido mucho éxito en Latinoamérica; hemos transmitido desde sedes como México, Colombia y Chile. Nuestros cursos se han llevado a cabo en México, Costa Rica, Perú, Colombia, Argentina, Chile y próximamente estaremos en España. Este año queremos que Centroamérica sea nuestra sede y transmitir al mundo lo que está pasando en la región y esperamos contar con tu apoyo.</p>
<p><a href="http://mejorando.la/conferencia"><img src="http://www.maestrosdelweb.com/images/2012/05/mejornadola-conferencia.jpg" alt="Mejorando.la/conferencia" /></a></p>
<p>Organizar un evento en donde tienes conferencistas internacionales, expertos en sus áreas y contenido de gran valor no es tarea fácil. La logística empieza con encontrar una sede accesible para los participantes, entender el mercado, conocer la audiencia y las dinámicas culturales. No es lo mismo organizar un evento en Chile que hacerlo para México. La logística en Argentina es muy diferente de la logística en Colombia. Son muchos los factores que debes contemplar y sobre todo, saber que tu audiencia está interesada y quiere participar.</p>
<h3>¿Qué se necesita para un evento Mejorando.la/conferencia?</h3>
<p>Mejorando.la/conferencia es un evento global, es lo más importante de entender, que la sede esté en tu país no significa que sólo los asistentes de la sede estén presentes en el evento, en realidad en nuestra última transmisión logramos que más de 50 mil personas estuvieran conectadas durante 2 días en la serie de conferencias que preparamos para el evento. Así, que no estamos organizando un evento sólo para las 200 o 500 personas en un salón, estamos organizando un evento para 50 mil personas más fuera de ese salón.</p>
<p><iframe width="640" height="360" src="http://www.youtube.com/embed/x4ZwpiKR7ew" frameborder="0" allowfullscreen></iframe></p>
<p>Sin embargo, que la transmisión sea desde un país o región en específico es una gran oportunidad para que profesionales destacados locales muestren lo que está sucediendo en su país. Además, tendrán la oportunidad de conversar con los conferencistas extranjeros, aprovechar el networking y casi siempre, logramos que los participantes se vayan con premios o regalos de los patrocinadores. Entonces dejenme compartirles las piezas que necesitamos ir armando para lograr que el próximo evento de mejorando.la/conferencia sea transmitido desde Centroamérica para el mundo.</p>
<ul>
<li><strong>Participación:</strong> Es muy importante detectar el interés de la audiencia en el país o región. Saber si el lugar seleccionado permitirá que personas de la región viajen al lugar del evento. Desafortunadamente no podemos estar en todos los países, pero sí podemos escoger una Ciudad que sea accesible a muchos más.</li>
<li><strong>Patrocinadores: </strong>Tenemos diferentes rangos de patrocinadores, como sabrán el traer conferencistas y hospedarlos cuesta dinero. Además, la sede en ocasiones es un patrocinio y en otras ocasiones debemos pagarla, el internet también es un servicio que debe pagarse y no siempre las empresas del país están interesadas en patrocinar con ese servicio. Otros patrocinadores nos dan de sus productos para regalar y otros patrocinan con su servicio.</li>
<li><strong>Conferenciastas:</strong> Debemos seleccionar cuidadosamente a los conferencistas, saber qué temas quiere la audiencia, conocer el mercado y lo que les interesa. Además, cuando pensamos en conferencistas muy populares en el medio, su agenda es complicada y debemos garantizarnos un espacio. En este tipo de conferencias se le cubren todos los gastos al conferencista y eso también cuesta dinero. </li>
<li><strong>Sede/Lugar:</strong> Como les comenté, en ocasiones se patrocina la sede, pero en otras simplemente el mercado no ofrece muchas opciones y debemos acudir a alquilar el lugar. Gestionar sus servicio y costos de todo: sillas, mesas, luz, conexiones y el doloroso servicios de Internet que en Latinoamérica siempre será un tema difícil. </li>
<li><strong>Promoción:</strong> Tenemos nuestros canales en donde informamos sobre nuestras actividades, en ocasiones blogger influyentes del lugar también hacen mención e invitan a participar. Las redes sociales y nuestras cuentas también las usamos para promover. Pero, también hemos tenido patrocinio de medios del país, empresas interesadas en que el evento suene en los medios tradicionales y sabemos que también es importante estar allí. </li>
<li><strong>Staff:</strong> Siempre contamos con el apoyo de la comunidad, personas que llegan y nos ofrecen su tiempo o por lo menos orientarnos de cómo funcionan las cosas en su país. Tener personas locales siempre es de gran ayuda, porque nos gusta entender cómo funcionan los mercados, entenderlos y brindar lo mejor de nuestro trabajo.</li>
</ul>
<p>Parecerá que en estos <strong>6 puntos</strong> son fáciles de lograr, pero debo recordarles que son mucho matices en cada uno de ellos. Traté de simplificar para exponerles nuestro interes por hacer un evento en Centroamérica, pero que sin duda no lo podemos lograr sin la ayuda, el interes y colaboración de ustedes. Si están interesados en hacer que esto sea posible, les pregunto <strong>¿en cuál de estos 6 puntos nos quieren apoyar?</strong> nos interesa sumar esfuerzos y seguir promoviendo la tecnología, el talento y los proyectos que existen en la región hispana para el mundo. Feliz fin de semana. Enjoy!</p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/128.png" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Stephanie Falla Aroche</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/mejorando-laconferencia-centroamerica/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/mejorando-laconferencia-centroamerica/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/mejorando-laconferencia-centroamerica/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/mejornadola-conferencia.jpg" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/mejornadola-conferencia.jpg" medium="image">
			<media:title type="html">Mejorando.la/conferencia</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/128.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>GeeksOnAPlane: emprendimientos de Miami y México DF</title>
		<link>http://www.maestrosdelweb.com/actualidad/geeksonaplane-emprendimientos-de-miami-y-mexico-df/</link>
		<comments>http://www.maestrosdelweb.com/actualidad/geeksonaplane-emprendimientos-de-miami-y-mexico-df/#comments</comments>
		<pubDate>Thu, 17 May 2012 14:54:45 +0000</pubDate>
		<dc:creator>Claudio Cossio</dc:creator>
				<category><![CDATA[Actualidad]]></category>
		<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Eventos]]></category>
		<category><![CDATA[emprendimiento]]></category>
		<category><![CDATA[geeks on a plane]]></category>
		<category><![CDATA[geeoksonaplane]]></category>
		<category><![CDATA[miami]]></category>
		<category><![CDATA[startup]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24601</guid>
		<description><![CDATA[No hay mejor manera de abrir este articulo que citando a uno de los emprendedores y organizadores que hicieron que Geeks On A Plane llegara a tierras Aztecas: Lo que esta ahora sucediendo en la casa del Embajador de Estados Unidos en México pasara a la historia como un momento clave para el emprendimiento en [...]]]></description>
			<content:encoded><![CDATA[<p>No hay mejor manera de abrir este articulo que citando a uno de los emprendedores y organizadores que hicieron que <strong>Geeks On A Plane</strong> llegara a tierras Aztecas:</p>
<blockquote><p>Lo que esta ahora sucediendo en la casa del Embajador de Estados Unidos en México pasara a la historia como un momento clave para el emprendimiento en Latino América &#8211; <em>Cesar Salazar &#8211; Cofundador de Mexican.vc</em></p></blockquote>
<p><a href="http://www.maestrosdelweb.com/images/2012/05/photo1.jpg"><img class="alignleft  wp-image-24673" style="border: 5px solid white" src="http://www.maestrosdelweb.com/images/2012/05/photo1-e1337188991392-337x450.jpg" alt="" width="207" height="273" /></a>Estoy completamente de acuerdo con Cesar, pero creo que no solo ha sido ese momento lo que ha marcado un hito en el ecosistema de emprendimiento de América Latina; ha sido el esfuerzo colectivo de todas las diferentes iniciativas de emprendedores de Latino América durante un periodo de 5 años que ha logrado que estemos ahora pasando por una de las mejores etapas en países como México, Chile, Colombia, Argentina y Brasil.</p>
<p>Como todo, no siempre los primeros exploradores han sido los que han recibido el mérito y el reconocimiento que se merecen, estoy hablando de gente como Tomas Pollak, Nicolas Orellana, Leo Prieto, Juan Francisco Diez, Adan Vecindad, Carlos Mondragon, Santiago Siri, Damian Voltes, Ivan Sosa, Juan David Vargas y muchos otros que han tenido éxito en sus emprendimientos, pero a pesar de ello tenemos que reconocer que nunca hemos dejado de ser un &#8220;grupo de geeks&#8221; o &#8220;frikis&#8221; con ganas de cambiar el mundo.</p>
<p>El esfuerzo de plantar la semilla emprendedora esta dando sus frutos con Startups como <a href="welcu.com" target="_blank">Welcu</a>, <a href="http://angel.co/yogome" target="_blank">Yogome</a>, <a href="http://angel.co/fontacto" target="_blank">Fontacto</a>, <a href="http://angel.co/ovia" target="_blank">Ovia</a>, <a href="preyproject.com" target="_blank">PreyProject</a>, <a href="http://frogtek.org/" target="_blank">Frogtek</a> y muchas otras mas que tienen a emprendedores Latino Americanos como fundadores.</p>
<h3>Miami como punta de lanza para conectar con Hispanos en Estados Unidos.</h3>
<p>Quede muy impresionado con la versatilidad de esa ciudad, a pesar de tener la etiqueta de &#8220;turística&#8221;; esta haciendo un esfuerzo para hacer uso de lo mejor que tiene: una conexión con dos mundos dentro de un mismo país &#8211; contacto con la población inmigrante latina y anglosajona de Estados Unidos.</p>
<blockquote><p>Nadie conoce mejor a la población hispana en Estados Unidos  y Latino Americana que la comunidad de Miami &#8211; Adriana Cisneros &#8211; CEO de Corporativo Cisneros.</p></blockquote>
<p>Sin embargo aunque esta ofreciendo muchos incentivos por parte de la Asociación de Empresarios del Condado de Miami y varios grupos de Meetups de Tecnología; no vi un hub de talento para alimentar tu Startup. Esta es una pieza fundamental para cualquier empresa tecnológica pueda crecer en un mercado tan demandante como el de Internet, esto no lo vi reflejado en este viaje; espero en algún momento regresar con mas tiempo para tener esto mas claro.</p>
<p>Definitivamente hay capital en la ciudad, aunque no veo que sea un capital inteligente en el sentido que tenga la experiencia de fondear Startups y entiendan la tolerancia al riesgo que se requiere de un inversor en tecnología. Esto no quiere decir que no se pueda recibir inversión de capital riesgo o algún business ángel, en años venideros aterrizaran muchas empresas Latino Americanas en aquella hermosa ciudad que nos hechiza con sus playas y su ambiente Latino que se respira en cada esquina.</p>
<p>Miami será una excelente opción cuando lleguen a tener suficientes Startups y empresas de tecnología en los alrededores para poder auto-abastecerse para que entre ellas mismas se puedan sustentar; sobre todo la necesidad de talento que requiere un ecosistema de emprendimiento tecnológico.</p>
<h3>StartupWeekend Mexico DF, el pais Azteca despertando el interes de geeks de Silicon Valley.</h3>
<p>Algo que se ha venido trabajando desde el 2009 con el primer evento de emprendimiento en la Ciudad de Mexico por parte de la iniciativa de <a href="http://iweekend.org" target="_blank">iWeekend</a>, varias reuniones de hackers Mexicanos como el <a href="http://superhappydevhouse.org/w/page/16345504/FrontPage" target="_blank">SuperHappyDevHouse</a> y <a href="http://mobilecamp.mx/" target="_blank">MobilecampMX</a>. Ha culminado con 4 eventos de <a href="http://startupweekend.org/" target="_blank">StartupWeekend</a> en México (<a href="http://startupweekendgdl.org/" target="_blank">Guadalajara</a>, <a href="http://aguascalientes.startupweekend.org/" target="_blank">Aguascalientes</a>, <a href="http://morelia.startupweekend.org/" target="_blank">Morelia</a> y <a href="http://tijuana.startupweekend.org/" target="_blank">Tijuana</a>) con rotundo éxito y que se proyecta hacer más de 15 en todo el país.</p>
<p><a href="http://www.maestrosdelweb.com/images/2012/05/Captura-de-pantalla-2012-05-16-a-las-2.13.09-PM.png"><img class="alignleft size-full wp-image-24670" style="border: 5px solid white" src="http://www.maestrosdelweb.com/images/2012/05/Captura-de-pantalla-2012-05-16-a-las-2.13.09-PM.png" alt="" width="140" height="179" /></a>Lo que hace memorable esta tercera edición de México DF sea espectacular, es que tuvo un jurado estelar con figuras como David Weekly, Dave McClure, Allen Taylor, e integrantes de GeeksOnAPlane y mas juzgando a 11 proyectos con un potencial de primer nivel. Se reunieron los líderes de todas la comunidades de tecnología de México desde Guadalajara hasta San Luis Potosí, trajeron a su mejor talento y se vio claro en lo que son los 3 primeros lugares del evento.</p>
<blockquote><p>Estamos buscando proyectos que podamos fusionar con Startups en SiliconValley y el ganador de StartupWeekend tiene muchas sinergias con TaskRabbit una empresa de nuestro portafolio &#8211; Dave McClure hablando de Encarguitos.</p></blockquote>
<p>Con el primer lugar que fue Encarguitos, así como Legal You (2do lugar) se vio claro como se pudo identificar una necesidad a nivel global, poder ejecutar a nivel local y como poderla escalar de manera orgánica. Esa fue la propuesta de valor que tuvo Encarguitos, que merecidamente ganaron en <a href="http://startupweekenddf.com/" target="_blank">StartupWeekend México DF</a>.</p>
<p>Me llamo la atención Instareal que es una app para colocar bienes inmuebles de manera sencilla y sindicalizarlos en varias plataformas de búsqueda de bienes raíces. La mención honorífica de RockMob fue para una app que te ayuda a poder quitar la &#8220;frustración&#8221; de aprender a tocar un instrumento musical y pudieron hacer una demostración en vivo para que alguien pudiera tocar una guitarra.</p>
<h3>Convivencia de emprendedores, hackers e inversores en América Latina.</h3>
<p>Lo mejor que esta haciendo <a href="http://geeksonaplane.com" target="_blank">Geeks On A Plane</a>, es habilitar eventos donde se reúne gente clave de las diferentes comunidades y provoca que puedan establecer una conexión que aunque sea momentánea, tenga el potencial de habilitar futuras conversaciones. Hemos visto eventos como <a href="http://twitter.com/#!/traweln" target="_blank">Traweln</a> y <a href="http://twitter.com/#!/traweln" target="_blank">La Red Innova</a> que han permitido mediante conferencias hacer estas conexiones en Chile y España, con representación por parte de iniciativas Ibéricas como <a href="http://dad.es" target="_blank">Digital Asset Deployment</a> (DAD &#8211; fondo de inversión) y <a href="http://smartup.es" target="_blank">Smartup</a> (firma de marketing digital).</p>
<p>Ya que en un periodo de 10 días sabemos que la intimidad de compartir cuartos de hotel, comidas, cenas, almuerzos y como no, algunas bebidas &#8220;refrescantes&#8221; permitirá generar la confianza necesaria para que se pueda trabajar en futuros proyectos.</p>
<blockquote><p>La confianza que genera un emprendedor en el inversor, es la misma que tiene que generar un fondo de inversión con sus inversores. Es una pieza clave para que cualquier ecosistema de emprendimiento pueda florecer a pesar esta crisis global que se esta viviendo; por eso es clave encontrar a estas &#8220;figuras de confianza&#8221; para crearlo &#8211; Paul Ahlstrom &#8211; fundador de Alta Ventures.</p></blockquote>
<p>Así que no se pierdan lo que se publica diariamente en el hashtag <a href="http://twitter.com/#!/search/%23GOAP" target="_blank">#GOAP</a> en twitter para estar al tanto de lo que acontece en esta gira por Latino America de los <strong>Geeks On A Plane</strong>.</p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/360-33.jpg" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Claudio Cossio</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/actualidad/geeksonaplane-emprendimientos-de-miami-y-mexico-df/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/actualidad/geeksonaplane-emprendimientos-de-miami-y-mexico-df/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/actualidad/geeksonaplane-emprendimientos-de-miami-y-mexico-df/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/photo1-e1337188991392-150x150.jpg" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/photo1-e1337188991392.jpg" medium="image">
			<media:title type="html">GeeksOnAPlane</media:title>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/photo1-e1337188991392-150x150.jpg" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/Captura-de-pantalla-2012-05-16-a-las-2.13.09-PM.png" medium="image">
			<media:title type="html">Logo StartupWeekend Mexico DF</media:title>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/Captura-de-pantalla-2012-05-16-a-las-2.13.09-PM-140x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/360-33.jpg" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Curso Symfony 2: Instalando Bundles de Terceros</title>
		<link>http://www.maestrosdelweb.com/editorial/curso-symfony2-instlando-bundles-de-terceros/</link>
		<comments>http://www.maestrosdelweb.com/editorial/curso-symfony2-instlando-bundles-de-terceros/#comments</comments>
		<pubDate>Wed, 16 May 2012 14:13:07 +0000</pubDate>
		<dc:creator>Maycol Alvarez</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Behaviors]]></category>
		<category><![CDATA[bundles]]></category>
		<category><![CDATA[capitulo12]]></category>
		<category><![CDATA[curso]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[guia]]></category>
		<category><![CDATA[symfony 2]]></category>
		<category><![CDATA[symfony2]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=20051</guid>
		<description><![CDATA[En reiteradas ocaciones existe la necesidad de implementar librerías de terceros en nuestros proyectos con el objetivo primordial de aprovecharlas, reutilizar código y mejorar nuestros tiempos de entrega; como ya saben en Symfony 2 todo se distribuye en forma de “Bundles” y las librerías de terceros no son la excepción, además en symfony2bundles.org (actualmente http://knpbundles.com/) [...]]]></description>
			<content:encoded><![CDATA[<p>En reiteradas ocaciones existe la necesidad de implementar librerías de terceros en nuestros proyectos con el objetivo primordial de aprovecharlas, reutilizar código y mejorar nuestros tiempos de entrega; como ya saben en Symfony 2 todo se distribuye en forma de “Bundles” y las librerías de terceros no son la excepción, además en symfony2bundles.org (actualmente <a href="http://knpbundles.com/">http://knpbundles.com/</a>) podrás encontrar miles de bundles que podrías necesitar.</p>
<p>En este capítulo nos concentraremos en la instalación de uno de los Bundles más atractivos para incluir en nuestros proyectos, se trata del <a href="https://github.com/stof/StofDoctrineExtensionsBundle">StofDoctrineExtensionsBundle</a> por Christophe Coevoet el cual hace una implementación del complemento <a href="https://github.com/l3pp4rd/DoctrineExtensions">Doctrine2 behavioral extensions</a> creado por Gediminas Morkevicius, cuyo propósito es proveer de los aclamados Comportamientos (behaviors) de Doctrine; en general explicaremos la configuración de 3 comportamientos ampliamente utilizados, como lo son Timestampable, Sluggable y Loggable, reiteramos que el objetivo del capítulo es la instalación de Bundles de Terceros en Symfony2 y no el de profundizar en todos los comportamientos que provee el StofDoctrineExtensionsBundle.</p>
<h3>Paso 1: Instalando el Bundle</h3>
<p>En Symfony 2 existen varias formas para la instalación de los bundles de terceros, entre ellas (y la más práctica) es la instalación por medio de submodule en GIT, si no sabes que es GIT te recomiendo visitar <a href="http://progit.org/book/es/">http://progit.org/book/es/</a> y tratar de instalarlo en tu sistema.</p>
<p>Comenzamos instalando la librería principal de Doctrine Behavioral Extensions, para ello accedemos a nuestra consola, nos ubicamos en la raíz del proyecto de symfony y ejecutamos:</p>
<div class="codigo">
<pre>~$ git submodule add git://github.com/l3pp4rd/DoctrineExtensions.git vendor/gedmo-doctrine-extensions</pre>
</div>
<div class="tipexperto"><h3>Nota</h3> <div class="tipcont">Si tienes problemas puedes descargar manualmente <a href="https://github.com/l3pp4rd/DoctrineExtensions">el paquete</a>, sólo debes descomprimir su contenido y copiarlo al directorio /ruta_hacia_proyecto/<strong>vendor</strong>/gedmo-doctrine-extensions</div></div>
<p>Ahora si añadimos el StofDoctrineExtensionsBundle:</p>
<div class="codigo">
<pre>~$ git submodule add git://github.com/stof/StofDoctrineExtensionsBundle.git vendor/bundles/Stof/DoctrineExtensionsBundle</pre>
</div>
<div class="tipexperto"><h3>Nota</h3> <div class="tipcont">Si tienes problemas puedes descargar manualmente <a href="https://github.com/stof/StofDoctrineExtensionsBundle">el paquete</a>, sólo debes descomprimir su contenido y copiarlo al directorio /ruta_hacia_proyecto/<strong>vendor/bundles</strong>/Stof/DoctrineExtensionsBundle.</div></div>
<p>Registramos los Namespaces en nuestro app/autoload.php:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

use Symfony\Component\ClassLoader\UniversalClassLoader;
use Doctrine\Common\Annotations\AnnotationRegistry;

$loader = new UniversalClassLoader();
$loader-&gt;registerNamespaces(array(
    'Symfony'          =&gt; array(__DIR__.'/../vendor/symfony/src', __DIR__.'/../vendor/bundles'),
    'Sensio'           =&gt; __DIR__.'/../vendor/bundles',
    'JMS'              =&gt; __DIR__.'/../vendor/bundles',
    'Doctrine\\Common' =&gt; __DIR__.'/../vendor/doctrine-common/lib',
    'Doctrine\\DBAL'   =&gt; __DIR__.'/../vendor/doctrine-dbal/lib',
    'Doctrine'         =&gt; __DIR__.'/../vendor/doctrine/lib',
    'Monolog'          =&gt; __DIR__.'/../vendor/monolog/src',
    'Assetic'          =&gt; __DIR__.'/../vendor/assetic/src',
    'Metadata'         =&gt; __DIR__.'/../vendor/metadata/src',
    // Aquí registramos:
    'Stof'  =&gt; __DIR__.'/../vendor/bundles',
    'Gedmo' =&gt; __DIR__.'/../vendor/gedmo-doctrine-extensions/lib',
));
// ... resto del archivo
</pre>
<p>Añadimos el Bundle a nuestro app/AppKernel.php:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
            new Symfony\Bundle\SecurityBundle\SecurityBundle(),
            new Symfony\Bundle\TwigBundle\TwigBundle(),
            new Symfony\Bundle\MonologBundle\MonologBundle(),
            new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
            new Symfony\Bundle\DoctrineBundle\DoctrineBundle(),
            new Symfony\Bundle\AsseticBundle\AsseticBundle(),
            new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
            new JMS\SecurityExtraBundle\JMSSecurityExtraBundle(),
            new MDW\BlogBundle\MDWBlogBundle(),
            new MDW\DemoBundle\MDWDemoBundle(),
            // Aquí Añadimos:
            new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),
        );
// ... resto del archivo
</pre>
<p>Básicamente es todo lo que se realiza para incluir un Bundle.</p>
<h3>Paso 2: Configurando el Bundle</h3>
<p>En nuestro caso el <strong>StofDoctrineExtensionsBundle</strong> para funcionar requiere agregar configuración adicional al archivo app/config/<strong>config.yml</strong> de la aplicación (la mayoría de los bundles pueden detallar tales configuraciones en su documentación), para ello agregamos estos segmentos:</p>
<p>En la sección <em>Doctrine Configuration</em>, añadimos al final el mapping para StofDoctrineExtensions Bundle:</p>
<div class="codigo">
<pre># Doctrine Configuration
doctrine:
    dbal:
        driver:   %database_driver%
        host:     %database_host%
        port:     %database_port%
        dbname:   %database_name%
        user:     %database_user%
        password: %database_password%
        charset:  UTF8

    orm:
        auto_generate_proxy_classes: %kernel.debug%
        auto_mapping: true
        # Añadimos el Mapping para StofDoctrineExtensionsBundle: -------------
        mappings:
            StofDoctrineExtensionsBundle: ~
# ... resto del archivo</pre>
</div>
<p>Luego añadimos <em>al final del mismo archivo</em> la siguiente configuración:</p>
<div class="codigo">
<pre># Añadimos las configuraciones específicas para el StofDoctrineExtensionsBundle
stof_doctrine_extensions:
    default_locale: en_US
    orm:
        default:
            sluggable: true
            timestampable: true
            loggable: true
            #demás behaviors para activar</pre>
</div>
<p>Donde <strong>default:</strong> representa la configuración para todos los entornos, eso quiere decir que puedes añadir una configuración específica para cada entorno.</p>
<h3>Paso 3: Utilizando los Comportamientos (Behaviors) en los modelos</h3>
<p>En este tutorial nos concentraremos en los comportamientos sluggable, timestampable y loggable, para hacer las cosas más fáciles se recomienda añadir el siguiente Namespace a cada una de nuestras entidades en donde queramos añadir los comportamientos:</p>
<pre class="brush: php; title: ; notranslate">
// añadimos luego del Namespace de la Entidad:
use Gedmo\Mapping\Annotation as Gedmo;
</pre>
<p>Algunos Behaviors como Loggable disponen de Entidades propias que requieren crearse en base de datos, para garantizar ello solo debemos ejecutar en consola el comando siguiente, de este modo Doctrine creará las tablas necesarias para almacenar los datos generados por los comportamientos que lo requieran:</p>
<div class="codigo">
<pre>~$ php app/console doctrine:schema:update --force</pre>
</div>
<p><strong>Sluggable</strong>: Permite que Doctrine cree automáticamente el “slug” o la típica cadena optimizada para buscadores utilizada comúnmente al indexar artículos de un blog. Para definir el slug debemos tener un <em>campo destino</em> que es donde se almacenará y uno o más <em>campos origen</em> (los Sluggable) de los cuales se construirá el slug y es tan simple como agregar los siguientes <strong>Metadatos</strong> a nuestros campos del modelo:</p>
<pre class="brush: php; title: ; notranslate">
    // … dentro de una Entidad
    // Campo origen:
    /**
     * @var string $title
     *
     * @ORM\Column(name=&quot;title&quot;, type=&quot;string&quot;, length=255)
     * @Gedmo\Sluggable()
     */
    private $title;

    // … otras variables

    // Campo Destino:
    /**
     * @var string $slug
     *
     * @ORM\Column(name=&quot;slug&quot;, type=&quot;string&quot;, length=255)
     * @Gedmo\Slug(style=&quot;camel&quot;, separator=&quot;_&quot;, updatable=false, unique=true)
     */
    private $slug;
    // … dentro de una Entidad
</pre>
<p>Note que el campo desde donde se creará el slug ($title) tiene el Metadato @Gedmo\Sluggable(), de hecho puede definir más de uno. En cambio el campo de destino ($slug) tiene el Metadato @Gedmo\Slug(&#8230;) y por convención debe ser uno solo, los argumentos style, separator, updatable y unique son opcionales y se detallan en la documentación propia del autor, en este ejemplo se tiene una forma básica de configuración.</p>
<p>Cada vez que se cree un registro de la entidad, Doctrine automáticamente generará el slug y lo aplicará al campo destino, en el caso de modificaciones depende del valor del argumento updatable.<br />
<strong></strong></p>
<p><strong>Timestampable:</strong> permite que Doctrine gestione la actualización del Timestamp en campos específicos al realizar operaciones de inserción y/o actualización. Para definir un campo con Timestampable solo debemos añadir el Metadato Gedmo\Timestampable(on=&#8221;action&#8221;), donde <em>action</em> puede ser created o updated respectivamente.</p>
<pre class="brush: php; title: ; notranslate">
    // … dentro de una Entidad
    // Campo created:
    /**
     * @var date $created
     *
     * @ORM\Column(name=&quot;created&quot;, type=&quot;date&quot;)
     * @Gedmo\Timestampable(on=&quot;create&quot;)
     */
    private $created;
    // Campo updated:
    /**
     * @var datetime $updated
     *
     * @ORM\Column(name=&quot;updated&quot;, type=&quot;datetime&quot;)
     * @Gedmo\Timestampable(on=&quot;update&quot;)
     */
    private $updated;
    // … dentro de una Entidad
</pre>
<p>Doctrine automáticamente aplicará un nuevo Date al campo definido on=”create” al crear un nuevo registro de la entidad y actualizará el Timestamp del campo definido on=”update” al actualizar el registro de la entidad.</p>
<p><strong>Loggable</strong>: permite que Doctrine lleve un control de Versiones sobre los campos indicados, permitiendo consultar las versiones y revertir hacia una versión anterior.<br />
Para crear campos con <em>log</em> (control de versión) solo debemos añadir a cada campo el Metadato @Gedmo\Versioned(), además de añadir el Metadato @Gedmo\Loggable() a la Entidad correspondiente:</p>
<pre class="brush: php; title: ; notranslate">
// ... encabezados del archivo
// definimos el Metadato @Gedmo\Loggable() a la Entidad:
/**
 * MDW\BlogBundle\Entity\Articles
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass=&quot;MDW\BlogBundle\Entity\ArticlesRepository&quot;)
 * @Gedmo\Loggable()
 */
class Articles
{
    // … dentro de una Entidad
    // Campo $content será Versionable:
    /**
     * @var text $content
     *
     * @ORM\Column(name=&quot;content&quot;, type=&quot;text&quot;)
     * @Gedmo\Versioned()
     */
    private $content;
    // … demás contenido de la entidad
</pre>
<p>Doctrine automáticamente supervisará los updates hacia los atributos marcados como Versioned de  la entidad y llevará un control de versiones en la Entidad (Stof\DoctrineExtensionsBundle\Entity\LogEntry), y gracias al Repositorio de dicha entidad (\Gedmo\Loggable\Entity\Repository\LogEntryRepository) podremos consultar las Versiones e incluso Revertir los cambios (función $logRepositoryInstance-&gt;revert($Entity, $version);), aquí apreciamos un ejemplo de un controlador que lista los cambios:</p>
<pre class="brush: php; title: ; notranslate">
    // Ejemplo dentro de un Controller:
    public function updateArticleAction($id) {
      $em = $this-&gt;getDoctrine()-&gt;getEntityManager();

      $article = $em-&gt;getRepository('MDWBlogBundle:Articles')-&gt;findOneBy(array('id' =&gt; $id));

      $article-&gt;setContent('editado');
      $em-&gt;persist($article);
      $em-&gt;flush();

      $content = '';
      // ver cambios
      $log = $em-&gt;getRepository('Stof\DoctrineExtensionsBundle\Entity\LogEntry');
      /* @var $log \Gedmo\Loggable\Entity\Repository\LogEntryRepository */

      $query_changues = $log-&gt;getLogEntriesQuery($article); //use $log-&gt;getLogEntries() para un result directo
      $changues = $query_changues-&gt;getResult();
      /* @var $version Stof\DoctrineExtensionsBundle\Entity\LogEntry */
      foreach ($changues as $version) {
        $fields = $version-&gt;getData();
        $content.= ' fecha: ' .
            $version-&gt;getLoggedAt()-&gt;format('d/m/Y H:i:s') .
            ' accion: &quot;'  . $version-&gt;getAction() . '&quot;'.
            ' usuario: &quot;' . $version-&gt;getUsername() . '&quot;'.
            ' objeto: &quot;'  . $version-&gt;getObjectClass() . '&quot;'.
            ' id: &quot;'      . $version-&gt;getObjectId() . '&quot;'.
            ' Version: &quot;' . $version-&gt;getVersion() . '&quot;'.
            ' datos:';
            foreach ($fields as $field =&gt; $value) {
              $content.= &quot;-- &quot; . $field . ': '. $value . '';
            }
      }
      // generamos una salida básica
      $r = new \Symfony\Component\HttpFoundation\Response();
      $r-&gt;setContent($content);
      return $r;
    }
</pre>
<p>De esta forma podemos aprovecharnos de algunos de los comportamientos más utilizados de Doctrine, reutilizar código y automatizar tareas en nuestros modelos.</p>
<h3>Resumen Final</h3>
<p>Como pudimos apreciar con Symfony2 disponemos de una amplia variedad de bundles de terceros a incluir para extender las capacidades de nuestras aplicaciones, aprovechar y reutilizar código mejorando considerablemente el tiempo en el desarrollo de nuestros proyectos; aprendimos que existen diversas formas de incluir nuestros bundles y que en dado caso podemos hacer instalaciones a mano, también de lo importante que es seguir la documentación de cada bundle para agregarlo en el Autoload o Kernel según corresponda y aplicar las configuraciones requeridas por el mismo.</p>
<hr /><p style="height: 64px;"><img alt='Maycol Alvarez' src='http://0.gravatar.com/avatar/0457a9460a25fb50aca9a46f561f37c9?s=64&amp;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&amp;r=G' class='avatar avatar-64 photo' height='64' width='64' style="float:left;padding:0 5px" /> <strong>Maycol Alvarez</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-instlando-bundles-de-terceros/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-instlando-bundles-de-terceros/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/curso-symfony2-instlando-bundles-de-terceros/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:thumbnail url="http://0.gravatar.com/avatar/0457a9460a25fb50aca9a46f561f37c9?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" />
		<media:content url="http://0.gravatar.com/avatar/0457a9460a25fb50aca9a46f561f37c9?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" medium="image">
			<media:title type="html">Maycol Alvarez</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Curso Django: El Shell de Django</title>
		<link>http://www.maestrosdelweb.com/editorial/curso-django-el-shell-de-django/</link>
		<comments>http://www.maestrosdelweb.com/editorial/curso-django-el-shell-de-django/#comments</comments>
		<pubDate>Mon, 14 May 2012 17:14:50 +0000</pubDate>
		<dc:creator>Sergio Infante Montero</dc:creator>
				<category><![CDATA[django]]></category>
		<category><![CDATA[Editorial]]></category>
		<category><![CDATA[curso django]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24410</guid>
		<description><![CDATA[En el capítulo anterior, vimos lo fácil que es crear un modelo con Django, en este capítulo veremos que podemos hacer con los modelos. Si llegaste a este capítulo y no leiste los anteriores, quizas lo encuentres un poco dificil de entender, así que dale un vistazo a los capítulos anteriores. Los modelos nos van [...]]]></description>
			<content:encoded><![CDATA[<p>En el <a href="http://www.maestrosdelweb.com/editorial/curso-django-el-modelo-de-datos/">capítulo anterior</a>, vimos lo fácil que es crear un modelo con Django, en este capítulo veremos que podemos hacer con los modelos. Si llegaste a este capítulo y no leiste los anteriores, quizas lo encuentres un poco dificil de entender, así que dale <a href="http://www.maestrosdelweb.com/guias/#guias-django" title="Curso Django en Maestros del Web">un vistazo a los capítulos anteriores</a>.</p>
<p>Los modelos nos van a permitir manipular los datos: registrarlos, editarlos, actualizarlos, consultarlos, eliminarlos y realizar procesos con ellos. Toda está manipulación se reflejará luego en las vistas y posteriormente en las plantillas para mostrar los resultados en el navegador, esta manipulación se le conoce generalmente como: Consultas.</p>
<h2>El Shell</h2>
<p>El Shell es el interprete interactivo de Python, que nos permitirá probar los modelos, hacer consultas, analizar resultados, antes de elaborar las vistas. Es muy útil si queremos ahorrar tiempo al momento de responder a los requerimientos que los usuarios de la aplicación puedan necesitar.</p>
<p>Para poder acceder a la shell, abrimos una terminal o ventana de comandos, y nos ubicamos en la carpeta de proyecto (en donde se encuentre el archivo manage.py) y digitamos:</p>
<div class="codigo">
<pre>python manage.py shell</pre>
</div>
<p>Debemos visualizar el siguiente resultado:</p>
<div id="attachment_24585" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-inicio.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-inicio-450x82.png" alt="Shell" width="450" height="82" class="size-medium wp-image-24585" /></a><p class="wp-caption-text">Shell</p></div>
<p>Lo importante es reconocer los elementos: <a href="http://es.wikipedia.org/wiki/Prompt" title="Prompt">el prompt</a> se representa por &gt;&gt;&gt; y el resultado de nuestras instrucciones se visualizarán en nuevas líneas (sin ningún símbolo previo a ellas)</p>
<h2>Las consultas</h2>
<p>Las consultas en base a los modelos de Django son la base de todo el desarrollo en este framework estas consultas nos pueden permitir saber, por ejemplo, la lista de usuarios, los correos electronicos de los que hacen comentarios, el primero comentario de un artículo, los artículos del mes de mayo, y la lista de posiblidades es larga.</p>
<p>Las consultas <a href="https://docs.djangoproject.com/en/1.4/topics/db/queries/" title="Consultas en Django">están descritas muy claramente en la documentación oficial</a>, para poder hacer esto más simple aquí también usaremos esta pequeña chuleta o cheat sheet como también es conocido.</p>
<div id="attachment_24589" class="wp-caption aligncenter" style="width: 351px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-queries.pdf" target='_blank'><img src="http://www.maestrosdelweb.com/images/2012/05/django-queries-341x450.jpg" alt="Django Queryset CheatSheet" width="341" height="450" class="size-medium wp-image-24589" /></a><p class="wp-caption-text">Django Queryset CheatSheet</p></div>
<p><a href="https://docs.djangoproject.com/en/1.4/ref/models/querysets/" title="Querysets en Django">La referencia de todos estos métodos</a> se encuentran también en la documentación oficial.</p>
<h2>Ejemplos</h2>
<p>Ahora pasamos a lo divertido, <a href="http://neosergio.github.com/recetario_mdw/" title="Recetario de Maestros del Web">seguimos trabajando con nuestro proyecto de ejemplo</a>, para poder realizar algunos ejemplos tenemos que modificar y corregir el <em>models.py</em> y dejarlo así: (ya no existe el modelo Bebida, ya no es necesario, también se debe eliminar cualquier rastro del modelo Bebida de <em>admin.py</em>)</p>
<div id="attachment_24570" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-models-receta.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-models-receta-450x203.png" alt="models.py" width="450" height="203" class="size-medium wp-image-24570" /></a><p class="wp-caption-text">models.py</p></div>
<p>Una vez que tenemos listo el models.py , reiniciamos el modelo (si no recuerdas como reiniciar revisa el capítulo: <a href="http://www.maestrosdelweb.com/editorial/curso-django-el-modelo-de-datos/" title="El modelo de datos Django">El modelo de datos</a>)</p>
<div class="codigo">
<pre>python manage.py reset principal</pre>
</div>
<p>Una vez con los modelos listos, es hora de probar el interprete interactivo (shell). No olvidar que la siguiente instrucción se debe lanzar desde el directorio donde se encuentra el archivo manage.py</p>
<div class="codigo">
<pre>python manage.py shell</pre>
</div>
<p>Una vez dentro del shell, empezamos a importar los modelos, para ello digitamos</p>
<div class="codigo">
<pre>from principal.models import Receta, Comentario</pre>
</div>
<p>Esta instrucción importa todo el modelo al shell. Aquí es donde podemos consultar el contenido de los modelos y otras consultas, la sintaxis es del tipo:</p>
<div class="codigo">
<pre>Nombre_de_modelo.objects.metodo()</pre>
</div>
<p>Donde podemos reemplazar Nombre_de_modelo y método por las diversas opciones que están en el cheatsheet (chuleta)</p>
<div id="attachment_24571" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-01.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-01-450x113.png" alt="all()" width="450" height="113" class="size-medium wp-image-24571" /></a><p class="wp-caption-text">all()</p></div>
<p>En la imagen vemos como resultado una lista vacia [], entonces vamos a agregar elementos, para ello también necesitamos al modelo usuario que ya lo tiene Django, una vez que lo importamos sacamos al usuario cuya llave primaria (pk) sea 1.</p>
<div id="attachment_24569" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-importar-usuario-shell.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-importar-usuario-shell-450x69.png" alt="User.objects.get(pk=1)" width="450" height="69" class="size-medium wp-image-24569" /></a><p class="wp-caption-text">User.objects.get(pk=1)</p></div>
<p>Ahora si introducimos datos a los modelos: (la r es solo una variable cualquiera)</p>
<div id="attachment_24572" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-02.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-02-450x137.png" alt="create()" width="450" height="137" class="size-medium wp-image-24572" /></a><p class="wp-caption-text">create()</p></div>
<p>Y comprobamos que se ha registrado:</p>
<div id="attachment_24573" class="wp-caption aligncenter" style="width: 263px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-03.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-03.png" alt="Receta.objects.all()" width="253" height="67" class="size-full wp-image-24573" /></a><p class="wp-caption-text">Receta.objects.all()</p></div>
<p>Agregamos un comentario a la receta anterior: (la c es solo una variable cualquiera)</p>
<div id="attachment_24574" class="wp-caption aligncenter" style="width: 393px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-04.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-04.png" alt="create() en Comentario" width="383" height="139" class="size-full wp-image-24574" /></a><p class="wp-caption-text">create() en Comentario</p></div>
<p>Agregamos una receta mas: (Se puede escribir todo en una sola línea, yo lo hago para que se vea bien en la imagen)</p>
<div id="attachment_24575" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-05.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-05-450x182.png" alt="create() podría ir en una sola línea" width="450" height="182" class="size-medium wp-image-24575" /></a><p class="wp-caption-text">create() podría ir en una sola línea</p></div>
<p>Sigamos jugando, ahora mostraremos las recetas cuyos ingredientes no empiecen con la letra A: (notar que luego de ingredientes hay <strong>dos</strong> guiones bajos)</p>
<div id="attachment_24576" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-06.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-06-450x55.png" alt="exclude y startswith" width="450" height="55" class="size-medium wp-image-24576" /></a><p class="wp-caption-text">exclude y startswith</p></div>
<p>Ahora las recetas, que mencionen en su preparación la palabra &#8216;tetera&#8217;:</p>
<div id="attachment_24577" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-07.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-07-450x54.png" alt="filter y contains" width="450" height="54" class="size-medium wp-image-24577" /></a><p class="wp-caption-text">filter y contains</p></div>
<p>Y si queremos ordenar alfabéticamente por titulo de receta:</p>
<div id="attachment_24578" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-08.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-08-450x76.png" alt="order_by()" width="450" height="76" class="size-medium wp-image-24578" /></a><p class="wp-caption-text">order_by()</p></div>
<p>Ahora lo invertimos:</p>
<div id="attachment_24579" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-09.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-09-450x60.png" alt="order_by y reverse" width="450" height="60" class="size-medium wp-image-24579" /></a><p class="wp-caption-text">order_by y reverse</p></div>
<p>Mostramos los comentarios de cada receta:</p>
<div id="attachment_24580" class="wp-caption aligncenter" style="width: 405px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-10.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-10.png" alt="filter()" width="395" height="112" class="size-full wp-image-24580" /></a><p class="wp-caption-text">filter()</p></div>
<p>Ahora me gustaría actualizar el titulo &#8216;Huevo Frito&#8217; a la de &#8216;Huevito Frito&#8217;:</p>
<div id="attachment_24581" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-11.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-11-450x62.png" alt="update()" width="450" height="62" class="size-medium wp-image-24581" /></a><p class="wp-caption-text">update()</p></div>
<p>Sigo agregando comentarios a la primera receta y deseo saber cuantos comentarios hay hasta el momento en ambas recetas:</p>
<div id="attachment_24582" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-12.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-12-450x168.png" alt="count()" width="450" height="168" class="size-medium wp-image-24582" /></a><p class="wp-caption-text">count()</p></div>
<p>Agrego un comentario a la segunda receta (un comentario troll) y luego lo elimino:</p>
<div id="attachment_24583" class="wp-caption aligncenter" style="width: 404px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-13.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-13.png" alt="delete()" width="394" height="196" class="size-full wp-image-24583" /></a><p class="wp-caption-text">delete()</p></div>
<p>Ahora deseo saber el nombre de usuario y correo electrónico del usuario que agregó la receta con el título exacto de &#8216;Agua hervida&#8217;:</p>
<div id="attachment_24584" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-14.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-14-450x79.png" alt="Todo está orientado a objetos" width="450" height="79" class="size-medium wp-image-24584" /></a><p class="wp-caption-text">Todo está orientado a objetos</p></div>
<p>Como verán hacer consultas en Django es simple, sin embargo <a href="https://docs.djangoproject.com/en/dev/ref/models/querysets/" title="Django QuerySet API Reference">siempre es bueno tener la documentación a la mano</a>, ya que recordar tantos métodos puede ser tedioso al principio.</p>
<div class='tipexperto'>
<h4>Nota:</h4>
<div class='tipcont'>Las consultas que se realizan en el Shell no se guardan en el proyecto, es por ello que si <a href="http://neosergio.github.com/recetario_mdw/">revisan el repositorio del proyecto de ejemplo</a>, sólo encontraran cambios en models.py y admin.py (retirando la clase Bebida, que ya no es necesaria)</div>
</div>
<p>Las consultas son el paso previo a trabajar con las vistas y las plantillas, nos permitirán entregar a los usuarios del proyecto, la información que requieran. El próximo capítulo será: Las vistas.</p>
<p>Práctica tus propias consultas, juega con los modelos, diviértete, que el momento de aplicarlas serán en el próximo capítulo.</p>
<hr /><p style="height: 64px;"><img alt='Sergio Infante Montero' src='http://1.gravatar.com/avatar/3ca2b43e8aedb28a82fdca67e28281a1?s=64&amp;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&amp;r=G' class='avatar avatar-64 photo' height='64' width='64' style="float:left;padding:0 5px" /> <strong>Sergio Infante Montero</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/curso-django-el-shell-de-django/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/curso-django-el-shell-de-django/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/curso-django-el-shell-de-django/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-inicio-150x129.png" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-inicio.png" medium="image">
			<media:title type="html">django-shell-inicio</media:title>
			<media:description type="html">Shell</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-inicio-150x129.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-queries.jpg" medium="image">
			<media:title type="html">Django Queryset CheatSheet</media:title>
			<media:description type="html">Django Queryset CheatSheet</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-queries-150x150.jpg" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-models-receta.png" medium="image">
			<media:title type="html">models.py</media:title>
			<media:description type="html">models.py</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-models-receta-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-01.png" medium="image">
			<media:title type="html">all()</media:title>
			<media:description type="html">all()</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-01-150x129.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-importar-usuario-shell.png" medium="image">
			<media:title type="html">User.objects.get(pk=1)</media:title>
			<media:description type="html">User.objects.get(pk=1)</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-importar-usuario-shell-150x74.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-02.png" medium="image">
			<media:title type="html">create()</media:title>
			<media:description type="html">create()</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-02-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-03.png" medium="image">
			<media:title type="html">Receta.objects.all()</media:title>
			<media:description type="html">Receta.objects.all()</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-03-150x67.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-04.png" medium="image">
			<media:title type="html">create() en Comentario</media:title>
			<media:description type="html">create() en Comentario</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-04-150x139.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-05.png" medium="image">
			<media:title type="html">create() podría ir en una sola línea</media:title>
			<media:description type="html">create() podría ir en una sola línea</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-05-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-06.png" medium="image">
			<media:title type="html">exclude y startswith</media:title>
			<media:description type="html">exclude y startswith</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-06-150x69.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-07.png" medium="image">
			<media:title type="html">filter y contains</media:title>
			<media:description type="html">filter y contains</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-07-150x69.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-08.png" medium="image">
			<media:title type="html">order_by()</media:title>
			<media:description type="html">order_by()</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-08-150x80.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-09.png" medium="image">
			<media:title type="html">order_by y reverse</media:title>
			<media:description type="html">order_by y reverse</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-09-150x71.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-10.png" medium="image">
			<media:title type="html">filter()</media:title>
			<media:description type="html">filter()</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-10-150x112.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-11.png" medium="image">
			<media:title type="html">update()</media:title>
			<media:description type="html">update()</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-11-150x110.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-12.png" medium="image">
			<media:title type="html">count()</media:title>
			<media:description type="html">count()</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-12-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-13.png" medium="image">
			<media:title type="html">delete()</media:title>
			<media:description type="html">delete()</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-13-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-14.png" medium="image">
			<media:title type="html">Todo está orientado a objetos</media:title>
			<media:description type="html">Todo está orientado a objetos</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-shell-ejemplo-14-150x110.png" />
		</media:content>
		<media:content url="http://1.gravatar.com/avatar/3ca2b43e8aedb28a82fdca67e28281a1?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" medium="image">
			<media:title type="html">Sergio Infante Montero</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Es viernes: Diseña tu portafolio de trabajos</title>
		<link>http://www.maestrosdelweb.com/editorial/disena-tu-portafolio-de-trabajos/</link>
		<comments>http://www.maestrosdelweb.com/editorial/disena-tu-portafolio-de-trabajos/#comments</comments>
		<pubDate>Fri, 11 May 2012 17:32:20 +0000</pubDate>
		<dc:creator>Stephanie Falla Aroche</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Productividad]]></category>
		<category><![CDATA[es viernes!]]></category>
		<category><![CDATA[Freelancer]]></category>
		<category><![CDATA[Portafolio]]></category>
		<category><![CDATA[redes sociales]]></category>
		<category><![CDATA[reputación digital]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24506</guid>
		<description><![CDATA[El portafolio en línea es la mejor forma de mostrarle al mundo tu conocimiento, lo que te apasiona y de lo que eres capaz. Sin embargo, muchos diseñadores, desarrolladores y freelancer al momento de preguntarles sobre su portafolio de trabajo, tienen excusas relacionadas con la falta de tiempo, el exceso de trabajo o incluso muchos [...]]]></description>
			<content:encoded><![CDATA[<p>El <strong>portafolio en línea</strong> es la mejor forma de mostrarle al mundo tu conocimiento, lo que te apasiona y de lo que eres capaz. Sin embargo, muchos diseñadores, desarrolladores y freelancer al momento de preguntarles sobre su portafolio de trabajo, tienen excusas relacionadas con la falta de tiempo, el exceso de trabajo o incluso muchos consideran que no es necesario tenerlo. En la siguiente conferencia sobre <strong>&#8220;Publica tu pasión al mundo&#8221;</strong> compartí algunas referencias de portafolios en la web y los aspectos básicos que debe contemplar un portafolio.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/OUFsNh0i13o" frameborder="0" allowfullscreen></iframe></p>
<p>Insisto en el tema porque recibo mensajes en redes sociales y correos en donde muchas personas quieren conversar sobre trabajo o sus proyectos pero no tienen un enlace que me brinde toda la información. En este mundo tan conectado la mejor forma de comunicarnos es a través de la síntesis de ideas, claras y puntuales que brinden el mensaje adecuado. <strong>Tu portafolio en línea es la mejora carta de presentación profesional</strong>, tu reputación digital es tan valiosa como tu reputación profesional y las referencias de trabajo.</p>
<h3>El portafolio y la reputación digital</h3>
<p><img src="http://www.maestrosdelweb.com/images/2008/12/promover-redes.jpg" alt="El portafolio y la reputación digital" style="float:right;padding:5px" />En el mundo web el portafolio y la proyección en las rede sociales es fundamental, debido a que es muy sencillo escribir tu nombre en un buscador, hacernos una idea de tu trabajo y del tipo de persona que eres. Al inicio, la gente creía que en Internet era libre y anónimo con el tiempo las redes sociales nos volvieron más visibles con nombre y apellido de tal forma que hemos construido a lo largo de nuestras cuentas una reputación digital. </p>
<ul>
<li><a href="http://www.maestrosdelweb.com/editorial/%C2%BFtienes-tu-portafolio-en-la-web/">¿Tienes tu portafolio en la web?</a> Conoce las razones por las que un portafolio en línea es indispensable para todo freelancer e inspirate en una serie de referencias. </li>
<li><a href="http://www.maestrosdelweb.com/editorial/es-viernes-freelance-proyeccion-en-redes-sociales/">La proyección en redes sociales:</a> Todo comentario, aporte o publicación en la web con tu nombre o nickname se encuentra registrado en los buscadores. Tus cuentas en redes sociales son parte de tu identidad digital y por ello debes comprender cuál es la mejor forma de proyectarse.</li>
<li><a href="http://www.maestrosdelweb.com/editorial/tips-para-promover-tu-trabajo-en-la-web/">Tips para promover tu trabajo en la web:</a> En otra ocasión compartí sobre la importancia del portafolio y las redes sociales para promover tu trabajo. Pero, también existen algunos tips que expertos en el medio nos han aportado para implementar como el regalar algo a la comunidad.</li>
<li><a href="http://www.maestrosdelweb.com/editorial/creativos-y-hermosos-portafolios/">Inspírate y diseña tu portafolio:</a> Nunca está de más tener referencias del trabajo de otros, ver cómo lo han logrado los demás y revisar estás fuentes puede ser el primer paso para saber por dónde empezar nuestro proyecto de portafolio de evidencias.</li>
</ul>
<h3>Más portafolios de inspiración</h3>
<ul>
<li><a href="http://www.wellsriley.com/">Wellsriley.com</a>: Wells Rilley, diseñador de experiencias. En su portafolio hace uso de tecnologías, diseño, con información clara y puntual. </li>
<li><a href="http://www.lahive.co.uk/about/">Lahive.co.uk</a>: Steve, diseñador y de una forma muy minimalista nos muestra su trabajo y la información de contacto. </li>
<li><a href="http://attackemart.in/">Attackemart.in</a>: Martin Gaue, con su portafolio simplemente nos hace vivir una experiencia del uso de tecnologías y nos despierta la curiosidad. </li>
<li><a href="http://www.stedesign.com/">Stedesign.com:</a> Muestra de un portafolio en una sola página, algo que se está poniendo muy de moda y que ahorra una serie de navegación y links.</li>
</ul>
<p><a href="http://www.Attackemart.in"><img src="http://www.maestrosdelweb.com/images/2012/05/portafolio-android.png" alt="Portafolio" /></a></p>
<p>Debemos superar el curriculum vitae e incursionar en el portafolio de evidencias de nuestra experiencia y capacidad. El conocimiento aplicado, sin duda resulta más atractivo en esta industria en donde necesitamos obtener resultados y menos procesos teóricos para ejecutar proyectos, realizar innovación y ser cada vez más competitivos en el medio. Si aún no tienes un portafolio <strong>hoy es un buen momento para inspirarte y empezar un nuevo proyecto</strong>, que con el tiempo, tendrá sus beneficios y será más práctico al momento de presentarte como freelancer. Feliz fin de semana. Enjoy!</p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/128.png" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Stephanie Falla Aroche</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/disena-tu-portafolio-de-trabajos/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/disena-tu-portafolio-de-trabajos/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/disena-tu-portafolio-de-trabajos/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2008/12/promover-redes.jpg" />
		<media:content url="http://www.maestrosdelweb.com/images/2008/12/promover-redes.jpg" medium="image">
			<media:title type="html">El portafolio y la reputación digital</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/portafolio-android.png" medium="image">
			<media:title type="html">Portafolio</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/128.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Curso Symfony 2: Integrando jQuery</title>
		<link>http://www.maestrosdelweb.com/editorial/curso-symfony-2-integrando-jquery/</link>
		<comments>http://www.maestrosdelweb.com/editorial/curso-symfony-2-integrando-jquery/#comments</comments>
		<pubDate>Wed, 09 May 2012 07:00:25 +0000</pubDate>
		<dc:creator>Maycol Alvarez</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[curso]]></category>
		<category><![CDATA[ejemplos]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[symfony2]]></category>
		<category><![CDATA[vistas]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24420</guid>
		<description><![CDATA[En esta ocasión y motivado a sus peticiones con respecto al capítulo &#8220;Integrando AJAX&#8221; les traemos 2 ejemplos, elaborados con la participación de Juan Ardissone y mi persona, con el objetivo de aclarar sus dudas con respecto al manejo de AJAX en Symfony2 y darles ejemplos prácticos de su uso. Como mencioné anteriormente Symfony2 es [...]]]></description>
			<content:encoded><![CDATA[<p>En esta ocasión y motivado a sus peticiones con respecto al capítulo &#8220;<a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-integrando-ajax/">Integrando AJAX</a>&#8221; les traemos 2 ejemplos, elaborados con la participación de <a href="http://www.maestrosdelweb.com/author/jardissone/">Juan Ardissone</a> y mi persona, con el objetivo de aclarar sus dudas con respecto al manejo de AJAX en Symfony2 y darles ejemplos prácticos de su uso.</p>
<p>Como mencioné anteriormente Symfony2 es un Framework PHP orientado al desarrollo en el servidor, por su parte AJAX es una técnica que se implementa desde el JavaScript (JS) cliente, cuyo único objetivo es realizar las peticiones HTTP desde JavaScript y obtener la respuesta para manipularla directamente, sea añadiéndola al DOM o lo que quieras con JavaScript, por lo cual en dicho caso tanto Symfony2 como PHP sólo pueden detectar si la petición fue realizada por dicha técnica, razón por la cual su implementación es realmente simple; también aclaramos que desde su versión 1.3 el proyecto Symfony ha optado por no apoyar ni integrar ningún Framework JS, debido a que ello queda a elección del programador.</p>
<p>En esta continuación del capítulo anterior elegimos a jQuery como el Framework JS a utilizar para los ejemplos, por ser uno de los más populares y fáciles de implementar, reiteramos que puedes usar el FW JS que desees y queda bajo tu absoluta elección, además aclaro que los ejemplos se concentran en el uso de AJAX con jQuery y que para conservar la facilidad con la que implementen los ejemplos no se usaron modelos reales de doctrine, en su caso arrays multidimensionales, si quieren complementarlos con Doctrine, pueden consultar su capítulo: <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-configurando-bases-de-datos/">Configurando nuestra Base de Datos</a>.</p>
<h3>Ejemplo 1: Ejecutando una llamada ajax con jQuery</h3>
<p>Descargamos el script de la página de jQuery y la guardamos en el directorio web\js\. Para este caso la versión actual es jquery-1.7.2.min.js.</p>
<p>Importamos el archivo dentro del template base que se encuentra en app\Resources\views\base.html.twig:</p>
<div class="codigo">
<pre>&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
        &lt;title&gt;{% block title %}Welcome!{% endblock %}&lt;/title&gt;
        {% block stylesheets %}{% endblock %}
        &lt;link rel="shortcut icon" href="{{ asset('favicon.ico') }}" /&gt;
                &lt;script src="{{ asset('js/jquery-1.7.2.min.js') }}"&gt;&lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
        {% block body %}{% endblock %}
        {% block javascripts %}{% endblock %}
    &lt;/body&gt;
&lt;/html&gt;</pre>
</div>
<p>Con esto ya tenemos el soporte para jQuery en todas nuestras páginas que hereden mediante Twig a este template.</p>
<p>Ya teníamos la página http://localhost/Symfony/web/app_dev.php/articulos/listar que nos mostraba una lista de artículos de la base de datos por lo que podemos hacer otra que simplemente llame por ajax a esta página y muestre los artículos. Para esto creamos la página ver-articulos que simplemente tendrá una link para cargar por ajax el contenido de la página que contiene la lista de artículos. Como cada vez que necesitamos crear una página hacemos los 3 pasos:</p>
<p><strong>CREAMOS LA RUTA</strong></p>
<p>Agregamos a nuestro archivo routing.yml las siguientes líneas para crear la nueva ruta:</p>
<div class="codigo">
<pre>ver_articulos:
    pattern:  /ver-articulos
    defaults: { _controller: MDWDemoBundle:Articulos:verArticulos }</pre>
</div>
<p><strong>CREAMOS EL ACTION</strong></p>
<div class="codigo">
<pre>//Dentro del controlador src\MDW\DemoBundle\Controller\ArticulosController.php agregamos el siguiente action
public function verArticulosAction()
{
        return $this-&gt;render('MDWDemoBundle:Articulos:ver_articulos.html.twig', array());
}</pre>
</div>
<p>Como podemos ver lo único que hace es llamar a la vista que creamos a continuación.</p>
<p><strong>CREAMOS LA VISTA</strong></p>
<p>Creamos el archivo ver_articulos.html.twig dentro de la carpeta src\MDW\DemoBundle\Resources\views\Articulos</p>
<div class="codigo">
<pre>{% extends '::base.html.twig' %}

{% block title %}Symfony - AJAX{% endblock %}

{% block body %}

&lt;div id="articulos"&gt;&lt;/div&gt;
&lt;a id="link_articulos" href="#"&gt;Cargar articulos&lt;/a&gt;

{% endblock %}

{% block javascripts %}
&lt;script&gt;

$(document).ready(function(){
        $('#link_articulos').click(function(){
                $('#articulos').load('{{ path('articulo_listar') }}');
        });
});

&lt;/script&gt;
{% endblock %}</pre>
</div>
<p>En esta página hemos heredado el contenido de template base con el extend y hemos incluído los bloques. Vemos que en el body lo único que tenemos es un div vacío con id &#8220;articulos&#8221; y link con id &#8220;link_articulos&#8221; para obtenerlo utilizamos jQuery. La idea es que al ingresar a la página solo nos muestre el link y no así los artículos. Al dar click sobre el link &#8220;Cargar Artículos&#8221; se ejecutará una llamada ajax mediante jQuery y cargaremos asincrónicamente la ruta {{ path(&#8216;articulo_listar&#8217;) }} que sería la página que ya tenemos lista y que vimos en el <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-manipulando-datos-con-doctrine/">capítulo 9 &#8211; Manipulando datos con Doctrine</a>.</p>
<p>Entendamos el código jQuery:</p>
<div class="codigo">
<pre>&lt;script&gt;

$(document).ready(function(){
        $('#link_articulos').click(function(){
                $('#articulos').load('{{ path('articulo_listar') }}');
        });
});

&lt;/script&gt;</pre>
</div>
<p>Primeramente registramos el evento ready para que ejecute la función anónima una vez que todo el DOM sea cargado.</p>
<p>Una vez ejecutado el evento ready, agregamos una acción al evento click de nuestro link que ejecutará la función que carga la segunda página:</p>
<div class="codigo">
<pre>$('#link_articulos').click(function(){
        $('#articulos').load('{{ path('articulo_listar') }}');
});</pre>
</div>
<p>La función load() de jQuery se ejectua sobre el div vacío para que el resultado de la respuesta Ajax se cargue dentro de este div y como argumento del método pasamos la dirección en donde, para no escribir la URL a mano, usamos la función Twig {{ path(&#8216;articulo_listar&#8217;) }} para que los genere la ruta relativa de la ruta articulo_listar.</p>
<p>Con esto ya podemos acceder a la página http://localhost/Symfony/web/app_dev.php/ver-articulos donde veremos un link &#8220;Cargar artículos&#8221;. Presionando el link veremos como se obtiene, sin recargar la página, el listado de artículos de la base de datos.</p>
<h3>Ejemplo 2: Gestionando llamadas AJAX con jQuery, Twig y herencia en 3 niveles</h3>
<p>En el ejemplo anterior apreciamos lo sencillo que es implementar una llamada AJAX por medio del FW jQuery y comprendimos que en realidad Symfony2 interviene prácticamente en nada porque su alcance se limita al desarrollo del lado del servidor, en este ejemplo práctico haremos uso de las facilidades que brinda Symfony para detectar peticiones AJAX y modificar la respuesta en función de las necesidades.</p>
<p>Para este ejemplo crearemos una sección o módulo de noticias, en donde nos aparece un listado principal de noticias de las cuales al hacer click nos redirigirá al detalle de la noticia como tal. La idea es conservar un enlace directo a cada noticia, con el cual un motor de búsqueda pueda indexar y a su vez cargar el detalle de la noticia en una capa por medio de AJAX (con load jQuery) con el objetivo de que el usuario pueda cargar las noticias sin recargar la página y si en caso llega desde un buscador pueda apreciar la noticia y el resto de contenidos que ofrezca nuestro layout principal.</p>
<p>Para ello creamos primero nuestro layout:</p>
<div class="codigo">
<pre>{# /src/MDW/DemoBundle/views/layout.html.twig #}
{% extends '::base.html.twig'  %} {# extendemos del layout por defecto #}

{% block javascripts %}
{# añadimos la CDN de jQuery o en su defecto lo descargamos e incluimos con:
&lt;script src="{{ asset('js/jquery-1.7.2.min.js') }}"&gt;&lt;/script&gt;
 #}
&lt;script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"&gt;&lt;/script&gt;
{% endblock javascripts %}

{# creamos una estructura para el layout general #}
{% block body %}
&lt;div&gt;
    &lt;h1&gt;*** Web de Noticias ***&lt;/h1&gt;
    {# según el patrón de 3 niveles, creamos el bloque de contenido #}
    {% block content %}{% endblock content %}
&lt;/div&gt;
{% endblock body%}</pre>
</div>
<p>Procedemos ahora a crear las rutas hacia nuestro controlador, abre el src/MDW/DemoBundle/Resources/config/routing.yml y agrega:</p>
<div class="codigo">
<pre># /src/MDW/DemoBundle/Resources/config/routing.yml

MDWDemoBundle_noticias:
    pattern:  /noticias
    defaults: { _controller: MDWDemoBundle:Notice:index }

MDWDemoBundle_noticeView:
    pattern:  /leerNoticia/{notice_id}
    defaults: { _controller: MDWDemoBundle:Notice:noticeView }</pre>
</div>
<p>Procedemos ahora a crear el controlador, en este ejemplo utilizaremos como Modelo un array de noticias, para enfocarnos en el uso de AJAX:</p>
<div class="codigo">
<pre>&lt;?php
// src/MDW/DemoBundle/Controller/NoticeController.php
namespace MDW\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class NoticeController extends Controller
{
    // tenemos un array con los datos básicos
    private $array_notice = array(
        array(
            'title' =&gt; 'Titulo de noticia 0',
            'content' =&gt; 'Contenido de noticia 0'
        ),
        array(
            'title' =&gt; 'Titulo de noticia 1',
            'content' =&gt; 'Contenido de noticia 1'
        ),
    );    

    public function indexAction()
    {
        // suponiendo que obtenemos del modelo el listado de noticias
        return $this-&gt;render('MDWDemoBundle:Notice:index.html.twig', array(
            'notices' =&gt; $this-&gt;array_notice
        ));
    }

    public function noticeViewAction($notice_id)
    {
        //obtenemos la noticia del modelo, en este ejemplo proviene de un array
        $notice = $this-&gt;array_notice[$notice_id];
        return $this-&gt;render('MDWDemoBundle:Notice:noticeView.html.twig', array(
            'notice' =&gt; $notice
        ));
    }
}</pre>
</div>
<p>Procedemos ahora a crear las vistas principales:</p>
<div class="codigo">
<pre>{# src/MDW/DemoBundle/Resources/views/Notice/index.html.twig #}

{% extends 'MDWDemoBundle::layout.html.twig'  %}
{% block content %}
&lt;div&gt;
    &lt;p&gt;Noticias recientes&lt;/p&gt;
    &lt;ol&gt;
        {% for index,notice in notices %}
        &lt;li&gt;&lt;a href="{{ path('MDWDemoBundle_noticeView', {'notice_id': index}) }}"&gt;{{notice.title}}&lt;/a&gt;&lt;/li&gt;
        {% endfor %}
    &lt;/ol&gt;
    &lt;div id="notice_viewer"&gt;
    {# en esta capa serán cargadas las noticias por ajax #}
    &lt;/div&gt;
&lt;/div&gt;
{% endblock content %}

{# extendemos el bloque javascript #}
{% block javascripts %}
{{parent()}} {# incluimos las declaraciones de script del layout, como jQuery #}

&lt;script type="text/javascript"&gt;
{# añadirmos una función al evento click de todos los enlaces a.notice_link, para
usar AJAX en vez de su comportamiento por defecto #}
$(document).ready(function(){
    $('a.notice_link').click(function(event){
        event.preventDefault(); //cancela el comportamiento por defecto
        $('#notice_viewer').load($(this).attr('href')); //carga por ajax a la capa "notice_viewer"
    });
});
&lt;/script&gt;
{% endblock javascripts %}</pre>
</div>
<p>Como puede notar en index.html.twig se ha extendido el bloque JavaScript para añadir la carga por medio de jQuery.load (AJAX) hacia la capa DIV “notice_viewer”, esto con el objetivo de que si un buscador indexa nuestra página pueda hallar los links íntegros de las noticias sin afectar al SEO, además de que nos permite cargar por AJAX el contenido de nuestras noticias directamente en la capa asignada.</p>
<div class="codigo">
<pre>{# src/MDW/DemoBundle/Resources/views/Notice/noticeView.html.twig #}

{# note que en este caso utilizamos el layout de ajax para así no cargar todo el contenido del layout general #}
{% extends app.request.isXmlHttpRequest ? "MDWDemoBundle::layout_ajax.html.twig" : "MDWDemoBundle::layout.html.twig" %}
{% block content %}
&lt;div&gt;
    &lt;h2&gt;{{notice.title}}&lt;/h2&gt;
    &lt;p&gt;{{notice.content}}&lt;/p&gt;
&lt;/div&gt;
{% endblock content %}</pre>
</div>
<p>Como puede apreciar ahora en noticeView.html.twig se hace una bifurcación de los layouts para cuando se trata de una petición AJAX, en la cual se utiliza el layout principal cuando el enlace es accedido directamente (origen de un buscador, o de un usuario con Javascript desactivado) y al contrario si proviene de AJAX se utiliza un layout especial:</p>
<div class="codigo">
<pre>{# /src/MDW/DemoBundle/views/layout_ajax.html.twig #}

{# como puede apreciar, el layout para ajax sólo debe incluir el bloque contenido,
adicionalmente podemos añadir extras #}
&lt;div&gt;
    &lt;strong&gt;Visor de Noticias&lt;/strong&gt;
    {% block content %}{% endblock content %}
&lt;/div&gt;</pre>
</div>
<p>De esta forma con Symfony podemos adaptar las respuestas en función de si la petición es AJAX o no, y en este caso devolver sólo el contenido necesario, debido a que en una petición AJAX no es necesario devolver la estructura completa HTML como en una petición normal, sino el fragmento de código que nos interesa.</p>
<h3>CONCLUSIÓN</h3>
<p>Como bien se explica más arriba, las interacciones Ajax no son parte del framework Symfony ya que para esto usamos JavaScript mientras que Symfony es un framework PHP. Existiendo tantas librerías bien robustas para manejo de Ajax como por ejemplo jQuery, incluímos la que más nos guste y ejecutamos la llamada al ajax. La manera de trabajar con librerías JavaScript en Symfony es simplemente incluírlo como un asset de la misma forma que trabajaríamos con las librerías http://www.tinymce.com o http://lightbox.com. Incluímos el archivo y la programación que hacemos para usarla ya es JavaScript y no PHP.</p>
<hr /><p style="height: 64px;"><img alt='Maycol Alvarez' src='http://0.gravatar.com/avatar/0457a9460a25fb50aca9a46f561f37c9?s=64&amp;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&amp;r=G' class='avatar avatar-64 photo' height='64' width='64' style="float:left;padding:0 5px" /> <strong>Maycol Alvarez</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/curso-symfony-2-integrando-jquery/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/curso-symfony-2-integrando-jquery/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/curso-symfony-2-integrando-jquery/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:thumbnail url="http://0.gravatar.com/avatar/0457a9460a25fb50aca9a46f561f37c9?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" />
		<media:content url="http://0.gravatar.com/avatar/0457a9460a25fb50aca9a46f561f37c9?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" medium="image">
			<media:title type="html">Maycol Alvarez</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Curso Django: El modelo de datos</title>
		<link>http://www.maestrosdelweb.com/editorial/curso-django-el-modelo-de-datos/</link>
		<comments>http://www.maestrosdelweb.com/editorial/curso-django-el-modelo-de-datos/#comments</comments>
		<pubDate>Mon, 07 May 2012 13:28:51 +0000</pubDate>
		<dc:creator>Sergio Infante Montero</dc:creator>
				<category><![CDATA[django]]></category>
		<category><![CDATA[Editorial]]></category>
		<category><![CDATA[curso django]]></category>
		<category><![CDATA[datos]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[guia python]]></category>
		<category><![CDATA[modelo]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24336</guid>
		<description><![CDATA[Una vez que ya tenemos instalado Django, creado nuestro primer proyecto y haber revisado como funciona, necesitamos definir el modelo de datos para nuestra aplicación. El Modelo Un modelo es la representación de los datos de nuestra aplicación. Contiene los campos básicos y el comportamiento de los datos que serán almacenados. Por lo general, cada [...]]]></description>
			<content:encoded><![CDATA[<p>Una vez que ya tenemos <a href="http://www.maestrosdelweb.com/editorial/curso-django-instalacion-y-primera-aplicacion/" title="Instalación y primera aplicación Django">instalado Django, creado nuestro primer proyecto</a> y <a href="http://www.maestrosdelweb.com/editorial/curso-django-entendiendo-como-trabaja-django/" title="Entendiendo Django">haber revisado como funciona</a>, necesitamos definir el modelo de datos para nuestra aplicación.</p>
<h2>El Modelo</h2>
<p>Un modelo es la representación de los datos de nuestra aplicación. Contiene los campos básicos y el comportamiento de los datos que serán almacenados. Por lo general, cada modelo se convierte en una tabla de la base de datos.</p>
<h3>Lo fundamental</h3>
<ul>
<li>Cada modelo es una subclase de <strong>django.db.models.Model.</strong></li>
<li>Cada atributo de un modelo representa a un campo de una tabla.</li>
<li>Django automáticamente nos da acceso a la base de datos.</li>
</ul>
<h3>Referencia de los campos</h3>
<p>La referencia de la versión actual esta detallada por completo <a href="https://docs.djangoproject.com/en/1.4/ref/models/fields/" title="Referencia del Modelo en Django">en la documentación del framework</a>, con este recurso podemos elaborar todas las referencias necesarias para el proyecto, sin embargo leerlo por completo puede resultar al principio un poco tedioso.</p>
<p>Para ello siempre es muy útil un cheatsheet o chuleta para poder visualizarlos juntos.</p>
<div id="attachment_24371" class="wp-caption aligncenter" style="width: 328px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-models.jpg" target='_blank'><img src="http://www.maestrosdelweb.com/images/2012/05/django-models-318x450.jpg" alt="Chuleta - Modelos en Django" width="318" height="450" class="size-medium wp-image-24371" /></a><p class="wp-caption-text">Chuleta - Modelos en Django</p></div>
<h3>Ejemplo de modelo en nuestro proyecto</h3>
<p>Vamos con el ejemplo del capítulo para poder entender mejor como va esto del modelo. </p>
<div class="tipexperto">
<h4>Nota</h4>
<div class="tipcont">Para poder continuar con este ejemplo, tienen que seguir el curso desde el primer capítulo y evitar solamente copiar y pegar, escribanlo que es mejor en todo sentido.</div>
</div>
<p>Nuestro archivo: <strong>models.py</strong> de la semana pasada quedó así:</p>
<div class="codigo">
<pre>
from django.db import models

class Bebida(models.Model):
	nombre = models.CharField(max_length=50)
	ingredientes = models.TextField()
	preparacion = models.TextField()

	def __unicode__(self):
		return self.nombre
</pre>
</div>
<p>Este modelo solo fue un ejemplo para saber cómo funcionaba, ahora redactaré algunas líneas que nos ayudarán a tener un modelo más completo:</p>
<div class="codigo">
<pre>
#encoding:utf-8
from django.db import models
from django.contrib.auth.models import User

class Bebida(models.Model):
  nombre = models.CharField(max_length=50)
  ingredientes = models.TextField()
  preparacion = models.TextField()

  def __unicode__(self):
      return self.nombre

class Receta(models.Model):
  titulo = models.CharField(max_length=100, unique=True)
  ingredientes = models.TextField(help_text='Redacta los ingredientes')
  prepacion = models.TextField(verbose_name='Preparación')
  imagen = models.ImageField(upload_to='recetas', verbose_name='Imágen')
  tiempo_registro = models.DateTimeField(auto_now=True)
  usuario = models.ForeignKey(User)

  def __unicode__(self):
      return self.titulo
</pre>
</div>
<p>Son clases en Python (respetar la indentación), les explicaré de que trata todo esto:</p>
<div class="codigo">
<pre>
#encoding:utf-8 &lt;- Esta línea permite usar tíldes y caracteres especiales
from django.db import models &lt;- Clase con la descripción de modelos
from django.contrib.auth.models import User &lt;- Llama al modelo usuario
</pre>
</div>
<p>La clase Bebida de la semana anterior sólo era un ejemplo, no le daremos importancia de ahora en adelante, pasemos con la clase Receta (y sus respectivos comentarios previos a cada línea).</p>
<div class="codigo">
<pre>
#Dato cadena, longitud máxima 100 y único
titulo = models.CharField(max_length=100, unique=True)

#Dato texto, con texto de ayuda
ingredientes = models.TextField(help_text='Redacta los ingredientes')

#Dato texto, con nombre: Preparación
prepacion = models.TextField(verbose_name='Preparación')

#Dato imagen, se almacenarán en la carpeta recetas, titulo: Imágen
imagen = models.ImageField(upload_to='recetas', verbose_name='Imágen')

#Dato Fecha y Hora, almacena la fecha actual
tiempo_registro = models.DateTimeField(auto_now=True)

#Enlace al modelo Usuario que Django ya tiene construido
usuario = models.ForeignKey(User)
</pre>
</div>
<p>La clase Receta (modelo) tiene un atributo imagen, el cuál está direccionando las cargas que haga el usuario a la carpeta &#8216;recetas&#8217; (carpeta que estará dentro de otra llamada: &#8216;carga&#8217;), para que esto funcione debemos modificar nuestro archivo settings.py, exactamente debemos buscar la línea: MEDIA_ROOT (debe ser la número 56 aproximadamente), y dejarla así:</p>
<div class="codigo">
<pre>
MEDIA_ROOT = os.path.join(RUTA_PROYECTO,'carga')
</pre>
</div>
<p>Luego de haber puesto esta línea, debemos crear una carpeta que se llame &#8216;carga&#8217; dentro de la carpeta del proyecto. Debemos tener un árbol de ficheros de este tipo:</p>
<div id="attachment_24392" class="wp-caption aligncenter" style="width: 131px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-tree-directory.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-tree-directory-121x450.png" alt="Mapa de ficheros del proyecto recetario" width="121" height="450" class="size-medium wp-image-24392" /></a><p class="wp-caption-text">Mapa de ficheros del proyecto recetario</p></div>
<p>Dentro de esta carpeta &#8216;carga&#8217; aparecerá una carpeta &#8216;recetas&#8217; al momento de guardar un registro. Pero antes de ello debemos buscar el archivo admin.py y dejarlo asi:</p>
<div class="codigo">
<pre>
from principal.models import Bebida, Receta
from django.contrib import admin

admin.site.register(Bebida)
admin.site.register(Receta)
</pre>
</div>
<p>Esto nos permitirá agregar el modelo Receta dentro de la interfaz administrativa.</p>
<p>Por último debemos habilitar las URL para poder visualizar las imágenes, para ello debemos dejar el archivo urls.py asi:</p>
<div class="codigo">
<pre>
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf import settings

admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$','principal.views.lista_bebidas'),
    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^media/(?P.*)$','django.views.static.serve',
		{'document_root':settings.MEDIA_ROOT,}
	),
)
</pre>
</div>
<p>Esto nos permitirá acceder a las imágenes que subamos desde http://127.0.0.1:8000/media/recetas/nombre-imagen.jpg (o cualquier otra imagen).</p>
<h3>Poniendo a correr todo</h3>
<p>Para hacer funcionar todo, debemos sincronizar la base de datos nuevamente (esto se debe hacer cada vez que se modifique el modelo).</p>
<div class="tipexperto">
<h4>Nota</h4>
<div class="tipcont">Toda ejecución de comando se debe hacer desde una terminal o ventana de comando y dentro de la carpeta del proyecto (donde se encuentra el archivo manage.py)</div>
</div>
<div class="codigo">
<pre>
python manage.py syncdb
</pre>
</div>
<p>Y esto nos debe mostrar un resultado así (prestar atención a la segunda línea):<br />
<div id="attachment_24391" class="wp-caption aligncenter" style="width: 408px"><a href="http://www.maestrosdelweb.com/images/2012/05/django-models-syncdb.png"><img src="http://www.maestrosdelweb.com/images/2012/05/django-models-syncdb.png" alt="python manage.py syncdb" width="398" height="111" class="size-full wp-image-24391" /></a><p class="wp-caption-text">python manage.py syncdb</p></div></p>
<p>En caso de que queramos modificar un modelo ya existente podemos también reiniciar todos los modelos de la aplicación principal así:</p>
<div class="codigo">
<pre>
python manage.py reset principal
</pre>
</div>
<p>Sin embargo si ya se tienen datos almacenados estos se perderán al momento de reiniciarlos, para evitar eso podemos usar aplicaciones como <a href="http://south.aeracode.org/" title="South para Django">South</a>, que nos permitirán trabajar con los datos de manera más profesional. Aquí un video de ejemplo:</p>
<span style="text-align:center; display: block;"><a href="http://www.maestrosdelweb.com/editorial/curso-django-el-modelo-de-datos/"><img src="http://img.youtube.com/vi/s41rV2kfRPI/2.jpg" alt="" /></a></span>
<h3>Probando el ejemplo</h3>
<p>Ya tenemos todo listo, el modelo nuevo sincronizado, las configuraciones listas y la interfaz administrativa. Corremos el proyecto:</p>
<div class="codigo">
<pre>
python manage.py runserver
</pre>
</div>
<p>Entramos a http://127.0.0.1:8000/admin y debemos observar el nuevo modelo: Recetas, listo para ser usado. Para ver las imágenes que se van cargando podemos ir a http://127.0.0.1:8000/media/recetas/nombre-imagen.jpg y si son proactivos, pueden modificar la plantilla de la semana pasada para poder ver el nuevo modelo de Recetas y sus imágenes, o pueden crear nuevos modelos para ver como pueden interactuar entre sí.</p>
<p>No se olviden que pueden revisar el <a href="http://neosergio.github.com/recetario_mdw" title="Recetario para Maestros del Web">repositorio del proyecto en github</a> si desean comprobar como deben quedar los archivos (en orden y en contenido). </p>
<p>La próxima semana sabremos que hacer con estos modelos y como interactuar con sus datos, lo haremos a través de la Shell de Django.</p>
<p>Que tengan un buen inicio de semana con Django, no se olviden comentar, twittear y hacer todas sus consultas, para poder ayudarlos.</p>
<hr /><p style="height: 64px;"><img alt='Sergio Infante Montero' src='http://1.gravatar.com/avatar/3ca2b43e8aedb28a82fdca67e28281a1?s=64&amp;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&amp;r=G' class='avatar avatar-64 photo' height='64' width='64' style="float:left;padding:0 5px" /> <strong>Sergio Infante Montero</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/curso-django-el-modelo-de-datos/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/curso-django-el-modelo-de-datos/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/curso-django-el-modelo-de-datos/feed/</wfw:commentRss>
		<slash:comments>56</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-models-150x150.jpg" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-models.jpg" medium="image">
			<media:title type="html">Chuleta &#8211; Modelos en Django</media:title>
			<media:description type="html">Chuleta - Modelos en Django</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-models-150x150.jpg" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-tree-directory.png" medium="image">
			<media:title type="html">Mapa de ficheros del proyecto recetario</media:title>
			<media:description type="html">Mapa de ficheros del proyecto recetario</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-tree-directory-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/django-models-syncdb.png" medium="image">
			<media:title type="html">python manage.py syncdb</media:title>
			<media:description type="html">python manage.py syncdb</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/django-models-syncdb-150x111.png" />
		</media:content>
		<media:content url="http://img.youtube.com/vi/s41rV2kfRPI/2.jpg" medium="image" />
		<media:content url="http://1.gravatar.com/avatar/3ca2b43e8aedb28a82fdca67e28281a1?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" medium="image">
			<media:title type="html">Sergio Infante Montero</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Es viernes: ¿Cómo despejar la mente y concretar ideas?</title>
		<link>http://www.maestrosdelweb.com/editorial/como-despejar-la-mente-y-concretar-ideas/</link>
		<comments>http://www.maestrosdelweb.com/editorial/como-despejar-la-mente-y-concretar-ideas/#comments</comments>
		<pubDate>Fri, 04 May 2012 07:00:08 +0000</pubDate>
		<dc:creator>Stephanie Falla Aroche</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Productividad]]></category>
		<category><![CDATA[es viernes!]]></category>
		<category><![CDATA[Freelancer]]></category>
		<category><![CDATA[metas]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24357</guid>
		<description><![CDATA[En la actualidad estamos tan saturados de información, trabajo, estímulos visuales y auditivos. Sales a la calle y escuchas las bocinas de los automóviles, sientes el olor de la ciudad y respiras la contaminación, miras el entorno saturado de imágenes, anuncios y marcas que buscan el top on mind. Pareciera que necesitamos de ese ruido [...]]]></description>
			<content:encoded><![CDATA[<p>En la actualidad estamos tan saturados de información, trabajo, estímulos visuales y auditivos. Sales a la calle y escuchas las bocinas de los automóviles, sientes el olor de la ciudad y respiras la contaminación, miras el entorno saturado de imágenes, anuncios y marcas que buscan el top on mind. Pareciera que necesitamos de ese ruido de fondo como una manifestación de la existencia, de lo real y cotidiano. Pero, entre tanto estímulo, distracción y ocupaciones <strong>¿cómo logramos despejar la mente?</strong> ¿encontrar nuestros pensamientos? <strong>¿volver realidad muchas de esas ideas? </strong>¿concretar proyecto?</p>
<p><a href="http://www.flickr.com/photos/grahamking/826142536/"><img src="http://www.maestrosdelweb.com/images/2012/05/yoga.png" alt="Despejar la mente" /><br />
</a><br />
Con todas estas <a href="http://www.maestrosdelweb.com/editorial/distracciones-limitacion-productividad-teletrabajo/">distracciones</a> del día a día es fácil perder el enfoque, dejar pasar el tiempo y simplemente nos convertimos en espectadores de como las ideas, sueños y proyectos de los demás se van concretando. Pensamos, yo también tengo muchas ideas, pero no tengo tiempo. Yo también tengo una lista de propósitos pero en cuanto salga de este trabajo las iré cumpliendo. En cuanto tenga el dinero suficiente me dedicaré a lo que realmente me gusta y así la vida se nos va. <strong>¿Crees que hoy es un buen día para cambiar de dinámica? </strong></p>
<h3>Con enfoque y determinación</h3>
<p>Era un domingo en la mañana, tenía que correr 20 kilómetros y el terreno era variado, empezamos en un plano, luego un par de bajadas y finalmente 5 kilómetros de subida. Las cuestas son los tramos más complicados para muchos corredores, porque se requiere de muchos factores para superarlas. Primero, una cuesta necesita concentración, canalizar energía en los brazos y piernas, relajación, técnica pero sobre todo: <strong>determinación</strong>. Menciono esto porque el enfoque y la determinación son factores importantes cuando queremos concretar ideas, desarrollar proyectos y cumplir con nuestros objetivos.</p>
<p>Con el tiempo nuestra mente se satura, resulta curioso como nuestro cansancio al final del día no es físico, resulta mental y por lo tanto te olvidas de cualquier actividad física. Pero, quiero compartir contigo algunos tips que te ayudarán a despejar la mente:</p>
<ul>
<li><a href="http://www.maestrosdelweb.com/editorial/es-viernes-salgamos-a-correr-respirar-aire-fresco/">Correr:</a> Es mi favorito, sólo necesitas un par de tenis, ropa cómoda y la determinación para desconectarte de todo por 30 minutos, 40 o 1 hora. Mientras corres tu mente se relaja, tu corazón trabaja, tus músculos se activan y segregas substancias naturales como la endorfina que te produce felicidad.</li>
<li><strong>Nadar:</strong> Recomendable para las personas con sobrepeso, que tienen lesiones o dolores en las articulaciones. Es un ejercicio muy noble y de cero impacto, puedes empezar con 100mts, luego 300mts y así hasta dedicarle 1 hora al día. Con la natación mejoras tu circulación, tienes más aire, mueves todos los músculos de tu cuerpo y te llenas de energía.</li>
<li> <a href="http://www.maestrosdelweb.com/editorial/es-viernes-que-tal-si-empiezas-a-ejercitarte-un-poco/">Yoga:</a> Quizás has escuchado muchas veces sobre las bondades del Yoga, pero aunque parece un ejercicio fácil de hacer y en el que sólo debes respirar. El reto, precisamente se encuentra en cómo logras despejar la mente para respirar adecuadamente, tu concentración se incrementa, tu capacidad de sentir tu entorno y oxigenas tu cuerpo de una forma sorprendente. </li>
</ul>
<h3>Con esfuerzo y automotivación</h3>
<p>La vida esta llena de obstáculos, dificultades y limitaciones. Pero, también está llena de soluciones, apoyo y oportunidades que llegan a uno de diferentes formas. La educación recibida en la escuela, los valores inculcados en casa y el entorno en el que nos desarrollamos, pueden ser factores a favor o en contra de nuestra capacidad de automotivación y determinación. Lo mejor es ver primero hacia dentro, escudriñar nuestras limitaciones y defectos; pero también evaluar nuestras virtudes y características que nos permiten enfrentar el día a día.</p>
<p>Luego de despejar la mente, la pregunta es ¿cómo concreto mis ideas? considero que lo más importante para ello es establecer prioridades, buscar un esquema, pedir ayuda si es necesario, utilizar métodos o herramientas que nos permitan no perder el enfoque. </p>
<ul>
<li><a href="http://www.maestrosdelweb.com/editorial/es-viernes-tecnica-pomodoro-productividad/">Técnica para concretar:</a> Empecemos hablando de técnicas que te permiten optimizar el tiempo, evaluar cuánto tiempo inviertes en tus sueños, las prioridades y se pone a prueba tu disciplina.</li>
<li><a href="http://www.maestrosdelweb.com/editorial/piensa-o-realizas-tus-suenos/">Metas a plazos:</a> Define tus metas a corto, mediano y largo plazo. Incluso toma un calendario, asigna fechas y tiempo de desarrollo de cada meta. Al final, procura evaluar tus resultados y los factores que no te permitieron cumplir con lo propuesto para volverlo a intentar.</li>
<li><a href="http://www.maestrosdelweb.com/editorial/crea-nuevos-habitos-de-productividad/">Crea nuevos hábitos:</a> Como sabrás son todas aquellas acciones que realizamos de forma automática, porque la hemos realizado por tanto tiempo que están instaladas en nuestro disco duro. Pero, tenemos buenos y malos hábitos por ello, trabajemos en crear nuevos que aún no están incorporados en nosotros.</li>
</ul>
<p>Hace unos días un amigo en Twitter me pidió que escribiera sobre este tema, precisamente porque me expresaba su dificultad en concretar proyectos, ideas o simples acciones de beneficio para su vida. Espero que estas ideas y referencias a otros artículos en donde reflexiono más sobre temas similares a este sirvan de apoyo y los motiven a saber que no están solos en este proceso de la superación personal, hacer sus sueños realidad y los fracasos en el intento. Feliz fin de semana. Enjoy!</p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/128.png" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Stephanie Falla Aroche</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/como-despejar-la-mente-y-concretar-ideas/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/como-despejar-la-mente-y-concretar-ideas/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/como-despejar-la-mente-y-concretar-ideas/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/05/yoga.png" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/05/yoga.png" medium="image">
			<media:title type="html">Despejar la mente</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/128.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Curso Symfony 2: Integrando AJAX</title>
		<link>http://www.maestrosdelweb.com/editorial/curso-symfony2-integrando-ajax/</link>
		<comments>http://www.maestrosdelweb.com/editorial/curso-symfony2-integrando-ajax/#comments</comments>
		<pubDate>Wed, 02 May 2012 14:11:43 +0000</pubDate>
		<dc:creator>Maycol Alvarez</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[capitulo11]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[guia]]></category>
		<category><![CDATA[symfony 2]]></category>
		<category><![CDATA[symfony2]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=20141</guid>
		<description><![CDATA[En la actualidad muchos de nuestros proyectos están orientados hacia la web 2.0, y es por esto que la necesidad de implementar AJAX (XmlHttpRequest) es cada vez más grande, desde su versión 1.3 el proyecto Symfony a optado por no apoyar (ni integrar) ningún framework de desarrollo Frontend (básicamente en lo que se refiere Javascript), [...]]]></description>
			<content:encoded><![CDATA[<p>En la actualidad muchos de nuestros proyectos están orientados hacia la <a href="http://www.maestrosdelweb.com/editorial/web2/">web 2.0</a>, y es por esto que la necesidad de implementar <a href="http://www.maestrosdelweb.com/editorial/ajax/">AJAX</a> (XmlHttpRequest) es cada vez más grande, desde su versión 1.3 el proyecto Symfony a optado por no apoyar (ni integrar) ningún framework de desarrollo Frontend (básicamente en lo que se refiere Javascript), pero eso no impide que puedas utilizar cualquier framework Javascript en tu proyecto, de hecho Symfony2 es compatible con Assetic y te permite, entre otras cosas, utilizar el YUI-compressor para optimizar los assets de tu proyecto web.</p>
<p>Entrando de nuevo en el tema, en este capítulo nos concentraremos en las herramientas básicas que provee Symfony2 para manipular y detectar peticiones AJAX, las cuales son completamente transparentes para el cliente web (o framework que utilices), de esta forma podrás implementar AJAX de la forma que quieras y con el Framework JS que desees.</p>
<h3>Detectando peticiones XmlHttpRequest desde el controlador</h3>
<p>La clase Request contiene un función para verificar si la petición HTTP fue enviada por AJAX, es decir por medio del XmlHttpRequest:</p>
<pre class="brush: php; title: ; notranslate">
// retorna true o false
$this-&gt;getRequest()-&gt;isXmlHttpRequest();
</pre>
<p>¡Así de simple!, con ello puedes comprobar de forma efectiva desde tus controladores si la petición fue enviada por AJAX, lo que te permite, entre otras cosas, renderizar una plantilla específica, crear un objeto Response y controlar una salida personalizada como por ejemplo un JSON o XML.</p>
<h3>Detectando peticiones AJAX desde la Vista</h3>
<p>Controlar AJAX desde el controlador es muy efectivo, pero a veces por la estructura interna de nuestras plantillas (las que usas como layout y las que heredan un layout con la estructura HTML) puede resultar tedioso modificar cada controlador para devolver una plantilla específica, y ¿si dicha plantilla extiende un layout HTML (&lt;html&gt;, &lt;head&gt; y &lt;body&gt;)?: sabemos muy bien que en el caso de AJAX solo necesitamos <strong>el fragmento HTML específico</strong>, no un árbol HTML completo, por suerte en <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-la-vista-twig/">TWIG</a> podremos hacer esto:</p>
<div class="codigo">
<pre>{% extends app.request.isXmlHttpRequest ? "MDWDemoBundle::layout_ajax.html.twig" : "::base.html.twig" %}</pre>
</div>
<p>De esta forma Twig nos permite comprobar si la petición es AJAX y de este modo tener un layout específico para cada situación.</p>
<p>En el caso de plantillas con PHP, simplemente podemos acceder al objeto Request gracias al contenedor de Inyección de Dependencias (DI) en nuestras vistas:</p>
<pre class="brush: php; title: ; notranslate">
$this-&gt;container-&gt;get('request')-&gt;isXmlHttpRequest()
</pre>
<p>Note que se hace una llamada a <strong>$this-&gt;container</strong> esto motivado a que en las plantillas $this-&gt;get() intentará cargar los Helpers, con ello especificamos que queremos cargar explícitamente un servicio, en nuestro caso el “Request”.</p>
<p>Esto es todo lo básico que necesitas conocer para implementar AJAX con Symfony 2. ¡Fue muy simple, corto y rápido!, ¿lo querías más difícil? <img src='http://www.maestrosdelweb.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' />  <strong>Simplicidad: ése es el objetivo</strong>, con esto puedes integrar perfectamente cualquier código JS AJAX, frameworks como jQuery, MooTools, Prototype, ExtJS, Dojo, YUI, etc.</p>
<hr /><p style="height: 64px;"><img alt='Maycol Alvarez' src='http://0.gravatar.com/avatar/0457a9460a25fb50aca9a46f561f37c9?s=64&amp;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&amp;r=G' class='avatar avatar-64 photo' height='64' width='64' style="float:left;padding:0 5px" /> <strong>Maycol Alvarez</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-integrando-ajax/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-integrando-ajax/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/curso-symfony2-integrando-ajax/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
	
		<media:thumbnail url="http://0.gravatar.com/avatar/0457a9460a25fb50aca9a46f561f37c9?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" />
		<media:content url="http://0.gravatar.com/avatar/0457a9460a25fb50aca9a46f561f37c9?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" medium="image">
			<media:title type="html">Maycol Alvarez</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Curso Django: Entendiendo como trabaja Django</title>
		<link>http://www.maestrosdelweb.com/editorial/curso-django-entendiendo-como-trabaja-django/</link>
		<comments>http://www.maestrosdelweb.com/editorial/curso-django-entendiendo-como-trabaja-django/#comments</comments>
		<pubDate>Mon, 30 Apr 2012 13:28:50 +0000</pubDate>
		<dc:creator>Sergio Infante Montero</dc:creator>
				<category><![CDATA[django]]></category>
		<category><![CDATA[Editorial]]></category>
		<category><![CDATA[archivos]]></category>
		<category><![CDATA[curso django]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[guia python]]></category>
		<category><![CDATA[modelo]]></category>
		<category><![CDATA[mtv]]></category>
		<category><![CDATA[plantillas]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rutas]]></category>
		<category><![CDATA[vista]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24085</guid>
		<description><![CDATA[La semana pasada vimos lo fácil que fue crear un proyecto y ejecutarlo en unos cuantos pasos, sin embargo esa simplicidad debe ir acompañada de una fuerte lógica para poder aplicar Django a proyectos reales, es por eso que esta semana nos dedicaremos a entender como es que Django hace toda esa magia. Antes de [...]]]></description>
			<content:encoded><![CDATA[<p>La semana pasada vimos lo fácil que fue crear un proyecto y ejecutarlo en unos cuantos pasos, sin embargo esa simplicidad debe ir acompañada de una fuerte lógica para poder aplicar Django a proyectos reales, es por eso que esta semana nos dedicaremos a entender como es que Django hace toda esa magia.</p>
<div class="tipexperto"><h3>Nota</h3> <div class="tipcont">Para tener una estupenda experiencia con Django, el orden de los archivos y directorios deben respetarse, caso contrario el caos llegará rápidamente a nuestro proyecto y fracasará al momento de hacerlo crecer con mas personas o requerimientos.</div></div>
<p>Antes de iniciar con la explicación de como funciona Django, dale un vistazo a este vídeo:</p>
<span style="text-align:center; display: block;"><a href="http://www.maestrosdelweb.com/editorial/curso-django-entendiendo-como-trabaja-django/"><img src="http://img.youtube.com/vi/c6JLEsXhEEc/2.jpg" alt="" /></a></span>
<p>Ahora que ya entiendes el contexto, empezamos!</p>
<h2>MTV y Django</h2>
<p>Se podría clasificar a Django como parte de la tercera generación del desarrollo web:</p>
<div id="attachment_24087" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/desarrolloweb.png"><img src="http://www.maestrosdelweb.com/images/2012/04/desarrolloweb-450x193.png" alt="Generaciones del desarrollo web" width="450" height="193" class="size-medium wp-image-24087" /></a><p class="wp-caption-text">Generaciones del desarrollo web</p></div>
<p>Sin embargo más alla de las clasificaciones que podrían existir, está el entender como funciona realmente, al entenderlo se puede llegar a dominarlo.</p>
<p><a href="http://www.maestrosdelweb.com/editorial/curso-django-introduccion/">Al principio del curso</a> de Django, les dije que era un framework MTV (una modificación de MVC, nada que ver con música), esto se debe a que los desarrolladores no tuvieron la intención de seguir algún patron de desarrollo, sino hacer el framework lo más funcional posible.</p>
<p>Para empezar a entender MTV debemos fijarnos en la analogía con MVC.</p>
<ul>
<li>El <em>modelo</em> en Django sigue siendo <strong>modelo</strong></li>
<li>La <em>vista</em> en Django se llama <strong>Plantilla (Template)</strong></li>
<li>El <em>controlador</em> en Django se llama <strong>Vista</strong></li>
</ul>
<p>Una imagen nos hará entender mejor esta relación:</p>
<div id="attachment_24088" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/esquema-mtv.png"><img src="http://www.maestrosdelweb.com/images/2012/04/esquema-mtv-450x121.png" alt="Funcionamiento del MTV de Django" width="450" height="121" class="size-medium wp-image-24088" /></a><p class="wp-caption-text">Funcionamiento del MTV de Django</p></div>
<p>Veamos que hace cada uno de ellos con un poco más de detalle y algunos conceptos adicionales.</p>
<h3>El modelo</h3>
<p>El modelo define los datos almacenados, se encuentra en forma de clases de Python, cada tipo de dato que debe ser almacenado se encuentra en una variable con ciertos parámetros, posee métodos también. Todo esto permite indicar y controlar el comportamiento de los datos.</p>
<h3>La vista</h3>
<p>La vista se presenta en forma de funciones en Python, su propósito es determinar que datos serán visualizados, entre otras cosas más que iremos viendo conforme avanzamos con el curso. El <a href="http://es.wikipedia.org/wiki/Mapeo_objeto-relacional" title="ORM en la wikipedia">ORM</a> de Django permite escribir código Python en lugar de SQL para hacer las consultas que necesita la vista. La vista también se encarga de tareas conocidas como el envío de correo electrónico, la autenticación con servicios externos y la validación de datos a través de formularios. Lo mas importante a entender con respecto a la vista es que no tiene nada que ver con el estilo de presentación de los datos, sólo se encarga de los datos, la presentación es tarea de la plantilla.</p>
<h3>La plantilla</h3>
<p>La plantilla es básicamente una página HTML con algunas etiquetas extras propias de Django, en si no solamente crea contenido en HTML (también XML, CSS, Javascript, CSV, etc). </p>
<p>Por ahora nos enfocaremos a lo básico el HTML. La plantilla recibe los datos de la vista y luego los organiza para la presentación al navegador web. Las etiquetas que Django usa para las plantillas permiten que sea flexible para los diseñadores del frontend, incluso tiene estructuras de datos como if, por por si es necesaria una presentación lógica de los datos, estas estructuras son límitadas para evitar un desorden poniendo cualquier tipo de código Python. </p>
<p>Esto permite que la lógica del sistema siga permaneciendo en la vista.</p>
<h3>La configuración de las rutas</h3>
<p>Django posee un mapeo de URLs que permite controlar el despliegue de las vistas, esta configuración es conocida como URLConf. El trabajo del URLConf es leer la URL que el usuario solicitó, encontrar la vista apropiada para la solicitud y pasar cualquier variable que la vista necesite para completar su trabajo. El URLConf esta construido con expresiones regulares en <a href="http://www.maestrosdelweb.com/editorial/guia-python/">Python</a> y sigue la filosofia de Python: <a href="http://www.python.org/dev/peps/pep-0020/" title="El PEP 20 de Python">Explicito es mejor que implícito.</a> Este URLConf permite que las rutas que maneje Django seán agradables y entendibles para el usuario.</p>
<p>Si consideramos al URLConf en el esquema anterior tendríamos este resultado más completo.</p>
<div id="attachment_24089" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/esquema-mtv-urlconf.png"><img src="http://www.maestrosdelweb.com/images/2012/04/esquema-mtv-urlconf-450x126.png" alt="Funcionamiento del MTV de Django y su URLConf" width="450" height="126" class="size-medium wp-image-24089" /></a><p class="wp-caption-text">Funcionamiento del MTV de Django y su URLConf</p></div>
<h2>Los archivos predeterminados</h2>
<p>Otra parte importante es entender el propósito de los archivos que se crean de manera predeterminada, estos son:</p>
<h3>Archivos del proyecto</h3>
<ul>
<li><strong>__init__.py</strong>: Este es un archivo vacío que le dice a Python que debe considerar este directorio como un paquete de Python. Si se desea saber más, se puede consultar <a href="http://docs.python.org/tutorial/modules.html#packages" title="Paquetes en Python"> la documentación sobre los paquetes.</a></li>
<li><strong>manage.py</strong>: Este archivo contiene una porción de código que permite interactuar con el proyecto de Django de muchas formas. Si se desea mayor detalle se encuentra la <a href="https://docs.djangoproject.com/en/dev/ref/django-admin/#ref-django-admin" title="Django y el manage.py">documentación oficial con respecto a manage.py.</a></li>
<li><strong>settings.py</strong>: Este archivo contiene todas las configuraciones para el proyecto, la documentación al respecto puede darnos mas detalles de la <a href="https://docs.djangoproject.com/en/dev/topics/settings/#topics-settings" title="Django y el settings.py">configuración de un proyecto en Django.</a></li>
<li><strong>urls.py</strong>: Contiene las rutas que están disponibles en el proyecto, manejado por URLConf, los detalles completos como siempre en la documentación oficial nos da mas detalles sobre las <a href="https://docs.djangoproject.com/en/dev/topics/http/urls/#topics-http-urls" title="Django y sus urls">urls y Django.</a></li>
</ul>
<h3>Archivos de la aplicación</h3>
<ul>
<li><strong>__init__.py</strong>: La misma descripción anterior (líneas arriba).</li>
<li><strong>models.py</strong>: En este archivo se declaran las clases del modelo.</li>
<li><strong>views.py</strong>: En este archivo se declaran las funciones de la vista.</li>
<li><strong>test.py</strong>: En este archivo se declaran las pruebas necesarias para la aplicación, para mayor detalle sobre las <a href="https://docs.djangoproject.com/en/dev/topics/testing/" title="Pruebas con Django">pruebas y Django</a> se puede consultar la documentación del proyecto.</li>
</ul>
<p>Una vez que tenemos claro el funcionamiento básico de Django, desarrollemos un ejemplo dentro del <a href="http://www.maestrosdelweb.com/editorial/curso-django-instalacion-y-primera-aplicacion/">proyecto que iniciamos la semana pasada</a>, para experimentar por nuestra cuenta. </p>
<h3>Modelo, Vista y Plantilla en 15 minutos</h3>
<p>Antes de continuar, deben entender que esto solamente es un pequeño ejemplo, el modelo, vista y plantillas serán desarrolladas a detalle en las próximas semanas. Si existen dudas del porque de las instrucciones, estas serán resueltas a detalle en los siguientes capítulos. Si eres muy impaciente siempre tienes a disposición <a href="https://docs.djangoproject.com/" title="Documentación oficial de Django">la documentación oficial del proyecto</a>.</p>
<p>Nuestro proyecto debe tener una estructura similar a esta:<br />
<div id="attachment_24317" class="wp-caption aligncenter" style="width: 175px"><a href="http://www.maestrosdelweb.com/images/2012/04/django_estructura_proyecto.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django_estructura_proyecto-165x450.png" alt="Árbol de ficheros de un proyecto en Django" width="165" height="450" class="size-medium wp-image-24317" /></a><p class="wp-caption-text">Árbol de ficheros de un proyecto en Django</p></div></p>
<p>Tendremos que manejar para este proyecto 6 archivos:</p>
<ul>
<li><strong>models.py</strong> (ya existe dentro de la carpeta principal).</li>
<li><strong>views.py</strong> (ya existe dentro de la carpeta principal).</li>
<li><strong>admin.py</strong> (aún no existe, pero estará dentro de la carpeta principal).</li>
<li><strong>urls.py</strong> (ya existe dentro de la carpeta recetario).</li>
<li><strong>settings.py</strong> (ya existe dentro de la carpeta recetario).</li>
<li><strong>lista_bebidas.html</strong> (aún no existe, estará dentro de una carpeta en la carpeta recetario).</li>
</ul>
<h4>models.py</h4>
<p>Al principio <em>models.py</em> luce asi:<br />
<div id="attachment_24318" class="wp-caption aligncenter" style="width: 386px"><a href="http://www.maestrosdelweb.com/images/2012/04/django_models_inicio.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django_models_inicio.png" alt="models.py predeterminado" width="376" height="159" class="size-full wp-image-24318" /></a><p class="wp-caption-text">models.py predeterminado</p></div></p>
<p>Usamos nuestro editor de texto favorito para editar models.py y redactamos lo siguiente:</p>
<div class="codigo">
<pre>
from django.db import models

class Bebida(models.Model):
	nombre = models.CharField(max_length=50)
	ingredientes = models.TextField()
	preparacion = models.TextField()

	def __unicode__(self):
		return self.nombre
</pre>
</div>
<h4>views.py</h4>
<p><em>views.py</em> luce así al principio:<br />
<div id="attachment_24321" class="wp-caption aligncenter" style="width: 416px"><a href="http://www.maestrosdelweb.com/images/2012/04/django_views_inicio.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django_views_inicio.png" alt="views.py predeterminado" width="406" height="119" class="size-full wp-image-24321" /></a><p class="wp-caption-text">views.py predeterminado</p></div></p>
<p>Igualmente con nuestro editor favorito abrimos views.py y lo dejamos de la siguiente forma:</p>
<div class="codigo">
<pre>
from principal.models import Bebida
from django.shortcuts import render_to_response

def lista_bebidas(request):
	bebidas = Bebida.objects.all()
	return render_to_response('lista_bebidas.html',{'lista':bebidas})
</pre>
</div>
<h4>admin.py</h4>
<p>Este archivo no existe, así que lo creamos manualmente dentro de nuestro directorio de la aplicación, en este caso dentro del directorio principal. Lo debemos dejar de esta manera:</p>
<div class="codigo">
<pre>
from principal.models import Bebida
from django.contrib import admin

admin.site.register(Bebida)
</pre>
</div>
<h4>urls.py</h4>
<p>Este archivo ya existe, se encuentra dentro del directorio recetario, así que lo único que debemos hacer es modificarlo para dejarlo de la siguiente manera:</p>
<div class="codigo">
<pre>
from django.conf.urls import patterns, include, url
from django.contrib import admin

admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$','principal.views.lista_bebidas'),
    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    url(r'^admin/', include(admin.site.urls)),
)
</pre>
</div>
<h4>settings.py</h4>
<p>Este archivo lo modificamos la semana pasada, se encuentra dentro de recetario. Debemos buscar la directiva TEMPLATE_DIRS (Debe encontrarse en la línea 113 aproximadamente). Debemos dejar esta sección de esta forma:</p>
<div class="codigo">
<pre>
TEMPLATE_DIRS = (
    os.path.join(RUTA_PROYECTO,'plantillas'),
)
</pre>
</div>
<p>En esta sección le estamos diciendo que debe buscar las plantillas dentro de la carpeta del proyecto, en una carpeta llamada plantillas, como esta carpeta aún no existe debemos crearla manualmente dentro de recetario.</p>
<h4>lista_bebidas.html</h4>
<p>Este archivo no existe, lo crearemos manualmente dentro de la carpeta plantillas (si, esa que acabas de crear dentro de recetario). </p>
<p>Debes finalizar con una estructura similar a esta:<br />
<div id="attachment_24316" class="wp-caption aligncenter" style="width: 181px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-estructura-plantillas.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-estructura-plantillas-171x450.png" alt="Árbol de ficheros del proyecto recetario" width="171" height="450" class="size-medium wp-image-24316" /></a><p class="wp-caption-text">Árbol de ficheros del proyecto recetario</p></div></p>
<p>Una vez creado le ponemos la etiquetación HTML que nos permita visualizar la lista de bebidas. Podría quedarse de esta manera:</p>
<div class="codigo">
<pre>
&lt;!DOCTYPE html&gt;
&lt;html lang='es'&gt;
  &lt;head&gt;
	&lt;title&gt;Lista de bebidas de ejemplo&lt;/title&gt;
	&lt;meta charset='utf-8'&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;Recetario de Bebidas&lt;/h1&gt;
	{% for elemento in lista %}
	&lt;ul&gt;
	  &lt;li&gt;&lt;strong&gt;{{elemento.nombre}}&lt;/strong&gt;&lt;/li&gt;
	  &lt;li&gt;{{elemento.ingredientes}}&lt;/li&gt;
	  &lt;li&gt;{{elemento.preparacion}}&lt;/li&gt;
	&lt;/ul&gt;
	{% endfor %}
  &lt;/body&gt;
&lt;/html&gt;
</pre>
</div>
<div class='tipexperto'>
<h3>Nota: Python es sensible a las mayúsculas y minúsculas</h3>
<div>Tener precaución al momento de digitar el código en Python, las mayúsculas y minúsculas importan y mucho.</div>
</div>
<h4>Poner en funcionamiento todo</h4>
<p>Listo, tenemos todo listo para ver funcionando nuestro ejemplo, para ello debemos de sincronizar nuevamente nuestra base de datos, para ello, nos ubicamos en la carpeta principal del proyecto (aquella donde se encuentra el archivo manage.py). Una vez en la carpeta principal, desde una terminal digitamos:</p>
<div class="codigo">
<pre>
python manage.py syncdb
</pre>
</div>
<p>Esto nos dará el siguiente resultado: (prestar atención a la segunda línea que nos indica la creación de una nueva tabla):<br />
<div id="attachment_24320" class="wp-caption aligncenter" style="width: 408px"><a href="http://www.maestrosdelweb.com/images/2012/04/django_syncdb_nuevo_modelo.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django_syncdb_nuevo_modelo.png" alt="Creación de tabla principal_bebidas" width="398" height="94" class="size-full wp-image-24320" /></a><p class="wp-caption-text">Creación de tabla principal_bebidas</p></div></p>
<p>Una vez realizado esto, lanzamos nuestro servidor de desarrollo:</p>
<div class="codigo">
<pre>
python manage.py runserver
</pre>
</div>
<p>Nos ubicamos en <strong>http://127.0.0.1:8000/admin</strong>, ingresamos con nuestros datos configurados en la primera vez que sincronizamos la base de datos (si no recuerdas los datos que pusiste, puedes borrar el archivo recetario.db y volver a digitar: python manage.py syncdb para resincronizar).</p>
<p>Una vez dentro de la interfaz administrativa veremos: (notar que aparece una opción Bebidas).<br />
<div id="attachment_24314" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django_admin_models.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django_admin_models-450x216.png" alt="Interfaz administrativa de Django + Bebidas" width="450" height="216" class="size-medium wp-image-24314" /></a><p class="wp-caption-text">Interfaz administrativa de Django + Bebidas</p></div></p>
<p>Podemos seguir intuitivamente la interfaz e ingresar datos:<br />
<div id="attachment_24319" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-recetario-bebida-admin-add.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-recetario-bebida-admin-add-450x216.png" alt="Interfaz inicial de bebidas" width="450" height="216" class="size-medium wp-image-24319" /></a><p class="wp-caption-text">Interfaz inicial de bebidas</p></div><br />
<div id="attachment_24312" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-admin-bebida-save.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-admin-bebida-save-450x371.png" alt="Formulario para ingreso de datos" width="450" height="371" class="size-medium wp-image-24312" /></a><p class="wp-caption-text">Formulario para ingreso de datos</p></div><br />
<div id="attachment_24315" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-ejemplo-add-admin.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-ejemplo-add-admin-450x371.png" alt="Ingreso de contenido" width="450" height="371" class="size-medium wp-image-24315" /></a><p class="wp-caption-text">Ingreso de contenido</p></div><br />
<div id="attachment_24313" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-admin-ejemplo.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-admin-ejemplo-450x227.png" alt="Lista de elementos ingresados" width="450" height="227" class="size-medium wp-image-24313" /></a><p class="wp-caption-text">Lista de elementos ingresados</p></div></p>
<p>Una vez guardados podemos ir a <strong>http://127.0.0.1:8000/</strong> y veremos lo que acabamos de ingresar. De esta manera ya tienes una interfaz rápida de ingreso y visualización de datos.</p>
<div id="attachment_24323" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-ejemplo-resultado.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-ejemplo-resultado-450x227.png" alt="Ejemplo de plantilla con Django" width="450" height="227" class="size-medium wp-image-24323" /></a><p class="wp-caption-text">Ejemplo de plantilla con Django</p></div>
<p>Hay muchos puntos que en este capítulo he tenido que tocar superficialmente, esto no debe preocuparte, porque en los siguientes capítulos desarrollaré a detalle esos puntos, deseo recordarte que el objetivo de este pequeño ejemplo, es disfrutar la experiencia de la velocidad de Django, para el desarrollo de aplicaciones.</p>
<p>Si desean ver los archivos oficiales del proyecto, no olviden que pueden acceder al <a href="http://neosergio.github.com/recetario_mdw" title="Recetario para maestros del web con Django">repositorio del mismo en github</a>. Los datos de acceso para la interfaz administrativa del ejemplo del repositorio son los siguientes:</p>
<ul>
<li>usuario:sergio</li>
<li>clave:maestros</li>
</ul>
<p>La próxima semana tendremos el capítulo dedicado a <strong>El Modelo</strong>. Muchas gracias por sus comentarios en el capítulo anterior, eso enriquece mucho más cada capítulo.</p>
<hr /><p style="height: 64px;"><img alt='Sergio Infante Montero' src='http://1.gravatar.com/avatar/3ca2b43e8aedb28a82fdca67e28281a1?s=64&amp;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&amp;r=G' class='avatar avatar-64 photo' height='64' width='64' style="float:left;padding:0 5px" /> <strong>Sergio Infante Montero</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/curso-django-entendiendo-como-trabaja-django/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/curso-django-entendiendo-como-trabaja-django/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/curso-django-entendiendo-como-trabaja-django/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
	
		<media:thumbnail url="http://img.youtube.com/vi/c6JLEsXhEEc/2.jpg" />
		<media:content url="http://img.youtube.com/vi/c6JLEsXhEEc/2.jpg" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/desarrolloweb.png" medium="image">
			<media:title type="html">Generaciones del desarrollo web</media:title>
			<media:description type="html">Generaciones del desarrollo web</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/desarrolloweb-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/esquema-mtv.png" medium="image">
			<media:title type="html">Funcionamiento del MTV de Django</media:title>
			<media:description type="html">Funcionamiento del MTV de Django</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/esquema-mtv-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/esquema-mtv-urlconf.png" medium="image">
			<media:title type="html">Funcionamiento del MTV de Django y su URLConf</media:title>
			<media:description type="html">Funcionamiento del MTV de Django y su URLConf</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/esquema-mtv-urlconf-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django_estructura_proyecto.png" medium="image">
			<media:title type="html">Árbol de ficheros de un proyecto en Django</media:title>
			<media:description type="html">Árbol de ficheros de un proyecto en Django</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django_estructura_proyecto-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django_models_inicio.png" medium="image">
			<media:title type="html">models.py predeterminado</media:title>
			<media:description type="html">models.py predeterminado</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django_models_inicio-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django_views_inicio.png" medium="image">
			<media:title type="html">views.py predeterminado</media:title>
			<media:description type="html">views.py predeterminado</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django_views_inicio-150x119.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-estructura-plantillas.png" medium="image">
			<media:title type="html">Árbol de ficheros del proyecto recetario</media:title>
			<media:description type="html">Árbol de ficheros del proyecto recetario</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-estructura-plantillas-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django_syncdb_nuevo_modelo.png" medium="image">
			<media:title type="html">Creación de tabla principal_bebidas</media:title>
			<media:description type="html">Creación de tabla principal_bebidas</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django_syncdb_nuevo_modelo-150x94.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django_admin_models.png" medium="image">
			<media:title type="html">Interfaz administrativa de Django + Bebidas</media:title>
			<media:description type="html">Interfaz administrativa de Django + Bebidas</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django_admin_models-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-recetario-bebida-admin-add.png" medium="image">
			<media:title type="html">Interfaz inicial de bebidas</media:title>
			<media:description type="html">Interfaz inicial de bebidas</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-recetario-bebida-admin-add-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-admin-bebida-save.png" medium="image">
			<media:title type="html">Formulario para ingreso de datos</media:title>
			<media:description type="html">Formulario para ingreso de datos</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-admin-bebida-save-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-ejemplo-add-admin.png" medium="image">
			<media:title type="html">Ingreso de contenido</media:title>
			<media:description type="html">Ingreso de contenido</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-ejemplo-add-admin-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-admin-ejemplo.png" medium="image">
			<media:title type="html">Lista de elementos ingresados</media:title>
			<media:description type="html">Lista de elementos ingresados</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-admin-ejemplo-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-ejemplo-resultado.png" medium="image">
			<media:title type="html">Ejemplo de plantilla con Django</media:title>
			<media:description type="html">Ejemplo de plantilla con Django</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-ejemplo-resultado-150x150.png" />
		</media:content>
		<media:content url="http://1.gravatar.com/avatar/3ca2b43e8aedb28a82fdca67e28281a1?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" medium="image">
			<media:title type="html">Sergio Infante Montero</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Es viernes: &#8220;No comparto mi idea porque me la pueden robar&#8221;</title>
		<link>http://www.maestrosdelweb.com/editorial/me-pueden-robar-mi-idea/</link>
		<comments>http://www.maestrosdelweb.com/editorial/me-pueden-robar-mi-idea/#comments</comments>
		<pubDate>Fri, 27 Apr 2012 18:51:08 +0000</pubDate>
		<dc:creator>Stephanie Falla Aroche</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Negocios]]></category>
		<category><![CDATA[Productividad]]></category>
		<category><![CDATA[emprendimiento]]></category>
		<category><![CDATA[es viernes!]]></category>
		<category><![CDATA[Freelancer]]></category>
		<category><![CDATA[ideas]]></category>
		<category><![CDATA[latinoamérica]]></category>
		<category><![CDATA[oportunidades]]></category>
		<category><![CDATA[proyectos]]></category>
		<category><![CDATA[trabajo en equipo]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24290</guid>
		<description><![CDATA[¿Cuántos de ustedes en algún momento han pensado lo mismo? no compartimos nuestra idea en un evento, porque me la pueden copiar y no me darán crédito. No presento mi proyecto en ningún evento de emprendimiento porque si no gano, otros con los recursos sí lo llevarán a cabo. No publico mi propuesta en ningún [...]]]></description>
			<content:encoded><![CDATA[<p><strong>¿Cuántos de ustedes en algún momento han pensado lo mismo? </strong>no compartimos nuestra idea en un evento, porque me la pueden copiar y no me darán crédito. No presento mi proyecto en ningún evento de emprendimiento porque si no gano, otros con los recursos sí lo llevarán a cabo. No publico mi propuesta en ningún medio de financiamiento colectivo porque corro el riesgo de que otro la tome. Entonces, como no hago nada de esto, mi proyecto lleva 5 años en el disco duro porque estoy esperando el momento preciso, la gran oportunidad, la gente adecuada y entonces el mundo sabrá de lo que soy capaz.</p>
<p><img src="http://www.maestrosdelweb.com/images/2012/04/ideas-latinoamerica.jpeg" alt="Webprendedor" /></p>
<p>Existen muchos factores que nos hacen pensar de esa manera, principalmente en Latinoamérica en donde nuestros países son tan peligrosos, no existe cultura de respeto, carecemos de oportunidades y en el momento menos esperado alguien se aprovecha de nosotros ¿cierto?. Yo amo mi país, pero, vivimos a la defensiva, no confiamos en la gente, creemos en la estafa, en un abrir y cerrar de ojos nos despojan de lo que es nuestro. En un contexto como este ¿cómo no vamos a pensar de esta manera? creo que es justificable y necesitamos el escepticismo como arma de defensa.</p>
<h3>Canalizar el escepticismo hacia las oportunidades</h3>
<p>Sin embargo, porque siempre debe existir una manera diferente de ver las cosas, podemos aprovechar todas esas alertas que tenemos y canalizarlas de forma positiva. Si somos tan hábiles para saber cuando alguien nos &#8220;miente o nos quiere ver la cara&#8221; por qué no utilizamos ese sentido agudo para detectar personas con talento y capaces de formar parte de nuestro proyecto. Por qué, si somos tan capaces de elevar la voz para denunciar un abuso, un robo o asalto. No utilizamos ese valor para felicitar a otros que con esfuerzo están logrando proyectos interesantes y aprendemos de ellos.</p>
<p>En este medio, <strong>compartir tus ideas no es un riesgo de perdida</strong>, al contrario es una oportunidad para que más personas con tus mismos intereses te descubran y puedan construir algo en conjunto. Tenemos muchas herramientas de comunicación, el compartir y aprender de alguien extranjero, ya no es un lujo que sólo tienen quienes salen del país a cursar un posgrado o de quienes tienen suficiente dinero para pagar estudios fuera del país. Los medios sociales y las herramientas de comunicación nos permiten armar equipos múltidisciplinarios entorno al Interne sin importar el espacio geográfico.</p>
<h3>Comparte tus ideas y proyectos</h3>
<p>Debemos aprender a ser proactivos, independientes de los recursos, libres y seguros de las cosas que deseamos alcanzar. Nos decimos freelancer, emprendedores, trabajadores independientes, pero seguimos dependiendo de que la oportunidad, las personas indicadas y el momento preciso llame a nuestra puerta. Cuando en realidad todo eso que buscamos está allá, afuera, en Internet, los eventos, en la calle, la universidad, las redes sociales y hasta en este espacio. ¿Entonces, por qué nuestra idea se sigue llenando de polvo? ¿qué necesitamos? ¿cómo empezar?</p>
<p>No existen fórmulas para lograrlo, pero algo sí te aseguro, existen muchos caminos y muchas oportunidades para hacerlo. Pero, no llegarán a tí, tu debes buscar, trabajar y (des)aprender de las experiencias que no te han permitido lograrlo hasta el momento. Hace una semanas en <a href="http://mejorando.la">mejorando.la</a> con @freddier y @cvander hablamos sobre proyectos de financiamiento colectivo, en especial hablamos de <a href="http://mejorando.la/videos/crowdfunding-kickstarter-geeks-espacio/">Crowdfunding con Kickstarter</a>. Además, hablamos de proyectos similares como: </p>
<ul>
<li><a href="http://www.idea.me">Idea.me</a>: Ayuda para creadores latinos para realiar sus proyectos  través del financiamiento colectivo.</li>
<li><a href="http://www.lanzamos.com">Lanzanos.com</a>: Iniciativa española de Público.es donde puedes enviar tus proyectos y obtener el finamiento que necesitas.</li>
<li><a href="http://www.goteo.org/">Goteo.org</a>: Red social para cofinanciar y colaborar con proyectos creativos. </li>
<li><a href="http://Kickstarter.com">Kickstarter.com</a>: Proyecto en inglés que permite el financiamiento colectivo para proyectos.</li>
</ul>
<p>Existen muchas formas de lograr que tu proyecto sea conocido, empieza leyendo blogs sobre el tema, <a href="http://www.maestrosdelweb.com/guias/#guia-startup">Guías de emprendimiento</a>, participa en comunidades, procura ir a eventos sobre temáticas similares. Invierte, participa y cree en otros proyectos latinos como el tuyo y construye ese buen karma. Pero sobre todo, no tengas temor de hablar sobre tu idea porque sólo será  una limitante en la búsqueda de llevarla a cabo con éxito. Feliz fin de semana. Enjoy!</p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/128.png" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Stephanie Falla Aroche</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/me-pueden-robar-mi-idea/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/me-pueden-robar-mi-idea/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/me-pueden-robar-mi-idea/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/ideas-latinoamerica.jpeg" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/ideas-latinoamerica.jpeg" medium="image">
			<media:title type="html">Webprendedor</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/128.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Curso Symfony 2: Validación de datos y creación de formularios</title>
		<link>http://www.maestrosdelweb.com/editorial/curso-symfony2-validacion-de-datos-y-creacion-de-formularios/</link>
		<comments>http://www.maestrosdelweb.com/editorial/curso-symfony2-validacion-de-datos-y-creacion-de-formularios/#comments</comments>
		<pubDate>Wed, 25 Apr 2012 07:00:52 +0000</pubDate>
		<dc:creator>Juan Ardissone</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Guías]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[@asserts]]></category>
		<category><![CDATA[curso]]></category>
		<category><![CDATA[datos]]></category>
		<category><![CDATA[entidades]]></category>
		<category><![CDATA[entities]]></category>
		<category><![CDATA[fomularios]]></category>
		<category><![CDATA[sql injection]]></category>
		<category><![CDATA[symfony2]]></category>
		<category><![CDATA[validación]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24217</guid>
		<description><![CDATA[Ahora que ya hemos trabajado con la base de datos y con los datos en sí vamos a tocar dos temas que serán de mucha ayuda. El primero es como el framework nos ayuda a validar los datos que vamos a grabar en nuestra base de datos y el segundo es como crear los formularios [...]]]></description>
			<content:encoded><![CDATA[<p>Ahora que ya hemos trabajado con la <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-configurando-bases-de-datos/">base de datos</a> y con los <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-manipulando-datos-con-doctrine/">datos en sí</a> vamos a tocar dos temas que serán de mucha ayuda. El primero es como el framework nos ayuda a validar los datos que vamos a grabar en nuestra base de datos y el segundo es como crear los formularios para que los usuarios finales ingresen los datos en la aplicación.</p>
<h3>Validación de datos</h3>
<p>Como ya hemos visto cada tabla de nuestra base de datos es representada por medio de un Entity en el que usamos annotations para definir los metadatos. Para usar estos annotations importamos el paquete &#8220;use Doctrine\ORM\Mapping as ORM;&#8221; arriba del archivo y usamos los mismos por medio del alias ORM de esta manera &#8220;@ORM\Id&#8221;.</p>
<p>Para la validación de los datos importaremos otro namespace: &#8220;use Symfony\Component\Validator\Constraints as Assert;&#8221; y por medio del alias Assert, utilizando annotations definiremos los validadores para los campos que queramos. El listado completo de validadores o también llamados constraints los puedes ver en la <a href="http://symfony.com/doc/current/book/validation.html#constraints">documentación oficial</a>.</p>
<p>Algo que resulta muy importante entender es que la definición de los metadatos que escribimos usando el alias @ORM no tiene el mismo propósito que cuando usamos el @Assert. Por ejemplo, en el caso de nuestro Entity Article, hemos definido que la propiedad (campo/columna) $title no permite nulos. Esto lo hicimos porque dejamos su mapeo como @ORM\Column(name=&#8221;title&#8221;, type=&#8221;string&#8221;, length=255) donde por defecto es not null pero esto no implica la validación de los datos ya que lo que acabamos de escribir es que para la creación de la tabla se debe tener en cuenta que no es nulo y esto sirve para generar correctamente el CREATE TABLE necesario.</p>
<p>Para asegurarnos de que no sea nulo a la hora de ingresar los datos debemos usar el @Assert\NotNull() cuyo objetivo es realmente decirle al validador de datos que efectivamente al intentar grabar datos por medio del entity este debe ser validado como que no permite valores nulos.</p>
<p>Estos annotations tienen la misma forma que los anteriores. Son llamadas a métodos que pueden recibir parámetros opcionales. Por ejemplo, si ponemos:</p>
<pre>/**
* @var string $title
*
* @ORM\Column(name="title", type="string", length=255)
* @Assert\NotNull()
*/
private $title;</pre>
<p>estamos diciendo que la propiedad title no debe permitir valores nulos y al momento de validarlos saldrá una mensaje diciendo eso en ingles, si queremos cambiar el mensaje por defecto lo hacemos agregando el argumento a la invocación de esta manera:</p>
<pre>/**
 * @var string $title
 *
 * @ORM\Column(name="title", type="string", length=255)
 * @Assert\NotNull(message="Debe escribir un titulo")
 */
 private $title;</pre>
<p>Si quisiéramos validar que un campo debe ser de tipo email usaremos el annotation @Assert\Email() de esta manera:</p>
<pre>/**
 * @Assert\Email(
 *     message = "El mail '{{ value }}' ingresado no tiene el formato correcto.",
 * )
 */
 protected $email;</pre>
<p>Haciendo referencia a {{ value }} va a mostrar el valor ingresado como parte del mensaje.</p>
<p>Como último ejemplo, si quisiéramos validar la máxima cantidad de caracteres ingresados, podríamos usar el @Assert\MaxLength():</p>
<pre>/**
 * @var string $title
 *
 * @ORM\Column(name="title", type="string", length=255)
 * @Assert\NotNull(message="Debe escribir un titulo")
 * @Assert\MaxLength(255)
 */
 private $title;</pre>
<p>Y si quisiéramos además de la máxima cantidad de caracteres, controlar la mínima cantidad simplemente lo agregamos también:</p>
<pre>/**
 * @var string $title
 *
 * @ORM\Column(name="title", type="string", length=255)
 * @Assert\NotNull(message="Debe escribir un titulo")
 * @Assert\MaxLength(255)
 * @Assert\MinLength(5)
 */
 private $title;</pre>
<p>Con esto ya estamos controlando que mínimamente debemos escribir 5 caracteres en el título y como máximo 255.<br />
<div class="tipexperto"><h3>Nota</h3> <div class="tipcont">Cuando usamos el @Assert\MaxLength(), la cantidad de caracteres que permitimos debe ser menor o igual al length definido en el @ORM\Column() ya que de lo contrario la aplicación dejaría pasar valores mayores y al llegar a la base de datos nos devolvería un error pero del motor de datos.</div></div></p>
<p>Como ya había mencionado más arriba, en la <a href="http://symfony.com/doc/current/book/validation.html#constraints">documentación oficial</a> tenemos los constraints soportados y si damos click sobre cada uno de ellos veremos como  se utilizan con un ejemplo. Entre ellos encontrarán NotNull, NotBlank, Email, MinLength y MaxLength (para cantidad de caracteres), Max y Min (para valores numéricos), Date, DateTime, Time, Choice (para campos que serán ingresados por medio de un combo de valores por ejemplo).</p>
<p>Al escribir los Asserts en realidad estamos configurando las validaciones que queremos tener pero para validar los datos debemos invocar al validador. Para esto usemos como base el ejemplo que teníamos para la inserción de artículos del <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-manipulando-datos-con-doctrine/">capítulo anterior</a>:</p>
<pre>public function crearAction()
{
    $articulo = new Articles();
    $articulo-&gt;setTitle('Articulo de ejemplo 1');
    $articulo-&gt;setAuthor('John Doe');
    $articulo-&gt;setContent('Contenido');
    $articulo-&gt;setTags('ejemplo');
    $articulo-&gt;setCreated(new \DateTime());
    $articulo-&gt;setUpdated(new \DateTime());
    $articulo-&gt;setSlug('articulo-de-ejemplo-1');
    $articulo-&gt;setCategory('ejemplo');

    $em = $this-&gt;getDoctrine()-&gt;getEntityManager();
    $em-&gt;persist($articulo);
    $em-&gt;flush();

    return $this-&gt;render('MDWDemoBundle:Articulos:articulo.html.twig', array('articulo' =&gt; $articulo));
 }</pre>
<p>En código anterior, sin validar nada y pasando por alto los constraints de nuestro Entity intenta grabar los datos y si por ejemplo no cargamos un dato obligatorio como el título, el error devuelto será el que la misma base de datos valida ya que la columna fue creada como not null pero lo que queremos es poder obtener la validación en la aplicación, antes que llegue el insert a la base de datos, y esto lo haremos por medio del validador agregando el siguiente código antes de la invocación al EntityManager:</p>
<pre>$errores = $this-&gt;get('validator')-&gt;validate($articulo);</pre>
<p>Por medio del objeto $this-&gt;get(&#8216;validator&#8217;) le decimos que valide la entidad $articulo, quién ya sabe como validarse por si misma ya que los annotations están dentro de la misma. Este método validate() nos devolverá un array de errores que podemos iterar y obtenerlos por medio del método getMessage():</p>
<pre>public function crearAction()
{
    $articulo = new Articles();
    //-- No cargamos el dato para title
    $articulo-&gt;setAuthor('John Doe');
    $articulo-&gt;setContent('Contenido');
    $articulo-&gt;setTags('ejemplo');
    $articulo-&gt;setCreated(new \DateTime());
    $articulo-&gt;setUpdated(new \DateTime());
    $articulo-&gt;setSlug('articulo-de-ejemplo-1');
    $articulo-&gt;setCategory('ejemplo');

    $errores = $this-&gt;get('validator')-&gt;validate($articulo);

    if(!empty($errores))
    {
        foreach($errores as $error)
        echo $error-&gt;getMessage();

        return new Response();
    }

    $em = $this-&gt;getDoctrine()-&gt;getEntityManager();
    $em-&gt;persist($articulo);
    $em-&gt;flush();

    return $this-&gt;render('MDWDemoBundle:Articulos:articulo.html.twig', array('articulo' =&gt; $articulo));
 }</pre>
<p>En el código de arriba hemos borrado la línea del setTitle(). Esto nos mostrará en pantalla el mensaje &#8220;Debe escribir un titulo&#8221; y si tenemos más errores los mensajes por cada error.</p>
<p>Ahora bien, realmente no tiene mucho sentido mostrar de esta manera los mensajes de errores ya que finalmente ni siquiera cargamos los datos a mano como lo estamos haciendo, sino que son ingresados por un formulario y es aquí donde pasamos al siguiente tema, la creación de formularios.</p>
<h3>Creación de Formularios</h3>
<p>La posibilidad de crear formularios es uno de los temas que más me gusta de Symfony ya que los mismos no se escriben en HTML sino que son programados como objetos y el mismo framework se encarga de hacer render del HTML necesario y asegurándonos que serán escritos de la mejor manera posible incluso utilizando las validaciones de <a href="http://www.maestrosdelweb.com/guias/#guia-html5">HTML5</a>.</p>
<p>Un formulario siempre debería ser representado por un objeto que se lo conoce como <strong>Type</strong>. Este objeto hace referencia a otro que puede ser un Entity (del que ya hablamos en los capítulos anteriores) o un POPO (Plain Old PHP Object).<br />
<div class="tipexperto"><h3>Nota</h3> <div class="tipcont">Un POPO (Plain Old PHP Object) es simplemente una clase con propiedades y métodos tradicionales, es decir que es muy parecido a los Entities pero sin los annotations. Por ejemplo en caso de ser una clase que representará a un formulario para contacto donde tendremos simplemente una propiedad asunto, email, nombre y texto con sus respectivos setters y getters.</div></div></p>
<p>Un objeto <strong>Type</strong> se debe tomar como la definición del formulario. Este objeto recibirá cual es el Entity o POPO en el cual se almacenan los datos cargados en el formulario. Podríamos tener más de un Type para un mismo objeto ya que dependiendo de ciertos perfiles por ejemplo, podríamos querer mostrar algunos campos u otros dependiendo de que el usuario sea operador normal o administrador.</p>
<h4>Definición de nuestro formulario</h4>
<p>Para nuestro ejemplo tomaremos en cuenta el Entity Article que venimos usando y crearemos un objeto Type para representar a este formulario. Los formularios se deben crear dentro de nuestro Bundle en una carpeta Form por lo que crearemos el archivo <strong>ArticleType</strong> dentro de nuestra carpeta <strong>src/MDW/DemoBundle/Form</strong>:</p>
<pre>&lt;?php
namespace MDW\DemoBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class ArticleType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder-&gt;add('title')
                -&gt;add('author')
                -&gt;add('created');
    }
    public function getName()
    {
        return 'article_form';
    }
}</pre>
<p>Como podemos ver en el ejemplo, el nombre de la clase esta formado por un nombre que yo he elegido concatenado con el sufijo Type y debe heredar de AbstractType para contener las funcionalidades base.</p>
<p>En el método <strong>buildForm()</strong>, por medio del $builder, que se recibe como argumento, agregamos los campos que vamos a usar. Estos campos son los nombres de los campos que tendrá el formulario y deben coincidir con las propiedades de nuestro Entity Article aunque todavía no hemos dicho que el formulario representará a Article ya que eso lo hacemos en la invocación desde el controller. El argumento options nos servirá para crear el formulario con otras opciones de personalización.</p>
<p>El método <strong>getName()</strong> deberá retornar el identificador de nuestro formulario y este String puede tomar el nombre que queramos siempre y cuando sea único. Tenemos que tener en cuenta que este nombre será usado para los atributos &#8220;name&#8221; de los componentes de formularios. Por ejemplo vemos que tenemos un componente llamado &#8220;title&#8221; que hemos agregado en el método buildForm() por lo que la etiqueta creada será:</p>
<pre>&lt;input type="text" name="article_form[title]" /&gt;</pre>
<p>Hay que notar que esta es la sintaxis para cargar datos en un array (usando los corchetes) por lo que &#8220;article_form&#8221; será simplemente un array con una clave asociativa &#8220;title&#8221; que contendrá el valor ingresado por el usuario. Esta sintaxis nos permite tener en un array todos los datos del formulario al hacer el submit.</p>
<p>Con esto lo que hemos hecho es crear la representación básica de nuestro formulario, diciéndole cual es el identificador del formulario y los campos que deberá contener.</p>
<div class="tipexperto"><h3>Nota</h3> <div class="tipcont">Escribiendo los objetos Type NO definimos como será <span style="text-decoration: underline;">visualmente</span> el formulario sino como será <span style="text-decoration: underline;">CONCEPTUALMENTE</span>.</div></div>
<h4>Invocación y Visualización del formulario</h4>
<p>Para poder mostrar el formulario HTML en nuestra página debemos invocar a nuestra clase <strong>ArticleType</strong> desde nuestro controlador, o más específicamente desde el action que llama a nuestra página, para esto vamos a crear un action nuevo dentro de nuestro ArticulosController al que vamos a llamar newAction.</p>
<p>Primeramente creamos nuestra ruta en el archivo routing.yml</p>
<pre>articulo_new:
 pattern: /articulo/new
 defaults: { _controller: MDWDemoBundle:Articulos:new }</pre>
<p>Una vez creada nuestra ruta iremos a crear nuestro <strong>newAction</strong> en src\MDW\DemoBundle\Controller\ArticulosController.php (MDWDemoBundle:Articulos:new). Para esto agregamos el siguiente código:</p>
<pre>//--  Al estar utilizando la clase ArticleType dentro de nuestro método no debemos olvidar importar el namespace al principio del archivo
use MDW\DemoBundle\Form\ArticleType; 
//-- Agregar este método como uno nuevo
public function newAction()
{
    $articulo = new Articles();
    $form = $this-&gt;createForm(new ArticleType(), $articulo);
    return $this-&gt;render('MDWDemoBundle:Articulos:new.html.twig', array(
        'form' =&gt; $form-&gt;createView(),
    ));
}</pre>
<div class="tipexperto"><h3>Nota</h3> <div class="tipcont">Un dato importante es que en el código de arriba hemos creado un nuevo <strong>$articulo</strong> desde un <span style="text-decoration: underline;">objeto vacío</span> lo cual hará que el formulario se muestre vacío. Si queremos, por ejemplo en un formulario de modificación de registro, mostrar ya los datos del artículo a modificar esto simplemente implicaría obtener los datos desde la base de datos utilizando un DQL o el método find() que vimos en el capítulo anterior antes de pasarlo al método createForm().</div></div>
<p>El código que debe contener nuestro action es muy sencillo. Primeramente creamos un objeto Article y luego, por medio del método <strong>$this-&gt;createForm()</strong> invocamos a nuestro objeto <span style="text-decoration: underline;">ArticleType</span> pasándole nuestro objeto recién creado <span style="text-decoration: underline;">$articulo,</span> devolviéndonos un objeto de tipo formuario. Finalmente invocamos a la vista <span style="text-decoration: underline;">como siempre hacemos</span> y pasamos como parámetro el resultado de ejecutar $form-&gt;createView().</p>
<p>Con esto ya seremos capaces de ver el código de nuestra vista  <strong>MDWDemoBundle:Articulos:new.html.twig</strong> que de acuerdo a este nombre lógico debemos crear el archivo new.html.twig dentro de la carpeta src/MDW/DemoBundle/Resources/views/Articulos/ con el siguiente código:</p>
<pre>&lt;form action="{{ path('articulo_new') }}" method="post"&gt;
    {{ form_widget(form) }}
    &lt;input type="submit" /&gt;
&lt;/form&gt;</pre>
<p>La creación de la etiqueta formulario la hacemos normalmente así como también el botón de submit. Lo único importante aquí es que el action del form debe apuntar a la misma página por lo que creamos el link por medio de path(&#8216;articulo_new&#8217;).</p>
<p>La parte mágica está en {{ form_widget(form) }} donde, por medio de form_widget y Twig, pasamos como argumento la variable que nuestro action nos ha enviado y se imprime en la página el código necesario para nuestro formulario. Es decir que veremos el formulario al ingresar a la dirección:  <a href="http://localhost/Symfony/web/app_dev.php/articulo/new" target="_blank">http://localhost/Symfony/web/app_dev.php/articulo/new</a></p>
<p><img class="aligncenter" src="https://lh3.googleusercontent.com/-6AqVL9JpQ6s/T5b-A-i1DyI/AAAAAAAAAVU/NW5ePFHP_YE/s800/form1.png" alt="" width="198" height="122" /></p>
<p>Si miramos el código HTML veremos lo siguiente:</p>
<pre>&lt;form action="/Symfony/web/app_dev.php/articulo/new" method="post"&gt;
    &lt;div id="article_form"&gt;
        &lt;input type="hidden" id="article_form__token" name="article_form[_token]" value="62bc1a503b32de46b8755e9a5f5d8855bc8eb877" /&gt;
        &lt;div&gt;
            &lt;label for="article_form_title" class=" required"&gt;Title&lt;/label&gt;
            &lt;input type="text" id="article_form_title" name="article_form[title]" required="required" maxlength="20" /&gt;
        &lt;/div&gt;
       &lt;div&gt;
            &lt;label for="article_form_author" class=" required"&gt;Author&lt;/label&gt;
            &lt;input type="text" id="article_form_author" name="article_form[author]" required="required" maxlength="255" /&gt;
       &lt;/div&gt;
       &lt;div&gt;
             &lt;label class=" required"&gt;Created&lt;/label&gt;
             &lt;div id="article_form_created"&gt;
                 &lt;select id="article_form_created_year" name="article_form[created][year]" required="required"&gt;
                     &lt;option value="2007"&gt;2007&lt;/option&gt;
                     &lt;option value="2008"&gt;2008&lt;/option&gt;
                     ...
                 &lt;/select&gt;
             &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;input type="submit" /&gt;

&lt;/form&gt;</pre>
<div class="tipexperto"><h3>Nota</h3> <div class="tipcont">Muy importante es notar que a parte de los campos que hemos agregado para que sean mostrados en el $builder, también se muestra un campo article_form[_token] con un valor aleatorio. Esto lo hace automáticamente para luchar contra uno de los ataques más usados por los hackers llamado <a href="http://es.wikipedia.org/wiki/Cross_Site_Request_Forgery" target="_blank">CSRF</a>. Con eso ya vemos como Symfony nos propone ya un estándar de seguridad. A esta seguridad también se suma que por medio de Doctrine también tenemos validado los problemas de SQL Injection.</div></div>
<p>Si miramos el código podemos notar los atributos &#8220;name&#8221; como los explicamos arriba y también vemos que mágicamente el campo &#8220;created&#8221; se muestra como un campo para seleccionar una fecha. Esto es debido a que el framework reconoce el tipo de input a mostrar ya que sabe, por medio del objeto Articles, que esa propiedad es una fecha. Esto es tremendamente útil ya que muchas veces podría ya reconocer que type agregarle a las etiquetas input, pero si necesitamos definir por nosotros mismos el atributo type lo hacemos agregando un segundo argumento al momento de agregar el campo al $builder:</p>
<pre>public function buildForm(FormBuilder $builder, array $options)
{
    $builder-&gt;add('title')
        -&gt;add('author', 'checkbox')
        -&gt;add('created');
}</pre>
<p>Mientras que si necesitamos hacer que un campo no sea obligatorio lo hacemos enviando un array como tercer argumento ya que por defecto todos los campos son puestos como requeridos con validaciones HTML5:</p>
<pre>public function buildForm(FormBuilder $builder, array $options)
{
    $builder-&gt;add('title')
        -&gt;add('author', 'text', array('required' =&gt; false))
        -&gt;add('created');
}</pre>
<p>Como vemos el formulario HTML es impreso directamente en la página usando el {{ form_widget(form) }} incluyendo divs que nos ayudarán a formatear por medio de CSS y mejorar la estructura de mismo pero en caso de querer crear formularios más complejos en diseño también se cuentan con las siguientes opciones que para no extender mucho este capítulo lo veremos quizá en otra entrega:</p>
<ul>
<li><strong>form_errors(form):</strong> Renderiza lo errores que se encuentren en el formulario.</li>
<li><strong>form_rest(form):</strong> Renderiza los campos de formulario que no hayan sido agregados manualmente con el form_row.</li>
<li><strong>form_row(form.field):</strong> Renderiza un campo específico dentro de un div.</li>
<li><strong>form_errors(form.field):</strong> Renderiza el error para un campo específico.</li>
<li><strong>form_label(form.field):</strong> Renderiza la etiqueta label para un campo específico.</li>
<li><strong>form_widget(form.field):</strong> Renderiza un campo específico.</li>
</ul>
<h4>Procesamiento del Formulario</h4>
<p>Ahora que ya vimos como mostrar el formulario en la página y habiendo dicho el action de un form va al mismo action para ser procesado, entremos en detalle de las modificaciones que tenemos que tener en cuenta en el código original dentro del método newAction().</p>
<p>Lo primero que tenemos que pensar es que si para procesar el formulario llamamos al mismo action, ¿Cómo sabemos cuándo mostrar el formulario y cuándo procesarlo?. La respuesta es bien sencilla, cuando el request fue de tipo GET lo deberíamos de mostrar pero en caso de que se haya dado click en el botón submit se ejecuta un request de tipo POST y por lo tanto se debería procesar. Veamos el código modificado de nuestro newAction():</p>
<pre>public function newAction()
{
    //-- Obtenemos el request que contendrá los datos
    $request = $this-&gt;getRequest();

    $articulo = new Articles();
    $form = $this-&gt;createForm(new ArticleType(), $articulo);

    //-- En caso de que el request haya sido invocado por POST
    //   procesaremos el formulario
    if($request-&gt;getMethod() == 'POST')
    {
        //-- Pasamos el request el método bindRequest() del objeto 
        //   formulario el cual obtiene los datos del formulario
        //   y los carga dentro del objeto Article que está contenido
        //   también dentro del objeto Type
        $form-&gt;bindRequest($request);

        //-- Con esto nuestro formulario ya es capaz de decirnos si
        //   los dato son válidos o no y en caso de ser así
        if($form-&gt;isValid())
        {
            //-- Procesamos los datos que ya están automáticamente
            //   cargados dentro de nuestra variable $articulo, ya sea
            //   grabándolos en la base de datos, enviando un mail, etc

            //-- Finalmente, al finalizar el procesamiento, siempre es
            //   importante realizar una redirección para no tener el
            //   problema de que al intentar actualizar el navegador
            //   nos dice que lo datos se deben volver a reenviar. En
            //   este caso iremos a la página del listado de artículos
            return $this-&gt;redirect($this-&gt;generateURL('articulos'));
        }
    }
    return $this-&gt;render('MDWDemoBundle:Articulos:new.html.twig', array(
        'form' =&gt; $form-&gt;createView(),
    ));
}</pre>
<p>Como vemos en las explicaciones del código casi todo es automáticamente realizado por el objeto ArticleType quién al conocer el request ya nos devuelve el mismo objeto original $articulo que le fue entregado en el createForm(new ArticleType(), $articulo);.</p>
<p>En caso de que los datos no sean válidos y el método isValid() retorne false seguirá el hasta mostrar nuevamente el formulario llamando al método $this-&gt;render() y el {{ form_widget(form) }} puesto en nuestra misma vista se encargará de mostrar los errores de validación.</p>
<div class="tipexperto"><h3>Nota</h3> <div class="tipcont">Symfony2 agrega las validaciones de los formularios en HTML5 y del lado del servidor. Si el navegador no soporta las validaciones por medio de HTML5 el método isValid() lo valida en el servidor y al retornar la respuesta por el método render() se mostrarán los mensajes de validación del servidor. Puede que tu navegador ya acepte las validaciones HTML5 por lo que al intentar enviar los datos no notes la validación del lado del servidor aunque lo mismo se están realizando.</p>
<p>Por ejemplo el campo $title está puesto como &lt;input type=&#8221;text&#8221; id=&#8221;article_form_title&#8221; name=&#8221;article_form[title]&#8221; <strong>required=&#8221;required&#8221;</strong> <strong>maxlength=&#8221;255&#8243;</strong> <strong>pattern=&#8221;.{10,255}&#8221;</strong> /&gt; donde se puede ver que las validaciones de HTML5 fueron ya puestas.</p>
<p>Si no tienes un navegador que NO soporte HTML5 para probar como se muestran los mensajes de validación del servidor puedes, utilizando el Firebug del Firefox, eliminar el texto <strong>required=&#8221;required&#8221;</strong> <strong>maxlength=&#8221;255&#8243;</strong> <strong>pattern=&#8221;.{10,255}&#8221;</strong> de la etiqueta input y luego presionar el botón de submit <img src='http://www.maestrosdelweb.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Como verás, los hackers que quieren usar esta técnica también serán detenidos por las validaciones del servidor.</div></div>
<h3>Resumen Final</h3>
<p>En este capítulo hemos trabajado muchísimo viendo dos temas sumamente importantes: la validación de los Entities y los formularios.</p>
<p>Para las validaciones hemos hablado sobre los @Asserts, simples anotaciones que realizan validaciones poderosas con poco código y vemos que Symfony2 ya nos provee de la gran mayoría que necesitaremos usar.</p>
<p>Hablando sobre los formularios hemos notado la gran diferencia de diseñar los formularios y programar los formularios por medio de clases. Me gusta decir que en Symfony, el concepto de un formulario NO es simplemente introducción de texto sino introducción de texto VÁLIDO para la aplicación, libre de los problemas que hoy se tienen al crear un formulario a mano y tener que recordar pelear con ataques CSRF, XSS, SQL Injection y cambios en caliente con herramientas como Firebug.</p>
<p>El sub-framework de formularios es uno de los que más me hicieron sentir la diferencia entre usar un framework y no hacerlo y todavía hay muchas otras herramientas que nos permite usar como los formularios embebidos.</p>
<p>En el primer capítulo de esta guía hablamos sobre que uno de los objetivos de Symfony es plantear que cada cosa debe ir en su lugar, respetando el concepto del MVC. Con esto podemos ver que no solo podríamos tener un equipo de desarrollo, con personas expertas en cada área, trabajando con el modelado, otras con los controladores y a los diseñadores en la vista, sino que también podríamos hablar de personas que trabajen netamente en la creación de los formularios de la aplicación.</p>
<p>En el siguiente capítulo hablaremos sobre la integración de Ajax en nuestras aplicaciones hechas con Symfony2.</p>
<hr /><p style="height: 64px;"><img alt='Juan Ardissone' src='http://0.gravatar.com/avatar/2b99c333759f4f7f2fa8b1b1e1ca4804?s=64&amp;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&amp;r=G' class='avatar avatar-64 photo' height='64' width='64' style="float:left;padding:0 5px" /> <strong>Juan Ardissone</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-validacion-de-datos-y-creacion-de-formularios/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-validacion-de-datos-y-creacion-de-formularios/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/curso-symfony2-validacion-de-datos-y-creacion-de-formularios/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com//lh3.googleusercontent.com/-6AqVL9JpQ6s/T5b-A-i1DyI/AAAAAAAAAVU/NW5ePFHP_YE/s800/form1.png" />
		<media:content url="http://www.maestrosdelweb.com//lh3.googleusercontent.com/-6AqVL9JpQ6s/T5b-A-i1DyI/AAAAAAAAAVU/NW5ePFHP_YE/s800/form1.png" medium="image" />
		<media:content url="http://0.gravatar.com/avatar/2b99c333759f4f7f2fa8b1b1e1ca4804?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" medium="image">
			<media:title type="html">Juan Ardissone</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Curso Django: Instalación y primera aplicación</title>
		<link>http://www.maestrosdelweb.com/editorial/curso-django-instalacion-y-primera-aplicacion/</link>
		<comments>http://www.maestrosdelweb.com/editorial/curso-django-instalacion-y-primera-aplicacion/#comments</comments>
		<pubDate>Mon, 23 Apr 2012 07:00:50 +0000</pubDate>
		<dc:creator>Sergio Infante Montero</dc:creator>
				<category><![CDATA[django]]></category>
		<category><![CDATA[Editorial]]></category>
		<category><![CDATA[curso django]]></category>
		<category><![CDATA[descarga django]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[instalación django]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24036</guid>
		<description><![CDATA[Requisitos para su instalación Django es un framework hecho en Python, por lo tanto se necesita que hayas previamente instalado Python (2.6 o 2.7) y tengas a la mano tu editor de texto favorito. Si no sabes que editores de texto usar, o como instalar Python lee la primera parte de la Guia Python, con [...]]]></description>
			<content:encoded><![CDATA[<h2>Requisitos para su instalación</h2>
<p>Django es un framework hecho en Python, por lo tanto se necesita que hayas previamente instalado <a href="http://www.maestrosdelweb.com/editorial/guia-python/">Python</a> (2.6 o 2.7) y tengas a la mano tu editor de texto favorito. Si no sabes que editores de texto usar, o como instalar Python lee la <a href="http://www.maestrosdelweb.com/editorial/guia-python/">primera parte de la Guia Python</a>, con esto es suficiente para empezar a trabajar.</p>
<div class="tipexperto"><h3>Nota: Django y Python 3.0</h3> <div class="tipcont"> Django no funciona con Python 3.0 actualmente, debido a incompatibilidades con el intérprete de Python.</div></div>
<p>Al estar hecho en Python, sería bueno tener en cuenta la sintaxis y fundamentos de este lenguaje, así que si aún no lo sabes y quieres reforzar tus conocimientos, revisa <a href="http://www.maestrosdelweb.com/guias/#guia-python" title="Guía de Python en Maestros del Web">la guía de Python</a> primero antes de continuar con esta, o da un vistazo a este video de <a href="http://mejorando.la/" title="Mejorando la Web">mejorando.la</a></p>
<span style="text-align:center; display: block;"><a href="http://www.maestrosdelweb.com/editorial/curso-django-instalacion-y-primera-aplicacion/"><img src="http://img.youtube.com/vi/wp4DgNbGAUI/2.jpg" alt="" /></a></span>
<h2>Obtener Django</h2>
<p>Para obtener Django se puede:</p>
<ul>
<li><strong>Descargar la versión estable oficial más reciente</strong>, desde el <a href="https://www.djangoproject.com/download/">sitio oficial de Django</a> y descomprimir el archivo, debe aparecer una carpeta con el nombre de Django seguido del número de la versión bajada. (Para esta guía usaremos la versión 1.4)</li>
<li><strong>Obtener la versión de desarrollo desde el repositorio de Django</strong>, para ello se debe usar Subversión, de esta manera:
<div class="codigo">
<pre>
svn co http://code.djangoproject.com/svn/django/trunk/</pre>
</div>
<p>Una vez que se ha obtenido Django, es momento de instalarlo.</li>
</ul>
<h3>Python y las variables de entorno en Windows</h3>
<p>Los usuarios de Windows deben asegurarse de tener Python dentro de las variables de entorno, esto servirá para poder instalar Django y usarlo fácilmente. Si no sabes como hacerlo, mira el siguiente vídeo:</p>
<span style="text-align:center; display: block;"><a href="http://www.maestrosdelweb.com/editorial/curso-django-instalacion-y-primera-aplicacion/"><img src="http://img.youtube.com/vi/ciYoJPw9ORg/2.jpg" alt="" /></a></span>
<h2>Instalar Django</h2>
<p>Una vez que se descomprime el archivo descargado, debemos acceder a la carpeta desde una terminal o ventana de comandos (en caso de los usuarios de Windows). Suponiendo que la versión que elegimos es la 1.4, se tendría que digitar:</p>
<div class="codigo">
<pre> cd Django-1.4</pre>
</div>
<p>Ya en la carpeta de instalación de Django, se debe digitar la siguiente instrucción: (Debes de tener permisos de administrador)</p>
<div class="codigo">
<pre> python setup.py install</pre>
</div>
<p>Si usas Ubuntu GNU/Linux, sería algo así:</p>
<div class="codigo">
<pre>sudo python setup.py install</pre>
</div>
<p>Listo eso es todo, ya tienes Django instalado. Si se desea mayor información de como instalarlo o quizás algunas otras opciones, siempre está la documentación del mismo proyecto para guiarnos. Aquí pueden encontrar la<a href="https://docs.djangoproject.com/en/1.4/topics/install/"> Guía completa de instalación de Django</a>.</p>
<p>Si usas OS X Lion, quizás lo más recomendado sería instalar Django usando pip:<br />
Primero, debemos tener Setup Tools para instalarlo, lo descargamos, lo descomprimimos y dentro del directorio (via el terminal)</p>
<div class='codigo'>
<pre> sudo python setup.py install </pre>
</div>
<p>Una vez con Setup Tools instalado usamos pip:</p>
<div class='codigo'>
<pre> sudo pip install Django </pre>
</div>
<h2>Primer proyecto</h2>
<p>Antes de empezar es bueno aclarar que la versión que vamos a utilizar en esta guía es la más reciente (1.4), y varias cosas han cambiado, la información que podrían encontrar en Internet probablemente se encuentre desactualizada.</p>
<p>Para crear nuestro primer proyecto, abrimos una terminal (o ventana de comandos si asi lo conoces en windows), nos ubicamos en la carpeta en donde queremos crear nuestro proyecto y digitamos:</p>
<div class="codigo">
<pre>django-admin.py startproject recetario</pre>
</div>
<p>Esta instrucción creará dos directorios con el nombre del proyecto (en este caso: recetario) y 5 archivos distribuidos de la siguiente manera:</p>
<ul>
<li>manage.py</li>
<li>recetario
<ul>
<li>__init__.py</li>
<li>settings.py</li>
<li>urls.py</li>
<li>wsgi.py</li>
</ul>
</li>
</ul>
<p>Para ver que el proyecto está funcionando en la terminal debemos escribir:</p>
<div class="codigo">
<pre>python manage.py runserver</pre>
</div>
<p>Al ejecutar esa instrucción debemos visualizar un resultado como el siguiente:</p>
<div id="attachment_24070" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-runserver.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-runserver-450x113.png" alt="python manage.py runserver" width="450" height="113" class="size-medium wp-image-24070" /></a><p class="wp-caption-text">python manage.py runserver</p></div>
<p>Abrimos el navegador web la dirección <strong>http://127.0.0.1:8000/</strong> y debemos ver lo siguiente:</p>
<div id="attachment_24069" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-primer-web.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-primer-web-450x226.png" alt="Django http://127.0.0.1:8000" width="450" height="226" class="size-medium wp-image-24069" /></a><p class="wp-caption-text">Django http://127.0.0.1:8000</p></div>
<p>Ya tenemos nuestro proyecto creado. <img src='http://www.maestrosdelweb.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>En el caso de que nos salga un error porque el puerto asignado esta en uso como la siguiente imagen:</p>
<div id="attachment_24066" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-error-port.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-error-port-450x108.png" alt="Django en puertos en uso" width="450" height="108" class="size-medium wp-image-24066" /></a><p class="wp-caption-text">Django en puertos en uso</p></div>
<p>sólo debemos indicar que puerto usaremos para lanzar el servicio, por ejemplo si se desea usar el puerto 8888 entonces se tendría que digitar:</p>
<div class="codigo">
<pre>python manage.py runserver 8888</pre>
</div>
<p>Usaríamos la dirección <strong>http://127.0.0.1:8888/</strong> y tendríamos como resultado lo siguiente: </p>
<div id="attachment_24062" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-8888.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-8888-450x116.png" alt="Django en un puerto 8888" width="450" height="116" class="size-medium wp-image-24062" /></a><p class="wp-caption-text">Django en un puerto 8888</p></div>
<p>Cada proyecto necesita de aplicaciones donde se puedan gestionar los modelos y las vistas. Un proyecto puede tener muchas aplicaciones:</p>
<h2>Primera aplicación</h2>
<p>Para crear nuestra primer aplicación, desde la terminal y en la carpeta del proyecto, debemos digitar:</p>
<div class="codigo">
<pre>python manage.py startapp principal</pre>
</div>
<p>Esto creará un directorio y cuatro archivos más, lo que nos dejaría con una estructura de archivos como esta:</p>
<ul>
<li>manage.py</li>
<li>recetario
<ul>
<li>__init__.py</li>
<li>settings.py</li>
<li>urls.py</li>
<li>wsgi.py</li>
</ul>
</li>
<li>principal
<ul>
<li>__init__.py</li>
<li>models.py</li>
<li>test.py</li>
<li>views.py</li>
</ul>
</li>
</ul>
<h2>El poderoso settings.py</h2>
<p>Una parte muy importante del proyecto es el archivo <strong>settings.py</strong>, este archivo permite configurar la conexión a la base de datos, la zona horaria, el idioma, los directorios principales del proyecto, las aplicaciones del proyecto, entre otras cosas.</p>
<p>Aprender a configurar este archivo permite optimizar el funcionamiento del proyecto, veremos las instrucciones principales a configurar:</p>
<h4>Codificación de caracteres</h4>
<p>Nuestro idioma esta lleno de caracteres especiales como las tildes y las eñes que son las más comunes, la primera sugerencia para manejar esto eficientemente en django debemos agregar la siguiente línea al archivo settings.py</p>
<div class="codigo">
<pre>#encoding:utf-8</pre>
</div>
<h4>Ruta del proyecto</h4>
<p>Una configuración importante es configurar la ruta del proyecto, esto permitirá lanzar la aplicación desde cualquier directorio y mover el proyecto a cualquier computador con Django instalado. Para ello debemos escribir las siguientes líneas en el archivo settings.py:</p>
<div class="codigo">
<pre>
# Identificando la ruta del proyecto
import os
RUTA_PROYECTO = os.path.dirname(os.path.realpath(__file__))
</pre>
</div>
<div class='tipexperto'>
<h3>Ruta del proyecto</h3>
<div class='tipcont'>Si no se configura la ruta del proyecto, cada vez que se cambia de directorio o de PC, se tendrá que cambiar las rutas de las plantillas, archivos estáticos y directorio de subida de contenido de los usuarios.</div>
</div>
<h4>Administradores</h4>
<p>Cuando Django tiene la opción de DEBUG=False, las notificaciones de error de código deben ser enviadas vía correo electrónico a los administradores, junto con<br />
los detalles completos del error. Para poner los datos de los administradores debemos buscar la siguiente porción:</p>
<div class="codigo">
<pre>
ADMINS = (
    # ('Your Name', 'your_email@example.com'),
)
</pre>
</div>
<p>Y modificarla para que quede con los nombres de los administradores en forma de tupla, en mi caso lo dejaré así:</p>
<div class="codigo">
<pre>ADMINS = (
    ('Sergio Infante Montero', 'raulsergio9@gmail.com'),
)
</pre>
</div>
<h4>Configuración de la base de datos</h4>
<p>También podemos configurar la conexión a la base de datos según nuestras necesidades, Django soporta de manera predeterminada la conexión con postgresql, mysql, sqlite3 y oracle. En nuestro proyecto usaremos sqlite3.</p>
<p>Debemos buscar la siguiente sección del archivo:</p>
<div class="codigo">
<pre>
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': '',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}
</pre>
</div>
<p>Y dejarla de la siguiente manera:</p>
<div class="codigo">
<pre>
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'recetario.db',          # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}
</pre>
</div>
<h4>Zona Horaria</h4>
<p>Django permite configurar la zona horaria del proyecto, <a href="http://en.wikipedia.org/wiki/List_of_tz_zones_by_name" title="Lista de zonas horarias">la lista de zonas horarias disponibles</a> se pueden encontrar en la wikipedia. Para configurar debemos buscar lo siguiente:</p>
<div class="codigo">
<pre>TIME_ZONE = 'America/Chicago'</pre>
</div>
<p>Yo lo configurare en la zona horaria de Lima/Perú, así que lo modificare de esta forma:</p>
<div class="codigo">
<pre>TIME_ZONE = 'America/Lima'</pre>
</div>
<h4>Configuración del idioma</h4>
<p>Django también permite configurar el idioma que usará de manera predeterminada para su funcionamiento, para configurar esto debemos buscar lo siguiente:</p>
<div class="codigo">
<pre>LANGUAGE_CODE = 'en-us'</pre>
</div>
<p>Se puede consultar la <a href="http://www.i18nguy.com/unicode/language-identifiers.html" title="Lista de idiomas disponibles">lista de idiomas disponibles</a> para adecuarlo a nuestras necesidades, yo lo configurare como español de Perú:</p>
<div class="codigo">
<pre>LANGUAGE_CODE = 'es-PE'</pre>
</div>
<h3>Aplicaciones instaladas</h3>
<p>Un proyecto en Django necesita de aplicaciones, algunas ya vienen configuradas de manera predeterminada. En nuestro proyecto usaremos la aplicación de administración y su documentación, estas ya vienen construidas, y también nuestra primera aplicación creada líneas arriba, llamada principal. Para habilitar estas aplicaciones debemos buscar la siguiente sección que se encuentra casi al final del archivo <strong>settings.py</strong></p>
<div class="codigo">
<pre>
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    # 'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
)
</pre>
</div>
<p>Y modificarlas de la siguiente manera:</p>
<div class="codigo">
<pre>
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'django.contrib.admindocs',
    'principal',
)
</pre>
</div>
<h3>Otras opciones de settings.py</h3>
<p>Existen otras configuraciones que iremos modificando durante el desarrollo del curso, como el directorio de plantillas, el contenido estático, los archivos cargados por los usuarios, entre otras. Por ahora con estas instrucciones tenemos lo básico para continuar con nuestro proyecto.</p>
<h2>Creación de la base de datos</h2>
<p>Hasta el momento no se ha creado la base de datos o las tablas predeterminadas del proyecto, solo se ha configurado los parametros de conexión. Para crear la base de datos, debemos digitar desde la terminal o ventana de comandos, la siguiente instrucción (recordar que debemos estar en la carpeta de proyecto para que todo se realice correctamente):</p>
<div class="codigo">
<pre>python manage.py syncdb</pre>
</div>
<p>Esta instrucción deberá mostrar el siguiente resultado:</p>
<div id="attachment_24068" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-primer-syncdb.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-primer-syncdb-450x135.png" alt="python manage.py syncdb" width="450" height="135" class="size-medium wp-image-24068" /></a><p class="wp-caption-text">python manage.py syncdb</p></div>
<p>Hay una pregunta que debemos responder, se refiere a la creación de un superusuario (un administrador del proyecto), para lo cual respondemos: yes (en caso de responder negativamente, no podremos usar inmediatamente el administrador predeterminado de Django). Luego de ello completamos la información que nos solicita.</p>
<div id="attachment_24071" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-superuser.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-superuser-450x94.png" alt="Django creación del super usuario" width="450" height="94" class="size-medium wp-image-24071" /></a><p class="wp-caption-text">Django creación del super usuario</p></div>
<p>Al finalizar ya estará creada la base de datos, como en este proyecto se usara sqlite3, debera aparecer un archivo nuevo llamado recetario.db, este contiene las tablas y los datos iniciales del proyecto.</p>
<h2>Las direcciones URL del proyecto</h2>
<p>Para poder visualizar los cambios que hicimos y la interfaz administrativa de Django, aún falta modificar un archivo mas, este es: urls.py (recordar que este archivo se encuentra dentro del directorio recetario). Este archivo contiene lo siguiente:</p>
<div class="codigo">
<pre>
from django.conf.urls import patterns, include, url

# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'recetario.views.home', name='home'),
    # url(r'^recetario/', include('recetario.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    # url(r'^admin/', include(admin.site.urls)),
)
</pre>
</div>
<p>Debemos dejarlo de esta manera:</p>
<div class="codigo">
<pre>
from django.conf.urls import patterns, include, url
from django.contrib import admin

admin.autodiscover()

urlpatterns = patterns('',
    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    url(r'^admin/', include(admin.site.urls)),
)
</pre>
</div>
<h2>Ejecución del proyecto</h2>
<p>Una vez que tenemos todo listo y configurado, debemos nuevamente iniciar el servidor de desarrollo que tiene el proyecto. Ya hicimos esto al principio, solo debemos digitar desde la terminal nuevamente (dentro del directorio del proyecto):</p>
<div class="codigo">
<pre>python manage.py runserver</pre>
</div>
<p>Lucirá de esta manera:</p>
<div id="attachment_24067" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-first-web.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-first-web-450x226.png" alt="Django 404 predeterminado" width="450" height="226" class="size-medium wp-image-24067" /></a><p class="wp-caption-text">Django 404 predeterminado</p></div>
<p>Nos muestra un error 404, luego veremos el por qué. Para ingresar a la interfaz administrativa que ya viene construida con Django, ingresaremos a la dirección: <strong>http://127.0.0.1:8000/admin</strong>, en donde debemos poner el nombre del superusuario y su respectiva contraseña, creados anteriormente (líneas arriba) con la opción syncdb.</p>
<div id="attachment_24064" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-admin-login.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-admin-login-450x249.png" alt="Django admin login" width="450" height="249" class="size-medium wp-image-24064" /></a><p class="wp-caption-text">Django admin login</p></div>
<p>Si todo fue correcto debemos visualizar la interfaz administrativa:</p>
<div id="attachment_24063" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.maestrosdelweb.com/images/2012/04/django-admin-dashboard.png"><img src="http://www.maestrosdelweb.com/images/2012/04/django-admin-dashboard-450x255.png" alt="Interfaz administrativa predeterminada de Django" width="450" height="255" class="size-medium wp-image-24063" /></a><p class="wp-caption-text">Interfaz administrativa predeterminada de Django</p></div>
<p>Nuestro primer proyecto ya se encuentra configurado para continuar con la construcción de los modelos. Sin embargo antes de ello debemos entender como funciona Django, ese será nuestro próximo capítulo: <strong>Entendiendo como trabaja Django.</strong></p>
<div class='tipexperto'>
<h3>Repositorio del proyecto</h3>
<div class='tipcont'><a href="http://neosergio.github.com/recetario_mdw" title="Recetario para Maestros del Web en Github">El proyecto se encuentra en github</a> por si te perdiste de algo y deseas ver algún archivo del mismo.</div>
</div>
<p>Hasta la próxima semana <img src='http://www.maestrosdelweb.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<hr /><p style="height: 64px;"><img alt='Sergio Infante Montero' src='http://1.gravatar.com/avatar/3ca2b43e8aedb28a82fdca67e28281a1?s=64&amp;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&amp;r=G' class='avatar avatar-64 photo' height='64' width='64' style="float:left;padding:0 5px" /> <strong>Sergio Infante Montero</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/curso-django-instalacion-y-primera-aplicacion/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/curso-django-instalacion-y-primera-aplicacion/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/curso-django-instalacion-y-primera-aplicacion/feed/</wfw:commentRss>
		<slash:comments>97</slash:comments>
	
		<media:thumbnail url="http://img.youtube.com/vi/wp4DgNbGAUI/2.jpg" />
		<media:content url="http://img.youtube.com/vi/wp4DgNbGAUI/2.jpg" medium="image" />
		<media:content url="http://img.youtube.com/vi/ciYoJPw9ORg/2.jpg" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-runserver.png" medium="image">
			<media:title type="html">django-runserver</media:title>
			<media:description type="html">python manage.py runserver</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-runserver-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-primer-web.png" medium="image">
			<media:title type="html">django-primer-web</media:title>
			<media:description type="html">Django http://127.0.0.1:8000</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-primer-web-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-error-port.png" medium="image">
			<media:title type="html">django-error-port</media:title>
			<media:description type="html">Django en puertos en uso</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-error-port-150x137.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-8888.png" medium="image">
			<media:title type="html">django-8888</media:title>
			<media:description type="html">Django en un puerto 8888</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-8888-150x146.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-primer-syncdb.png" medium="image">
			<media:title type="html">django-primer-syncdb</media:title>
			<media:description type="html">python manage.py syncdb</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-primer-syncdb-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-superuser.png" medium="image">
			<media:title type="html">django-superuser</media:title>
			<media:description type="html">Django creación del super usuario</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-superuser-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-first-web.png" medium="image">
			<media:title type="html">django-first-web</media:title>
			<media:description type="html">Django 404 predeterminado</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-first-web-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-admin-login.png" medium="image">
			<media:title type="html">django-admin-login</media:title>
			<media:description type="html">Django admin login</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-admin-login-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/django-admin-dashboard.png" medium="image">
			<media:title type="html">django-admin-dashboard</media:title>
			<media:description type="html">Interfaz administrativa predeterminada de Django</media:description>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/django-admin-dashboard-150x150.png" />
		</media:content>
		<media:content url="http://1.gravatar.com/avatar/3ca2b43e8aedb28a82fdca67e28281a1?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" medium="image">
			<media:title type="html">Sergio Infante Montero</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Es viernes: Educación en línea y cursos gratuitos</title>
		<link>http://www.maestrosdelweb.com/editorial/educacion-en-linea-curso-gratuitos/</link>
		<comments>http://www.maestrosdelweb.com/editorial/educacion-en-linea-curso-gratuitos/#comments</comments>
		<pubDate>Fri, 20 Apr 2012 16:53:37 +0000</pubDate>
		<dc:creator>Stephanie Falla Aroche</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Productividad]]></category>
		<category><![CDATA[Capacitación]]></category>
		<category><![CDATA[cursos gratuitos]]></category>
		<category><![CDATA[educacion]]></category>
		<category><![CDATA[es viernes!]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24178</guid>
		<description><![CDATA[En el mundo de la tecnología desarrolladores y diseñadores expresan su descontento con el contenido de los cursos que se imparte en las universidades. Señalan las carencias del sistema, los lenguajes de programación, herramientas y procesos obsoletos no aplicables a la vida real. Sin embargo, en la actualidad tenemos recursos en línea para aprender de [...]]]></description>
			<content:encoded><![CDATA[<p>En el mundo de la tecnología desarrolladores y diseñadores expresan su descontento con el contenido de los cursos que se imparte en las universidades. Señalan las carencias del sistema, los lenguajes de programación, herramientas y procesos obsoletos no aplicables a la vida real. Sin embargo, en la actualidad tenemos recursos en línea para aprender de forma independiente pero son pocos los autodidactas que ponen disciplina al proceso de aprendizaje colaborativo para ser competitivos en su campo.</p>
<p><a href="http://www.maestrosdelweb.com/guias/"><img src="http://www.maestrosdelweb.com/images/2012/04/cursos.jpg" alt="Cursos Maestros del Web" /></a></p>
<p>Quiero compartir con ustedes algunos de los recursos que he encontrado en la web para capacitarme y también compartir los nuevo cursos que hemos diseñado para satisfacer esas necesidades que la comunidad ha expresado. Es fácil criticar al sistema y justificar nuestra carencias por la educación poco vigente, pero considero que ante esa problemática que experimenta Latinoamérica en general, debemos aprovechar mejor las herramientas actuales y disciplinarnos para iniciar un proceso según nuestras necesidades y que nos llene de satisfacción.</p>
<h3>Cursos, Guías y Streaming</h3>
<p>En línea existen muchas opciones para actualizarnos, pero lo más importante es cómo logramos la disciplina necesaria para aprovechar esos recursos. Además, nuestros proyectos tienen el mismo objetivo de proveer de información y conocimiento, por ello me gustaría que revisen los cursos que tenemos disponibles. </p>
<ul>
<li><a href="http://www.maestrosdelweb.com/editorial/plataformas-educativas-web/">Plataformas educativas:</a> Existen muchas plataformas diseñadas para ofrecer nuevas alternativas de educación y muchas de ellas utilizan el vídeo como un recurso primario, además de ofrecer alternativas de evaluación y ejercicios.</li>
<li><a href="http://www.maestrosdelweb.com/editorial/universidades-latino-america-recursos-gratuito/">Recursos gratuitos:</a> Además, las universidades al rededor del mundo están ofreciendo desde sus sitios conocimiento abierto, recursos y hasta cursos. </li>
<li><a href="http://www.maestrosdelweb.com/editorial/curso-django-introduccion">Curso Django:</a> El framework para perfeccionista, un curso diseñado para agilizar el desarrollo, con muchas ventajas y características para un trabajo más simple y eficiente. El curso arranca esta semana y puedes revisar el contenido completo. </li>
<li><a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-introduccion-instalacion">Curso Symfony:</a> El framework PHP orientado a objetos, fue diseñado para optimizar el desarrollo de aplicaciones Web y tienes un curso completo a tu disposición. </li>
<li><a href="http://www.maestrosdelweb.com/editorial/curso-android/">Curso Android:</a> Uno de nuestros cursos más famoso, con más de 100 mil lecturas y puedes descargarlo completo en diversos formatos. Además, puede hacer tus consultas en línea.</li>
<li><a href="http://www.maestrosdelweb.com/guias/">Guías:</a> Desde que arrancamos con nuestra sección de guías, nuestro catálogo sigue creciendo y lo que pretende es proveer de información y conocimiento para que los autodidactas sigan aprendiendo y creando contenido colaborativo a través de sus comentarios y sugerencias. Los invitamos a que descarguen nuestras guías en los hermosos formatos .PDF o los demás formatos.</li>
<li><a href="http://mejorando.la">Mejorando.la:</a> Finalmente quiero invitarte <strong>todos los jueves</strong> a que te conectes a mejorando.la el streaming en donde <a href="http://twitter.com/freddier">@freddier</a>, <a href="http://twitter.com/cvander">@cvander</a> y algunos invitados nos actualizan de las tendencias de la industria, imparten cursos, evaluan proyectos y nos muestran otras opciones de aprendizaje.</li>
</ul>
<p>Esperamos que estos recursos te sirvan como un primer paso para iniciar el proceso de aprendizaje. Recuerda que en ocasiones sólo depende de nosotros, los buenos hábitos y el aprovechar bien el tiempo para canalizar nuestra energía para mejorar y no para sólo quejarnos de lo que el sistema no nos puede proveer. Feliz fin de semana. Enjoy!</p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/128.png" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Stephanie Falla Aroche</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/educacion-en-linea-curso-gratuitos/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/educacion-en-linea-curso-gratuitos/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/educacion-en-linea-curso-gratuitos/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/cursos.jpg" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/cursos.jpg" medium="image">
			<media:title type="html">Cursos Maestros del Web</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/128.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Manipulando datos con Doctrine</title>
		<link>http://www.maestrosdelweb.com/editorial/curso-symfony2-manipulando-datos-con-doctrine/</link>
		<comments>http://www.maestrosdelweb.com/editorial/curso-symfony2-manipulando-datos-con-doctrine/#comments</comments>
		<pubDate>Wed, 18 Apr 2012 07:00:54 +0000</pubDate>
		<dc:creator>Juan Ardissone</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Guías]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=22615</guid>
		<description><![CDATA[En el capítulo anterior ya hemos configurado nuestra base de datos y hemos mostrado como, a partir de nuestra aplicación, crear la base de datos y las tablas. En este capítulo nos concentraremos en acceder a los datos de las tablas para consultarlos, insertarlos, actualizarlos y borrarlos. Al tener nuestro ORM bien configurado y nuestros [...]]]></description>
			<content:encoded><![CDATA[<p>En el <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-configurando-bases-de-datos/">capítulo anterior</a> ya hemos configurado nuestra base de datos y hemos mostrado como, a partir de nuestra aplicación, crear la base de datos y las tablas. En este capítulo nos concentraremos en acceder a los datos de las tablas para consultarlos, insertarlos, actualizarlos y borrarlos. Al tener nuestro ORM bien configurado y nuestros Entities mapeando las tablas veremos como fácilmente tenemos acceso a los datos de las mismas.</p>
<p>De ahora en más cuando nos refiramos a una tabla dentro de Symfony hablaremos de un entity o entidad ya que este último es la forma en que Symfony ve a las tablas es decir objetos. Recordemos que nuestras entidades se encuentran dentro de nuestro Bundle en de carpeta src\MDW\DemoBundle\Entity\ y tenemos mapeadas las tablas &#8220;articles&#8221; y &#8220;comments&#8221;.</p>
<p>El acceso a nuestras entidades se hará por medio de un objeto de Doctrine llamado <strong>EntityManager</strong> que vamos a decir que sería como el administrador de las entidades y quién sabrá como interactuar con ellas. Para obtener este objeto simplemente, dentro de nuestro action lo invocamos de la siguiente manera:</p>
<pre>$em = $this-&gt;getDoctrine()-&gt;getEntityManager();</pre>
<p>Con esto ya tenemos la referencia a este objeto dentro de una variable &#8220;$em&#8221;. Ahora bien, para trabajar con los datos necesitaremos de un <strong>repositorio</strong>. Este repositorio sería el objeto que nos permite solicitar y actualizar datos y para obtenerlo simplemente usamos el nombre lógico de nuestra entidad de esta manera:</p>
<pre>$em-&gt;getRepository('MDWDemoBundle:Articles');</pre>
<h2>Obteniendo Datos</h2>
<p>Para obtener datos de las tablas tenemos varios métodos realmente mágicos:</p>
<ul>
<li><strong>findAll():</strong> Obtiene todos los registros de la tabla. Retorna un array.</li>
<li><strong>find():</strong> Obtiene un registro a partir de la clave primaria de la tabla.</li>
<li><strong>findBy():</strong> Obtiene los registros encontrados pudiendo pasar como argumentos los valores que irían dentro del WHERE. Retorna un array.</li>
<li><strong>findOneBy():</strong> obtiene un registro pudiendo pasar como argumentos los valores que irían dentro del WHERE.</li>
</ul>
<p>Veamos unos ejemplos de la utilización de estos métodos:</p>
<pre>$em = $this-&gt;getDoctrine()-&gt;getEntityManager();
//-- Obtenemos todos los artículos de la tabla
$articulos = $em-&gt;getRepository('MDWDemoBundle:Articles')-&gt;findAll();
//-- Obtenemos el artículo con el id igual a 5
$articulo = $em-&gt;getRepository('MDWDemoBundle:Articles')-&gt;find(5);
//-- Obtenemos el artículo cuyo slug sea "articulo-1"
$articulos = $em-&gt;getRepository('MDWDemoBundle:Articles')-&gt;findOneBy(array('slug' =&gt; 'articulo-1'));
//-- Obtenemos todos los artículos de autor John Doe que sean de la categoría "Symfony"
$articulos = $em-&gt;getRepository('MDWDemoBundle:Articles')-&gt;findBy(
	array(
		'author' =&gt; 'John Doe',
		'category' =&gt; 'Symfony'
	)
);</pre>
<h2>Caso de ejemplo</h2>
<p>Para realizar nuestros ejemplos, crearemos unas páginas para nuestras pruebas. Primeramente como ya vimos en el capítulo 3 tenemos que crear nuestras rutas en el archivo src\MDW\DemoBundle\Resources\config\routing.yml, por lo tanto agreguemos el siguiente código:</p>
<pre>articulo_listar:
    pattern:  /articulos/listar
    defaults: { _controller: MDWDemoBundle:Articulos:listar }

articulo_crear:
    pattern:  /articulos/crear
    defaults: { _controller: MDWDemoBundle:Articulos:crear }

articulo_editar:
    pattern:  /articulos/editar/{id}
    defaults: { _controller: MDWDemoBundle:Articulos:editar }

articulo_visualizar:
    pattern:  /articulos/visualizar/{id}
    defaults: { _controller: MDWDemoBundle:Articulos:visualizar }

articulo_borrar:
    pattern:  /articulos/borrar/{id}
    defaults: { _controller: MDWDemoBundle:Articulos:borrar }</pre>
<p>Como segundo paso crearemos un nuevo controlador dentro de nuestro Bundle con el nombre ArticulosController.php. El archivo lo crearemos dentro de src\MDW\DemoBundle\Controller y contendrá inicialmente el siguiente código con 5 actions para nuestras pruebas, uno por cada ruta creada anteriormente:</p>
<pre>&lt;?php

namespace MDW\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use MDW\DemoBundle\Entity\Articles;

class ArticulosController extends Controller
{
	public function listarAction()
	{

	}

	public function crearAction()
	{

	}

	public function editarAction($id)
	{

	}

	public function borrarAction($id)
	{

	}
}</pre>
<p>Ahora crearemos dos plantillas para usarlas como visualización de respuesta de nuestros actions. Los archivos los crearemos en  src\MDW\DemoBundle\Resources\views\Articulos\ con los nombres <strong>listar.html.twig</strong> y <strong>articulo.html.twig</strong>.</p>
<ul>
<li><strong>listar.html.twig:</strong> Conforme un array de artículos crea una tabla para mostrar datos:</li>
</ul>
<pre>&lt;h1&gt;Listado de Articulos&lt;/h1&gt;
&lt;table border="1"&gt;
    &lt;tr&gt;
        &lt;th&gt;ID&lt;/th&gt;
        &lt;th&gt;Titulo&lt;/th&gt;
        &lt;th&gt;Fecha de Creacion&lt;/th&gt;
    &lt;/tr&gt;
    {% for articulo in articulos %}
    &lt;tr&gt;
        &lt;td&gt;{{ articulo.id }}&lt;/td&gt;
        &lt;td&gt;{{ articulo.title }}&lt;/td&gt;
        &lt;td&gt;{{ articulo.created | date('d-m-Y') }}&lt;/td&gt;
    &lt;/tr&gt;
    {% endfor %}
&lt;/table&gt;</pre>
<ul>
<li><strong>articulo.html.twig</strong>: Conforme a un artículo muestra sus datos:</li>
</ul>
<pre>&lt;h1&gt;Articulo con ID {{ articulo.id }}&lt;/h1&gt;
&lt;ul&gt;
    &lt;li&gt;Titulo: {{ articulo.title }}&lt;/li&gt;
    &lt;li&gt;Fecha de creacion: {{ articulo.created | date('d-m-Y') }}&lt;/li&gt;
&lt;/ul&gt;</pre>
<p>Ahora ya tenemos nuestro código inicial y así que comencemos a trabajar con los datos.</p>
<h2>Manipulando datos</h2>
<p><strong>1. Inserción de datos</strong><br />
Primeramente trabajaremos en el método crearAction() de nuestro ArticulosController en donde usaremos la entidad Articles para insertar registros. Para esto es bueno notar que en las primeras lineas de nuestro controlador estamos importando el namespace de la entidad con la palabra reservada &#8220;use&#8221;.</p>
<p>Crearemos un objeto nuevo de la manera tradicional:</p>
<pre>$articulo = new Articles();
$articulo-&gt;setTitle('Articulo de ejemplo 1');
$articulo-&gt;setAuthor('John Doe');
$articulo-&gt;setContent('Contenido');
$articulo-&gt;setTags('ejemplo');
$articulo-&gt;setCreated(new \DateTime());
$articulo-&gt;setUpdated(new \DateTime());
$articulo-&gt;setSlug('articulo-de-ejemplo-1');
$articulo-&gt;setCategory('ejemplo');</pre>
<p>Usando los setters insertamos los datos y pongamos atención en que no usamos el setId() ya que le dijimos a nuestra entidad que se encargue de generarlo por medio de la anotación @ORM\GeneratedValue(strategy=&#8221;AUTO&#8221;). Tambień notemos que para asignar las fechas de creación y modificación cargamos un objeto DateTime nuevo agregándole una barra invertida adelante para especificar que es una clase del CORE de php ya que si no la ponemos va a esperar que importemos un namespace tal cual como lo hicimos con la clase Articles.</p>
<p>Una vez que tenemos nuestro objeto creado por medio del EntityManager le diremos que sea insertado con el siguiente código:</p>
<pre>$em = $this-&gt;getDoctrine()-&gt;getEntityManager();
$em-&gt;persist($articulo);
$em-&gt;flush();</pre>
<p>Con el método persist() le decimos que el objeto pasado por argumento sea guardado para ser insertado y la inserción en sí se realizará cuando ejecutemos el método flush(). Con esta orden Doctrine generará la sentencia INSERT necesaria. Finalmente vamos a invocar a nuestra plantilla a quién le pasaremos el artículo para que muestre sus datos:</p>
<pre>return $this-&gt;render('MDWDemoBundle:Articulos:articulo.html.twig', array('articulo' =&gt; $articulo));</pre>
<p><strong> 2. Actualizando datos</strong><br />
La actualización de datos es exactamente igual a la inserción con la diferencia que estamos modificando un objeto Articles ya existente, para este ejemplo crearemos el siguiente código en el método editarAction($id):</p>
<pre>$em = $this-&gt;getDoctrine()-&gt;getEntityManager();

$articulo = $em-&gt;getRepository('MDWDemoBundle:Articles')-&gt;find($id);

$articulo-&gt;setTitle('Articulo de ejemplo 1 - modificado');
$articulo-&gt;setUpdated(new \DateTime());

$em-&gt;persist($articulo);
$em-&gt;flush();

return $this-&gt;render('MDWDemoBundle:Articulos:articulo.html.twig', array('articulo' =&gt; $articulo));</pre>
<p>El método obtiene el id que llega por GET y por medio del EntityManager obtiene el registro y nos devuelve el objeto al cual, usando los setters asignamos los cambios y de la misma forma que la inserción ejecutamos el persist() y el flush(). Esto creará un update en lugar de un insert ya que doctrine puede identificar perfectamente que el artículo ya existe en la base de datos porque ya fue persistido con anterioridad.</p>
<p><strong>3. Mostrando un listado de artículos</strong><br />
Para obtener todos los artículos de una entidad ya vimos el método findAll() por lo que tendremos el siguiente código dentro del método listarAction() para luego enviar el array de Articles a la vista que se encargará de mostrarlos en una tabla.</p>
<pre>$em = $this-&gt;getDoctrine()-&gt;getEntityManager();

$articulos = $em-&gt;getRepository('MDWDemoBundle:Articles')-&gt;findAll();

return $this-&gt;render('MDWDemoBundle:Articulos:listar.html.twig', array('articulos' =&gt; $articulos));</pre>
<p><strong>4. Eliminar un artículo</strong><br />
Para eliminar un artículo simplemente lo obtenemos e invocamos el método remove() que marcará el artículo para ser borrado hasta que ejecutemos el método flush(). Este código lo pondremos en el método borrarAction()</p>
<pre>$em = $this-&gt;getDoctrine()-&gt;getEntityManager();

$articulo = $em-&gt;getRepository('MDWDemoBundle:Articles')-&gt;find($id);

$em-&gt;remove($articulo);
$em-&gt;flush();

return $this-&gt;redirect(
    $this-&gt;generateUrl('articulo_listar')
);</pre>
<p>Una vez que lo borramos, redirigimos al usuario a la ruta &#8220;articulo_listar&#8221;.</p>
<h2>Formas alternativas de obtener datos</h2>
<p><strong>1. Extensión de los métodos findBy() y findOneBy()</strong><br />
Los métodos findBy() y findOneBy() tienen otros métodos similares conocidos como findBy*() y findOneBy*() donde el asterísco representa cualquier propiedad de nuestra entidad:</p>
<pre>//-- Obtenemos todos los artículos de la categoría 'Symfony'
$articulos = $em-&gt;getRepository('MDWDemoBundle:Articles')-&gt;findByCategory('Symfony');
//-- Obtenemos el artículo con el slug 'artículo-1'
$articulo = $em-&gt;getRepository('MDWDemoBundle:Articles')-&gt;findOneBySlug('articulo-1');</pre>
<p><strong>2. Utilizando las claves foráneas</strong><br />
Otra de las formas de obtener datos es por medio de las claves foráneas las cuales fueros configuradas en nuestra entidad por medio de los annotatios @ManyToOne, @OneToMany. Una vez que obtemos por ejemplo un artículo podríamos obtener todos sus comentarios de la siguiente manera.</p>
<pre>$em = $this-&gt;getDoctrine()-&gt;getEntityManager();
$articulo = $em-&gt;getRepository('MDWDemoBundle:Articles')-&gt;findOneBySlug('articulo-de-ejemplo-1');
$comentarios = $articulo-&gt;getComments();

foreach($comentarios as $c)
{
    echo $c-&gt;getContent();
}</pre>
<p>Al utilizar la clave foránea configurada en nuestra entidad invocando al getter getComments(), doctrine se encargará se generar la sentencia SELECT necesaria para obtener todos los comentarios.</p>
<p><strong>3. Generando DQL</strong><br />
Por si las formas de obtener datos que ya vimos nos quedan cortas, cosa que por lo general es así, Doctrine nos permite trabajar con algo muy parecido al SQL estándar al que estamos acostumbrados a trabajar solo que como estamos trabajando con el ORM se llama <a href="http://www.doctrine-project.org/docs/orm/2.1/en/reference/dql-doctrine-query-language.html" target="_blank">DQL</a> es decir Doctrine Query Language.</p>
<p>El DQL es realmente muy parecido al SQL con la diferencia que en lugar de hacer queries contra registros de las tablas, los hacemos sobre objetos de tipo Entity, por ejemplo un select bien sencillo:</p>
<pre>SELECT * FROM articles</pre>
<p>en DQL sería:</p>
<pre>select a from MDWDemoBundle:Articles a</pre>
<p>donde la &#8220;a&#8221; es nada más que un simple alias que podemos llamar como queramos. El cambio principal se nota en que en lugar se hacer referencia a la tabla articles estamos haciendo referencia a la entidad MDWDemoBundle:Articles. Con esta sintaxis estamos dejando que doctrine se encargue de la traducción al SQL necesario para el motor de base de datos utilizado y configurado inicialmente.</p>
<p>También es posible pedir solo algunos campos y no un SELECT * poniendo los nombres de las propiedades del objeto usando el alias:</p>
<pre>select a.id, a.title, c.author from MDWDemoBundle:Articles a</pre>
<p>Para decirle a Doctrine que ejecute este DQL lo hacemos a través del EntityManager de la siguiente manera:</p>
<pre>$em = $this-&gt;getDoctrine()-&gt;getEntityManager();
$dql = "select a from MDWDemoBundle:Articles a";
$query = $em-&gt;createQuery($dql);
$articulos = $query-&gt;getResult();</pre>
<p>Con el código anterior utilizamos el DQL para generar un objeto de Doctrine llamado &#8220;Doctrine_Query&#8221; representado por $query y luego a este objeto le pedimos que nos devuelva los resultados invocando al getResult() lo que nos devolverá un array de objetos Articles y para acceder a sus datos simplemente utilizamos los getters del objeto. Por ejemplo si quisieramos recorrer el array de articulos y obtener el id lo haríamos así ya que siguen siendo objetos metidos dentro de un array:</p>
<pre>foreach($articulos as $articulo)
{
    $id = $articulo-&gt;getId();
    $title = $articulo-&gt;getTitle();
}</pre>
<p>En caso de necesitar pasar filtros para el WHERE, podemos hacerlo usando el método setParameter() del objeto Doctrine_Query de la siguiente manera:</p>
<pre>$em = $this-&gt;getDoctrine()-&gt;getEntityManager();
$dql = "select a from MDWDemoBundle:Articles a where a.author=:author and a.title like :title";
$query = $em-&gt;createQuery($dql);
$query-&gt;setParameter('author', 'John Doe');
$query-&gt;setParameter('title', '%ejemplo 1%');
$articulos = $query-&gt;getResult();</pre>
<p>Con la utilización del setParameter() ya no nos preocupamos de poner por ejemplo comillas a los filtros que no son numéricos ya que Doctrine ya sabe de que tipo de dato es cada columna por medio de la definición que hicimos de la entidad.</p>
<p>También tenemos por supuesto soporte para unir entidades por medio de la cláusula JOIN por lo que este SQL estándar lo podríamos convertir a DQL de la siguiente manera:</p>
<pre>$em = $this-&gt;getDoctrine()-&gt;getEntityManager();
$dql = "select a.id, a.title, c.author
        from MDWDemoBundle:Comments c
        join c.article a
        where a.author=:author
        and a.title like :title";
$query = $em-&gt;createQuery($dql);
$query-&gt;setParameter('author', 'John Doe');
$query-&gt;setParameter('title', '%ejemplo 1%');
$articulos = $query-&gt;getResult();</pre>
<p>Hay una diferencia a la hora de obtener los datos. Ya que estamos obteniendo una mezcla de datos de articulos y comentarios, el método getResult() nos devuelve todo ya directamente en un array como siempre estuvimos acostumbrados a trabajar con PDO por lo tanto la estructura del array devuelto sería la siguiente:</p>
<pre>Array
(
    [0] =&gt; Array
    (
        [id] =&gt; 4
        [title] =&gt; Articulo de ejemplo 1
        [author] =&gt; Autor 1
    )
    [1] =&gt; Array
    (
        [id] =&gt; 4
        [title] =&gt; Articulo de ejemplo 1
        [author] =&gt; Autor 2
    )
)</pre>
<p><strong>4. Utilizando el Repositorio</strong><br />
En el capítulo anterior cuando nos ocupamos de crear nuestras entidades Articles y Comments con el generador doctrine:entity:create, se nos hizo una pregunta   sobre si queríamos que el generador nos cree un repositorio vacío para la entidad a crear y hemos dicho que sí. Esto hizo que se cree un segundo archivo a parte de la entidad llamado NombreEntidadRepository.php. Para nuestro ejemplo hemos creado el ArticlesRepository.php y el CommentsRepository.php.</p>
<p>Estos archivos se utilizan para organizar sentencias DQL de una entidad en cuestión. Por ejemplo, en lugar de tener todos los códigos de DQL escritos más arriba esparcidos por nuestros Controladores, podríamos ( y deberíamos para mantener el código más ordenado y mantenible)  tener todos las consultas relacionadas con los articulos dentro de nuestro repositorio ArticlesRepository.php. Esto es muy útil ya que desde el primer capítulo hablamos que Symfony intenta mantener todas las cosas en su lugar y es realmente útil.</p>
<p>En este mismo momento nuestro repositorio de artículos se encuentra de la siguiente manera:</p>
<pre>&lt;?php
namespace MDW\DemoBundle\Entity;
use Doctrine\ORM\EntityRepository;
/**
 * ArticlesRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class ArticlesRepository extends EntityRepository
{
}</pre>
<p>Dentro de esta clase crearemos métodos que serán cada una de nuestras consultas . Fijémonos que la clase hereda de EntityRepository lo cual ya nos da ciertas ventajas por ejemplo que para obtener el EntityManager simplemente tenemos que invocarlo como $this-&gt;getEntityManager(). Así que podríamos tener por ejemplo un método para obtener artículos de un autor con un cierto contenido en el título creando el siguiente método:</p>
<pre>public function findArticlesByAuthorAndTitle($author, $title)
{
    $em = $this-&gt;getEntityManager();

    $dql = "select a.id, a.title, c.author
        from MDWDemoBundle:Comments c
        join c.article a
        where a.author=:author
        and a.title like :title";

    $query = $em-&gt;createQuery($dql);
    $query-&gt;setParameter('author', $author);
    $query-&gt;setParameter('title', '%' . $title . '%');

    $articulos = $query-&gt;getResult();

    return $articulos;
}</pre>
<p>Una vez que tengamos nuestros métodos en el repositorio lo accedemos de la misma forma que los métodos find() o findAll() ya vistos dentro de nuestros actions en los controladores:</p>
<pre>$em = $this-&gt;getDoctrine()-&gt;getEntityManager();
$articulos = $em-&gt;getRepository('MDWDemoBundle:Articles')-&gt;findArticlesByAuthorAndTitle('John Doe', 'ejemplo 1');</pre>
<p>En cada repositorio podemos tener la cantidad de métodos que necesitemos y hasta podríamos hacer que métodos genéricos que reutilicen otros métodos de la misma clase lo cual, si pensamos en una aplicación que puede llegar a utilizar muchas sentencias SQL lograríamos tener un código mucho más ordenado y por supuesto también tenemos identificado donde pueden ocurrir los errores ya que cada cosa está en su lugar.</p>
<h2>Resumen Final</h2>
<p>Si pensáramos nuevamente en la arquitectura Model-View-Controller (MVC) estaríamos viendo que la <strong>presentación de los datos (View)</strong> se encuentran en las plantillas, la programación del <strong>modelado de datos y trabajo con los mismos (Model)</strong> se encuentran en las Entidades y Repositorios.</p>
<p>Por último nos queda la<strong> lógica de la aplicación (Controller)</strong> que se mantendrá dentro de los actions programados dentro de cada Controlador. Esto al mirarlo desde un enfoque de arquitectura de software demuestra un proyecto muy ordenado y por sobre todo con facilidades de mantener y escalar a futuro, con un equipo de desarrollo donde cada quién maneja su parte. Algo que siempre suelo decir es que si una página llega a tener más de 20 líneas de código es porque nos estamos olvidando de modularizar y es probable que una de las partes del MVC no se encuentre en el lugar correcto.</p>
<p>En el siguiente capítulo, el último orientado al modelado, hablaremos sobre la validación de los datos que Doctrine nos proporciona y sobre como Symfony nos ayuda a crear objetos de tipo formularios para que los usuarios finales interactuen con la aplicación.</p>
<hr /><p style="height: 64px;"><img alt='Juan Ardissone' src='http://0.gravatar.com/avatar/2b99c333759f4f7f2fa8b1b1e1ca4804?s=64&amp;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&amp;r=G' class='avatar avatar-64 photo' height='64' width='64' style="float:left;padding:0 5px" /> <strong>Juan Ardissone</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-manipulando-datos-con-doctrine/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-manipulando-datos-con-doctrine/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/curso-symfony2-manipulando-datos-con-doctrine/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:thumbnail url="http://0.gravatar.com/avatar/2b99c333759f4f7f2fa8b1b1e1ca4804?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" />
		<media:content url="http://0.gravatar.com/avatar/2b99c333759f4f7f2fa8b1b1e1ca4804?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" medium="image">
			<media:title type="html">Juan Ardissone</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Próximo curso: Django, el web framework para perfeccionistas</title>
		<link>http://www.maestrosdelweb.com/editorial/curso-django-introduccion/</link>
		<comments>http://www.maestrosdelweb.com/editorial/curso-django-introduccion/#comments</comments>
		<pubDate>Mon, 16 Apr 2012 07:00:03 +0000</pubDate>
		<dc:creator>Sergio Infante Montero</dc:creator>
				<category><![CDATA[django]]></category>
		<category><![CDATA[Editorial]]></category>
		<category><![CDATA[curso django]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Guías]]></category>
		<category><![CDATA[introduccion]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=22819</guid>
		<description><![CDATA[El crecimiento de Python es cada vez mayor y esto se ha hecho más notorio en los últimos años, con la aparición de herramientas que hacen el trabajo más simple y eficiente con este lenguaje de programación. Una de esas herramientas es Django, el framework hecho en python para perfeccionistas. Ventajas de Django Aparte de [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.maestrosdelweb.com/images/2012/01/python-django.png"><img style="float:right;padding:5px" class="alignleft size-thumbnail wp-image-22625" src="http://www.maestrosdelweb.com/images/2012/01/python-django-150x150.png" alt="Django y Python" width="150" height="150" /></p>
<p></a>El crecimiento de Python es cada vez mayor y esto se ha hecho más notorio en los últimos años, con la aparición de herramientas que hacen el trabajo más simple y eficiente con este lenguaje de programación. Una de esas herramientas es <a href="https://www.djangoproject.com/" title="Django Project">Django, el framework hecho en python para perfeccionistas</a>.</p>
<h2>Ventajas de Django</h2>
<p>Aparte de las ventajas que tiene por ser framework, Django promueve el desarrollo rápido, se construyen aplicaciones en cuestión de días y con el conocimiento suficiente esos días se pueden reducir a horas.</p>
<p>Django impulsa el desarrollo de código limpio al promover buenas prácticas de desarrollo web, sigue el <a href="http://es.wikipedia.org/wiki/No_te_repitas">principio DRY</a> (conocido también como Una vez y sólo una).</p>
<p>Django usa una modificación de la arquitectura <a href="http://es.wikipedia.org/wiki/Modelo_Vista_Controlador" title="MVC">Modelo-Vista-Controlador (MVC)</a>, <a href="http://jeffcroft.com/blog/2007/jan/11/django-and-mtv/" title="Django MTV ">llamada MTV (Model &#8211; Template &#8211; View)</a>, que sería Modelo-Plantilla-Vista, está forma de trabajar permite que sea pragmático.</p>
<h2>Origen de Django</h2>
<p>Django nace como un proyecto para publicación de noticias de <a href="http://www2.ljworld.com/" title="Lawrence Journal World">Lawrence Journal-World</a>, lo interesante de Django es que desde un principio fue construido como una herramienta para resolver problemas reales en un entorno empresarial, fue diseñado para optimizar el tiempo de desarrollo y los requerimientos exigentes de los desarrolladores web. </p>
<p>El nombre de Django es en honor al famoso músico frances Django Reinhardt.</p>
<span style="text-align:center; display: block;"><a href="http://www.maestrosdelweb.com/editorial/curso-django-introduccion/"><img src="http://img.youtube.com/vi/nS2ylPAUxzA/2.jpg" alt="" /></a></span>
<h2>¿Quienes usan Django?</h2>
<p>La lista de sitios web alrededor del mundo es enorme, pero es bueno fijarnos en los sitios más populares que usan Django como solución a sus necesidades. Estos son:</p>
<ul>
<li><a href='http://dpaste.com/'>dpaste.com</a></li>
<li><a href='http://www.washingtonpost.com/'>The Washington post (en parte)</a></li>
<li><a href='https://bitbucket.org/'>Bitbucket.org</a></li>
<li><a href='http://disqus.com/'>Disqus</a></li>
<li><a href='http://instagram.com/'>Instagram</a></li>
<li><a href='http://pinterest.com/'>Pinterest</a></li>
<li><a href='http://michaelmoore.com/'>michaelmoore.com</a></li>
<li><a href='http://www.guardian.co.uk/'>theguardian</a></li>
<li><a href='http://www.lawrence.com/'>lawrence.com</a></li>
<li><a href='http://curse.com/'>curse</a></li>
<li><a href='http://projects.nytimes.com/represent/'>The New York Times (represent project)</a></li>
<li><a href='http://www.fluendo.com/'>Fluendo</a></li>
</ul>
<p>Se pueden encontrar mas casos de implementación e incluso varios de ellos con el código fuente en <a href='http://www.djangosites.org/'>djangosites</a>.</p>
<h2>Django en América Latina</h2>
<p>En américa latina las experiencias con Django también están presentes, en la mayoria de paises ya se han hecho implementaciones y desarrollo con este estupendo framework. Por ejemplo en el Campus Party de Colombia del 2010 se dio esta presentación:</p>
<span style="text-align:center; display: block;"><a href="http://www.maestrosdelweb.com/editorial/curso-django-introduccion/"><img src="http://img.youtube.com/vi/pQTlJ1-ODuU/2.jpg" alt="" /></a></span>
<h2>¿Dónde encontrar mayor información sobre Django?</h2>
<p>La mejor fuente de información con respecto a Django es la <a href="https://docs.djangoproject.com/en/1.4/">documentación oficial del proyecto</a>, también existen otras fuentes muy buenas de información, aquí una lista de estos recursos:</p>
<ul>
<li><a href="http://django.es/">Django en Español</a>: Sitio web de la comunidad española de Django.</li>
<li><a href="http://groups.google.com/group/django-es">Grupo de Google para usuarios de habla hispana de Django</a>.</li>
<li><a href="http://djangosnippets.org/">Django Snippets</a>: Sitio donde se comparten Snippets</li>
</ul>
<h2>Curso Django en Maestros del web</h2>
<p>En Maestros del Web desarrollaremos un curso para aprender el uso de este potente framework, en el encontrarán recursos, recomendaciones, videos para que puedan usarlos como referencia y lograr cosas geniales en corto tiempo.</p>
<h2>Modo de trabajo</h2>
<p>Con el contenido del curso desarrollaremos una aplicación sencilla tocando los puntos más importantes. La aplicación será un recetario de comidas y bebidas, el cual se ira construyendo a lo largo de los capítulos, el código será publicado en github.</p>
<h2>Lanzamiento de curso en línea</h2>
<p>Cada lunes estaremos publicando un capítulo del curso iniciando la próxima semana. Los 10 capítulos a desarrollar en el curso son:<br />
<img style="float:right;padding:5px" src="http://www.maestrosdelweb.com/images/2012/04/curso-django-libro.jpg" alt="django-libro" />
<ol>
<li>Instalación y primera aplicación</li>
<li>Entendiendo como trabaja Django</li>
<li>El modelo de datos</li>
<li>El Shell de Django</li>
<li>Las vistas</li>
<li>Las plantillas</li>
<li>Los formularios</li>
<li>Los archivos estáticos</li>
<li>Gestión de usuarios</li>
<li>Despliegue en el servidor web</li>
</ol>
<p>Al finalizar la guía estará disponible para descargar en los formatos: .PDF, .epub y disponible en Amazon para el Kindle. </p>
<hr /><p style="height: 64px;"><img alt='Sergio Infante Montero' src='http://1.gravatar.com/avatar/3ca2b43e8aedb28a82fdca67e28281a1?s=64&amp;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&amp;r=G' class='avatar avatar-64 photo' height='64' width='64' style="float:left;padding:0 5px" /> <strong>Sergio Infante Montero</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/curso-django-introduccion/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/curso-django-introduccion/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/curso-django-introduccion/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/01/python-django-150x150.png" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/01/python-django.png" medium="image">
			<media:title type="html">python-django</media:title>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/01/python-django-150x150.png" />
		</media:content>
		<media:content url="http://img.youtube.com/vi/nS2ylPAUxzA/2.jpg" medium="image" />
		<media:content url="http://img.youtube.com/vi/pQTlJ1-ODuU/2.jpg" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/curso-django-libro.jpg" medium="image">
			<media:title type="html">django-libro</media:title>
		</media:content>
		<media:content url="http://1.gravatar.com/avatar/3ca2b43e8aedb28a82fdca67e28281a1?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" medium="image">
			<media:title type="html">Sergio Infante Montero</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Es viernes: ¿Qué quieren saber los freelancers?</title>
		<link>http://www.maestrosdelweb.com/editorial/informacion-para-freelancer/</link>
		<comments>http://www.maestrosdelweb.com/editorial/informacion-para-freelancer/#comments</comments>
		<pubDate>Fri, 13 Apr 2012 18:29:09 +0000</pubDate>
		<dc:creator>Stephanie Falla Aroche</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Productividad]]></category>
		<category><![CDATA[ebook]]></category>
		<category><![CDATA[es viernes!]]></category>
		<category><![CDATA[Freelancer]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=24125</guid>
		<description><![CDATA[Proveer de información, conocimiento y experiencias de aprendizajes son los objetivos de nuestros proyectos en la web. Hace varios años empecé escribiendo en este espacio con el objetivo de resolver dudas, plantear cuestionamiento y hacer debate en los comentarios. Nuestros proyectos buscan satisfacer las necesidades de quienes lo utilizan y en esta ocasión quiero compartir [...]]]></description>
			<content:encoded><![CDATA[<p>Proveer de información, conocimiento y experiencias de aprendizajes son los objetivos de nuestros proyectos en la web. Hace varios años empecé escribiendo en este espacio con el objetivo de resolver dudas, plantear cuestionamiento y hacer debate en los comentarios. Nuestros proyectos buscan satisfacer las necesidades de quienes lo utilizan y en esta ocasión quiero compartir con ustedes el próximo proyecto que pretende ser ayuda para los freelancer en Latinoamérica.</p>
<p><a href="http://www.flickr.com/photos/peterpearson/518529136/"><img src="http://www.maestrosdelweb.com/images/2012/04/athome.jpeg" alt=" ¿Qué quieren saber los freelancers?" /></a></p>
<p>&#8220;<a href="http://www.maestrosdelweb.com/comunicación">Adictos a la comunicación</a>&#8221; fue mi primer ebook publicado en <a href="http://www.twitter.com/maestros">@maestros</a> en 2011, el cual cuenta con más de 100 mil descargas. Al ver la reacción a este proyecto, se me ocurrió el desarrollo de una nueva guía pero esta vez enfocada a <strong>Freelancers</strong>, pero con la idea de responder <strong>¿qué quieres saber los freelancers?</strong> <strong>¿qué información necesitan?</strong> <strong>¿qué temas les gustaría que se desarrollen en ella?</strong></p>
<h3>Guía para Freelancers</h3>
<p>Con ese objetivo, lanzo este artículo en donde me gustaría conocer ¿qué información y conocimiento necesitan? en el transcurso de esta serie de Es viernes! me he alimentado de sus ideas, comentarios y sugerencias para seguir desarrollando contenidos. Pero, en esta ocasión me gustaría ser más directa y preguntarles sobre la información que quieren leer en un ebook sobre <strong>&#8220;Freelancer&#8221;</strong> precisamente porque a estas alturas, considero que el tiempo es muy valioso y también la interacción, me resulta más dinámico escribir un texto que satisface necesidades a escribir mis percepciones o experiencias individuales.</p>
<p>Creemos que este será un proyecto interesante, en el que junto a mi socio <a href="http://www.twitter.com/cvander">Cvander</a> podemos resolver puntualmente las dudas, brindar sugerencias, investigar y plasmar la información exacta que ustedes necesitan obtener de una <strong>Guía para Freelancers</strong>. Les agradeceré que en sus comentarios realicen sus propuestas de los temas que les gustaría que desarrollemos. Luego de su retroalimentación, empezaremos a trabajar en ello y esperamos que sea un nuevo ebook de referencia, utilidad y satisfaga sus necesidades. </p>
<h3>¿Por qué es importante emprender este tipo de proyectos?</h3>
<p>Cuando te has especializado en algún tema, la mejor forma de seguir aprendiendo sobre él y de concretizar tus ideas es cuando lo compartes y produces conocimiento. Escribir no es una tarea sencilla, empezando porque organizar las ideas para que ese conocimiento tenga forma y llegue a otros no siempre se logra. Además, porque siempre habrán críticas sobre lo que haces y no todos estamos dispuestos a exponer públicamente lo que sabemos.</p>
<p>Pero, recuerda que en la actualidad, cuando buscas trabajar con alguien o pides trabajo, lo primero que harás o te pedirán es una prueba de lo que sabes. Por ello, creemos que nuestra mejor carta de presentación ante el mundo son nuestros proyectos, las tecnologías que usamos, la forma en que nos proyectamos en los medios sociales, la opinión que nos atrevemos a emitir en los diversos canales y sobre todo el contenido que producimos.</p>
<p>Entonces, nos encantaría emprender este proyecto de una <strong>Guía para Freelancers</strong> conociendo las necesidades principales de nuestros lectores, escríbenos sobre los temas que te gustaría encontrar en el proyecto y cada sugerencias será tomada en cuenta para construir contenido de calidad y que satisface tus necesidades de conocimiento. Desde ya, gracias por sus comentarios. Buen fin de semana. Enjoy!</p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/128.png" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Stephanie Falla Aroche</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/informacion-para-freelancer/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/informacion-para-freelancer/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/informacion-para-freelancer/feed/</wfw:commentRss>
		<slash:comments>38</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/athome.jpeg" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/athome.jpeg" medium="image">
			<media:title type="html"> ¿Qué quieren saber los freelancers?</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/128.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Configurando nuestra Base de Datos</title>
		<link>http://www.maestrosdelweb.com/editorial/curso-symfony2-configurando-bases-de-datos/</link>
		<comments>http://www.maestrosdelweb.com/editorial/curso-symfony2-configurando-bases-de-datos/#comments</comments>
		<pubDate>Wed, 11 Apr 2012 15:01:18 +0000</pubDate>
		<dc:creator>Juan Ardissone</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Guías]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[curso]]></category>
		<category><![CDATA[guia]]></category>
		<category><![CDATA[symfony2]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=22345</guid>
		<description><![CDATA[En este capítulo entraremos al mundo de Doctrine usándolo dentro de nuestro proyecto para así tener ya los datos dinámicamente almacenados en nuestra base de datos y poder manipularlos. Como ya lo habíamos hablado en el capítulo 1, Doctrine es un ORM (Object-Relational Mapping). Cuando hablamos de relaciones en conceptos de base de datos, estamos [...]]]></description>
			<content:encoded><![CDATA[<p>En este capítulo entraremos al mundo de Doctrine usándolo dentro de nuestro proyecto para así tener ya los datos dinámicamente almacenados en nuestra base de datos y poder manipularlos.</p>
<p>Como ya lo habíamos hablado en el <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-introduccion-instalacion/">capítulo 1</a>, Doctrine es un ORM (Object-Relational Mapping). Cuando hablamos de relaciones en conceptos de base de datos, estamos refiriéndonos a las tablas diciendo entonces que existe una vinculación entra las tablas y objetos. Al usar un ORM mapeamos cada tabla con objetos dentro de nuestras aplicaciones, por ejemplo si tenemos una tabla de personas en la base de datos, tendremos un objeto Persona en la aplicación que conoce cuales son sus campos, tipos de datos, índices, etc. logrando con esto que la <strong>aplicación</strong> conozca el <strong>modelo de los datos</strong> desde un punto de vista orientado a objetos, es decir representado con Clases y Objetos.</p>
<p>Doctrine nos permitirá, conociendo nuestras tablas como hablamos anteriormente, crear las sentencias SQL por nosotros ya que toda la información necesaria para crear estos queries se encuentra &#8220;mapeada&#8221; en código PHP.</p>
<p>Como si esto fuera poco, la mayor de las ventajas de contar con un ORM será que nos permite como desarrolladores, abstraernos de que motor de base de datos estemos usando para el proyecto y nos permitirá, con solo un poco de configuración, cambiar toda nuestra aplicación por ejemplo de una base de datos MySQL a PostgreSQL o a cualquier otra soportada por el framework Doctrine.</p>
<h2>Configuración de la base de datos</h2>
<p>Para configurar los datos de la conexión del servidor de base de datos se deberán ingresar los valores en el archivo app\config\parameters.ini dentro de las variables ya definidas:</p>
<ul>
<li><code><code>database_driver = pdo_mysql</code></code></li>
<li><code><code>database_host = localhost</code></code></li>
<li><code><code>database_port =</code></code></li>
<li><code><code>database_name = blog</code></code></li>
<li><code><code>database_user = maestros</code></code></li>
<li><code><code>database_password = clavesecreta</code></code></li>
</ul>
<p>Estos datos serán usados por Doctrine para conectarse al servidor y trabajar con la base de datos. No hay necesidad de ingresar el puerto si se está usando el que figura por defecto para la base de datos que usemos, para nuestro caso MySQL.</p>
<p>Una vez que ya tenemos configurada nuestra base de datos, podemos usar el comando &#8220;console&#8221; para decirle a nuestro proyecto que se encargue de crear la base de datos en el servidor ejecutándolo de la siguiente manera:</p>
<p><code>C:\wamp\www\Symfony&gt;php app\console doctrine:database:create<br />
Created database for connection named &lt;comment&gt;blog&lt;/comment&gt;</code></p>
<p>Esto nos retornará un mensaje diciéndonos, si los permisos estaban correctos, que la base de datos <strong>blog</strong> fue creada. Podemos revisar ahora nuestra base de datos por medio del phpMyAdmin y veremos que la base de datos ya existe.</p>
<div class="tipexperto"><h3>Nota</h3> <div class="tipcont">En caso de necesitar borrar la base de datos podemos usar el comando &#8220;doctrine:database:create &#8211;force&#8221;, donde tendremos que pasarle el parámetro especial &#8211;force para confirmar que ejecute la acción.</div></div>
<p>El concepto que suele ser muy utilizado en frameworks de este tipo es ir <strong>creando la base de datos desde la aplicación</strong>, es decir, que la aplicación se encargue de crear la base de datos, las tablas, relaciones, índices y los datos de ejemplo. Este concepto lo iremos ahondando durante estos capítulos.</p>
<h2>Creando las tablas y conociendo las Entidades</h2>
<p>Como ejemplo usaremos dos tablas para nuestro manual simplemente para ver como trabajar con ellas usando el framework. Crearemos una tabla de Artículos y una de Comentarios para tener como ejemplo el concepto ya bien conocido de un blog.</p>
<p>A continuación tenemos el SQL de las tablas con sus campos:</p>
<pre>CREATE TABLE IF NOT EXISTS `articles` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `author` varchar(255) NOT NULL,
  `content` longtext NOT NULL,
  `tags` varchar(255) NOT NULL,
  `created` date NOT NULL,
  `updated` date NOT NULL,
  `slug` varchar(255) NOT NULL,
  `category` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `comments` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `author` varchar(255) NOT NULL,
  `content` longtext NOT NULL,
  `reply_to` int(11) NOT NULL,
  `article_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_A6E8F47C7294869C` (`article_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;</pre>
<p>Para crear estas tablas en la base de datos primeramente lo haremos en código PHP para que Doctrine conozca perfectamente las tablas para poder interactuar con ellas. Es aquí donde conocemos el concepto de las Entidades (Entities). Una entidad es la representación &#8220;orientada a objetos&#8221; de nuestras tablas, es decir que crearemos una clase por cada una de nuestras tablas. Para no tener que escribirlas a mano, Symfony nos provee un generador de Entidades que es invocado con nuestro comando console de la siguiente manera:</p>
<pre>C:\wamp\www\Symfony&gt;php app\console doctrine:generate:entity</pre>
<p>Al darle enter nos preguntará el nombre que usaremos para nuestra entidad y hay que entender que sigue el siguiente formato: <strong>IdentificadorDelBundle:NombreEntidad</strong>. Para nuestro caso, y como ya vimos en los capítulos anteriores, nuestro identificador del Bundle es MDWDemoBundle y primero crearemos la entidad para nuestra tabla de artículos por lo tanto escribiremos lo siguiente:</p>
<pre>The Entity shortcut name: MDWDemoBundle:Articles</pre>
<p>Al darle enter nos preguntará que formato queremos usar para agregar los metadatos que mapearan a la tabla proponiéndonos [annotation]. Aceptaremos la propuesta presionando Enter</p>
<pre>Configuration format (yml, xml, php, or annotation) [annotation]:</pre>
<p>Luego ya nos empezará a preguntar cuales serán las columnas de nuestra tabla y por cada columna el tipo de dato que arriba nos deja como ejemplo cuales podemos elegir. En caso de que sea un tipo de datos que necesite longitud también nos la pedirá y cuando ya no queramos ingresar columnas simplemente daremos un enter dejando vacío el valor.</p>
<div class="tipexperto"><h3>Nota</h3> <div class="tipcont">No será necesario ingresar el campo id de la tabla ya que Symfony lo creará automáticamente con la idea de ser usado como clave primaria autonumérica.</div></div>
<p>Una vez finalizada la carga de los campos, nos preguntará si queremos crear un repositorio vacío a lo que contestaremos SI para luego, como último paso preguntarnos si confirmamos la creación automática de la Entidad a lo que también diremos que SI:</p>
<pre>Instead of starting with a blank entity, you can add some fields now.
Note that the primary key will be added automatically (named id).

Available types: array, object, boolean, integer, smallint,
bigint, string, text, datetime, datetimetz, date, time, decimal, float.

New field name (press &lt;return&gt; to stop adding fields): title
Field type [string]:
Field length [255]:

New field name (press &lt;return&gt; to stop adding fields): author
Field type [string]:
Field length [255]:

New field name (press &lt;return&gt; to stop adding fields): content
Field type [string]: text

New field name (press &lt;return&gt; to stop adding fields): tags
Field type [string]:
Field length [255]:

New field name (press &lt;return&gt; to stop adding fields): created
Field type [string]: date

New field name (press &lt;return&gt; to stop adding fields): updated
Field type [string]: date

New field name (press &lt;return&gt; to stop adding fields): slug
Field type [string]:
Field length [255]:

New field name (press &lt;return&gt; to stop adding fields): category
Field type [string]:
Field length [255]:

New field name (press &lt;return&gt; to stop adding fields):

Do you want to generate an empty repository class [no]? yes

Summary before generation

You are going to generate a "MDWDemoBundle:Articles" Doctrine2 entity
using the "annotation" format.

Do you confirm generation [yes]?

Entity generation

Generating the entity code: OK

You can now start using the generated code!</pre>
<p>Una vez finalizado el generador, tendremos dos archivos creados dentro de la carpeta src\MDW\DemoBundle\Entity ya que como prefijo de nuestro nombre de Entidad usamos el identificador de nuestro Bundle (MDWDemoBundle). El primer archivo será nuestra entidad Articles.php y el otro será el repositorio de esa entidad ArticlesRepository.php del cual hablaremos en el siguiente capítulo.</p>
<p>Si revisamos el contenido de estos archivos podremos ver que es una Clase con el nombre Articles y que contiene como propiedades los datos que hemos cargado de las columnas de la tabla incluyendo sus métodos getters y setters. También podremos ver que la información que mapea los datos de la tabla se encuentra como parte de bloques de comentarios sobre cada propiedad usando el concepto de Anotaciones, concepto muy conocido en el lenguaje Java. Esta información será utilizada en runtime para conocer datos sobre la entidad. Comentemos algunos más importantes:</p>
<ul>
<li><strong>@ORM\Entity:</strong> Indica que esta tabla se comportará como una entidad, es decir que mapeará una tabla de la base de datos.</li>
<li><strong>@ORM\Table:</strong> Doctrine usará el nombre de nuestra entidad para crear una tabla en la base de datos con el mismo nombre y esta anotación nos permitirá especificar un nombre diferente si agregamos el parametro name: @ORM\Table(name=&#8221;nombre_tabla&#8221;).</li>
<li><strong>@ORM\Column:</strong> Indica que esta propiedad mapea una columna de la tabla y como argumentos recibe datos de la misma como por ejemplo el tipo de dato y el largo en el caso de ser string. Doctrine se encargará de crear estas columnas con el tipo de dato correspondiente para cada motor de base de datos</li>
<li><strong>@ORM\Id:</strong> Indica que esta propiedad/columna será la Clave Primaria de la tabla</li>
<li><strong>@ORM\GeneratedValue:</strong> Indica que este campo numérico se irá autoincrementando usando la estrategia que pasemos por parámetro. En este caso AUTO hará que elija la mejor forma según el motor de base de datos que usemos, por ejemplo si usamos MySQL creará un indice autonumérico mientras que si es PostgreSQL usará un dato de tipo SERIAL.</li>
</ul>
<div>Ahora creemos la entidad para la tabla de comentarios</div>
<div>
<pre>C:\wamp\www\Symfony&gt;php app\console doctrine:generate:entity

  Welcome to the Doctrine2 entity generator

This command helps you generate Doctrine2 entities.

First, you need to give the entity name you want to generate.
You must use the shortcut notation like AcmeBlogBundle:Post.

The Entity shortcut name: MDWDemoBundle:Comments

Determine the format to use for the mapping information.

Configuration format (yml, xml, php, or annotation) [annotation]:

Instead of starting with a blank entity, you can add some fields now.
Note that the primary key will be added automatically (named id).

Available types: array, object, boolean, integer, smallint,
bigint, string, text, datetime, datetimetz, date, time, decimal, float.

New field name (press &lt;return&gt; to stop adding fields): author
Field type [string]:
Field length [255]:

New field name (press &lt;return&gt; to stop adding fields): content
Field type [string]: text

New field name (press &lt;return&gt; to stop adding fields): reply_to
Field type [string]: integer

New field name (press &lt;return&gt; to stop adding fields):</pre>
</div>
<p>Una vez que tengamos estas 2 entidades creadas podemos probar crear las tablas en la base de datos con el siguiente comando:</p>
<pre>C:\wamp\www\Symfony&gt;php app\console doctrine:schema:create</pre>
<p>Ahora revisando la base de datos con el phpMyAdmin podremos ver como ambas tablas fueron creadas por nuestro proyecto y nos daremos cuenta como Doctrine, por medio de nuestras Entidades, conoce perfectamente como crearlas.</p>
<h2>Modificando la estructura de las tablas</h2>
<p>Ahora que ya tenemos nuestras Entidades tenemos que crear la relación que existe entre ellas. Para este caso decimos que un Articulo puede llegar a tener varios comentarios relacionados, mientras que un comentario pertenece a un artículo específico, por lo que en la tabla de comentarios deberíamos agregar una Clave Foránea apuntando a la tabla de artículos. Para esto, agregaremos la siguiente propiedad con sus respectivos getter y setter a nuestra entidad Comment:</p>
<pre>    /**
     * @ORM\ManyToOne(targetEntity="Articles", inversedBy="comments")
     * @ORM\JoinColumn(name="article_id", referencedColumnName="id")
     * @return integer
     */
    private $article;
    public function setArticle(\Mdw\BlogBundle\Entity\Articles $article)
    {
        $this-&gt;article = $article;
    }

    public function getArticle()
    {
        return $this-&gt;article;
    }</pre>
<p>Con este código estamos definiendo una relación entre ambas tablas y nuevamente las anotaciones permiten a Doctrine especificar como se define la FK:</p>
<ul>
<li><strong>@ORM\ManyToOne:</strong> Esta anotación le dice que desde esta tabla de comentarios existe una relación de muchos a uno con la entidad Articles</li>
<li><strong>@ORM\JoinColumn:</strong> Especifica las columnas que se usarán para hacer el join. Localmente se usará una campo article_id y en la tabla de referencia se usará la propiedad id</li>
</ul>
<div>Con esto hemos modelado la FK desde el punto de vista de la entidad Comment, iremos a la entidad Articles a escribir la relación desde su punto de vista agregando el siguiente código</div>
<pre>    /**
     * @ORM\OneToMany(targetEntity="Comments", mappedBy="article")
     */
    private $comments;
    public function __construct()
    {
        $this-&gt;comments = new \Doctrine\Common\Collections\ArrayCollection();
    }
    public function addComments(\Mdw\BlogBundle\Entity\Comments $comments)
    {
        $this-&gt;comments[] = $comments;
    }

    public function getComments()
    {
        return $this-&gt;comments;
    }</pre>
<p>Agregando la propiedad $comments estamos creando la referencia a la otra tabla ya que un artículo puede tener varios comentarios usamos la anotación inversa a la que vimos anteriormente @ORM\OneToMany y podremos ver que agregamos un constructor que inicializa la propiedad con un objeto del tipo ArrayCollection, que nos permitirá que un artículo contenga varios comentarios para así poder obtenerlos todos a través del método getComments().</p>
<p>Con estas modificaciones realizadas volvamos a generar nuestras tablas, pero como ya hemos creado ambas tablas, ejecutemos primeramente para borrarlas el siguiente comando:</p>
<pre>C:\wamp\www\Symfony&gt;php app\console doctrine:schema:drop --force</pre>
<p>Para luego volver a crearlas usando el comando ya conocido:</p>
<pre>C:\wamp\www\Symfony&gt;php app\console doctrine:schema:create</pre>
<p>La otra manera de actualizar nuestras tablas, en caso de no poder o no querer borrarlas es usando el comando de <strong>update</strong> donde podemos ver la gran potencia que nos provee Doctrine enviando solo el SQL necesario para actualizar las tablas</p>
<pre>C:\wamp\www\Symfony&gt;php app\console doctrine:schema:update --force</pre>
<div class="tipexperto"><h3>Nota</h3> <div class="tipcont">En cualquiera de los tres casos <strong>doctrine:schema:create</strong>, <strong>doctrine:schema:drop</strong> y <strong>doctrine:eschema:update </strong>podemos usar el parámetro especial &#8220;&#8211;dump-squl&#8221; para que en lugar de ejecutar el SQL necesario solo nos lo muestre en la pantalla para poder controlarlo:</div></div>
<pre>C:\wamp\www\Symfony&gt;php app\console doctrine:schema:create --dump-sql
ATTENTION: This operation should not be executed in a production environment.

CREATE TABLE Articles (id INT AUTO_INCREMENT NOT NULL, 
title VARCHAR(255) NOT NULL, author VARCHAR(255) NOT NULL,
content LONGTEXT NOT NULL, tags VARCHAR(255) NOT NULL,
created DATE NOT NULL, updated DATE NOT NULL,
slug VARCHAR(255) NOT NULL, category VARCHAR(255) NOT NULL,
PRIMARY KEY(id)) ENGINE = InnoDB;

CREATE TABLE Comments (id INT AUTO_INCREMENT NOT NULL,
author VARCHAR(255) NOT NULL, content LONGTEXT NOT NULL,
reply_to INT NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB

C:\wamp\www\Symfony&gt;php app\console doctrine:schema:update --dump-sql

ALTER TABLE comments ADD article_id INT DEFAULT NULL;
ALTER TABLE comments ADD CONSTRAINT FK_A6E8F47C7294869C FOREIGN KEY (article_id)
 REFERENCES Articles(id);
CREATE INDEX IDX_A6E8F47C7294869C ON comments (article_id)

C:\wamp\www\Symfony&gt;php app\console doctrine:schema:drop --dump-sql

ALTER TABLE comments DROP FOREIGN KEY FK_A6E8F47C7294869C;
DROP TABLE articles;
DROP TABLE comments</pre>
<h2>Resumen Final</h2>
<p>Como vemos, el framework Doctrine, al tener los datos de la base de datos y de las tablas, nos proporciona un soporte muy potente para trabajar con ellas y eso que solo hemos visto la parte de creación, borrado y modificación de tablas. En los siguientes capítulos trabajaremos manipulando los datos de las tablas y le proporcionaremos aún más información a nuestras entidades para ayudarnos a validar los datos ingresados en nuestros campos.</p>
<hr /><p style="height: 64px;"><img alt='Juan Ardissone' src='http://0.gravatar.com/avatar/2b99c333759f4f7f2fa8b1b1e1ca4804?s=64&amp;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&amp;r=G' class='avatar avatar-64 photo' height='64' width='64' style="float:left;padding:0 5px" /> <strong>Juan Ardissone</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-configurando-bases-de-datos/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/curso-symfony2-configurando-bases-de-datos/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/curso-symfony2-configurando-bases-de-datos/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
	
		<media:thumbnail url="http://0.gravatar.com/avatar/2b99c333759f4f7f2fa8b1b1e1ca4804?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" />
		<media:content url="http://0.gravatar.com/avatar/2b99c333759f4f7f2fa8b1b1e1ca4804?s=64&#38;d=http%3A%2F%2Fwww.maestrosdelweb.com%2Fwp-content%2Fthemes%2Fmdw2%2Fimages%2Fno-avatar64.png%3Fs%3D64&#38;r=G" medium="image">
			<media:title type="html">Juan Ardissone</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Es viernes! Muéstranos tu espacio de trabajo</title>
		<link>http://www.maestrosdelweb.com/editorial/organiza-tu-area-de-trabajo/</link>
		<comments>http://www.maestrosdelweb.com/editorial/organiza-tu-area-de-trabajo/#comments</comments>
		<pubDate>Fri, 06 Apr 2012 17:46:28 +0000</pubDate>
		<dc:creator>Santiago Bernal Betancourth</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Productividad]]></category>
		<category><![CDATA[area  de trabajo]]></category>
		<category><![CDATA[es viernes!]]></category>
		<category><![CDATA[escritorio]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=23272</guid>
		<description><![CDATA[Como invitado de la sección es viernes! quiero hablar un poco sobre la importancia de tener un espacio de trabajo adecuado y retomar la iniciativa de dar a conocer a nuestros lectores mediante sus escritorios y puestos de trabajo. El espacio de trabajo. Es ese lugar o templo como algunos lo llamamos en el cual descargamos [...]]]></description>
			<content:encoded><![CDATA[<p>Como invitado de la sección es viernes! quiero hablar un poco sobre la importancia de tener un espacio de trabajo adecuado y retomar la iniciativa de dar a conocer a nuestros lectores mediante sus escritorios y puestos de trabajo.</p>
<h3>El espacio de trabajo.</h3>
<p>Es ese lugar o templo como algunos lo llamamos en el cual descargamos todas las energias y conocimientos para desarrollar nuestras ideas, para algunos es una mesa de madera donde ubicas tu equipo, otros utilizan un comedor, una silla, un sofa, incluso la cama, pero, son estos últimos los espacios adecuados para trabajar.</p>
<p>Antes de definir cual debe ser nuestro espacio de trabajo ideal debemos tener en cuenta lo siguiente:</p>
<ul>
<li><strong>Comodidad y ergonomía</strong>: una <a href="http://www.maestrosdelweb.com/editorial/dinamicas-para-mantenerte-saludable-miestras-trabajas/">buena posición</a> nos puede ayudar a concentrarnos más y desgastarnos menos físicamente, a veces lo que creemos que es comodidad resulta ser un dolor de espalda u otra parte del cuerpo luego de un buen rato.</li>
<li><strong>Ruido</strong>: busca un lugar donde puedas trabajar sin que el ruido te afecte en la concentración, una buena técnica es ponerte unos auriculares y <strong>escuchar música relajante</strong> que te ayude a escribir, <a href="http://musicforprogramming.net/">programar</a>,  mejorar la productividad y así no desconcentrarte con el ruido externo.</li>
<li><strong>Luz:</strong> una buena iluminación ayuda a que tus ojos no se desgasten cuando estas frente al computador, a veces no basta con subirle todo el brillo a nuestro laptop, preferiblemente es bueno buscar espacios cerca de ventanas donde te de la luz del día.</li>
<li><strong>Elementos distractores:</strong> ¿son necesarios esos elementos que tienes al lado de tu equipo? recuerda que si tienes menos elementos en que pensar, tu mente se podrá enfocar más fácil en el trabajo. A veces esos elementos a nuestro al rededor le crean a nuestra mente una necesidad de observarlo y actual con ellos haciéndonos perder tiempo.</li>
</ul>
<h3>El fondo de escritorio de tu equipo.</h3>
<p>Hablando de los elementos distractores quiero hablar sobre el escritorio, primero sobre el wallpapaper de fondo y luego sobre los iconos.</p>
<p><strong>Wallpaper</strong>: tener una imagen de fondo de escritorio es bastante agradable, y puede hacer muy placentera nuestra estadía en el equipo, pero recuerda seleccionar muy bien la imagen, ten cuidado con los colores, y los elementos del mismo. una buena recomendación de wallpapers son los paisajes.</p>
<p><strong>iconos:</strong> normalmente nos encontramos con que tenemos muchos iconos y accesos directos en nuestro escritorio, si los usas muy poco entonces considera borrarlos o meterlos en una carpeta, recuerda que los sistemas operativos traen una carpeta personal para el usuario donde podemos almacenar nuestros archivos, y el objetivo de esta carpeta es que nuestro escritorio no se llene de archivos.</p>
<h3>Muéstranos tu escritorio:</h3>
<p>Retomando la iniciativa del <a href="http://www.maestrosdelweb.com/editorial/es-viernes-muestra-tu-espacio-de-trabajo/">anterior artículo</a>, quiero invitarlos a que nos dejen comentarios con sus espacios de trabajo y su fondo de escritorio.</p>
<p>Mi espacio de trabajo:</p>
<p><a href="http://www.maestrosdelweb.com/images/2012/04/IMG_0948.jpg"><img class="aligncenter size-medium wp-image-23973" src="http://www.maestrosdelweb.com/images/2012/04/IMG_0948-450x336.jpg" alt="fondo de escritorio" width="450" height="336" /></a></p>
<p>Mi fondo de escritorio:<br />
<a href="http://www.maestrosdelweb.com/images/2012/04/Captura-de-pantalla-2012-04-01-a-las-16.07.10.png"><img class="aligncenter size-medium wp-image-23972" src="http://www.maestrosdelweb.com/images/2012/04/Captura-de-pantalla-2012-04-01-a-las-16.07.10-450x281.png" alt="fondo de escritorio" width="450" height="281" /></a><br />
&nbsp;</p>
<p>Además, los invitamos a dejar sus recomendaciones y sugerencias para mejorar nuestra área de trabajo y cómo optimizar los recursos que tenemos para trabajar adecuadamente. </p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/367-17.jpg" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Santiago Bernal Betancourth</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/organiza-tu-area-de-trabajo/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/organiza-tu-area-de-trabajo/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/organiza-tu-area-de-trabajo/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/IMG_0948-150x150.jpg" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/IMG_0948.jpg" medium="image">
			<media:title type="html">fondo de escritorio</media:title>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/IMG_0948-150x150.jpg" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/Captura-de-pantalla-2012-04-01-a-las-16.07.10.png" medium="image">
			<media:title type="html">fondo de escritorio</media:title>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/Captura-de-pantalla-2012-04-01-a-las-16.07.10-150x150.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/367-17.jpg" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Mexico y América Latina se prepara para recibir a Geeksonaplane</title>
		<link>http://www.maestrosdelweb.com/actualidad/geeksonaplane-mexico-america-latina/</link>
		<comments>http://www.maestrosdelweb.com/actualidad/geeksonaplane-mexico-america-latina/#comments</comments>
		<pubDate>Wed, 04 Apr 2012 07:00:55 +0000</pubDate>
		<dc:creator>Claudio Cossio</dc:creator>
				<category><![CDATA[Actualidad]]></category>
		<category><![CDATA[Destacados]]></category>
		<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Eventos]]></category>
		<category><![CDATA[Negocios]]></category>
		<category><![CDATA[emprendedores]]></category>
		<category><![CDATA[geeksonaplane]]></category>
		<category><![CDATA[goap]]></category>
		<category><![CDATA[latam]]></category>
		<category><![CDATA[Silicon Valley]]></category>
		<category><![CDATA[startups]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=23977</guid>
		<description><![CDATA[Ya desde hace años la comunidad de Latino América ha estado recibiendo constantes visitas por parte de la industria Geek de nuestros vecinos del Norte. Ciudades como Sao Paulo, Santiago de Chile y Buenos Aires son lugares donde han tenido contacto desde hace tiempo con empresas de primer nivel de tecnología. Así que vemos como [...]]]></description>
			<content:encoded><![CDATA[<p>Ya desde hace años la comunidad de Latino América ha estado recibiendo constantes visitas por parte de la industria Geek de nuestros vecinos del Norte. Ciudades como Sao Paulo, Santiago de Chile y Buenos Aires son lugares donde han tenido contacto desde hace tiempo con empresas de primer nivel de tecnología. Así que vemos como los días 10 al 20 de Mayo <a href="http://geeksonaplane.com/destinations/2012-destinations/latin-america-2012/" target="_blank">Geeks On A Plane</a> visita países como México, Brasil y Argentina.</p>
<p style="text-align: center"><a href="http://www.maestrosdelweb.com/images/2012/04/geeksonaplane_logo.png"><img class="aligncenter size-full wp-image-23981" style="border: 5px solid white" src="http://www.maestrosdelweb.com/images/2012/04/geeksonaplane_logo.png" alt="" width="300" height="128" /></a></p>
<p>Intel, Mandriva (en su tiempo), Motorola y empresas consultoras a nivel mundial como McKinsey, Deloitte, Accenture, T-Systems han operado en las capitales de América Latina dando servicios a las industria locales. Dando resultados como la gente de India y otros países de outsourcing del talento.</p>
<p>Ahora vemos como también ha venido el capital para encontrar aquellos proyectos con potencial de internacionalización con brillantes emprendedores y se han estado dando los resultados; empresas detrás de proyectos como <a href="http://www.youtube.com/watch?v=ehjpFE8k5e8" target="_blank">PreyProject</a>, <a href="http://oja.la" target="_blank">Oja.la</a>, <a href="http://welcu.com/" target="_blank">Welcu</a> y <a href="http://oviahr.com/" target="_blank">Ovia</a> han tomado parte con iniciativas publicas y privadas para ir a competir al extranjero.</p>
<h3>Visita para interactuar con el talento de América Latina</h3>
<p>Tenemos las mismas oportunidades que proyectos que se crean en el extranjero con mayor acceso al capital tanto humano como económico; lograr crear empresas competitivas con una oferta de valor único. Ha costado años en que estos emprendedores como <strong>Tomas Pollak</strong>, <strong>Nicolas Orellana</strong>, <strong>Hernan Aracena</strong> , <strong>Jaime Romero</strong> y otros mas reciban invitaciones para participar como parte del ecosistema de Silicon Valley.</p>
<p>Todas estas son las razones que <a href="http://geeksonaplane.com/destinations/2012-destinations/latin-america-2012/" target="_blank">GeeksOnAPlane prepara en su segunda visita en América Latina</a> y escoge ciudades como Miami,  México Distrito Federal, Sao Paulo y Buenos Aires para conocer a sus emprendedores, inversionistas locales y sobre todo gente que ha triunfado en estos mercados; les expliquen sus necesidades y donde ven las oportunidades para crear <a href="http://www.maestrosdelweb.com/actualidad/movilidad-oportunidad-america-latina/">Startups</a>.</p>
<p>Durante 10 días de Mayo los Geeks estarán invadiendo 3 ciudades de Latino América para poder construir lazos de negocios y sobre todo conocer el talento detrás de aquellos proyectos punteros de cada región. Los invito a estar al tanto esos días y darse el tiempo para conocer emprendedores, para escuchar sus historias y sobre todo compartir experiencias y vivencias del mundo del emprendimiento que tiene sus similitudes independiente de la distancia de nuestros países.</p>
<p><a href="https://spreadsheets.google.com/a/500startups.com/spreadsheet/viewform?formkey=dEpodmJlVmJoYUFFejVwanoxcTlKdVE6MQ" target="_blank">Apúntense para que sean participantes de GeeksOnAPlane como invitados</a> y sobre todo den a conocer lo que están haciendo. Es la oportunidad de demostrar con acciones que aquí en América Latina también podemos crear empresas de tecnología con potencial mundial. No solamente consumimos, sino creamos para un mercado que esta por verse todo su potencial.</p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/360-33.jpg" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Claudio Cossio</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/actualidad/geeksonaplane-mexico-america-latina/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/actualidad/geeksonaplane-mexico-america-latina/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/actualidad/geeksonaplane-mexico-america-latina/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/geeksonaplane_logo-150x128.png" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/04/geeksonaplane_logo.png" medium="image">
			<media:title type="html">geeksonaplane_logo</media:title>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/04/geeksonaplane_logo-150x128.png" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/360-33.jpg" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Comunidades OSM en latinoamérica</title>
		<link>http://www.maestrosdelweb.com/editorial/comunidades-osm-latinoamerica/</link>
		<comments>http://www.maestrosdelweb.com/editorial/comunidades-osm-latinoamerica/#comments</comments>
		<pubDate>Tue, 03 Apr 2012 07:00:44 +0000</pubDate>
		<dc:creator>Gissela Peralta</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Guías]]></category>
		<category><![CDATA[colombia]]></category>
		<category><![CDATA[ecuador]]></category>
		<category><![CDATA[latinoamérica]]></category>
		<category><![CDATA[mapas]]></category>
		<category><![CDATA[openstreetmap]]></category>
		<category><![CDATA[peru]]></category>
		<category><![CDATA[venezuela]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=23738</guid>
		<description><![CDATA[OpenStreetMap (OSM) como alternativa a Google Maps está dando pasos agigantados en todo el mundo, recientemente Foursquare comenzó a utilizar los mapas de OSM y Apple también sustituyó a Google Maps por OSM para su servicio de iPhoto. Sin embargo, lo más importante de esta herramienta es la comunidad. Aunque los países con las comunidades más formadas [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.maestrosdelweb.com/editorial/guia-mapas-open-street-maps/">OpenStreetMap (OSM) como alternativa a Google Maps</a> está dando pasos agigantados en todo el mundo, recientemente <a href="http://blog.foursquare.com/2012/02/29/foursquare-is-joining-the-openstreetmap-movement-say-hi-to-pretty-new-maps/">Foursquare comenzó a utilizar los mapas de OSM</a> y <a href="http://blog.osmfoundation.org/2012/03/08/welcome-apple/">Apple también sustituyó a Google Maps por OSM</a> para su servicio de iPhoto.</p>
<p>Sin embargo, lo más importante de esta herramienta es<strong> la comunidad</strong>. Aunque los países con las comunidades más formadas son Alemania, Inglaterra en latinoamérica están creciendo cada vez más y hoy te queremos contar sobre ello.</p>
<p>Entrevistamos a referentes de varias comunidades OSM de latinoamerica: <strong>Fredy Rivera</strong> (Colombia), <strong>Gustavo Jarrín</strong> (Ecuador), <strong>Johnattan Rupire</strong>, <strong>Omar Vega</strong>, <strong>Miguel Vera León</strong> (Perú) y <strong>Hernán Ramirez</strong> (Venezuela).</p>
<p style="text-align: center;"><img class="aligncenter  wp-image-23761" title="osmlatam" src="http://www.maestrosdelweb.com/images/2012/03/osm-1024x575.jpg" alt="" width="663" height="373" /></p>
<h2>Distintos países, una comunidad</h2>
<h3>Colombia</h3>
<p style="text-align: center;"><img class="aligncenter  wp-image-23761" title="osmlatam" src="http://www.maestrosdelweb.com/images/2012/03/bandera-colombia.jpg" alt="" width="316" height="215" /></p>
<p><a href="http://fredyrivera.blogspot.com.ar/">Fredy Rivera</a> nos comentó que la comunidad funciona oficialmente desde mayo del 2008 con la creación de la <a href="http://bit.ly/talk-co">lista de correo</a>. Son aproximadamente 230 miembros suscritos, sin embargo calcula que unas 500 personas aportaron al mapa de Colombia en OSM.</p>
<p>&#8220;La comunidad OSM en Colombia ha priorizado desde el año 2010 la <strong>creación de un mapa que se pueda usar en </strong><strong>condiciones de crisis</strong>&#8221; explicó Fredy y agregó que estas acciones se hacen coordinadas con el equipo humanitario (<a href="http://hot.openstreetmap.org/weblog/">HOT Colombia</a>) y otras organizaciones como OCHA de la ONU y el Banco Mundial.</p>
<p>Entre los eventos que realizan hay visitas de difusión en instituciones y universidades, también los llamados Mapping party que son &#8220;talleres donde se enseña a la gente a crear a sus propios mapas en OSM&#8221;. Además participan en actividades de mapeo en crisis como <a href="http://www.rhok.org/">Rhok.org</a> y <a href="http://crisiscommons.org/">Crisiscamp</a>.</p>
<h3>Ecuador</h3>
<p style="text-align: center;"><img class="aligncenter  wp-image-23761" title="osmlatam" src="http://www.maestrosdelweb.com/images/2012/03/bandera-ecuador.jpg" alt="" width="316" height="215" /></p>
<p>Gustavo Jarrín trabaja desde hace 8 años con OSM y nos contó que en un inicio era el único que conocía esta herramienta en su país por lo que se suscribía a foros intercontinentales. Afirmó que hay un gran aumento de desarrolladores locales, mayor acogida y preferencia por OSM.</p>
<p>La comunidad OSM en Ecuador, formada por desarrolladores y geografos, cuenta con 20 miembros registrados (en aumento) y para Gustavo esto significa un gran avance. Recalcó que <strong>el tema de interés se centra en la caracteristica Open Source</strong> de OpenStreetMap. Dicho espacio se utiliza para transmitir novedades, inquietudes y organizar el &#8220;Map Party&#8221;.</p>
<h3>Perú</h3>
<p style="text-align: center;"><img class="aligncenter  wp-image-23761" title="osmlatam" src="http://www.maestrosdelweb.com/images/2012/03/bandera-peru.jpg" alt="" width="316" height="215" /></p>
<p>Desde el 2008 hay registro de la <a href="http://lists.openstreetmap.org/listinfo/talk-pe">lista de correos</a> de la <a href="http://wiki.openstreetmap.org/wiki/Per%C3%BA:Comunidad">comunidad OSM en Perú</a>, según nos comentaron Johnattan Rupire y Omar Vega. &#8220;Se logró mayor participación desde una reunión convocada a mediados del 2010 por un compañero que venía de visita desde Oxford, quien nos donó un receptor GPS de parte de la comunidad en Inglaterra&#8221; nos contó Johnattan.</p>
<p>&#8220;<strong>La comunidad es pequeña, pero muy unida</strong>&#8221; afirmó Miguel Vera, son aproximadamente 6 miembros activos sin embargo &#8220;son varias las personas que contribuyen a cartografiar Perú desde diferentes partes del mundo&#8221; agregó Omar Vega.</p>
<p>Entre los eventos que realizan están las reuniones de coordinación y cartografiado, las &#8220;Mapping parties&#8221;, el Open Data Meetup Lima además de reuniones y conferencias en las universidades.</p>
<h3>Venezuela</h3>
<p style="text-align: center;"><img class="aligncenter  wp-image-23761" title="osmlatam" src="http://www.maestrosdelweb.com/images/2012/03/bandera-venezuela.jpg" alt="" width="316" height="215" /></p>
<p>La comunidad OSM en Venezuela empezó a finales del 2008, &#8220;en esa época ya los teléfonos inteligentes empezaron a incluir GPS lo que me motivó a utilizar mapas digitales, incluso ir más allá y levantar data para el grupo de usuarios GPS de Venezuela&#8221; nos contó Hernán Ramirez.</p>
<p>&#8220;A partir de abril del 2009 empecé a levantar la data de Mérida y promocioné OSM entre mis amigos y colegas; llegué a la comunidad de GPS de Mérida que facilitó mucha data y permitió que hoy día el mapa de Mérida sea el más completo de Venezuela&#8221; nos dijo Hernán agregando que en seguida crearon el <a href="http://wiki.openstreetmap.org/wiki/Venezuela">wiki de la comunidad</a> y en agosto del 2010 el <a href="http://www.openstreetmap.org.ve/">sitio OSM de Venezuela</a>.</p>
<p>Existen casi 40 usuarios inscriptos en la <a href="http://lists.openstreetmap.org/listinfo/talk-ve">lista de correo</a> sin embargo según Hernán hay personas que colaboran que no están en el grupo. Algunos de los eventos y actividades que se realizan son la MapParty, charlas divulgativas, desarrollo de aplicaciones con OpenLayer, sistema monitoreo realizado para SAIME y otros proyectos que utilizan OSM como plataforma.</p>
<h3>Desafios para OSM en latinoamérica</h3>
<p>Preguntamos a nuestros entrevistados sobre los desafios que ven en cuanto a OSM en latinoamerica, Johnattan Rupire y Omar Vega afirmaron que:</p>
<blockquote><p>Latinoamerica tiene una geografia muy interesante y diversa, pero lamentablemente muchos de estos lugares no están cartografiados aún</p></blockquote>
<p>Agregaron que el tener cartografiado muchos de estos lugares permitiría a muchos otros proyectos que dependan del georeferenciado puedan usar estos mapas y ser de una gran utilidad en la difusión del proyecto también.</p>
<p>Todos coinciden en que <strong>falta más difusión de esta herramienta</strong> no solo para técnicos sino también para usuarios en general. Gustavo Jarrín menciona que si un usuario conoce de OSM solicitará aplicaciones que lo contengan y por ende se distribuirá este concepto entre los desarrolladores.</p>
<p>Para Miguel Vera <strong>es importante incrementar el número de miembros activos</strong> y completar el mapeo en detalle de las ciudades más importantes y eventualmente de ciudades cada vez más pequeñas hasta tener un mapa completo del país. Así también Fredy Rivera agrega que hay que &#8220;<strong>lograr que nuestros paises cuenten con una cartografia usable y libre en los terminos de cualquier uso inclusive comercial</strong>&#8220;.</p>
<p>El referente de Venezuela, Hernan Ramirez, destaca a <a href="http://www.maestrosdelweb.com/editorial/curso-android/">Android</a> como plataforma ideal para la utilizacion y desarrollo de apps de mapas y por último Johnattan y Omar dicen que hay que &#8220;<strong>convencer a los gobiernos para puedan contribuir con la información geográfica</strong> y que los datos que son elaborados con el impuesto de los ciudadanos pueda estar a disposición de estos.&#8221;</p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/408-64.png" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Gissela Peralta</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/comunidades-osm-latinoamerica/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/comunidades-osm-latinoamerica/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/comunidades-osm-latinoamerica/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/03/osm-150x150.jpg" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/03/osm.jpg" medium="image">
			<media:title type="html">osmlatam</media:title>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/03/osm-150x150.jpg" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/03/osm.jpg" medium="image">
			<media:title type="html">osmlatam</media:title>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/03/osm-150x150.jpg" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/03/osm.jpg" medium="image">
			<media:title type="html">osmlatam</media:title>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/03/osm-150x150.jpg" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/03/osm.jpg" medium="image">
			<media:title type="html">osmlatam</media:title>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/03/osm-150x150.jpg" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/03/osm.jpg" medium="image">
			<media:title type="html">osmlatam</media:title>
			<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/03/osm-150x150.jpg" />
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/408-64.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
		<item>
		<title>Acceso al Internet: Un derecho humano</title>
		<link>http://www.maestrosdelweb.com/editorial/internet-derecho-humano/</link>
		<comments>http://www.maestrosdelweb.com/editorial/internet-derecho-humano/#comments</comments>
		<pubDate>Mon, 02 Apr 2012 07:00:49 +0000</pubDate>
		<dc:creator>Eugenia Tobar</dc:creator>
				<category><![CDATA[Editorial]]></category>
		<category><![CDATA[comunicacion]]></category>
		<category><![CDATA[convergencia]]></category>
		<category><![CDATA[derecho]]></category>
		<category><![CDATA[derecho humano]]></category>
		<category><![CDATA[frank la rue]]></category>
		<category><![CDATA[hipertext]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[Multimedia]]></category>
		<category><![CDATA[onu]]></category>
		<category><![CDATA[Periodismo]]></category>
		<category><![CDATA[periodismo digital]]></category>

		<guid isPermaLink="false">http://www.maestrosdelweb.com/?p=23421</guid>
		<description><![CDATA[El acceso a Internet se ha establecido dentro de los Derechos Humanos Universales por parte de las Naciones Unidas. Es exigido, debido a que Internet enlaza el cumplimiento del Derecho a la Libertad de Expresión es utilizado como herramienta de comunicación. ¿Qué es un derecho? Una de las definiciones que La Real Academia Española desgina [...]]]></description>
			<content:encoded><![CDATA[<p>El acceso a <a href="http://www.maestrosdelweb.com/editorial/internethis/">Internet</a> se ha establecido dentro de los <a href="http://www.un.org/es/documents/udhr/">Derechos Humanos Universales</a> por parte de las Naciones Unidas. Es exigido, debido a que Internet enlaza el cumplimiento del <a href="http://www.derechoshumanos.net/normativa/normas/1948-DeclaracionUniversal.htm#A19">Derecho a la Libertad de Expresión</a> es utilizado como herramienta de comunicación. </p>
<h3>¿Qué es un derecho?</h3>
<p>Una de las definiciones que <a href="http://www.rae.es/rae.html">La Real Academia Española</a> desgina a <a href="http://buscon.rae.es/draeI/SrvltConsulta?TIPO_BUS=3&#038;LEMA=derecho">derecho</a> es: &#8220;Facultad de hacer o exigir todo aquello que la ley o la autoridad establece en nuestro favor, o que el dueño de una cosa nos permite en ella.&#8221;</p>
<p><a href="http://www.flickr.com/photos/unisgeneva/6941356061/"><img style="float:right;padding:5px"  src="http://www.maestrosdelweb.com/images/2012/03/frank-la-rue-relator-onu.jpg" alt="Frank-la-rue" /></a>Entendiendo tal definición Frank La Rue, Relator Especial de las  <a href="Imagen: http://www.flickr.com/photos/unisgeneva/6941356061/">Naciones Unidas</a> encargado de la protección del derecho a la libertad de opinión y expresión desde agosto de 2008, realizó un <a href="http://documents.latimes.com/un-report-internet-rights/">reporte escrito</a> publicado el 3 de junio de 2011 declarando que el <a href="http://latimesblogs.latimes.com/technology/2011/06/united-nations-report-internet-access-is-a-human-right.html">Internet se ha convertido en una plataforma importante</a> dentro de la comunicación y la libre expresión de las personas por ello el acceso a Internet debería ser una prioridad para todos los países.</p>
<p>El papel de los gobiernos no es buscar <a href="http://www.maestrosdelweb.com/editorial/que-es-la-ley-sopa/">formas de censurar</a> Internet sino <a href="http://humanrightshouse.org/Articles/17088.html">facilitar el acceso a la información</a> que se maneja. Sin embargo, La Rue también marca algunas excepciones para la prohibición de la difusión de cierto contenido como: Pornografía infantil, discursos de odio, incitación al genocido y violencia.</p>
<h3>¿Por qué es importante el acceso a Internet?</h3>
<p>Ser un medio que nos permite la libertad de expresión es solamente hablar de una pequeña parte de todas las oportunidades que Internet nos ofrece. La tecnología avanza rápidamente, para países desarrollados esto es parte de su día a día pero para quienes no tienen el acceso representa un atraso para la sociedad. Es posible que lo sepamos pero no aceptemos que el uso de recursos digitales ya es una realidad.</p>
<p>Para los profesionales de la comunicación este derecho beneficiará de forma positiva y permitirá que la difusión de información llegue a más lectores con mayor facilidad y rapidez. Sin el acceso a Internet perderíamos alternativas de comunicarnos, oportunidades laborales y beneficios de aprendizaje.</p>
<h3>Convergencia de medios</h3>
<p><a href="https://twitter.com/#!/stephaniefalla">Stephanie Falla</a> define al <a href="http://www.maestrosdelweb.com/editorial/periodismo-digital-definiciones-caracteristicas/">Periodismo digital</a> como la <strong>convergencia de medios</strong> el cual reúne las características de ser <strong>interactivo, hipertextual y multimedial</strong> utilizando como plataforma de comunicación el Internet, el cual facilita la integración de  diversos medios de comunicación (Prensa, Radio y Televisión) para transmitir información.</p>
<p><a href="http://www.maestrosdelweb.com/editorial/periodismo-comunicacion-digital/"><img src="http://www.maestrosdelweb.com/images/2012/03/convergencia-medios.jpg" alt="Convergencia" /></a></p>
<p>Para personas como los <a href="http://www.maestrosdelweb.com/editorial/redacciones-digitales-nativos-digitales/">nativos digitales</a> ya es una realidad, la publicación de contenido lo realizan a diario en las redes sociales, sin embargo, la <a href="http://www.maestrosdelweb.com/editorial/periodismo-comunicacion-digital/">tansición del periodismo tradicional al digital</a> para algunos periodistas ha sido difícil y muchos son escépticos a una nueva forma de comunicar, a pesar de ello muchos periodistas y <a href="http://www.maestrosdelweb.com/editorial/los-periodicos-tradicionales-un-obituario/">periódicos tradicionales</a> han creado su versión digital, apostando mucho a esta &#8220;nueva&#8221; plataforma. </p>
<h3>Nuevas formas de consumo</h3>
<p>La forma en que consumimos información ha cambiado, cada vez hay menos interés en comprar la versión impresa de un periódico teniendo disponible de forma gratuita su versión digital. La cantidad de libros vendidos en <a href="http://www.amazon.com/">Amazon</a> sigue en aumento junto a dispositivos propios de lectura como el <a href="http://www.maestrosdelweb.com/editorial/kindle-lectores-tendencias-ebooks-nueva-decada/">Kindle</a>.<br />
<img src="http://www.maestrosdelweb.com/images/2012/03/kindle-image.jpg" alt="Kindle" /><br />
Pero escribir para la web no es solamente tomar el contenido de la versión impresa y <a href="http://www.maestrosdelweb.com/editorial/medios-digitales-impresos/">trasladarlo a lo digital</a>, se trata de conocer a nuestros lectores y suplir la necesidad de <a href="http://www.maestrosdelweb.com/editorial/tu-sitio-web-en-dispositivos-moviles/">consumir información en diversos dispositivos móviles</a>. </p>
<h3>Tendencias laborales para los periodistas</h3>
<p>Gracias a la evolución de la tecnología hemos encontrado nuevas oportunidades laborales en diversos campos, ahora orientados a la web. El <a href="http://www.maestrosdelweb.com/editorial/guia-community-manager-la-funcion/">Community Manager</a> suple la necesidad de la administrar las <a href="http://www.maestrosdelweb.com/editorial/redessociales/">redes sociales</a>, el <a href="http://www.maestrosdelweb.com/editorial/%C2%BFcomo-convertirse-en-un-seo-profesional/">SEO</a> posiciona a un sitio web dentro de los buscadores, el periodista debe aprender de edición, locución, escritura para utilizar al máximo la multimedialidad de la web, etc.</p>
<p><a href="http://www.flickr.com/photos/stormino/3883174942/"><img src="http://www.maestrosdelweb.com/images/2012/03/tendencias-laborales.jpg" alt="Tendencias" /></a><br />
Hemos sido testigos de muchas ideas que han crecido hasta convertirse en <a href="http://www.maestrosdelweb.com/editorial/ipo-facebook/">empresas exitosas</a>, es importante tener presente que podemos crear nuestro propio medio digital y no depender de una empresa editorial grande para difundir nuestra información, debemos pensar como <a href="http://www.maestrosdelweb.com/editorial/el-emprendimiento-requiere-enfoque/">emprendedores</a>.</p>
<h3>¡No tengo conexión!</h3>
<p>Imagina el sin fin de oportunidades que tener acceso a Internet nos ofrece, a veces no soportamos la idea de estar sin conexión 5 minutos imagina qué hubiera sido de tu vida si nunca habrías estado expuesto a Internet. Esperemos el día en que existan computadoras con acceso a Internet como si fueran teléfonos públicos y todo individuo pueda disfrutar de tal derecho.</p>
<hr /><p style="height: 64px;"><div class="entry_author_image"><img src="http://www.maestrosdelweb.com/wp-content/authors/eutobar-73.jpg" alt="" style="float:left;padding:0 5px" /></div>
 <strong>Eugenia Tobar</strong> para <a href="http://www.maestrosdelweb.com">Maestros del Web</a>.<br /><a href="http://www.maestrosdelweb.com/editorial/internet-derecho-humano/#respond">Agrega tu comentario</a> | <a href="http://www.maestrosdelweb.com/editorial/internet-derecho-humano/">Enlace permanente</a> al artículo</p><hr style="clear: both;"/>
		<p><strong>Síguenos en:</strong> <img src="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" style="vertical-align:middle;"> <a href="http://twitter.com/maestros">@maestros</a> | <img style="vertical-align:middle;" src="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png"> <a href="http://facebook.com/maestrosdelweb">Fan page</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.maestrosdelweb.com/editorial/internet-derecho-humano/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
	
		<media:thumbnail url="http://www.maestrosdelweb.com/images/2012/03/frank-la-rue-relator-onu.jpg" />
		<media:content url="http://www.maestrosdelweb.com/images/2012/03/frank-la-rue-relator-onu.jpg" medium="image">
			<media:title type="html">Frank-la-rue</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/03/convergencia-medios.jpg" medium="image">
			<media:title type="html">Convergencia</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/03/kindle-image.jpg" medium="image">
			<media:title type="html">Kindle</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/images/2012/03/tendencias-laborales.jpg" medium="image">
			<media:title type="html">Tendencias</media:title>
		</media:content>
		<media:content url="http://www.maestrosdelweb.com/wp-content/authors/eutobar-73.jpg" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/twitter.png" medium="image" />
		<media:content url="http://www.maestrosdelweb.com/diseno/imagenes/facebook.png" medium="image" />
	</item>
	</channel>
</rss>

