{"title":"Γράφοντας το πρώτο σας Django app, μέρος 3","version":"4.2","locale":"el","docname":"intro/tutorial03","url":"/el/4.2/intro/tutorial03/","canonical":"https://djangodocs.dev/el/4.2/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.»","html":"<h1>Γράφοντας το πρώτο σας Django app, μέρος 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=\"/el/4.2/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\" role=\"note\">\n<p class=\"admonition-title\">Που να ψάξετε για βοήθεια</p>\n<p>If you’re having trouble going through this tutorial, please head over to\nthe <a class=\"reference internal\" href=\"/el/4.2/faq/help/\"><span class=\"doc\">Getting Help</span></a> section of the FAQ.</p>\n</aside>\n<section id=\"overview\">\n<h2>Επισκόπηση<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>Blog homepage – προβάλει τα μερικά από τα τελευταία entries (καταχωρήσεις).</p></li>\n<li><p>Σελίδα «λεπτομερειών» μιας entry (καταχώρησης) – μια permalink σελίδα για ένα συγκεκριμένο entry.</p></li>\n<li><p>Σελίδα archive ανά ημερολογιακό χρόνο – προβάλει όλους τους μήνες που έχουν καταχωρήσεις για το δοθέντα έτος.</p></li>\n<li><p>Σελίδα archive ανά ημερολογιακό μήνα – προβάλει όλες τις μέρες που έχουν καταχωρήσεις για το δοθέντα μήνα.</p></li>\n<li><p>Σελίδα archive ανά ημερολογιακή μέρα – προβάλει όλα τα entries μια συγκεκριμένη μέρα.</p></li>\n<li><p>Προσθήκη σχολίου – χειρίζεται τα σχόλια πάνω στα posts για ένα συγκεκριμένο entry.</p></li>\n</ul>\n<p>Στη δική μας εφαρμογή, θα έχουμε τα ακόλουθα τέσσερα views:</p>\n<ul class=\"simple\">\n<li><p>Αρχική σελίδα («index») ερωτήσεων – προβάλει τις τελευταίες ερωτήσεις.</p></li>\n<li><p>Σελίδα «λεπτομερειών» μιας ερώτησης – προβάλει μια ερώτηση, χωρίς αποτελέσματα, αλλά με μια φόρμα (η οποία θα περιέχει τις επιλογές της ερώτησης) προς ψήφιση.</p></li>\n<li><p>Σελίδα «αποτελεσμάτων» μιας ερώτησης – προβάλει τα αποτελέσματα μιας συγκεκριμένης ερώτησης.</p></li>\n<li><p>Προσθήκη ψήφου – χειρίζεται τη ψήφο μιας συγκεκριμένης επιλογής μιας συγκεκριμένης ερώτησης.</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\">ME2/Sites/dirmod.htm?sid=&amp;type=gen&amp;mod=Core+Pages&amp;gid=A6CD4967199A42D9B65B1B</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\">/newsarchive/&lt;year&gt;/&lt;month&gt;/</code>.</p>\n<p>To get from a URL to a view, Django uses what are known as “URLconfs”. A\nURLconf maps URL patterns to views.</p>\n<p>This tutorial provides basic instruction in the use of URLconfs, and you can\nrefer to <a class=\"reference internal\" href=\"/el/4.2/topics/http/urls/\"><span class=\"doc\">URL dispatcher</span></a> for more information.</p>\n</section>\n<section id=\"writing-more-views\">\n<h2>Γράφοντας περισσότερα views<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>Ας προσθέσουμε τώρα μερικά views παραπάνω, στο αρχείο <code class=\"docutils literal notranslate\">polls/views.py</code>. Αυτά τα views είναι ελαφρώς διαφορετικά, επειδή παίρνουν και όρισμα (argument):</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/views.py</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=\"nf\">detail</span><span class=\"p\">(</span>request<span class=\"p\">,</span> question_id<span class=\"p\">):</span>\n    <span class=\"k\">return</span> HttpResponse<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> question_id<span class=\"p\">)</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">results</span><span class=\"p\">(</span>request<span class=\"p\">,</span> question_id<span class=\"p\">):</span>\n    response <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> HttpResponse<span class=\"p\">(</span>response <span class=\"o\">%</span> question_id<span class=\"p\">)</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">vote</span><span class=\"p\">(</span>request<span class=\"p\">,</span> question_id<span class=\"p\">):</span>\n    <span class=\"k\">return</span> HttpResponse<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> question_id<span class=\"p\">)</span>\n</code></pre></figure>\n<p>Wire these new views into the <code class=\"docutils literal notranslate\">polls.urls</code> module by adding the following\n<a class=\"reference internal\" href=\"/el/4.2/ref/urls/#django.urls.path\" title=\"django.urls.path\"><code class=\"xref py py-func docutils literal notranslate\">path()</code></a> calls:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/urls.py</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=\"nn\">django.urls</span> <span class=\"kn\">import</span> path\n\n<span class=\"kn\">from</span> <span class=\"nn\">.</span> <span class=\"kn\">import</span> views\n\nurlpatterns <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"c1\"># ex: /polls/</span>\n    path<span class=\"p\">(</span><span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span> views<span class=\"o\">.</span>index<span class=\"p\">,</span> name<span class=\"o\">=</span><span class=\"s2\">&quot;index&quot;</span><span class=\"p\">),</span>\n    <span class=\"c1\"># ex: /polls/5/</span>\n    path<span class=\"p\">(</span><span class=\"s2\">&quot;&lt;int:question_id&gt;/&quot;</span><span class=\"p\">,</span> views<span class=\"o\">.</span>detail<span class=\"p\">,</span> name<span class=\"o\">=</span><span class=\"s2\">&quot;detail&quot;</span><span class=\"p\">),</span>\n    <span class=\"c1\"># ex: /polls/5/results/</span>\n    path<span class=\"p\">(</span><span class=\"s2\">&quot;&lt;int:question_id&gt;/results/&quot;</span><span class=\"p\">,</span> views<span class=\"o\">.</span>results<span class=\"p\">,</span> name<span class=\"o\">=</span><span class=\"s2\">&quot;results&quot;</span><span class=\"p\">),</span>\n    <span class=\"c1\"># ex: /polls/5/vote/</span>\n    path<span class=\"p\">(</span><span class=\"s2\">&quot;&lt;int:question_id&gt;/vote/&quot;</span><span class=\"p\">,</span> views<span class=\"o\">.</span>vote<span class=\"p\">,</span> name<span class=\"o\">=</span><span class=\"s2\">&quot;vote&quot;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></figure>\n<p>Ρίξτε μια ματιά με τον browser σας στη σελίδα, «/polls/34/». Με το που πατήσετε enter, το GET request που κάνατε για αυτό το URL θα κάνει trigger το Django project σας, θα γίνει σκανάρισμα των URLs, θα ταιριάξει το δεύτερο URL pattern το οποίο με τη σειρά του θα καλέσει τη μέθοδο <code class=\"docutils literal notranslate\">detail()</code> και η τελευταία θα προβάλει το μήνυμα μαζί με το ID που εισήχθη στο URL (το response το οποίο επιστρέφει η <code class=\"docutils literal notranslate\">detail</code> συνάρτηση). Τώρα δοκιμάστε το «/polls/34/results/» και το «/polls/34/vote/» – αυτά τα URLs θα εμφανίσουν μια σελίδα placeholder για τα αποτελέσματα και τις ψηφοφορίες αντίστοιχα.</p>\n<p>When somebody requests a page from your website – say, «/polls/34/», Django\nwill load the <code class=\"docutils literal notranslate\">mysite.urls</code> Python module because it’s pointed to by the\n<a class=\"reference internal\" href=\"/el/4.2/ref/settings/#std-setting-ROOT_URLCONF\"><code class=\"xref std std-setting docutils literal notranslate\">ROOT_URLCONF</code></a> setting. It finds the variable named <code class=\"docutils literal notranslate\">urlpatterns</code>\nand traverses the patterns in order. After finding the match at <code class=\"docutils literal notranslate\">'polls/'</code>,\nit strips off the matching text (<code class=\"docutils literal notranslate\">&quot;polls/&quot;</code>) and sends the remaining text –\n<code class=\"docutils literal notranslate\">&quot;34/&quot;</code> – to the “polls.urls” URLconf for further processing. There it\nmatches <code class=\"docutils literal notranslate\">'&lt;int:question_id&gt;/'</code>, resulting in a call to the <code class=\"docutils literal notranslate\">detail()</code> view\nlike so:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"go\">detail(request=&lt;HttpRequest object&gt;, question_id=34)</span>\n</code></pre></div>\n<p>The <code class=\"docutils literal notranslate\">question_id=34</code> part comes from <code class=\"docutils literal notranslate\">&lt;int:question_id&gt;</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\">question_id</code> part of the string defines the name that\nwill be used to identify the matched pattern, and the <code class=\"docutils literal notranslate\">int</code> part is a\nconverter that determines what patterns should match this part of the URL path.\nThe colon (<code class=\"docutils literal notranslate\">:</code>) separates the converter and pattern name.</p>\n</section>\n<section id=\"write-views-that-actually-do-something\">\n<h2>Γράφοντας views οι οποίες κάνουν κάτι<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>Κάθε view είναι υπεύθυνο στο να κάνει ένα από δύο πράγματα: να επιστρέφει ένα <a class=\"reference internal\" href=\"/el/4.2/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponse</code></a> object το οποίο περιέχει το περιεχόμενο για την σελίδα που ζητήθηκε ή να κάνει raise κάποιο exception όπως το <a class=\"reference internal\" href=\"/el/4.2/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\">Http404</code></a>. Τα υπόλοιπα εξαρτώνται από εσάς.</p>\n<p>Το view σας μπορεί να διαβάσει records από την βάση δεδομένων ή όχι. Μπορεί να χρησιμοποιήσει ένα template system όπως αυτό του Django – ή κάποιο τρίτο Python template system – ή όχι. Μπορεί να παράγει κάποιο PDF αρχείο, να εξάγει XML, να δημιουργεί κάποιο ZIP αρχείο, να εξάγει JSON δεδομένα, βασικά μπορεί να κάνει τα πάντα χρησιμοποιώντας οποιεσδήποτε βιβλιοθήκες Python επιθυμείτε.</p>\n<p>Το μόνο που απαιτείται από το Django είναι ένα <a class=\"reference internal\" href=\"/el/4.2/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponse</code></a> ή μια exception.</p>\n<p>Επειδή είναι βολικό, θα χρησιμοποιήσουμε το database API του Django, το οποίο καλύψαμε στον <a class=\"reference internal\" href=\"/el/4.2/intro/tutorial02/\"><span class=\"doc\">Οδηγό 2</span></a>. Παρακάτω βλέπετε ένα καινούργιο view με το όνομα <code class=\"docutils literal notranslate\">index()</code>, το οποίο εμφανίζει τις τελευταίες 5 ερωτήσεις (που υπάρχουν στην βάση δεδομένων), διαχωρισμένες με κόμμα, βάση της ημερομηνίας που καταχωρήθηκαν (δημιουργήθηκαν):</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/views.py</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=\"nn\">django.http</span> <span class=\"kn\">import</span> HttpResponse\n\n<span class=\"kn\">from</span> <span class=\"nn\">.models</span> <span class=\"kn\">import</span> Question\n\n\n<span class=\"k\">def</span> <span class=\"nf\">index</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    latest_question_list <span class=\"o\">=</span> Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>order_by<span class=\"p\">(</span><span class=\"s2\">&quot;-pub_date&quot;</span><span class=\"p\">)[:</span><span class=\"mi\">5</span><span class=\"p\">]</span>\n    output <span class=\"o\">=</span> <span class=\"s2\">&quot;, &quot;</span><span class=\"o\">.</span>join<span class=\"p\">([</span>q<span class=\"o\">.</span>question_text <span class=\"k\">for</span> q <span class=\"ow\">in</span> latest_question_list<span class=\"p\">])</span>\n    <span class=\"k\">return</span> HttpResponse<span class=\"p\">(</span>output<span class=\"p\">)</span>\n\n\n<span class=\"c1\"># Leave the rest of the views (detail, results, vote) unchanged</span>\n</code></pre></figure>\n<p>Υπάρχει ένα πρόβλημα εδώ, όμως: ο σχεδιασμός της σελίδας (design) είναι γραμμένος στο view. Αν χρειαστεί να αλλάξετε τον τρόπο εμφάνιση της σελίδας σας, θα χρειαστεί να επεξεργαστείτε αυτόν τον Python κώδικα. Ας κάνουμε κάτι καλύτερο. Ας χρησιμοποιήσουμε το template system του Django για να διαχωρίσουμε το design από τον Python κώδικα δημιουργώντας ένα template που το view μπορεί να χρησιμοποιήσει.</p>\n<p>Για αρχή, δημιουργήστε ένα φάκελο με το όνομα <code class=\"docutils literal notranslate\">templates</code> κάτω από τον φάκελο <code class=\"docutils literal notranslate\">polls</code>. Το Django θα κοιτάξει για templates εκεί.</p>\n<p>Η ρύθμιση <a class=\"reference internal\" href=\"/el/4.2/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\">TEMPLATES</code></a> του project σας περιγράφει πως το Django θα φορτώνει και θα κάνει render τα templates. Η προεπιλεγμένη ρύθμιση στο αρχείο settings παραμετροποιεί το <code class=\"docutils literal notranslate\">DjangoTemplates</code> backend του οποίου η ρύθμιση <a class=\"reference internal\" href=\"/el/4.2/ref/settings/#std-setting-TEMPLATES-APP_DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">APP_DIRS</code></a> είναι ρυθμισμένη στο <code class=\"docutils literal notranslate\">True</code>. Έτσι, το <code class=\"docutils literal notranslate\">DjangoTemplates</code> ψάχνει για ένα υπό-φάκελο «templates» σε κάθε εφαρμογή (app) που είναι περασμένη στη ρύθμιση <a class=\"reference internal\" href=\"/el/4.2/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a>.</p>\n<p>Within the <code class=\"docutils literal notranslate\">templates</code> directory you have just created, create another\ndirectory called <code class=\"docutils literal notranslate\">polls</code>, and within that create a file called\n<code class=\"docutils literal notranslate\">index.html</code>. In other words, your template should be at\n<code class=\"docutils literal notranslate\">polls/templates/polls/index.html</code>. Because of how the <code class=\"docutils literal notranslate\">app_directories</code>\ntemplate loader works as described above, you can refer to this template within\nDjango as <code class=\"docutils literal notranslate\">polls/index.html</code>.</p>\n<aside class=\"admonition-template-namespacing admonition\" role=\"note\">\n<p class=\"admonition-title\">Template namespacing</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\">polls/templates</code> (rather than creating another <code class=\"docutils literal notranslate\">polls</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>Βάλτε τον ακόλουθο κώδικα στο template:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/templates/polls/index.html</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\">Σημείωση</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>Τώρα, ας ανανεώσουμε το <code class=\"docutils literal notranslate\">index</code> view μέσα στο αρχείο <code class=\"docutils literal notranslate\">polls/views.py</code> ούτως ώστε να χρησιμοποιήσει το νέο μας template:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/views.py</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=\"nn\">django.http</span> <span class=\"kn\">import</span> HttpResponse\n<span class=\"kn\">from</span> <span class=\"nn\">django.template</span> <span class=\"kn\">import</span> loader\n\n<span class=\"kn\">from</span> <span class=\"nn\">.models</span> <span class=\"kn\">import</span> Question\n\n\n<span class=\"k\">def</span> <span class=\"nf\">index</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    latest_question_list <span class=\"o\">=</span> Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>order_by<span class=\"p\">(</span><span class=\"s2\">&quot;-pub_date&quot;</span><span class=\"p\">)[:</span><span class=\"mi\">5</span><span class=\"p\">]</span>\n    template <span class=\"o\">=</span> loader<span class=\"o\">.</span>get_template<span class=\"p\">(</span><span class=\"s2\">&quot;polls/index.html&quot;</span><span class=\"p\">)</span>\n    context <span class=\"o\">=</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;latest_question_list&quot;</span><span class=\"p\">:</span> latest_question_list<span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n    <span class=\"k\">return</span> HttpResponse<span class=\"p\">(</span>template<span class=\"o\">.</span>render<span class=\"p\">(</span>context<span class=\"p\">,</span> request<span class=\"p\">))</span>\n</code></pre></figure>\n<p>Αυτός ο κώδικας φορτώνει το template με το όνομα <code class=\"docutils literal notranslate\">polls/index.html</code> και περνάει σε αυτό ένα context. Το context είναι ένα dictionary το οποίο αντιστοιχεί template variable ονόματα σε Python objects.</p>\n<p>Πηγαίνετε στη σελίδα με το browser σας στο «/polls/» και θα πρέπει να δείτε μια λίστα (με κουκίδες) η οποία περιέχει την ερώτηση «What’s up» που φτιάξαμε στον <a class=\"reference internal\" href=\"/el/4.2/intro/tutorial02/\"><span class=\"doc\">Οδηγό 2</span></a>. Το link δείχνει στην σελίδα με τις λεπτομέρειες της ερώτησης.</p>\n<section id=\"a-shortcut-render\">\n<h3>Η συντόμευση: <a class=\"reference internal\" href=\"/el/4.2/topics/http/shortcuts/#django.shortcuts.render\" title=\"django.shortcuts.render\"><code class=\"xref py py-func docutils literal notranslate\">render()</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>Είναι πολύ συνηθισμένο να φορτώνεται ένα template, να γεμίζεται ένα context και να επιστρέφεται ένα\n<a class=\"reference internal\" href=\"/el/4.2/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponse</code></a> object του οποίου το αποτέλεσμα θα είναι το rendered template. Το Django παρέχει μια συντόμευση για όλα αυτά. Ορίστε πάλι το <code class=\"docutils literal notranslate\">index()</code> view, γραμμένο από την αρχή:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/views.py</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=\"nn\">django.shortcuts</span> <span class=\"kn\">import</span> render\n\n<span class=\"kn\">from</span> <span class=\"nn\">.models</span> <span class=\"kn\">import</span> Question\n\n\n<span class=\"k\">def</span> <span class=\"nf\">index</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    latest_question_list <span class=\"o\">=</span> Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>order_by<span class=\"p\">(</span><span class=\"s2\">&quot;-pub_date&quot;</span><span class=\"p\">)[:</span><span class=\"mi\">5</span><span class=\"p\">]</span>\n    context <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s2\">&quot;latest_question_list&quot;</span><span class=\"p\">:</span> latest_question_list<span class=\"p\">}</span>\n    <span class=\"k\">return</span> render<span class=\"p\">(</span>request<span class=\"p\">,</span> <span class=\"s2\">&quot;polls/index.html&quot;</span><span class=\"p\">,</span> context<span class=\"p\">)</span>\n</code></pre></figure>\n<p>Σημειώστε ότι, αφού χρησιμοποιήσουμε την <a class=\"reference internal\" href=\"/el/4.2/topics/http/shortcuts/#django.shortcuts.render\" title=\"django.shortcuts.render\"><code class=\"xref py py-func docutils literal notranslate\">render()</code></a> για <em>όλες</em> τις views, δεν χρειάζεται πλέον να κάνουμε import τα <a class=\"reference internal\" href=\"/el/4.2/topics/templates/#module-django.template.loader\" title=\"django.template.loader\"><code class=\"xref py py-mod docutils literal notranslate\">loader</code></a> και <a class=\"reference internal\" href=\"/el/4.2/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponse</code></a>. Παραταύτα, θα χρειαστεί να κρατήσετε το <code class=\"docutils literal notranslate\">HttpResponse</code> αν έχετε ακόμη τις μεθόδους  για το``detail``, <code class=\"docutils literal notranslate\">results</code> και <code class=\"docutils literal notranslate\">vote</code> view.</p>\n<p>Η συνάρτηση <a class=\"reference internal\" href=\"/el/4.2/topics/http/shortcuts/#django.shortcuts.render\" title=\"django.shortcuts.render\"><code class=\"xref py py-func docutils literal notranslate\">render()</code></a> παίρνει ως πρώτο όρισμα το request object, ως δεύτερο το όνομα του template και ένα dictionary ως τρίτο προαιρετικό. Επιστρέφει ένα <a class=\"reference internal\" href=\"/el/4.2/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">HttpResponse</code></a> object του δηλωθέν template το οποίο template έχει γίνει rendered βάση του δοθέν context.</p>\n</section>\n</section>\n<section id=\"raising-a-404-error\">\n<h2>Raising σφάλμα 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>Σε αυτό το σημείο θα πειράξουμε το view που αφορά στις λεπτομέρειες μιας ερώτησης – τη σελίδα, δηλαδή, η οποία εμφανίζει την ερώτηση για μια συγκεκριμένη ψηφοφορία. Αυτό είναι το view:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/views.py</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=\"nn\">django.http</span> <span class=\"kn\">import</span> Http404\n<span class=\"kn\">from</span> <span class=\"nn\">django.shortcuts</span> <span class=\"kn\">import</span> render\n\n<span class=\"kn\">from</span> <span class=\"nn\">.models</span> <span class=\"kn\">import</span> Question\n\n\n<span class=\"c1\"># ...</span>\n<span class=\"k\">def</span> <span class=\"nf\">detail</span><span class=\"p\">(</span>request<span class=\"p\">,</span> question_id<span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        question <span class=\"o\">=</span> Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span>question_id<span class=\"p\">)</span>\n    <span class=\"k\">except</span> Question<span class=\"o\">.</span>DoesNotExist<span class=\"p\">:</span>\n        <span class=\"k\">raise</span> Http404<span class=\"p\">(</span><span class=\"s2\">&quot;Question does not exist&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> render<span class=\"p\">(</span>request<span class=\"p\">,</span> <span class=\"s2\">&quot;polls/detail.html&quot;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;question&quot;</span><span class=\"p\">:</span> question<span class=\"p\">})</span>\n</code></pre></figure>\n<p>Το νέο concept εδώ είναι: Το view κάνει raise την exception <a class=\"reference internal\" href=\"/el/4.2/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\">Http404</code></a> αν η ερώτηση με το συγκεκριμένο ID δεν υπάρχει (στη βάση δεδομένων).</p>\n<p>Θα συζητήσουμε τι μπορείτε να βάλετε μέσα στο template με το όνομα <code class=\"docutils literal notranslate\">polls/detail.html</code> λίγο αργότερα, αλλά τώρα αν βιάζεστε να δείτε πως θα φαίνεται γράψτε τα ακόλουθα στο αρχείο <code class=\"docutils literal notranslate\">polls/detail.html</code>:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/templates/polls/detail.html</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>Αυτό θα σας δώσει μια ιδέα.</p>\n<section id=\"a-shortcut-get-object-or-404\">\n<h3>Η συντόμευση: <a class=\"reference internal\" href=\"/el/4.2/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\">get_object_or_404()</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>Είναι συνηθισμένο να χρησιμοποιείται η μέθοδος <a class=\"reference internal\" href=\"/el/4.2/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\">get()</code></a> η οποία να κάνει raise το exception <a class=\"reference internal\" href=\"/el/4.2/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\">Http404</code></a> αν το object δεν υπάρχει. Το Django σας παρέχει μια συντόμευση και γι’ αυτό. Παρακάτω φαίνεται το <code class=\"docutils literal notranslate\">detail()</code> view, γραμμένο από την αρχή (πάλι):</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/views.py</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=\"nn\">django.shortcuts</span> <span class=\"kn\">import</span> get_object_or_404<span class=\"p\">,</span> render\n\n<span class=\"kn\">from</span> <span class=\"nn\">.models</span> <span class=\"kn\">import</span> Question\n\n\n<span class=\"c1\"># ...</span>\n<span class=\"k\">def</span> <span class=\"nf\">detail</span><span class=\"p\">(</span>request<span class=\"p\">,</span> question_id<span class=\"p\">):</span>\n    question <span class=\"o\">=</span> get_object_or_404<span class=\"p\">(</span>Question<span class=\"p\">,</span> pk<span class=\"o\">=</span>question_id<span class=\"p\">)</span>\n    <span class=\"k\">return</span> render<span class=\"p\">(</span>request<span class=\"p\">,</span> <span class=\"s2\">&quot;polls/detail.html&quot;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;question&quot;</span><span class=\"p\">:</span> question<span class=\"p\">})</span>\n</code></pre></figure>\n<p>Η συνάρτηση <a class=\"reference internal\" href=\"/el/4.2/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\">get_object_or_404()</code></a> παίρνει ως πρώτο όρισμα ένα Django model και ένα αυθαίρετο αριθμό από arguments, τα οποία τα δίνει στην μέθοδο <a class=\"reference internal\" href=\"/el/4.2/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\">get()</code></a> του manager του μοντέλου (model manager) που περάστηκε  ως πρώτο όρισμα. Η συνάρτηση αυτή κάνει raise το exception <a class=\"reference internal\" href=\"/el/4.2/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\">Http404</code></a> αν το object δεν υπάρχει.</p>\n<aside class=\"admonition-philosophy admonition\" role=\"note\">\n<p class=\"admonition-title\">Φιλοσοφία</p>\n<p>Γιατί όμως χρησιμοποιούμε την βοηθητική συνάρτηση (helper function) <a class=\"reference internal\" href=\"/el/4.2/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\">get_object_or_404()</code></a> αντί να κάνουμε αυτόματα το catch του exception <a class=\"reference internal\" href=\"/el/4.2/ref/exceptions/#django.core.exceptions.ObjectDoesNotExist\" title=\"django.core.exceptions.ObjectDoesNotExist\"><code class=\"xref py py-exc docutils literal notranslate\">ObjectDoesNotExist</code></a> σε ένα υψηλότερο επίπεδο; Επίσης, γιατί να βάλουμε το model API να κάνει raise το exception <a class=\"reference internal\" href=\"/el/4.2/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\">Http404</code></a> αντί του exception <a class=\"reference internal\" href=\"/el/4.2/ref/exceptions/#django.core.exceptions.ObjectDoesNotExist\" title=\"django.core.exceptions.ObjectDoesNotExist\"><code class=\"xref py py-exc docutils literal notranslate\">ObjectDoesNotExist</code></a>;</p>\n<p>Η απάντηση είναι ίδια και στις δύο ερωτήσεις. Επειδή αυτό θα δεσμεύσει το επίπεδο του model με το επίπεδο του view. Ένας από τους πρωταρχικούς στόχους του Django είναι να διατηρηθεί η ανεξαρτητοποίηση και η μη σύνδεση μεταξύ οντοτήτων (το λεγόμενο loose coupling). Μερικά ελεγχόμενα couplings παρουσιάζονται στο module <a class=\"reference internal\" href=\"/el/4.2/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\">django.shortcuts</code></a>.</p>\n</aside>\n<p>Υπάρχει επίσης η συνάρτηση <a class=\"reference internal\" href=\"/el/4.2/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\">get_list_or_404()</code></a>, η οποία λειτουργεί πανομοιότυπα με την <a class=\"reference internal\" href=\"/el/4.2/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\">get_object_or_404()</code></a> – με τη μόνη διαφορά ότι χρησιμοποιεί την μέθοδο <a class=\"reference internal\" href=\"/el/4.2/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\">filter()</code></a> αντί της <a class=\"reference internal\" href=\"/el/4.2/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\">get()</code></a>. Η <a class=\"reference internal\" href=\"/el/4.2/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\">get_list_or_404()</code></a> κάνει raise την exception <a class=\"reference internal\" href=\"/el/4.2/topics/http/views/#django.http.Http404\" title=\"django.http.Http404\"><code class=\"xref py py-exc docutils literal notranslate\">Http404</code></a> αν η λίστα είναι κενή (άδεια).</p>\n</section>\n</section>\n<section id=\"use-the-template-system\">\n<h2>Χρησιμοποιώντας ένα template system<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>Πίσω στο <code class=\"docutils literal notranslate\">detail()</code> view της εφαρμογής μας. Έχοντας το context variable με το όνομα <code class=\"docutils literal notranslate\">question</code>, το template <code class=\"docutils literal notranslate\">polls/detail.html</code> θα δείχνει κάπως έτσι:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/templates/polls/detail.html</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>Το template system χρησιμοποιεί την σύνταξη της τελείας για να ψάχνει μέσα στα variable attributes. Στο παράδειγμα του <code class=\"docutils literal notranslate\">{{ question.question_text }}</code>, το Django θα ψάξει πρώτα μέσα στο dictionary του object <code class=\"docutils literal notranslate\">question</code>. Αν δεν βρει τίποτα (δεν υπάρχει, δηλαδή, το key <code class=\"docutils literal notranslate\">question_text``στο υποτιθέμενο dictionary), προσπαθεί να βρει το ``question_text</code> σαν attribute του object – το οποίο στη συγκεκριμένη περίπτωση ισχύει. Αν όμως δεν υπήρχε, τότε θα έψαχνε σε μια λίστα να το βρει.</p>\n<p>Ο τρόπος για να καλείτε μεθόδους φαίνεται στο βρόγχο επανάληψης <a class=\"reference internal\" href=\"/el/4.2/ref/templates/builtins/#std-templatetag-for\"><code class=\"xref std std-ttag docutils literal notranslate\">{% for %}</code></a>:  το <code class=\"docutils literal notranslate\">question.choice_set.all</code> μεταφράζεται ως Python κώδικας <code class=\"docutils literal notranslate\">question.choice_set.all()</code>, το οποίο επιστρέφει ένα iterable από <code class=\"docutils literal notranslate\">Choice</code> objects και είναι βολικό προς χρήση (στην παρούσα) με τον βρόγχο επανάληψης <a class=\"reference internal\" href=\"/el/4.2/ref/templates/builtins/#std-templatetag-for\"><code class=\"xref std std-ttag docutils literal notranslate\">{% for %}</code></a> (το οποίο αναφέρεται και ως <code class=\"docutils literal notranslate\">template tag</code>).</p>\n<p>Δείτε το άρθρο <a class=\"reference internal\" href=\"/el/4.2/topics/templates/\"><span class=\"doc\">templates</span></a> για περισσότερα σχετικά με τα templates.</p>\n</section>\n<section id=\"removing-hardcoded-urls-in-templates\">\n<h2>Αφαίρεση των hardcoded URLs στα templates<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>Θυμηθείτε ότι πριν, δηλώσαμε στην HTML το link για την ερώτηση στο template <code class=\"docutils literal notranslate\">polls/index.html</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;/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>The problem with this hardcoded, tightly-coupled approach is that it becomes\nchallenging to change URLs on projects with a lot of templates. However, since\nyou defined the name argument in the <a class=\"reference internal\" href=\"/el/4.2/ref/urls/#django.urls.path\" title=\"django.urls.path\"><code class=\"xref py py-func docutils literal notranslate\">path()</code></a> functions in\nthe <code class=\"docutils literal notranslate\">polls.urls</code> module, you can remove a reliance on specific URL paths\ndefined in your url configurations by using the <code class=\"docutils literal notranslate\">{% url %}</code> template tag:</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>Ο τρόπος με τον οποίο λειτουργεί αυτό το template tag είναι κοιτώντας τα URLs που έχετε ορίσει στο module <code class=\"docutils literal notranslate\">polls.urls</code>. Μπορείτε να δείτε ακριβώς σε ποιο URL έχει οριστεί το όνομα “detail” παρακάτω:</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>\npath<span class=\"p\">(</span><span class=\"s2\">&quot;&lt;int:question_id&gt;/&quot;</span><span class=\"p\">,</span> views<span class=\"o\">.</span>detail<span class=\"p\">,</span> name<span class=\"o\">=</span><span class=\"s2\">&quot;detail&quot;</span><span class=\"p\">),</span>\n<span class=\"o\">...</span>\n</code></pre></div>\n<p>Αν θέλετε να αλλάξετε το URL αυτού του view σε κάτι άλλο (ίσως στο <code class=\"docutils literal notranslate\">polls/specifics/12/</code>), τότε αντί να ψάχνετε όλα τα templates που είχατε δηλώσει το παλιό URL προκειμένου να το αντικαταστήσετε με το καινούργιο, πολύ απλά πειράζετε ένα αρχείο (<code class=\"docutils literal notranslate\">polls/urls.py</code>) και όλα τα υπόλοιπα ανανεώνονται αυτόματα, χάρη στο template tag <code class=\"docutils literal notranslate\">{% url %}</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>\npath<span class=\"p\">(</span><span class=\"s2\">&quot;specifics/&lt;int:question_id&gt;/&quot;</span><span class=\"p\">,</span> views<span class=\"o\">.</span>detail<span class=\"p\">,</span> name<span class=\"o\">=</span><span class=\"s2\">&quot;detail&quot;</span><span class=\"p\">),</span>\n<span class=\"o\">...</span>\n</code></pre></div>\n</section>\n<section id=\"namespacing-url-names\">\n<h2>Χρησιμοποιώντας namespacing στα ονόματα των URL<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>Το project του οδηγού αυτού έχει μόνο μια εφαρμογή, την <code class=\"docutils literal notranslate\">polls</code>. Σε πραγματικά Django projects, ίσως να έχετε πέντε, δέκα, είκοσι ή περισσότερα apps. Πως μπορεί να ξέρει και να διαφοροποιεί το Django τα ονόματα των URLs ανάμεσα σε τόσα apps; Για παράδειγμα, η εφαρμογή <code class=\"docutils literal notranslate\">polls</code> έχει ένα <code class=\"docutils literal notranslate\">detail</code> view και ίσως ένα άλλο app (στο ίδιο project) να έχει το ίδιο όνομα για ένα δικό του view. Όταν το Django συναντήσει το template tag <code class=\"docutils literal notranslate\">{% url 'detail' %}</code> πως θα ξέρει σε ποιο view να αναφερθεί;</p>\n<p>Η απάντηση έρχεται με την προσθήκη namespaces στο URLconf. Στο αρχείο <code class=\"docutils literal notranslate\">polls/urls.py</code>, προσθέστε μια μεταβλητή <code class=\"docutils literal notranslate\">app_name</code> ούτως ώστε να θέσετε το namespace για αυτό το app:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/urls.py</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=\"nn\">django.urls</span> <span class=\"kn\">import</span> path\n\n<span class=\"kn\">from</span> <span class=\"nn\">.</span> <span class=\"kn\">import</span> views\n\napp_name <span class=\"o\">=</span> <span class=\"s2\">&quot;polls&quot;</span>\nurlpatterns <span class=\"o\">=</span> <span class=\"p\">[</span>\n    path<span class=\"p\">(</span><span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span> views<span class=\"o\">.</span>index<span class=\"p\">,</span> name<span class=\"o\">=</span><span class=\"s2\">&quot;index&quot;</span><span class=\"p\">),</span>\n    path<span class=\"p\">(</span><span class=\"s2\">&quot;&lt;int:question_id&gt;/&quot;</span><span class=\"p\">,</span> views<span class=\"o\">.</span>detail<span class=\"p\">,</span> name<span class=\"o\">=</span><span class=\"s2\">&quot;detail&quot;</span><span class=\"p\">),</span>\n    path<span class=\"p\">(</span><span class=\"s2\">&quot;&lt;int:question_id&gt;/results/&quot;</span><span class=\"p\">,</span> views<span class=\"o\">.</span>results<span class=\"p\">,</span> name<span class=\"o\">=</span><span class=\"s2\">&quot;results&quot;</span><span class=\"p\">),</span>\n    path<span class=\"p\">(</span><span class=\"s2\">&quot;&lt;int:question_id&gt;/vote/&quot;</span><span class=\"p\">,</span> views<span class=\"o\">.</span>vote<span class=\"p\">,</span> name<span class=\"o\">=</span><span class=\"s2\">&quot;vote&quot;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></figure>\n<p>Τώρα, πηγαίνετε και αλλάξτε το αρχείο <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">``</span></a>polls/index.html``από:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/templates/polls/index.html</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>στο:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"html+django\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">polls/templates/polls/index.html</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=\"/el/4.2/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":"Επισκόπηση","anchor":"overview","children":[]},{"title":"Γράφοντας περισσότερα views","anchor":"writing-more-views","children":[]},{"title":"Γράφοντας views οι οποίες κάνουν κάτι","anchor":"write-views-that-actually-do-something","children":[{"title":"Η συντόμευση: render()","anchor":"a-shortcut-render","children":[]}]},{"title":"Raising σφάλμα 404","anchor":"raising-a-404-error","children":[{"title":"Η συντόμευση: get_object_or_404()","anchor":"a-shortcut-get-object-or-404","children":[]}]},{"title":"Χρησιμοποιώντας ένα template system","anchor":"use-the-template-system","children":[]},{"title":"Αφαίρεση των hardcoded URLs στα templates","anchor":"removing-hardcoded-urls-in-templates","children":[]},{"title":"Χρησιμοποιώντας namespacing στα ονόματα των URL","anchor":"namespacing-url-names","children":[]}],"breadcrumbs":[{"docname":"intro/index","title":"Ξεκινώντας","url":"/el/4.2/intro/"}],"prev":{"docname":"intro/tutorial02","title":"Γράφοντας το πρώτο σας Django app, μέρος 2","url":"/el/4.2/intro/tutorial02/"},"next":{"docname":"intro/tutorial04","title":"Γράφοντας το πρώτο σας Django app, μέρος 4","url":"/el/4.2/intro/tutorial04/"},"formats":{"html":"/el/4.2/intro/tutorial03/","markdown":"/el/4.2/intro/tutorial03.md","json":"/el/4.2/intro/tutorial03.json"},"source":"https://github.com/django/django/blob/stable/4.2.x/docs/intro/tutorial03.txt","official":"https://docs.djangoproject.com/el/4.2/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","it","pt-br","ko","es","el","pl"]}