{"title":"Γράφοντας το πρώτο σας Django app, μέρος 3","version":"1.11","locale":"el","docname":"intro/tutorial03","url":"/el/1.11/intro/tutorial03/","canonical":"https://djangodocs.dev/el/1.11/intro/tutorial03/","summary":"Ο οδηγός αυτός ξεκινά εκεί που τελειώνει ο οδηγός 2 . Συνεχίζουμε με την εφαρμογή μας (σκοπός μας είναι φτιάξουμε ένα σύστημα ψηφοφορίας όπου θα γράφουμε τις…","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>Ο οδηγός αυτός ξεκινά εκεί που τελειώνει <a class=\"reference internal\" href=\"/el/1.11/intro/tutorial02/\"><span class=\"doc\">ο οδηγός 2</span></a>. Συνεχίζουμε με την εφαρμογή μας (σκοπός μας είναι φτιάξουμε ένα σύστημα ψηφοφορίας όπου θα γράφουμε τις ερωτήσεις και τι πιθανές επιλογές και ο κόσμος θα μπορεί να ψηφίζει). Αυτή τη φορά θα επικεντρωθούμε στην προβολή της ιστοσελίδας μας στο ευρύ κοινό, στα “views”.</p>\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>Ένα view είναι ένας «τύπος» μιας ιστοσελίδας (Web page) σε ένα Django application το οποίο, σε γενικές γραμμές, εξυπηρετεί μια συγκεκριμένη συνάρτηση και έχει ένα συγκεκριμένο template. Για παράδειγμα, ένα blog application, μπορεί να περιέχει τα ακόλουθα 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>Στο Django, οι ιστοσελίδες όπως επίσης και άλλα περιεχόμενα εξυπηρετούνται από τα views. Κάθε view αντιπροσωπεύεται από μια απλή Python συνάρτηση (ή μέθοδο, στην περίπτωση των class-based views). Το Django θα διαλέξει το view ανάλογα το URL το οποίο ζητήθηκε (πιο συγκεκριμένα, το μέρος του URL μετά το domain name).</p>\n<p>Ίσως μέχρι τώρα έχετε δει στην διαδικτυακή σας περιήγηση μερικές ομορφιές όπως «ME2/Sites/dirmod.asp?sid=&amp;type=gen&amp;mod=Core+Pages&amp;gid=A6CD4967199A42D9B65B1B». Ίσως θα σας χαροποιήσει το γεγονός ότι το Django χρησιμοποιεί (και το κάνει) πολύ πιο κομψά  <em>URL patterns</em> εν συγκρίσει με αυτά.</p>\n<p>Ένα URL pattern (μοτίβο) είναι απλά μια γενική φόρμα ενός URL – για παράδειγμα: <code class=\"docutils literal notranslate\"><span class=\"pre\">/newsarchive/&lt;year&gt;/&lt;month&gt;/</span></code>.</p>\n<p>Για να μεταβούμε από ένα URL σε ένα view, το Django χρησιμοποιεί κάτι το οποίο είναι γνωστό ως “URLconfs”. Ένα URLconf αντιστοιχεί URL μοτίβα (τα οποία περιγράφονται με regular expressions) σε views. Αυτά τα είδαμε περιληπτικά στον <a class=\"reference internal\" href=\"/el/1.11/intro/tutorial01/\"><span class=\"doc\">Οδηγό 1</span></a>.</p>\n<p>Ο συγκεκριμένος οδηγός προσφέρει βασικές οδηγίες στη χρήση των URLconfs. Επίσης, περισσότερες πληροφορίες μπορείτε να βρείτε στο module <a class=\"reference internal\" href=\"/el/1.11/ref/urlresolvers/#module-django.urls\" title=\"django.urls\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.urls</span></code></a>.</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\"><span class=\"pre\">polls/views.py</span></code>. Αυτά τα views είναι ελαφρώς διαφορετικά, επειδή παίρνουν και όρισμα (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>Συνδέστε τα καινούργια αυτά views με το αρχείο <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code> προσθέτοντας τον παρακάτω κώδικα στη κλήση της συνάρτησης <a class=\"reference internal\" href=\"/el/1.11/ref/urls/#django.conf.urls.url\" title=\"django.conf.urls.url\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">url()</span></code></a>:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/urls.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/urls.py\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.conf.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">url</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">views</span>\n\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"c1\"># ex: /polls/</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">index</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;index&#39;</span><span class=\"p\">),</span>\n    <span class=\"c1\"># ex: /polls/5/</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">detail</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;detail&#39;</span><span class=\"p\">),</span>\n    <span class=\"c1\"># ex: /polls/5/results/</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/results/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">results</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;results&#39;</span><span class=\"p\">),</span>\n    <span class=\"c1\"># ex: /polls/5/vote/</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/vote/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">vote</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;vote&#39;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></figure>\n<p>Ρίξτε μια ματιά με τον browser σας στη σελίδα, «/polls/34/». Με το που πατήσετε enter, το GET request που κάνατε για αυτό το URL θα κάνει trigger το Django project σας, θα γίνει σκανάρισμα των URLs, θα ταιριάξει το δεύτερο URL pattern το οποίο με τη σειρά του θα καλέσει τη μέθοδο <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> και η τελευταία θα προβάλει το μήνυμα μαζί με το ID που εισήχθη στο URL (το response το οποίο επιστρέφει η <code class=\"docutils literal notranslate\"><span class=\"pre\">detail</span></code> συνάρτηση). Τώρα δοκιμάστε το «/polls/34/results/» και το «/polls/34/vote/» – αυτά τα URLs θα εμφανίσουν μια σελίδα placeholder για τα αποτελέσματα και τις ψηφοφορίες αντίστοιχα.</p>\n<p>Όπως είπαμε και πιο πάνω όταν κάποιος κάνει request μια σελίδα από το website σας – ας πούμε την «/polls/34/», τότε το Django θα φορτώσει το <code class=\"docutils literal notranslate\"><span class=\"pre\">mysite.urls</span></code> Python module επειδή δείχνει σε αυτό η ρύθμιση <a class=\"reference internal\" href=\"/el/1.11/ref/settings/#std-setting-ROOT_URLCONF\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">ROOT_URLCONF</span></code></a>. Βρίσκει μέσα μια μεταβλητή με το όνομα <code class=\"docutils literal notranslate\"><span class=\"pre\">urlpatterns</span></code> και βλέπει-σκανάρει μία-μία τις regular expressions με τη σειρά που είναι δηλωμένες. Αφού βρει αυτή που ταιριάζει στο <code class=\"docutils literal notranslate\"><span class=\"pre\">'^polls/'</span></code>, κόβει το string που ταίριαξε (<code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;polls/&quot;</span></code>) και στέλνει το υπόλοιπο – <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;34/&quot;</span></code> – στο “polls.urls” URLconf για περαιτέρω επεξεργασία. Εκεί, ταιριάζει το <code class=\"docutils literal notranslate\"><span class=\"pre\">r'^(?P&lt;question_id&gt;[0-9]+)/$'</span></code>, με αποτέλεσμα να κληθεί το <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> view ως εξής:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">detail</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">=&lt;</span><span class=\"n\">HttpRequest</span> <span class=\"nb\">object</span><span class=\"o\">&gt;</span><span class=\"p\">,</span> <span class=\"n\">question_id</span><span class=\"o\">=</span><span class=\"s1\">&#39;34&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Το κομμάτι <code class=\"docutils literal notranslate\"><span class=\"pre\">question_id='34'</span></code> προκύπτει από το <code class=\"docutils literal notranslate\"><span class=\"pre\">(?P&lt;question_id&gt;[0-9]+)</span></code>. Χρησιμοποιώντας παρενθέσεις γύρω από ένα μοτίβο, «αιχμαλωτίζουμε» το κείμενο (text) που ταίριαξε (βάση του μοτίβου) και το στέλνουμε ως όρισμα (argument) στη συνάρτηση view (π.χ <code class=\"docutils literal notranslate\"><span class=\"pre\">detail</span></code>). Το <code class=\"docutils literal notranslate\"><span class=\"pre\">?P&lt;question_id&gt;</span></code> ορίζει το όνομα που θα χρησιμοποιηθεί για να αναγνωρίσουμε το κείμενο που ταίριαξε. Τέλος, το <code class=\"docutils literal notranslate\"><span class=\"pre\">[0-9]+</span></code> είναι μια regular expression η οποία ταιριάζει ακολουθίες ψηφίων (π.χ ένας αριθμός).</p>\n<p>Επειδή, στην ουσία, τα URL patterns είναι regular expressions, στην πραγματικότητα δεν υπάρχουν όρια για το τι μπορεί να επιτευχθεί με αυτά. Επίσης δεν υπάρχει λόγος να προσθέσετε άσχημες URL καταλήξεις όπως <code class=\"docutils literal notranslate\"><span class=\"pre\">.html</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=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^polls/latest\\.html$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">index</span><span class=\"p\">),</span>\n</code></pre></div>\n<p>Αλλά μην το κάνετε. Είναι ανόητο και μη επαγγελματικό.</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/1.11/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> object το οποίο περιέχει το περιεχόμενο για την σελίδα που ζητήθηκε ή να κάνει raise κάποιο exception όπως το <a class=\"reference internal\" href=\"/el/1.11/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>. Τα υπόλοιπα εξαρτώνται από εσάς.</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/1.11/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> ή μια exception.</p>\n<p>Επειδή είναι βολικό, θα χρησιμοποιήσουμε το database API του Django, το οποίο καλύψαμε στον <a class=\"reference internal\" href=\"/el/1.11/intro/tutorial02/\"><span class=\"doc\">Οδηγό 2</span></a>. Παρακάτω βλέπετε ένα καινούργιο view με το όνομα <code class=\"docutils literal notranslate\"><span class=\"pre\">index()</span></code>, το οποίο εμφανίζει τις τελευταίες 5 ερωτήσεις (που υπάρχουν στην βάση δεδομένων), διαχωρισμένες με κόμμα, βάση της ημερομηνίας που καταχωρήθηκαν (δημιουργήθηκαν):</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>Υπάρχει ένα πρόβλημα εδώ, όμως: ο σχεδιασμός της σελίδας (design) είναι γραμμένος στο view. Αν χρειαστεί να αλλάξετε τον τρόπο εμφάνιση της σελίδας σας, θα χρειαστεί να επεξεργαστείτε αυτόν τον Python κώδικα. Ας κάνουμε κάτι καλύτερο. Ας χρησιμοποιήσουμε το template system του Django για να διαχωρίσουμε το design από τον Python κώδικα δημιουργώντας ένα template που το view μπορεί να χρησιμοποιήσει.</p>\n<p>Για αρχή, δημιουργήστε ένα φάκελο με το όνομα <code class=\"docutils literal notranslate\"><span class=\"pre\">templates</span></code> κάτω από τον φάκελο <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code>. Το Django θα κοιτάξει για templates εκεί.</p>\n<p>Η ρύθμιση <a class=\"reference internal\" href=\"/el/1.11/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">TEMPLATES</span></code></a> του project σας περιγράφει πως το Django θα φορτώνει και θα κάνει render τα templates. Η προεπιλεγμένη ρύθμιση στο αρχείο settings παραμετροποιεί το <code class=\"docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code> backend του οποίου η ρύθμιση <a class=\"reference internal\" href=\"/el/1.11/ref/settings/#std-setting-TEMPLATES-APP_DIRS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">APP_DIRS</span></code></a> είναι ρυθμισμένη στο <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>. Έτσι, το <code class=\"docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code> ψάχνει για ένα υπό-φάκελο «templates» σε κάθε εφαρμογή (app) που είναι περασμένη στη ρύθμιση <a class=\"reference internal\" href=\"/el/1.11/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>Μέσα στο φάκελο <code class=\"docutils literal notranslate\"><span class=\"pre\">templates</span></code> που μόλις δημιουργήσατε, δημιουργήστε άλλο έναν φάκελο με το όνομα <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code> και μέσα σε αυτό το φάκελο ένα HTML αρχείο με το όνομα <code class=\"docutils literal notranslate\"><span class=\"pre\">index.html</span></code>. Με άλλα λόγια, το template σας θα πρέπει να βρίσκεται στο <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates/polls/index.html</span></code>. Λόγω του μηχανισμού λειτουργίας του φορτωτή template (template loader) <code class=\"docutils literal notranslate\"><span class=\"pre\">app_directories</span></code> όπως αναφέρθηκε παραπάνω, μπορείτε να αναφερθείτε σε αυτό το template μέσα στο Django ως <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\">Template namespacing</p>\n<p><em>Ίσως</em> θα αναρωτηθήκατε γιατί βάλαμε το template μέσα σε υπό-φάκελο (polls) και όχι μέσα στο φάκελο <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/templates</span></code>. Αν το κάναμε έτσι, τότε δεν θα ήταν και τόσο καλή ιδέα. Το Django θα ψάξει και θα βρει το πρώτο template βάση ονόματος. Αν, λοιπόν, εσείς έχετε ένα άλλο template με το ίδιο όνομα σε μία <em>διαφορετική</em> εφαρμογή, τότε το Django δεν θα είναι σε θέση να ξεχωρίσει ποια από τα δύο να χρησιμοποιήσει. Πρέπει καθοδηγήσουμε το Django στην επιλογή του template που θέλουμε και ο ευκολότερος τρόπος είναι να χρησιμοποιήσουμε την τεχνική <em>namespace</em>. Αυτό επιτυγχάνεται βάζοντας τα templates μέσα σε έναν <em>υπό-φάκελο</em> ο οποίος θα έχει το ίδιο όνομα με το όνομα της εφαρμογής.</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>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>Τώρα, ας ανανεώσουμε το <code class=\"docutils literal notranslate\"><span class=\"pre\">index</span></code> view μέσα στο αρχείο <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/views.py</span></code> ούτως ώστε να χρησιμοποιήσει το νέο μας template:</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>Αυτός ο κώδικας φορτώνει το template με το όνομα <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/index.html</span></code> και περνάει σε αυτό ένα context. Το context είναι ένα dictionary το οποίο αντιστοιχεί template variable ονόματα σε Python objects.</p>\n<p>Πηγαίνετε στη σελίδα με το browser σας στο «/polls/» και θα πρέπει να δείτε μια λίστα (με κουκίδες) η οποία περιέχει την ερώτηση «What’s up» που φτιάξαμε στον <a class=\"reference internal\" href=\"/el/1.11/intro/tutorial02/\"><span class=\"doc\">Οδηγό 2</span></a>. Το link δείχνει στην σελίδα με τις λεπτομέρειες της ερώτησης.</p>\n<section id=\"a-shortcut-render\">\n<h3>Η συντόμευση: <a class=\"reference internal\" href=\"/el/1.11/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>Είναι πολύ συνηθισμένο να φορτώνεται ένα template, να γεμίζεται ένα context και να επιστρέφεται ένα\n<a class=\"reference internal\" href=\"/el/1.11/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> object του οποίου το αποτέλεσμα θα είναι το rendered template. Το Django παρέχει μια συντόμευση για όλα αυτά. Ορίστε πάλι το <code class=\"docutils literal notranslate\"><span class=\"pre\">index()</span></code> view, γραμμένο από την αρχή:</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>Σημειώστε ότι, αφού χρησιμοποιήσουμε την <a class=\"reference internal\" href=\"/el/1.11/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> για <em>όλες</em> τις views, δεν χρειάζεται πλέον να κάνουμε import τα <a class=\"reference internal\" href=\"/el/1.11/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> και <a class=\"reference internal\" href=\"/el/1.11/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>. Παραταύτα, θα χρειαστεί να κρατήσετε το <code class=\"docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code> αν έχετε ακόμη τις μεθόδους  για το``detail``, <code class=\"docutils literal notranslate\"><span class=\"pre\">results</span></code> και <code class=\"docutils literal notranslate\"><span class=\"pre\">vote</span></code> view.</p>\n<p>Η συνάρτηση <a class=\"reference internal\" href=\"/el/1.11/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> παίρνει ως πρώτο όρισμα το request object, ως δεύτερο το όνομα του template και ένα dictionary ως τρίτο προαιρετικό. Επιστρέφει ένα <a class=\"reference internal\" href=\"/el/1.11/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> 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=\"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>Το νέο concept εδώ είναι: Το view κάνει raise την exception <a class=\"reference internal\" href=\"/el/1.11/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> αν η ερώτηση με το συγκεκριμένο ID δεν υπάρχει (στη βάση δεδομένων).</p>\n<p>Θα συζητήσουμε τι μπορείτε να βάλετε μέσα στο template με το όνομα <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/detail.html</span></code> λίγο αργότερα, αλλά τώρα αν βιάζεστε να δείτε πως θα φαίνεται γράψτε τα ακόλουθα στο αρχείο <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=\"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/1.11/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>Είναι συνηθισμένο να χρησιμοποιείται η μέθοδος <a class=\"reference internal\" href=\"/el/1.11/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> η οποία να κάνει raise το exception <a class=\"reference internal\" href=\"/el/1.11/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> αν το object δεν υπάρχει. Το Django σας παρέχει μια συντόμευση και γι’ αυτό. Παρακάτω φαίνεται το <code class=\"docutils literal notranslate\"><span class=\"pre\">detail()</span></code> view, γραμμένο από την αρχή (πάλι):</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>Η συνάρτηση <a class=\"reference internal\" href=\"/el/1.11/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> παίρνει ως πρώτο όρισμα ένα Django model και ένα αυθαίρετο αριθμό από arguments, τα οποία τα δίνει στην μέθοδο <a class=\"reference internal\" href=\"/el/1.11/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> του manager του μοντέλου (model manager) που περάστηκε  ως πρώτο όρισμα. Η συνάρτηση αυτή κάνει raise το exception <a class=\"reference internal\" href=\"/el/1.11/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> αν το object δεν υπάρχει.</p>\n<aside class=\"admonition-philosophy admonition\">\n<p class=\"admonition-title\">Φιλοσοφία</p>\n<p>Γιατί όμως χρησιμοποιούμε την βοηθητική συνάρτηση (helper function) <a class=\"reference internal\" href=\"/el/1.11/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> αντί να κάνουμε αυτόματα το catch του exception <a class=\"reference internal\" href=\"/el/1.11/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> σε ένα υψηλότερο επίπεδο; Επίσης, γιατί να βάλουμε το model API να κάνει raise το exception <a class=\"reference internal\" href=\"/el/1.11/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> αντί του exception <a class=\"reference internal\" href=\"/el/1.11/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>Η απάντηση είναι ίδια και στις δύο ερωτήσεις. Επειδή αυτό θα δεσμεύσει το επίπεδο του model με το επίπεδο του view. Ένας από τους πρωταρχικούς στόχους του Django είναι να διατηρηθεί η ανεξαρτητοποίηση και η μη σύνδεση μεταξύ οντοτήτων (το λεγόμενο loose coupling). Μερικά ελεγχόμενα couplings παρουσιάζονται στο module <a class=\"reference internal\" href=\"/el/1.11/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>Υπάρχει επίσης η συνάρτηση <a class=\"reference internal\" href=\"/el/1.11/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>, η οποία λειτουργεί πανομοιότυπα με την <a class=\"reference internal\" href=\"/el/1.11/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=\"reference internal\" href=\"/el/1.11/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> αντί της <a class=\"reference internal\" href=\"/el/1.11/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>. Η <a class=\"reference internal\" href=\"/el/1.11/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> κάνει raise την exception <a class=\"reference internal\" href=\"/el/1.11/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> αν η λίστα είναι κενή (άδεια).</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\"><span class=\"pre\">detail()</span></code> view της εφαρμογής μας. Έχοντας το context variable με το όνομα <code class=\"docutils literal notranslate\"><span class=\"pre\">question</span></code>, το template <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>Το template system χρησιμοποιεί την σύνταξη της τελείας για να ψάχνει μέσα στα variable attributes. Στο παράδειγμα του <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">question.question_text</span> <span class=\"pre\">}}</span></code>, το Django θα ψάξει πρώτα μέσα στο dictionary του object <code class=\"docutils literal notranslate\"><span class=\"pre\">question</span></code>. Αν δεν βρει τίποτα (δεν υπάρχει, δηλαδή, το key <code class=\"docutils literal notranslate\"><span class=\"pre\">question_text``στο</span> <span class=\"pre\">υποτιθέμενο</span> <span class=\"pre\">dictionary),</span> <span class=\"pre\">προσπαθεί</span> <span class=\"pre\">να</span> <span class=\"pre\">βρει</span> <span class=\"pre\">το</span> <span class=\"pre\">``question_text</span></code> σαν attribute του object – το οποίο στη συγκεκριμένη περίπτωση ισχύει. Αν όμως δεν υπήρχε, τότε θα έψαχνε σε μια λίστα να το βρει.</p>\n<p>Ο τρόπος για να καλείτε μεθόδους φαίνεται στο βρόγχο επανάληψης <a class=\"reference internal\" href=\"/el/1.11/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> μεταφράζεται ως Python κώδικας <code class=\"docutils literal notranslate\"><span class=\"pre\">question.choice_set.all()</span></code>, το οποίο επιστρέφει ένα iterable από <code class=\"docutils literal notranslate\"><span class=\"pre\">Choice</span></code> objects και είναι βολικό προς χρήση (στην παρούσα) με τον βρόγχο επανάληψης <a class=\"reference internal\" href=\"/el/1.11/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\">template</span> <span class=\"pre\">tag</span></code>).</p>\n<p>Δείτε το άρθρο <a class=\"reference internal\" href=\"/el/1.11/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\"><span class=\"pre\">polls/index.html</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;/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>Το πρόβλημα με τα hardcoded URLs (αλλά και γενικά με την hardcoded προσέγγιση), είναι ότι από ένα σημείο και μετά γίνεται δύσκολο (αν όχι ακατόρθωτο) να αλλάξετε όλα τα URLs στα projects σας τα οποία χρησιμοποιούν πολλά templates. Ωστόσο, εφόσον έχετε ονοματήσει τα URLs σας μέσα στη εκάστοτε συνάρτηση <a class=\"reference internal\" href=\"/el/1.11/ref/urls/#django.conf.urls.url\" title=\"django.conf.urls.url\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">url()</span></code></a> στο αρχείο <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></code>, μπορείτε να αναφέρεστε σε αυτά χρησιμοποιώντας το template tag <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>Ο τρόπος με τον οποίο λειτουργεί αυτό το template tag είναι κοιτώντας τα URLs που έχετε ορίσει στο module <code class=\"docutils literal notranslate\"><span class=\"pre\">polls.urls</span></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>\n<span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">detail</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;detail&#39;</span><span class=\"p\">),</span>\n<span class=\"o\">...</span>\n</code></pre></div>\n<p>Αν θέλετε να αλλάξετε το URL αυτού του view σε κάτι άλλο (ίσως στο <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/specifics/12/</span></code>), τότε αντί να ψάχνετε όλα τα templates που είχατε δηλώσει το παλιό URL προκειμένου να το αντικαταστήσετε με το καινούργιο, πολύ απλά πειράζετε ένα αρχείο (<code class=\"docutils literal notranslate\"><span class=\"pre\">polls/urls.py</span></code>) και όλα τα υπόλοιπα ανανεώνονται αυτόματα, χάρη στο template tag <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=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"o\">...</span>\n<span class=\"c1\"># added the word &#39;specifics&#39;</span>\n<span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^specifics/(?P&lt;question_id&gt;[0-9]+)/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">detail</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;detail&#39;</span><span class=\"p\">),</span>\n<span class=\"o\">...</span>\n</code></pre></div>\n</section>\n<section id=\"namespacing-url-names\">\n<h2>Χρησιμοποιώντας 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\"><span class=\"pre\">polls</span></code>. Σε πραγματικά Django projects, ίσως να έχετε πέντε, δέκα, είκοσι ή περισσότερα apps. Πως μπορεί να ξέρει και να διαφοροποιεί το Django τα ονόματα των URLs ανάμεσα σε τόσα apps; Για παράδειγμα, η εφαρμογή <code class=\"docutils literal notranslate\"><span class=\"pre\">polls</span></code> έχει ένα <code class=\"docutils literal notranslate\"><span class=\"pre\">detail</span></code> view και ίσως ένα άλλο app (στο ίδιο project) να έχει το ίδιο όνομα για ένα δικό του view. Όταν το Django συναντήσει το template tag <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">url</span> <span class=\"pre\">'detail'</span> <span class=\"pre\">%}</span></code> πως θα ξέρει σε ποιο view να αναφερθεί;</p>\n<p>Η απάντηση έρχεται με την προσθήκη namespaces στο URLconf. Στο αρχείο <code class=\"docutils literal notranslate\"><span class=\"pre\">polls/urls.py</span></code>, προσθέστε μια μεταβλητή <code class=\"docutils literal notranslate\"><span class=\"pre\">app_name</span></code> ούτως ώστε να θέσετε το namespace για αυτό το app:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/urls.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/urls.py\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.conf.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">url</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">views</span>\n\n<span class=\"n\">app_name</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;polls&#39;</span>\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">index</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;index&#39;</span><span class=\"p\">),</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">detail</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;detail&#39;</span><span class=\"p\">),</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/results/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">results</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;results&#39;</span><span class=\"p\">),</span>\n    <span class=\"n\">url</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;^(?P&lt;question_id&gt;[0-9]+)/vote/$&#39;</span><span class=\"p\">,</span> <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">vote</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;vote&#39;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></figure>\n<p>Τώρα, πηγαίνετε και αλλάξτε το αρχείο <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>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>στο:</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>Όταν αισθανθείτε άνετα με τη συγγραφή των views, διαβάστε το <a class=\"reference internal\" href=\"/el/1.11/intro/tutorial04/\"><span class=\"doc\">τέταρτο μέρος αυτού του οδηγού</span></a> για να μάθετε το πώς να διαχειρίζεστε απλές φόρμες και τα Django generic views.</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/1.11/intro/"}],"prev":{"docname":"intro/tutorial02","title":"Γράφοντας το πρώτο σας Django app, μέρος 2","url":"/el/1.11/intro/tutorial02/"},"next":{"docname":"intro/tutorial04","title":"Γράφοντας το πρώτο σας Django app, μέρος 4","url":"/el/1.11/intro/tutorial04/"},"formats":{"html":"/el/1.11/intro/tutorial03/","markdown":"/el/1.11/intro/tutorial03.md","json":"/el/1.11/intro/tutorial03.json"},"source":"https://github.com/django/django/blob/stable/1.11.x/docs/intro/tutorial03.txt","official":"https://docs.djangoproject.com/el/1.11/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","fr","ja","id","pt-br","ko","es","el","pl"]}