{"title":"Pisanie pierwszej aplikacji Django, część 3.","version":"2.0","locale":"pl","docname":"intro/tutorial03","url":"/pl/2.0/intro/tutorial03/","canonical":"https://djangodocs.dev/pl/2.0/intro/tutorial03/","summary":"Ten tutorial zaczyna się, gdzie skończył się Tutorial 2 . Kontynuujemy z aplikacją web-ankiet i skupimy się na tworzeniu publicznego interfejsu – „widoków”.…","html":"<h1>Pisanie pierwszej aplikacji Django, część 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>Ten tutorial zaczyna się, gdzie skończył się <a class=\"reference internal\" href=\"/pl/2.0/intro/tutorial02/\"><span class=\"doc\">Tutorial 2</span></a>. Kontynuujemy z aplikacją web-ankiet i skupimy się na tworzeniu publicznego interfejsu – „widoków”.</p>\n<section id=\"overview\">\n<h2>Przegląd<a class=\"heading-anchor\" href=\"#overview\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Widok jest „typem” strony internetowej w tworzej aplikacji Django, który w ogólności służy określonej funkcji i ma określony szablon. Na przykład w aplikacji blogowej, możesz mieć następujące widoki:</p>\n<ul class=\"simple\">\n<li><p>Strona główna bloga – wyświetla kilka najnowszych wpisów.</p></li>\n<li><p>Strona „szczegółów” wpisu – strona na pojedynczy wpis.</p></li>\n<li><p>Roczna strona archiwum – wyświetla wszystkie miesiące z wpisami w danym roku.</p></li>\n<li><p>Miesięczna strona archiwum – wyświetla wszystkie dni z wpisami w danym miesiącu.</p></li>\n<li><p>Dzienna strona archiwum – wyświetla wszystkie wpisy z danego dnia.</p></li>\n<li><p>Komentowanie – obsługuje dodawanie komentarzy do danego wpisu.</p></li>\n</ul>\n<p>W naszej aplikacji ankietowej będziemy mieć następujące cztery widoki:</p>\n<ul class=\"simple\">\n<li><p>Strona „główna” pytań – wyświetla klika najnowszych pytań.</p></li>\n<li><p>Strona „szczegółów” pytania – wyświetla treść pytania, bez wyników, ale z formularzem do głosowania.</p></li>\n<li><p>Strona „wyników” pytania – wyświetla wyniki dla wybranego pytania.</p></li>\n<li><p>Akcja głosowania – obsługuje głosowanie na konkretny wybór w wybranym pytaniu.</p></li>\n</ul>\n<p>W Django strony i inna treść są dostarczane przez widoki. Każdy widok jest reprezentowany przez prostą funkcję Pythona (lub metodę, w przypadku widoków opartych na klasach). Django wybierze widok sprawdzając URL, który jest zażądany (aby być dokładnym, część URL-a po nazwie domeny).</p>\n<p>Teraz w swoim czasie w Internecie można natknąć się na takie piękności jak „ME2/Sites/dirmod.asp?sid=&amp;type=gen&amp;mod=Core+Pages&amp;gid=A6CD4967199A42D9B65B1B”. Będziesz zadowolony wiedząc, że Django pozwala nam na znacznie bardziej eleganckie <em>wzorce adresów URL</em> niż ten.</p>\n<p>Wzorzec URL jest po prostu ogólną formą URL-a – na przykład: <code class=\"docutils literal notranslate\"><span class=\"pre\">/newsarchive/&lt;year&gt;/&lt;month&gt;/</span></code>.</p>\n<p>Aby przejść z URL-a do widoku, Django używa czegoś, co znane jest jako «URLconfs». URLconf mapuje wzorce URL na widoki.</p>\n<p>Ten tutorial zawiera podstawowe instrukcje użytkowania URLconfów. Możesz przejść do <a class=\"reference internal\" href=\"/pl/2.0/topics/http/urls/\"><span class=\"doc\">URL dispatcher</span></a> po więcej informacji.</p>\n</section>\n<section id=\"writing-more-views\">\n<h2>Pisanie kolejnych widoków<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>Teraz dodajmy kilka więcej widoków do <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code>. Te widoki są nieco inne, bo biorą argument:</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>Podłącz te nowe widoki do modułu <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code> dodając następujące wywołania <a class=\"reference internal\" href=\"/pl/2.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=\"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.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>Spójrz na „/polls/34/” w swojej przeglądarce. Uruchomi to metodę <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> i wyświetli jakiekolwiek ID podasz w URL-u. Spróbuj też „/polls/34/results/” i „/polls/34/vote/” – te wyświetlą strony wyników i głosowania.</p>\n<p>Kiedy ktoś żąda strony z twojej witryny – powiedzmy „/polls/34/”, Django załaduje moduł <code class=\"docutils literal notranslate\"><span class=\"pre\">mysite.urls</span></code> Pythona, ponieważ jest wskazany przez ustawienie <a class=\"reference internal\" href=\"/pl/2.0/ref/settings/#std-setting-ROOT_URLCONF\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ROOT_URLCONF</span></code></a>. Odnajduje on zmienną nazwaną <code class=\"docutils literal notranslate\"><span class=\"pre\">urlpatterns</span></code> i trawersuje po kolei wzorce. Po odnalezieniu dopasowania w <code class=\"docutils literal notranslate\"><span class=\"pre\">'polls/'</span></code>, odcina pasujący tekst (<code class=\"docutils literal notranslate\"><span class=\"pre\">„polls/”</span></code>) i wysyła pozostały tekst – <code class=\"docutils literal notranslate\"><span class=\"pre\">„34/”</span></code> – do URLconfa «polls.urls» do dalszego przetwarzania. Tam dopasowuje go do <code class=\"docutils literal notranslate\"><span class=\"pre\">'&lt;int:question_id&gt;/'</span></code>, co kończy się wywołaniem widoku <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> w ten sposób:</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>Część <code class=\"docutils literal notranslate\"><span class=\"pre\">question_id=34</span></code> pochodzi z <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;int:question_id&gt;</span></code>. Użycie nawiasów trójkątnych  „wyłapuje” część URL-a i wysyła ją jako argument do funkcji widoku. Część <code class=\"docutils literal notranslate\"><span class=\"pre\">:question_id&gt;</span></code> ciągu znaków określa nazwę, która zostanie użyta, aby zidentyfikować dopasowany wzorzec, a część <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;int:</span></code> jest konwerterem, który określa jakie wzorce powinny pasować do tej części ścieżki URL.</p>\n<p>Nie ma potrzeby dodawać wstawek do URL-i typu <code class=\"docutils literal notranslate\"><span class=\"pre\">.html</span></code> – chyba że tego chcesz, w takim przypadku możesz zrobić coś takiego:</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\">path</span><span class=\"p\">(</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>Ale nie rób tego. To głupie.</p>\n</section>\n<section id=\"write-views-that-actually-do-something\">\n<h2>Pisanie widoków, które faktycznie coś robią<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>Każdy widok jest odpowiedzialny za zrobienie jednej z dwóch rzeczy: zwrócenie obiektu <a class=\"reference internal\" href=\"/pl/2.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> zawierającego treść dla żądanej strony lub rzucenie wyjątku takiego jak <a class=\"reference internal\" href=\"/pl/2.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>. Reszta zależy od ciebie.</p>\n<p>Twój widok może czytać rekordy z bazy danych lub nie. Może używać systemu szablonów takiego jak Django – lub innego systemu szablonów Python – lub nie. Może generować plik PDF, zwracać XML, tworzyć w locie plik ZIP, cokolwiek chcesz, używając dowolnych bibliotek Pythona, których chcesz.</p>\n<p>Wszystko, czego chce Django, to ten <a class=\"reference internal\" href=\"/pl/2.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>. Lub wyjątek.</p>\n<p>Użyjmy własnego bazodanowego API Django, które omówiliśmy w <a class=\"reference internal\" href=\"/pl/2.0/intro/tutorial02/\"><span class=\"doc\">Tutorialu 2</span></a>, ponieważ jest wygodne. Tu jest próba w nowym widoku <code class=\"docutils literal notranslate\"><span class=\"pre\">index()</span></code>, która wyświetla ostatnie 5 pytań ankietowych w systemie, oddzielone przecinkami, według daty publikacji:</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>Chociaż mamy tutaj problem: design strony jest zahardcodowany w widoku. Jeśli chcesz zmienić sposób, w jaki wygląda strona, będziesz musiał zmienić ten kod Pythona. Użyjmy systemu szablonów Django, aby oddzielić design od Pythona tworząc szablon, który będzie mógł użyć widok.</p>\n<p>Najpierw stwórzmy katalog o nazwie <code class=\"docutils literal notranslate\"><span class=\"pre\">templates</span></code> w twoim katalogu <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code>. Django będzie tam szukał szablonów.</p>\n<p>Ustawienie <a class=\"reference internal\" href=\"/pl/2.0/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">TEMPLATES</span></code></a> twojego projektu opisuje jak Django będzie ładował i renderował szablony. Domyślny plik ustawień konfiguruje backend <code class=\"docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code>, którego opcja <a class=\"reference internal\" href=\"/pl/2.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> jest ustawiona na <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>. Według konwencji <code class=\"docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code> szuka podkatalogu „templates” w każdej z <a class=\"reference internal\" href=\"/pl/2.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>W katalogu <code class=\"docutils literal notranslate\"><span class=\"pre\">templates</span></code>, który właśnie stworzyłeś, stwórz kolejny katalog o nazwie <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code> i w tym katalogu stwórz plik o nazwie <code class=\"docutils literal notranslate\"><span class=\"pre\">index.html</span></code>. Innymi słowy, twój szablon powinien być pod <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates/polls/index.html</span></code>. Ponieważ loader szablonów <code class=\"docutils literal notranslate\"><span class=\"pre\">app_directories</span></code> działa jak opisano powyżej, możesz odwoływać się do tego szablonu w Django po prostu <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\">Przestrzeń nazw szablonu</p>\n<p>Teraz <em>moglibyśmy</em> poradzić sobie umieszczając nasze szablony bezpośrednio w <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates</span></code> (zamiast tworzyć kolejny podkatalog <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code>), ale w rzeczywistości byłoby to złym pomysłem. Django wybierze pierwszy szablon, którego nazwa się zgadza i jeśli miałbyś szablon o takiej samej nazwie w <em>innej</em> aplikacji, Django nie byłoby w stanie ich odróżnić. Musimy być w stanie wskazać Django odpowiedni szablon i najprostszym sposobem, aby to zapewnić jest <em>znamespace’owanie</em> ich. To znaczy umieszczenie tych szablonów w <em>innym</em> katalogu nazwanym dla samej aplikacji.</p>\n</aside>\n<p>Umieść następujący kod w tym szablonie:</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>Teraz zaktualizujmy nasz widok <code class=\"docutils literal notranslate\"><span class=\"pre\">index</span></code> w <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code>, aby używał szablonu:</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>Ten kod ładuje szablon o nazwie <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/index.html</span></code> i przekazuje mu kontekts. Kontekst jest słownikiem mapującym nazwy zmiennych szablonu do obiektów Pythona.</p>\n<p>Załaduj stronę kierując swoją przeglądarkę na „/polls/”. Powinnieneś zobaczyć wypunktowaną listę zawierającą pytanie „What’s up” z <a class=\"reference internal\" href=\"/pl/2.0/intro/tutorial02/\"><span class=\"doc\">Tutoriala 2</span></a>. Link kieruje do strony szczegółów pytania.</p>\n<section id=\"a-shortcut-render\">\n<h3>Skrót: <a class=\"reference internal\" href=\"/pl/2.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>To popularny idiom do ładowania szablonu, wypełniania kontekstu i zwracania obiektu <a class=\"reference internal\" href=\"/pl/2.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> z wynikiem wyrenderowanego szablonu. Djano daje skrót. Tutaj jest pełen widok <code class=\"docutils literal notranslate\"><span class=\"pre\">index()</span></code>, napisany na nowo:</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>Zwróć uwagę, że kiedy zrobiliśmy to w tych wszystkich widokach, nie potrzebujemy już importować <a class=\"reference internal\" href=\"/pl/2.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> i <a class=\"reference internal\" href=\"/pl/2.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> (będziesz chciał zatrzymać <code class=\"docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code> jeśli wciąż masz zaczątki metod dla <code class=\"docutils literal notranslate\"><span class=\"pre\">detail</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">results</span></code> i <code class=\"docutils literal notranslate\"><span class=\"pre\">vote</span></code>).</p>\n<p>Funkcja <a class=\"reference internal\" href=\"/pl/2.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> bierze obiekt request jako swój pierwszy argument, nazwę szablonu jako drugi argument i słownik jako swój opcjonalny trzeci argument. Zwraca obiekt <a class=\"reference internal\" href=\"/pl/2.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> danego szablonu wyrenderowany z danym kontekstem.</p>\n</section>\n</section>\n<section id=\"raising-a-404-error\">\n<h2>Zgłaszanie błędu 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>Teraz zawalczmy z widokiem szczegółów pytania – strony, która wyświetla treść pytania dla danej ankiety. Tutaj jest widok:</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>Nowy koncept tutaj: Widok zgłasza wyjątek <a class=\"reference internal\" href=\"/pl/2.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> jeśli pytanie o żądanym ID nie istnieje.</p>\n<p>Omówimy trochę później co mógłbyś umieścić w tym szablonie <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/detail.html</span></code>, ale jeśli chcesz, aby powyższy przykład szybko zaczął działać, plik zawierający tylko:</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>pomoże ci wystartować na teraz.</p>\n<section id=\"a-shortcut-get-object-or-404\">\n<h3>Skrót: <a class=\"reference internal\" href=\"/pl/2.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>To popularny idiom do używania <a class=\"reference internal\" href=\"/pl/2.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> i zgłaszania <a class=\"reference internal\" href=\"/pl/2.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> jeśli obiekt nie istnieje. Django daje skrót. Tutaj jest widok <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> przepisany:</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>Funkcja <a class=\"reference internal\" href=\"/pl/2.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> bierze model Django jako swój pierwszy argument i wyznaczoną wcześniej liczbę arguementów nazwanych, które przekazuje do funkcji <a class=\"reference internal\" href=\"/pl/2.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> menadżera modelu. Zgłasza <a class=\"reference internal\" href=\"/pl/2.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> jeśli obiekt nie istnieje.</p>\n<aside class=\"admonition-philosophy admonition\">\n<p class=\"admonition-title\">Filozofia</p>\n<p>Dlaczego używamy funkcji pomocniczej <a class=\"reference internal\" href=\"/pl/2.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> zamiast automatycznie wyłapywać wyjątki <a class=\"reference internal\" href=\"/pl/2.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> na wyższym poziomie lub powodując, że API modelu będzie zgłaszać <a class=\"reference internal\" href=\"/pl/2.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> zamiast <a class=\"reference internal\" href=\"/pl/2.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>Ponieważ to związałoby warstwę modelu z warstwą widoku. Jednym z najważniejszych celów projektowych Django było utrzymywania luźnych więzów. Trochę kontrolowanego wiązania jest wprowadzone w module <a class=\"reference internal\" href=\"/pl/2.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>Jest też funkcja <a class=\"reference internal\" href=\"/pl/2.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>, która działa tak samo jak <a class=\"reference internal\" href=\"/pl/2.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> – z wyjątkiem używania <a class=\"reference internal\" href=\"/pl/2.0/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">filter()</span></code></a> zamiast <a class=\"reference internal\" href=\"/pl/2.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>. Zgłasza wyjątek <a class=\"reference internal\" href=\"/pl/2.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> gdy lista jest pusta.</p>\n</section>\n</section>\n<section id=\"use-the-template-system\">\n<h2>Użyj systemu szablonów<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>Wracamy do widoku <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> naszej aplikacji ankietowej. Mając zmienną kontekstową <code class=\"docutils literal notranslate\"><span class=\"pre\">question</span></code>, tak mógłby wyglądać nasz szablon <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/detail.html</span></code>:</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>System szablonów używa składni kropkowego lookupu, aby dostać się do atrybutów zmiennej. W przykładzie <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">question.question_text</span> <span class=\"pre\">}}</span></code>, najpierw Django robi słownikowy lookup na obiekcie <code class=\"docutils literal notranslate\"><span class=\"pre\">question</span></code>. Gdy to się nie uda, próbuje atrybutowego lookupu – który w tym przypadku działa. Gdyby atrybutowy lookup się nie powiódł, spróbowałoby lookupu przez indeks listy.</p>\n<p>Wywoływanie metod dzieje się w pętli <a class=\"reference internal\" href=\"/pl/2.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> <span class=\"pre\">%}</span></code></a>: <code class=\"docutils literal notranslate\"><span class=\"pre\">question.choice_set.all</span></code> jest interpretowane jako kod Pythona <code class=\"docutils literal notranslate\"><span class=\"pre\">question.choice_set.all()</span></code>, który zwraca iterator obiektów <code class=\"docutils literal notranslate\"><span class=\"pre\">Choice</span></code> i jest odpowiedni do użycia w tagu <a class=\"reference internal\" href=\"/pl/2.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> <span class=\"pre\">%}</span></code></a>.</p>\n<p>Zobacz <a class=\"reference internal\" href=\"/pl/2.0/topics/templates/\"><span class=\"doc\">przewodnik po szablonach</span></a> po więcej informacji na temat szablonów.</p>\n</section>\n<section id=\"removing-hardcoded-urls-in-templates\">\n<h2>Usuwanie wstawionych na szytwno URL-i z szablonów<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>Pamiętasz, kiedy wpisaliśmy link do pytania w szablonie <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/index.html</span></code>, link był częściowo wpisany na sztywno, w ten sposób:</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>Problem z tym podejściem z hardkodowaniem jest taki, że staje się niezwykle trudna zmiana URL-i w projektach z dużą liczbą szablonów. Jednakże, odkąd zdefiniowałeś nazwany argument w funkcjach <a class=\"reference internal\" href=\"/pl/2.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> w module <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code>, możesz usunąć poleganie na poszczególnych ścieżkach URL zdefiniowanych w twoich konfiguracjach URL-i używając szablonowego taga <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>Działa to przez sprawdzenie definicji URL-a według specyfikacji w module <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code>. Możesz zobaczyć poniżej, gdzie dokładnie nazwa «detail» jest zdefiniowana w URL-u:</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>Jeśli chcesz zmienić URL widoku szczegółów ankiety na jakiś inny, na przykład na coś w stylu <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/specifics/12/</span></code>, zamiast robić to w szablonie (lub szablonach), zmieniłbyś to w <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>Przestrzenie nazw dla nazw URL-i<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>Projekt tutorialowy ma tylko jedną aplikację, <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code>. W prawdziwych projektach Django może być pięć, dziesięć, dwadzieścia lub więcej aplikacji. Jak Django odróżnia nazwy URL pomiędzy nimi? Na przykład aplikacja <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code> ma widok <code class=\"docutils literal notranslate\"><span class=\"pre\">detail</span></code> i tak samo mogłaby mieć aplikacja blogowa w tym samym projekcie. Jak zrobić, aby Django wiedziało, której aplikacji widok stworzyć dla urla w przypadku użycia taga <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">url</span> <span class=\"pre\">%}</span></code>?</p>\n<p>Odpowiedzią jest dodanie przestrzeni nazw do twojego URLconfa. W pliku <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/urls.py</span></code> dodaj <code class=\"docutils literal notranslate\"><span class=\"pre\">app_name</span></code>, aby ustawić przestrzeń nazw aplikacji:</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.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>Teraz zmień swój szablon <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/index.html</span></code> z:</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>aby wskazywał na widok szczegółów w przestrzeni nazw:</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>Jeśli czujesz się dobrze z pisaniem widoków, przeczytaj <a class=\"reference internal\" href=\"/pl/2.0/intro/tutorial04/\"><span class=\"doc\">część czwartą tego tutoriala</span></a>, aby dowiedzieć się na temat przetwarzania prostych formularzy i widokach generycznych.</p>\n</section>","rootId":"writing-your-first-django-app-part-3","toc":[{"title":"Przegląd","anchor":"overview","children":[]},{"title":"Pisanie kolejnych widoków","anchor":"writing-more-views","children":[]},{"title":"Pisanie widoków, które faktycznie coś robią","anchor":"write-views-that-actually-do-something","children":[{"title":"Skrót: render()","anchor":"a-shortcut-render","children":[]}]},{"title":"Zgłaszanie błędu 404","anchor":"raising-a-404-error","children":[{"title":"Skrót: get_object_or_404()","anchor":"a-shortcut-get-object-or-404","children":[]}]},{"title":"Użyj systemu szablonów","anchor":"use-the-template-system","children":[]},{"title":"Usuwanie wstawionych na szytwno URL-i z szablonów","anchor":"removing-hardcoded-urls-in-templates","children":[]},{"title":"Przestrzenie nazw dla nazw URL-i","anchor":"namespacing-url-names","children":[]}],"breadcrumbs":[{"docname":"intro/index","title":"Pierwsze kroki","url":"/pl/2.0/intro/"}],"prev":{"docname":"intro/tutorial02","title":"Pisanie pierwszej aplikacji Django, część 2.","url":"/pl/2.0/intro/tutorial02/"},"next":{"docname":"intro/tutorial04","title":"Pisanie pierwszej aplikacji Django, część 4.","url":"/pl/2.0/intro/tutorial04/"},"formats":{"html":"/pl/2.0/intro/tutorial03/","markdown":"/pl/2.0/intro/tutorial03.md","json":"/pl/2.0/intro/tutorial03.json"},"source":"https://github.com/django/django/blob/stable/2.0.x/docs/intro/tutorial03.txt","official":"https://docs.djangoproject.com/pl/2.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"],"inLocales":["en","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}