{"title":"Escribiendo su primera aplicación en Django, parte 3","version":"1.10","locale":"es","docname":"intro/tutorial03","url":"/es/1.10/intro/tutorial03/","canonical":"https://djangodocs.dev/es/1.10/intro/tutorial03/","summary":"Este tutorial comienza donde quedó el Tutorial 2 . Vamos a continuar con la aplicación Web para encuestas y vamos a enfocarnos en crear la interfaz pública…","html":"<h1>Escribiendo su primera aplicación en Django, parte 3<a class=\"heading-anchor\" href=\"#writing-your-first-django-app-part-3\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Este tutorial comienza donde quedó el <a class=\"reference internal\" href=\"/es/1.10/intro/tutorial02/\"><span class=\"doc\">Tutorial 2</span></a>. Vamos a continuar con la aplicación Web para encuestas y vamos a enfocarnos en crear la interfaz pública –“vistas”.</p>\n<section id=\"overview\">\n<h2>Información general<a class=\"heading-anchor\" href=\"#overview\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Una vista es un «tipo» de página Web de su aplicación Django, que generalmente cumple  una función específica y tiene una plantilla específica. Por ejemplo, en una aplicación de blog, usted puede tener las siguientes vistas:</p>\n<ul class=\"simple\">\n<li><p>La página de inicio del blog – muestra las últimas pocas entradas.</p></li>\n<li><p>Entry «detail» page – permalink page for a single entry.</p></li>\n<li><p>Página de archivo basado en el año – muestra todos los meses con entradas en un año determinado.</p></li>\n<li><p>Página de archivo basado en el mes – muestra todos los días con las entradas en un mes determinado.</p></li>\n<li><p>Página de archivo basado en el día– muestra todas las entradas de un día determinado.</p></li>\n<li><p>Comentar – gestiona la publicación de comentarios en  una entrada determinada.</p></li>\n</ul>\n<p>En nuestra aplicación encuestas, vamos a tener las siguientes cuatro vistas:</p>\n<ul class=\"simple\">\n<li><p>La página “índice” de preguntas – muestra las últimas preguntas.</p></li>\n<li><p>La página “de detalle” de preguntas– muestra un texto de pregunta sin resultados, pero con un formulario para votar.</p></li>\n<li><p>Página «resultados» de preguntas – muestra los resultados de una pregunta en particular.</p></li>\n<li><p>Votar – gestiona la votación para una elección concreta en una pregunta específica.</p></li>\n</ul>\n<p>En Django, las páginas Web y otros contenidos se entregan por medio de vistas. Cada vista está representada por una sencilla función Python (o método, en el caso de las vistas basadas en clases). Django escogerá una vista examinando la URL que se solicita (para ser preciso, la parte de la URL que se encuentra después del nombre del dominio).</p>\n<p>En todo el tiempo que ha pasado en la web es posible que haya encontrado este tipo de bellezas como «ME2/Sites/dirmod.asp?sid=&amp;type=gen&amp;mod=Core+Pages&amp;gid=A6CD4967199A42D9B65B1B». Usted estará encantado de saber que Django nos ofrece <em>patrones de URL</em> mucho más elegantes que ese.</p>\n<p>Un patrón de URL no es más que el formulario general de una URL, por ejemplo:<code class=\"docutils literal notranslate\"><span class=\"pre\">/newsarchive/&lt;year&gt;/&lt;month&gt;/</span></code>.</p>\n<p>Para llegar desde una URL a una vista, Django usa lo que se conoce como «URLconfs”. Un URLconf mapea patrones de URL (descritos como expresiones regulares) a las vistas.</p>\n<p>This tutorial provides basic instruction in the use of URLconfs, and you can\nrefer to <a class=\"reference internal\" href=\"/es/1.10/ref/urlresolvers/#module-django.urls\" title=\"django.urls\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.urls</span></code></a> for more information.</p>\n</section>\n<section id=\"writing-more-views\">\n<h2>Escribiendo más vistas<a class=\"heading-anchor\" href=\"#writing-more-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>A continuación vamos a agregar más vistas a <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code>. Estas vistas son un poco diferentes porque toman un argumento:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/views.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/views.py\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">detail</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">question_id</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"s2\">&quot;You&#39;re looking at question </span><span class=\"si\">%s</span><span class=\"s2\">.&quot;</span> <span class=\"o\">%</span> <span class=\"n\">question_id</span><span class=\"p\">)</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">results</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">question_id</span><span class=\"p\">):</span>\n    <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;You&#39;re looking at the results of question </span><span class=\"si\">%s</span><span class=\"s2\">.&quot;</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"n\">response</span> <span class=\"o\">%</span> <span class=\"n\">question_id</span><span class=\"p\">)</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">vote</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">question_id</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"s2\">&quot;You&#39;re voting on question </span><span class=\"si\">%s</span><span class=\"s2\">.&quot;</span> <span class=\"o\">%</span> <span class=\"n\">question_id</span><span class=\"p\">)</span>\n</code></pre></figure>\n<p>Envíe estas nuevas vistas al módulo <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code> añadiendo las siguientes llamadas :func:  ~django.conf.urls.url:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/urls.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/urls.py\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.conf.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">url</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">views</span>\n\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"c1\"># ex: /polls/</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">index</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;index&#39;</span><span class=\"p\">),</span>\n    <span class=\"c1\"># ex: /polls/5/</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">detail</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;detail&#39;</span><span class=\"p\">),</span>\n    <span class=\"c1\"># ex: /polls/5/results/</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/results/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">results</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;results&#39;</span><span class=\"p\">),</span>\n    <span class=\"c1\"># ex: /polls/5/vote/</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/vote/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">vote</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;vote&#39;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></figure>\n<p>Eche un vistazo en su navegador a «/polls/34/». Va a ejecutar el método <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code>  y mostrar cualquier ID que usted suministre en la URL. Pruebe  «/polls/34/results/» y  también «/polls/34/vote/» - estas mostrarán los resultados del marcador de posición y las páginas de votación.</p>\n<p>When somebody requests a page from your website – say, «/polls/34/», Django\nwill load the <code class=\"docutils literal notranslate\"><span class=\"pre\">mysite.urls</span></code> Python module because it’s pointed to by the\n<a class=\"reference internal\" href=\"/es/1.10/ref/settings/#std-setting-ROOT_URLCONF\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ROOT_URLCONF</span></code></a> setting. It finds the variable named <code class=\"docutils literal notranslate\"><span class=\"pre\">urlpatterns</span></code>\nand traverses the regular expressions in order. After finding the match at\n<code class=\"docutils literal notranslate\"><span class=\"pre\">'^polls/'</span></code>, it strips off the matching text (<code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;polls/&quot;</span></code>) and sends the\nremaining text – <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;34/&quot;</span></code> – to the “polls.urls” URLconf for further\nprocessing. There it matches <code class=\"docutils literal notranslate\"><span class=\"pre\">r'^(?P&lt;question_id&gt;[0-9]+)/$'</span></code>, resulting in a\ncall to the <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> view like so:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">detail</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">=&lt;</span><span class=\"n\">HttpRequest</span> <span class=\"nb\">object</span><span class=\"o\">&gt;</span><span class=\"p\">,</span> <span class=\"n\">question_id</span><span class=\"o\">=</span><span class=\"s1\">&#39;34&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>La parte question_id = “34”` proviene de `` (? P &lt;question_id&gt; [0-9] +) <code class=\"docutils literal notranslate\"><span class=\"pre\">.</span> <span class=\"pre\">Utilizar</span> <span class=\"pre\">paréntesis</span> <span class=\"pre\">en</span> <span class=\"pre\">torno</span> <span class=\"pre\">a</span> <span class=\"pre\">un</span> <span class=\"pre\">patrón</span> <span class=\"pre\">&quot;captura&quot;</span> <span class=\"pre\">el</span> <span class=\"pre\">texto</span> <span class=\"pre\">buscado</span> <span class=\"pre\">por</span> <span class=\"pre\">ese</span> <span class=\"pre\">patrón</span> <span class=\"pre\">y</span> <span class=\"pre\">lo</span> <span class=\"pre\">envía</span> <span class=\"pre\">como</span> <span class=\"pre\">un</span> <span class=\"pre\">argumento</span> <span class=\"pre\">a</span> <span class=\"pre\">la</span> <span class=\"pre\">función</span> <span class=\"pre\">de</span> <span class=\"pre\">vista;</span> <span class=\"pre\">``?P&lt;question_id&gt;</span></code> define el nombre que se utilizará para identificar el patrón buscado  y `` [0-9] + `` es una expresión regular para buscar una secuencia de dígitos (es decir, un número).</p>\n<p>Debido a que los patrones de URL son expresiones regulares, realmente no hay límites en lo que puede hacer con ellos. Además, no hay necesidad de añadir códigos redundantes a la URL como `` .html``; a  menos que lo desee, en cuyo caso usted puede hacer algo como esto</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^polls/latest\\.html$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">index</span><span class=\"p\">),</span>\n</code></pre></div>\n<p>Pero, no haga eso. Es una tontería.</p>\n</section>\n<section id=\"write-views-that-actually-do-something\">\n<h2>Escriba vistas que realmente hagan algo<a class=\"heading-anchor\" href=\"#write-views-that-actually-do-something\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Cada vista es responsable de hacer una de dos cosas: retornar un objeto <code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code> con el contenido de la página solicitada, o levantar una excepción como <code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">Http404</span></code> . El resto depende de usted.</p>\n<p>Su vista puede leer registros de una base de datos o no, puede usar un sistema de plantillas como el de Django o un sistema de plantillas Python de terceros o no. Puede generar un archivo PDF, salida XML, crear un archivo ZIP en la marcha, todo lo que quiera, utilizando cualquier librería de Python que desee.</p>\n<p>Todo Django quiere es ese objeto <a class=\"reference internal\" href=\"/es/1.10/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> o una excepción.</p>\n<p>Debido a que es conveniente, vamos a utilizar la propia API de base de datos de Django, que estudiamos en el <a class=\"reference internal\" href=\"/es/1.10/intro/tutorial02/\"><span class=\"doc\">Tutorial 2</span></a>. A continuación señalaremos una nueva vista <code class=\"docutils literal notranslate\"><span class=\"pre\">index()</span></code>  que muestra en el sistema las 5 últimas preguntas de la  encuesta, separadas por comas, según su fecha de publicación:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/views.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/views.py\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Question</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">index</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">latest_question_list</span> <span class=\"o\">=</span> <span class=\"n\">Question</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;-pub_date&#39;</span><span class=\"p\">)[:</span><span class=\"mi\">5</span><span class=\"p\">]</span>\n    <span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;, &#39;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">([</span><span class=\"n\">q</span><span class=\"o\">.</span><span class=\"n\">question_text</span> <span class=\"k\">for</span> <span class=\"n\">q</span> <span class=\"ow\">in</span> <span class=\"n\">latest_question_list</span><span class=\"p\">])</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"n\">output</span><span class=\"p\">)</span>\n\n<span class=\"c1\"># Leave the rest of the views (detail, results, vote) unchanged</span>\n</code></pre></figure>\n<p>Sin embargo, aquí hay un problema: el diseño de la página está codificado de forma fija en la vista. Si desea cambiar la forma en que se ve la página, tendrá que editar el código Python. Así que vamos a usar el sistema de plantillas de Django para separar el diseño de Python mediante la creación de una plantilla que la vista pueda utilizar.</p>\n<p>Primero, cree un directorio llamado «templates» en su directorio «polls». Django buscará las  plantillas allí.</p>\n<p>La configuración de <a class=\"reference internal\" href=\"/es/1.10/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">TEMPLATES</span></code></a> de su proyecto  describe cómo Django cargará y creará las plantillas. El archivo de configuración predeterminada configura un backend «DjangoTemplates» cuya :setting: opción APP_DIRS &lt;TEMPLATES-APP_DIRS&gt;  está configurada como «True».  Convencionalmente, «DjangoTemplates» busca un subdirectorio “templates” en cada una de las <a class=\"reference internal\" href=\"/es/1.10/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a>.</p>\n<p>Dentro del directorio <code class=\"docutils literal notranslate\"><span class=\"pre\">templates</span></code> que usted acaba de crear, cree otro directorio llamado        <code class=\"docutils literal notranslate\"><span class=\"pre\">polls`</span> <span class=\"pre\">`y</span> <span class=\"pre\">dentro</span> <span class=\"pre\">de</span> <span class=\"pre\">este</span> <span class=\"pre\">cree</span> <span class=\"pre\">un</span> <span class=\"pre\">archivo</span> <span class=\"pre\">llamado</span> <span class=\"pre\">``</span> <span class=\"pre\">index.html</span></code>. En otras palabras, su plantilla debe estar en <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates/polls/index.html</span></code>. Ya que  el cargador de plantillas `` app_directories``  funciona como se describió anteriormente, usted puede consultar esta plantilla dentro de Django simplemente como <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/index.html</span></code>.</p>\n<aside class=\"admonition-template-namespacing admonition\">\n<p class=\"admonition-title\">Espacio de nombres de plantillas</p>\n<p>Ahora <em>podríamos</em> salirnos con la nuestra poniendo nuestras plantillas directamente en <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates</span></code>  (en lugar de crear otro subdirectorio «polls»), pero en realidad sería una mala idea. Django elegirá la primera plantilla que encuentre cuyo nombre coincida, y si usted tuviera una plantilla con el mismo nombre en una aplicación <em>diferente</em>, Django no podría distinguir entre ellas.  Tenemos que ser capaces de indicarle a  Django la correcta, y la forma más fácil de asegurar esto es <em>organizándolas por espacio de nombres</em>, es decir, poniendo esas plantillas dentro de <em>otro</em> directorio que recibe el nombre de la aplicación.</p>\n</aside>\n<p>Introduzca el siguiente código en esa plantilla:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\"><code>polls/templates/polls/index.html</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/templates/polls/index.html\"><code><span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">latest_question_list</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">question</span> <span class=\"k\">in</span> <span class=\"nv\">latest_question_list</span> <span class=\"cp\">%}</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;/polls/</span><span class=\"cp\">{{</span> <span class=\"nv\">question.id</span> <span class=\"cp\">}}</span><span class=\"s\">/&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">question.question_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">else</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>No polls are available.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n</code></pre></figure>\n<p>Ahora vamos a actualizar nuestra vista <code class=\"docutils literal notranslate\"><span class=\"pre\">índex</span></code> en <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/</span> <span class=\"pre\">views.py</span></code> para usar la plantilla:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/views.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/views.py\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.template</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">loader</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Question</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">index</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">latest_question_list</span> <span class=\"o\">=</span> <span class=\"n\">Question</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;-pub_date&#39;</span><span class=\"p\">)[:</span><span class=\"mi\">5</span><span class=\"p\">]</span>\n    <span class=\"n\">template</span> <span class=\"o\">=</span> <span class=\"n\">loader</span><span class=\"o\">.</span><span class=\"n\">get_template</span><span class=\"p\">(</span><span class=\"s1\">&#39;polls/index.html&#39;</span><span class=\"p\">)</span>\n    <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;latest_question_list&#39;</span><span class=\"p\">:</span> <span class=\"n\">latest_question_list</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">))</span>\n</code></pre></figure>\n<p>Ese código carga la plantilla llamada <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/index.html</span></code> y le pasa un contexto. El contexto es un diccionario que relaciona los nombres de variables de plantillas con objetos Python.</p>\n<p>Cargue la página señalando su navegador en «/polls/»,  y usted debería ver una lista con viñetas que contiene la pregunta «¿Qué pasa?» del :doc:<a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>Tutorial 2 &lt;/intro/tutorial02&gt; <a href=\"#id3\"><span class=\"problematic\" id=\"id4\">`</span></a>. El enlace señala la página de detalles de la pregunta.</p>\n<section id=\"a-shortcut-render\">\n<h3>Un atajo: <a class=\"reference internal\" href=\"/es/1.10/topics/http/shortcuts/#django.shortcuts.render\" title=\"django.shortcuts.render\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">render()</span></code></a><a class=\"heading-anchor\" href=\"#a-shortcut-render\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Es una práctica muy común cargar una plantilla, llenar un contexto y retornar un objeto <code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code>  con el resultado de la plantilla creada. Django proporciona un atajo. A continuación la vista «índex()»completa, reescrita:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/views.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/views.py\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.shortcuts</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">render</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Question</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">index</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">latest_question_list</span> <span class=\"o\">=</span> <span class=\"n\">Question</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s1\">&#39;-pub_date&#39;</span><span class=\"p\">)[:</span><span class=\"mi\">5</span><span class=\"p\">]</span>\n    <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s1\">&#39;latest_question_list&#39;</span><span class=\"p\">:</span> <span class=\"n\">latest_question_list</span><span class=\"p\">}</span>\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"s1\">&#39;polls/index.html&#39;</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">)</span>\n</code></pre></figure>\n<p>Tenga en cuenta que una vez que hemos hecho esto en todas estas vistas, ya no necesitamos importar <a class=\"reference internal\" href=\"/es/1.10/topics/templates/#module-django.template.loader\" title=\"django.template.loader\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">loader</span></code></a>  y <a class=\"reference internal\" href=\"/es/1.10/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> (usted querrá continuar <code class=\"docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code>  si usted todavía tiene los métodos stub para «detail», «results» `` y «vote»).</p>\n<p>La función <a class=\"reference internal\" href=\"/es/1.10/topics/http/shortcuts/#django.shortcuts.render\" title=\"django.shortcuts.render\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">render()</span></code></a> toma el objeto solicitado como su primer argumento, un nombre de plantilla como su segundo argumento y un diccionario como su tercer argumento opcional. La función retorna un objeto <a class=\"reference internal\" href=\"/es/1.10/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> de la plantilla determinada creada con el contexto dado.</p>\n</section>\n</section>\n<section id=\"raising-a-404-error\">\n<h2>Levantar un error 404<a class=\"heading-anchor\" href=\"#raising-a-404-error\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Ahora  vamos a abordar la vista de detalle de la pregunta: la página que muestra el texto de pregunta para una encuesta determinada. Aquí está la vista:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/views.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/views.py\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Http404</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.shortcuts</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">render</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Question</span>\n<span class=\"c1\"># ...</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">detail</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">question_id</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"n\">question</span> <span class=\"o\">=</span> <span class=\"n\">Question</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">pk</span><span class=\"o\">=</span><span class=\"n\">question_id</span><span class=\"p\">)</span>\n    <span class=\"k\">except</span> <span class=\"n\">Question</span><span class=\"o\">.</span><span class=\"n\">DoesNotExist</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"n\">Http404</span><span class=\"p\">(</span><span class=\"s2\">&quot;Question does not exist&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"s1\">&#39;polls/detail.html&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;question&#39;</span><span class=\"p\">:</span> <span class=\"n\">question</span><span class=\"p\">})</span>\n</code></pre></figure>\n<p>El nuevo concepto aquí: La vista levanta la excepción <a class=\"reference internal\" href=\"/es/1.10/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a> si no existe una pregunta con la ID solicitada.</p>\n<p>Hablaremos de lo que podría poner en esa plantilla <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/detail.html</span></code> un poco más tarde, pero si desea empezar a trabajar con el ejemplo  anterior, un archivo que contenga simplemente:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\"><code>polls/templates/polls/detail.html</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/templates/polls/detail.html\"><code><span class=\"cp\">{{</span> <span class=\"nv\">question</span> <span class=\"cp\">}}</span>\n</code></pre></figure>\n<p>le ayudará a empezar por ahora.</p>\n<section id=\"a-shortcut-get-object-or-404\">\n<h3>Un atajo <a class=\"reference internal\" href=\"/es/1.10/topics/http/shortcuts/#django.shortcuts.get_object_or_404\" title=\"django.shortcuts.get_object_or_404\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">get_object_or_404()</span></code></a><a class=\"heading-anchor\" href=\"#a-shortcut-get-object-or-404\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Es una práctica muy común utilizar: meth:~ django.db.models.query.QuerySet.get y levantar la excepción :exc:` ~ django.http.Http404` si no existe el objeto. Django proporciona un atajo. Aquí está la vista «detail()», reescrita:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/views.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/views.py\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.shortcuts</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">get_object_or_404</span><span class=\"p\">,</span> <span class=\"n\">render</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Question</span>\n<span class=\"c1\"># ...</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">detail</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">question_id</span><span class=\"p\">):</span>\n    <span class=\"n\">question</span> <span class=\"o\">=</span> <span class=\"n\">get_object_or_404</span><span class=\"p\">(</span><span class=\"n\">Question</span><span class=\"p\">,</span> <span class=\"n\">pk</span><span class=\"o\">=</span><span class=\"n\">question_id</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"s1\">&#39;polls/detail.html&#39;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s1\">&#39;question&#39;</span><span class=\"p\">:</span> <span class=\"n\">question</span><span class=\"p\">})</span>\n</code></pre></figure>\n<p>La función <a class=\"reference internal\" href=\"/es/1.10/topics/http/shortcuts/#django.shortcuts.get_object_or_404\" title=\"django.shortcuts.get_object_or_404\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">get_object_or_404()</span></code></a> toma un modelo Django como su primer argumento y un número arbitrario de argumentos de palabra clave que pasa a la función <a class=\"reference internal\" href=\"/es/1.10/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get()</span></code></a>   del administrador del modelo. Levanta la excepción <a class=\"reference internal\" href=\"/es/1.10/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a> si no existe el objeto.</p>\n<aside class=\"admonition-philosophy admonition\">\n<p class=\"admonition-title\">Filosofía</p>\n<p>¿Por qué utilizamos una función auxiliar <a class=\"reference internal\" href=\"/es/1.10/topics/http/shortcuts/#django.shortcuts.get_object_or_404\" title=\"django.shortcuts.get_object_or_404\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">get_object_or_404()</span></code></a> en lugar de capturar las excepciones <a class=\"reference internal\" href=\"/es/1.10/ref/exceptions/#django.core.exceptions.ObjectDoesNotExist\" title=\"django.core.exceptions.ObjectDoesNotExist\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">ObjectDoesNotExist</span></code></a> en un nivel superior, o hacer que la API del modelo levante la excepción <a class=\"reference internal\" href=\"/es/1.10/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a> en vez de la excepción <a class=\"reference internal\" href=\"/es/1.10/ref/exceptions/#django.core.exceptions.ObjectDoesNotExist\" title=\"django.core.exceptions.ObjectDoesNotExist\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">ObjectDoesNotExist</span></code></a>?</p>\n<p>Porque eso acoplaría la capa de modelos con la capa de vistas. Uno de los objetivos de diseño más destacados de Django es mantener el bajo acoplamiento. Algo de acoplamiento controlado se introduce en el módulo <a class=\"reference internal\" href=\"/es/1.10/topics/http/shortcuts/#module-django.shortcuts\" title=\"django.shortcuts: Convenience shortcuts that span multiple levels of Django's MVC stack.\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.shortcuts</span></code></a>.</p>\n</aside>\n<p>También hay una función <code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">get_list_or_404()</span></code> , que funciona igual que  <a class=\"reference internal\" href=\"/es/1.10/topics/http/shortcuts/#django.shortcuts.get_object_or_404\" title=\"django.shortcuts.get_object_or_404\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">get_object_or_404()</span></code></a> - excepto usando <code class=\"xref py py-meth docutils literal notranslate\"> <span class=\"pre\">filter()</span></code> en  lugar de <a class=\"reference internal\" href=\"/es/1.10/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get()</span></code></a>. La misma levanta la excepción <a class=\"reference internal\" href=\"/es/1.10/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">Http404</span></code></a> si la lista está vacía.</p>\n</section>\n</section>\n<section id=\"use-the-template-system\">\n<h2>Utilice el sistema de plantillas<a class=\"heading-anchor\" href=\"#use-the-template-system\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Vuelva a la vista <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> para nuestra aplicación encuesta. Teniendo en cuenta la variable de contexto <code class=\"docutils literal notranslate\"><span class=\"pre\">question</span></code>, así es como la plantilla <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/detail.html</span></code> podría verse:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\"><code>polls/templates/polls/detail.html</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/templates/polls/detail.html\"><code><span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">question.question_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">choice</span> <span class=\"k\">in</span> <span class=\"nv\">question.choice_set.all</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">choice.choice_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n</code></pre></figure>\n<p>El sistema de plantillas utiliza la sintaxis de búsqueda con puntos para acceder a los atributos de variables. En el ejemplo de {{question.question_text}} , Django primero realiza una consulta en el  diccionario sobre el objeto ``question`. Si esto falla, intenta una búsqueda de atributos que en este caso funciona. Si la búsqueda de atributos hubiera fallado, hubiera intentado una búsqueda de índice de lista.</p>\n<p>El llamado del método ocurre en el bucle <a class=\"reference internal\" href=\"/es/1.10/ref/templates/builtins/#std-templatetag-for\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">for%}</span></code></a>:  <code class=\"docutils literal notranslate\"><span class=\"pre\">question.choice_set.all</span></code> se interpreta como el código Python` question.choice_set.all ()` que retorna un iterable de  objetos «Choice» y es adecuado para usarse en la etiqueta <a class=\"reference internal\" href=\"/es/1.10/ref/templates/builtins/#std-templatetag-for\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">for%}</span></code></a>.</p>\n<p>Consulte la :doc: guía de plantillas &lt;/topics/templates&gt; para más información sobre las plantillas.</p>\n</section>\n<section id=\"removing-hardcoded-urls-in-templates\">\n<h2>Quitar URLs codificadas de manera predeterminada en las plantillas<a class=\"heading-anchor\" href=\"#removing-hardcoded-urls-in-templates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Recuerde que cuando escribimos el enlace para una pregunta en la plantilla <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/index.html</span></code>, el enlace estaba parcialmente codificado de forma predeterminada como este:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;/polls/</span><span class=\"cp\">{{</span> <span class=\"nv\">question.id</span> <span class=\"cp\">}}</span><span class=\"s\">/&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">question.question_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>El problema con este método de codificación predeterminada y  estrechamente acoplada es que se hace difícil modificar las URLs en proyectos que tengan muchas plantillas. Sin embargo, puesto que usted definió el argumento de nombre en las funciones  <a class=\"reference internal\" href=\"/es/1.10/ref/urls/#django.conf.urls.url\" title=\"django.conf.urls.url\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">url()</span></code></a> en el módulo <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code>, usted puede eliminar la seguridad de rutas URL específicas definida en su configuración de URL usando la etiqueta de plantilla <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">url</span> <span class=\"pre\">%}</span></code>.</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{%</span> <span class=\"k\">url</span> <span class=\"s1\">&#39;detail&#39;</span> <span class=\"nv\">question.id</span> <span class=\"cp\">%}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">question.question_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>La forma como esto funciona es buscando la definición de la URL como  se específica en el módulo <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code>. Usted puede ver exactamente donde se define el nombre de la URL de “detail” a continuación:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"o\">...</span>\n<span class=\"c1\"># the &#39;name&#39; value as called by the {% url %} template tag</span>\n<span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">detail</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;detail&#39;</span><span class=\"p\">),</span>\n<span class=\"o\">...</span>\n</code></pre></div>\n<p>Si desea modificar la URL de la vista de detalle de las encuestas a algo diferente,  quizás a algo como <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/specifics/12/</span></code>, en lugar de hacerlo en la plantilla (o plantillas), usted la modificaría en <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/urls.py</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"o\">...</span>\n<span class=\"c1\"># added the word &#39;specifics&#39;</span>\n<span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^specifics/(?P&lt;question_id&gt;[0-9]+)/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">detail</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;detail&#39;</span><span class=\"p\">),</span>\n<span class=\"o\">...</span>\n</code></pre></div>\n</section>\n<section id=\"namespacing-url-names\">\n<h2>Asignando los nombres de URLs<a class=\"heading-anchor\" href=\"#namespacing-url-names\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>El proyecto tutorial solo tiene una aplicación; “polls”. En proyectos reales de Django, puede haber cinco, diez, veinte o más aplicaciones. ¿Cómo diferencia Django los nombres de las URLs entre ellos? Por ejemplo, la aplicación “polls” tiene una vista “detail”, como la podría tener también una aplicación en el mismo proyecto que es para un blog. ¿Cómo hacer para que Django sepa cual vista de aplicaciones crear para una URL cuando se utiliza la etiqueta de plantilla`` {% url%}``?</p>\n<p>La solución es añadir espacios de nombres a su URLconf. En el archivo <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/urls.py</span></code>,  añada un <code class=\"docutils literal notranslate\"><span class=\"pre\">app_name</span></code> para configurar el espacio de nombres de la aplicación:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/urls.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/urls.py\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.conf.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">url</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">views</span>\n\n<span class=\"n\">app_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;polls&#39;</span>\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">index</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;index&#39;</span><span class=\"p\">),</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">detail</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;detail&#39;</span><span class=\"p\">),</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/results/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">results</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;results&#39;</span><span class=\"p\">),</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/vote/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">vote</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;vote&#39;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></figure>\n<p>Ahora modifique su plantilla <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/index.html</span></code> desde:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\"><code>polls/templates/polls/index.html</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/templates/polls/index.html\"><code><span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{%</span> <span class=\"k\">url</span> <span class=\"s1\">&#39;detail&#39;</span> <span class=\"nv\">question.id</span> <span class=\"cp\">%}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">question.question_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n</code></pre></figure>\n<p>Para señalar la vista de detalle con espacio de nombres:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\"><code>polls/templates/polls/index.html</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/templates/polls/index.html\"><code><span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{%</span> <span class=\"k\">url</span> <span class=\"s1\">&#39;polls:detail&#39;</span> <span class=\"nv\">question.id</span> <span class=\"cp\">%}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">question.question_text</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n</code></pre></figure>\n<p>Cuando esté familiarizado con la escritura de vistas, lea la :doc:‘parte 4 de este tutorial’ &lt;/intro/tutorial04&gt;` para aprender más sobre el procesamiento simple de formularios y vistas genéricas.</p>\n</section>","rootId":"writing-your-first-django-app-part-3","toc":[{"title":"Información general","anchor":"overview","children":[]},{"title":"Escribiendo más vistas","anchor":"writing-more-views","children":[]},{"title":"Escriba vistas que realmente hagan algo","anchor":"write-views-that-actually-do-something","children":[{"title":"Un atajo: render()","anchor":"a-shortcut-render","children":[]}]},{"title":"Levantar un error 404","anchor":"raising-a-404-error","children":[{"title":"Un atajo get_object_or_404()","anchor":"a-shortcut-get-object-or-404","children":[]}]},{"title":"Utilice el sistema de plantillas","anchor":"use-the-template-system","children":[]},{"title":"Quitar URLs codificadas de manera predeterminada en las plantillas","anchor":"removing-hardcoded-urls-in-templates","children":[]},{"title":"Asignando los nombres de URLs","anchor":"namespacing-url-names","children":[]}],"breadcrumbs":[{"docname":"intro/index","title":"Empezando","url":"/es/1.10/intro/"}],"prev":{"docname":"intro/tutorial02","title":"Escribiendo su primera aplicación en Django, parte 2","url":"/es/1.10/intro/tutorial02/"},"next":{"docname":"intro/tutorial04","title":"Escribiendo su primera aplicación en Django, parte 4","url":"/es/1.10/intro/tutorial04/"},"formats":{"html":"/es/1.10/intro/tutorial03/","markdown":"/es/1.10/intro/tutorial03.md","json":"/es/1.10/intro/tutorial03.json"},"source":"https://github.com/django/django/blob/stable/1.10.x/docs/intro/tutorial03.txt","official":"https://docs.djangoproject.com/es/1.10/intro/tutorial03/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","fr","ja","id","pt-br","es","el","pl"]}