{"title":"Escribiendo su primera aplicación en Django, parte 3","version":"4.0","locale":"es","docname":"intro/tutorial03","url":"/es/4.0/intro/tutorial03/","canonical":"https://djangodocs.dev/es/4.0/intro/tutorial03/","summary":"This tutorial begins where Tutorial 2 left off. We’re continuing the web-poll application and will focus on creating the public interface – «views.» Dónde obtener…","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>This tutorial begins where <a class=\"reference internal\" href=\"/es/4.0/intro/tutorial02/\"><span class=\"doc\">Tutorial 2</span></a> left off. We’re\ncontinuing the web-poll application and will focus on creating the public\ninterface – «views.»</p>\n<aside class=\"admonition-where-to-get-help admonition\">\n<p class=\"admonition-title\">Dónde obtener ayuda:</p>\n<p>If you’re having trouble going through this tutorial, please head over to\nthe <a class=\"reference internal\" href=\"/es/4.0/faq/help/\"><span class=\"doc\">Getting Help</span></a> section of the FAQ.</p>\n</aside>\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>A view is a «type» of web page in your Django application that generally serves\na specific function and has a specific template. For example, in a blog\napplication, you might have the following views:</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>Página de entrada de «detail» – página de enlace permanente para una entrada individual.</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 «detalle» de preguntas– muestra un texto de pregunta sin resultados, pero con un formulario para votar.</p></li>\n<li><p>La 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>In Django, web pages and other content are delivered by views. Each view is\nrepresented by a Python function (or method, in the case of class-based views).\nDjango will choose a view by examining the URL that’s requested (to be precise,\nthe part of the URL after the domain name).</p>\n<p>Now in your time on the web you may have come across such beauties as\n<code class=\"docutils literal notranslate\"><span class=\"pre\">ME2/Sites/dirmod.htm?sid=&amp;type=gen&amp;mod=Core+Pages&amp;gid=A6CD4967199A42D9B65B1B</span></code>.\nYou will be pleased to know that Django allows us much more elegant\n<em>URL patterns</em> than that.</p>\n<p>A URL pattern is the general form of a URL - for example:\n<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”. Una URLconf mapea patrones de URL a vistas.</p>\n<p>Este tutorial proporciona instrucción básica en el uso de URLconfs. Usted puede consultar <a class=\"reference internal\" href=\"/es/4.0/topics/http/urls/\"><span class=\"doc\">URL dispatcher</span></a> para más información.</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=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><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>Una estas nuevas vistas al módulo <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code> añadiendo las siguientes llamadas <a class=\"reference internal\" href=\"/es/4.0/ref/urls/#django.urls.path\" title=\"django.urls.path\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">path()</span></code></a>:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">polls/urls.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">path</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\">path</span><span class=\"p\">(</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\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/&#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\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/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\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/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>Cuando alguien solicita una página desde su sitio web - digamos, «/polls/34/», Django cargará el módulo Python <code class=\"docutils literal notranslate\"><span class=\"pre\">mysite.urls</span></code> porque está señalado por la configuración <a class=\"reference internal\" href=\"/es/4.0/ref/settings/#std-setting-ROOT_URLCONF\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ROOT_URLCONF</span></code></a>. Él encuentra la variable llamada <code class=\"docutils literal notranslate\"><span class=\"pre\">urlpatterns</span></code> y recorre las expresiones regulares en orden. Cuando encuentra la coincidencia <code class=\"docutils literal notranslate\"><span class=\"pre\">'polls/'</span></code> retira el texto que coincide (<code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;polls/&quot;</span></code>) y envía el texto restante - <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;34/&quot;</span></code> - a la URLconf “polls.urls” para seguir siendo procesado. Allí la coincidencia <code class=\"docutils literal notranslate\"><span class=\"pre\">'&lt;int:question_id&gt;/'</span></code> resulta en una llamada a la vista <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> de la siguiente forma:</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=\"mi\">34</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>The <code class=\"docutils literal notranslate\"><span class=\"pre\">question_id=34</span></code> part comes from <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;int:question_id&gt;</span></code>. Using angle\nbrackets «captures» part of the URL and sends it as a keyword argument to the\nview function. The <code class=\"docutils literal notranslate\"><span class=\"pre\">question_id</span></code> part of the string defines the name that\nwill be used to identify the matched pattern, and the <code class=\"docutils literal notranslate\"><span class=\"pre\">int</span></code> part is a\nconverter that determines what patterns should match this part of the URL path.\nThe colon (<code class=\"docutils literal notranslate\"><span class=\"pre\">:</span></code>) separates the converter and pattern name.</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 <a class=\"reference internal\" href=\"/es/4.0/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> con el contenido de la página solicitada, o levantar una excepción como <a class=\"reference internal\" href=\"/es/4.0/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>. 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/4.0/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/4.0/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=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><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 <code class=\"docutils literal notranslate\"><span class=\"pre\">templates</span></code> en su directorio <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code>. Django buscará las plantillas allí.</p>\n<p>La configuración de <a class=\"reference internal\" href=\"/es/4.0/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 <code class=\"docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code> cuya opción <a class=\"reference internal\" href=\"/es/4.0/ref/settings/#std-setting-TEMPLATES-APP_DIRS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">APP_DIRS</span></code></a> está configurada como <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>. Convencionalmente, <code class=\"docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code> busca un subdirectorio «templates» en cada una de las <a class=\"reference internal\" href=\"/es/4.0/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>Within the <code class=\"docutils literal notranslate\"><span class=\"pre\">templates</span></code> directory you have just created, create another\ndirectory called <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code>, and within that create a file called\n<code class=\"docutils literal notranslate\"><span class=\"pre\">index.html</span></code>. In other words, your template should be at\n<code class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates/polls/index.html</span></code>. Because of how the <code class=\"docutils literal notranslate\"><span class=\"pre\">app_directories</span></code>\ntemplate loader works as described above, you can refer to this template within\nDjango as <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>Now we <em>might</em> be able to get away with putting our templates directly in\n<code class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates</span></code> (rather than creating another <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code> subdirectory),\nbut it would actually be a bad idea. Django will choose the first template\nit finds whose name matches, and if you had a template with the same name\nin a <em>different</em> application, Django would be unable to distinguish between\nthem. We need to be able to point Django at the right one, and the best\nway to ensure this is by <em>namespacing</em> them. That is, by putting those\ntemplates inside <em>another</em> directory named for the application itself.</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 class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates/polls/index.html</span></code></figcaption>\n<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=\"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<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Nota</p>\n<p>To make the tutorial shorter, all template examples use incomplete HTML. In\nyour own projects you should use <a class=\"reference external\" href=\"https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started#anatomy_of_an_html_document\">complete HTML documents</a>.</p>\n</aside>\n<p>Ahora vamos a actualizar nuestra vista <code class=\"docutils literal notranslate\"><span class=\"pre\">index</span></code> en <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code> para usar la plantilla:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><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 <a class=\"reference internal\" href=\"/es/4.0/intro/tutorial02/\"><span class=\"doc\">Tutorial 2</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/4.0/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 <a class=\"reference internal\" href=\"/es/4.0/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> con el resultado de la plantilla creada. Django proporciona un atajo. A continuación la vista <code class=\"docutils literal notranslate\"><span class=\"pre\">index()</span></code> completa, reescrita:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><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/4.0/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/4.0/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 <code class=\"docutils literal notranslate\"><span class=\"pre\">detail</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">results</span></code> y <code class=\"docutils literal notranslate\"><span class=\"pre\">vote</span></code>).</p>\n<p>La función <a class=\"reference internal\" href=\"/es/4.0/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/4.0/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=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><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/4.0/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 class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates/polls/detail.html</span></code></figcaption>\n<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=\"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/4.0/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 <a class=\"reference internal\" href=\"/es/4.0/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> y levantar la excepción <a class=\"reference internal\" href=\"/es/4.0/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. Django proporciona un atajo. Aquí está la vista <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code>, reescrita:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><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/4.0/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/4.0/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/4.0/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/4.0/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/4.0/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/4.0/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/4.0/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/4.0/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 <a class=\"reference internal\" href=\"/es/4.0/topics/http/shortcuts/#django.shortcuts.get_list_or_404\" title=\"django.shortcuts.get_list_or_404\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">get_list_or_404()</span></code></a> , que funciona igual que <a class=\"reference internal\" href=\"/es/4.0/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/4.0/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/4.0/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 class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates/polls/detail.html</span></code></figcaption>\n<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\">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 <code class=\"docutils literal notranslate\"><span class=\"pre\">{{question.question_text}}</span></code>, Django primero realiza una consulta en el diccionario sobre el objeto <code class=\"docutils literal notranslate\"><span class=\"pre\">question</span></code>. 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/4.0/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 <code class=\"docutils literal notranslate\"><span class=\"pre\">question.choice_set.all()</span></code> que retorna un iterable de objetos <code class=\"docutils literal notranslate\"><span class=\"pre\">Choice</span></code> y es adecuado para usarse en la etiqueta <a class=\"reference internal\" href=\"/es/4.0/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 <a class=\"reference internal\" href=\"/es/4.0/topics/templates/\"><span class=\"doc\">guía de plantillas</span></a> 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/4.0/ref/urls/#django.urls.path\" title=\"django.urls.path\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">path()</span></code></a> en el módulo <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code>, usted puede eliminar la dependencia en 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\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/&#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\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;specifics/&lt;int:question_id&gt;/&#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; <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code>. 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 <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code> tiene una vista <code class=\"docutils literal notranslate\"><span class=\"pre\">detail</span></code>, 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=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">polls/urls.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">path</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\">path</span><span class=\"p\">(</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\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/&#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\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/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\">path</span><span class=\"p\">(</span><span class=\"s1\">&#39;&lt;int:question_id&gt;/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 class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates/polls/index.html</span></code></figcaption>\n<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></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 class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates/polls/index.html</span></code></figcaption>\n<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;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>When you’re comfortable with writing views, read <a class=\"reference internal\" href=\"/es/4.0/intro/tutorial04/\"><span class=\"doc\">part 4 of this tutorial</span></a> to learn the basics about form processing and generic\nviews.</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/4.0/intro/"}],"prev":{"docname":"intro/tutorial02","title":"Escribiendo su primera aplicación en Django, parte 2","url":"/es/4.0/intro/tutorial02/"},"next":{"docname":"intro/tutorial04","title":"Escribiendo su primera aplicación en Django, parte 4","url":"/es/4.0/intro/tutorial04/"},"formats":{"html":"/es/4.0/intro/tutorial03/","markdown":"/es/4.0/intro/tutorial03.md","json":"/es/4.0/intro/tutorial03.json"},"source":"https://github.com/django/django/blob/stable/4.0.x/docs/intro/tutorial03.txt","official":"https://docs.djangoproject.com/es/4.0/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","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}