{"title":"Γράφοντας το πρώτο σας patch για το Django","version":"1.10","locale":"el","docname":"intro/contributing","url":"/el/1.10/intro/contributing/","canonical":"https://djangodocs.dev/el/1.10/intro/contributing/","summary":"Ενδιαφέρεστε να συνεισφέρετε στην κοινότητα; Ίσως έχετε βρει κάποιο σφάλμα προγράμματος (bug) στο Django και θέλετε να διορθωθεί ή θέλετε να προσθέσετε…","html":"<h1>Γράφοντας το πρώτο σας patch για το Django<a class=\"heading-anchor\" href=\"#writing-your-first-patch-for-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<section id=\"introduction\">\n<h2>Εισαγωγή<a class=\"heading-anchor\" href=\"#introduction\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Ενδιαφέρεστε να συνεισφέρετε στην κοινότητα; Ίσως έχετε βρει κάποιο σφάλμα προγράμματος (bug) στο Django και θέλετε να διορθωθεί ή θέλετε να προσθέσετε κάποια επιπλέον λειτουργία ή χαρακτηριστικό.</p>\n<p>Ο καλύτερος τρόπος να δείτε τις δικές σας προτάσεις-ιδέες να γίνονται πραγματικότητα είναι συνεισφέροντας στο Django. Αυτό στην αρχή ίσως σας φανεί περίπλοκο αλλά στην πραγματικότητα είναι αρκετά απλό. Θα σας καθοδηγήσουμε βήμα-βήμα μέσα σε όλη την διαδικασία ώστε να μπορέσετε να μάθετε μέσα από ένα παράδειγμα.</p>\n<section id=\"who-s-this-tutorial-for\">\n<h3>Σε ποιους απευθύνεται αυτό το tutorial<a class=\"heading-anchor\" href=\"#who-s-this-tutorial-for\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">Δείτε επίσης</p>\n<p>Αν ψάχνετε κάποια αναφορά σχετικά με το πως να υποβάλετε patches, δείτε το έγγραφο <a class=\"reference internal\" href=\"/el/1.10/internals/contributing/writing-code/submitting-patches/\"><span class=\"doc\">Καταθέτοντας patches</span></a>.</p>\n</aside>\n<p>Για αυτόν τον οδηγό (tutorial), θα πρέπει να γνωρίζετε τουλάχιστον τη βασική λειτουργία του Django. Αυτό σημαίνει ότι θα πρέπει να είστε εξοικειωμένοι με τους ήδη υπάρχοντες οδηγούς <a class=\"reference internal\" href=\"/el/1.10/intro/tutorial01/\"><span class=\"doc\">Γράφοντας το πρώτο σας Django app</span></a>. Επίσης, θα πρέπει να γνωρίζετε αρκετά καλά τη γλώσσα προγραμματισμού Python. Αν πάλι όχι, το βιβλίο <a class=\"reference external\" href=\"http://www.diveintopython3.net/\">Dive Into Python</a> είναι ένα εκπληκτικό (και δωρεάν) online βιβλίο για νέους προγραμματιστές στη γλώσσα Python.</p>\n<p>Για όσους από εσάς δεν είστε εξοικειωμένοι με τα εργαλεία συστημάτων ελέγχου εκδόσεων (VCS – version control system) και το Trac, δεν υπάρχει λόγος να ανησυχείτε. Αυτός ο οδηγός (και όποιοι σύνδεσμοι-links του) έχει τις απαραίτητες πληροφορίες για να ξεκινήσετε. Ωστόσο, ίσως να θέλετε να μάθετε περισσότερα σχετικά με αυτά τα εργαλεία, αν σκοπεύετε να συνεισφέρετε στο Django τακτικά.</p>\n<p>Εν τούτοις, αυτός ο οδηγός στο μεγαλύτερο του μέρος, προσπαθεί να εξηγήσει όσα περισσότερα μπορεί, ώστε να μπορεί να φανεί χρήσιμος στο μεγαλύτερο δυνατό ευρύ κοινό.</p>\n<aside class=\"admonition-where-to-get-help admonition\" role=\"note\">\n<p class=\"admonition-title\">Που να ψάξετε για βοήθεια</p>\n<p>Αν δυσκολεύεστε με αυτόν τον οδηγό, μπορείτε να στείλετε ένα μήνυμα στους <a class=\"reference internal\" href=\"/el/1.10/internals/mailing-lists/#django-developers-mailing-list\"><span class=\"std std-ref\">django-developers</span></a> ή να συμμετάσχετε στο κανάλι <a class=\"reference external\" href=\"irc://irc.freenode.net/django-dev\">#django-dev στο irc.freenode.net</a> για να μιλήσετε με άλλους Django χρήστες οι οποίοι μπορεί να σας βοηθήσουν.</p>\n</aside>\n</section>\n<section id=\"what-does-this-tutorial-cover\">\n<h3>Τι καλύπτει αυτός ο οδηγός;<a class=\"heading-anchor\" href=\"#what-does-this-tutorial-cover\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Σε αυτόν τον οδηγό θα φτιάξουμε παρέα ένα patch για το Django και θα το συνεισφέρουμε (contribute) στην κοινότητα για πρώτη φορά. Στο τέλος αυτού του οδηγού, θα έχετε λάβει τις βασικές γνώσεις των εργαλείων (tools) και των διαδικασιών (processes) που εμπλέκονται. Πιο συγκεκριμένα, θα καλύψουμε τα ακόλουθα:</p>\n<ul class=\"simple\">\n<li><p>Εγκατάσταση Git.</p></li>\n<li><p>Δημιουργία αντίγραφου της αναπτυξιακής έκδοσης (development version) του Django.</p></li>\n<li><p>Εκτέλεση της σουίτας δοκιμών του Django (test suite).</p></li>\n<li><p>Γράφοντας τεστ για το patch.</p></li>\n<li><p>Γράφοντας κώδικα για το ίδιο το patch.</p></li>\n<li><p>Πραγματοποίηση τεστ για το patch.</p></li>\n<li><p>Υποβολή αιτήματος έλξης.</p></li>\n<li><p>Που να κοιτάξετε για περισσότερες πληροφορίες.</p></li>\n</ul>\n<p>Αφού ολοκληρώσετε τον οδηγό, μπορείτε να διαβάσετε το :doc:` εγχειρίδιο (documentation) του Django σχετικά με την συνεισφορά &lt;/internals/contributing/index&gt;`. Περιέχει πολλές πληροφορίες και αν θέλετε να συνεισφέρετε τακτικά στο Django θα πρέπει να το διαβάσετε. Αν έχετε απορίες, τότε πιθανόν το εγχειρίδιο να έχει την απάντηση.</p>\n<aside class=\"admonition-python-3-required admonition\" role=\"note\">\n<p class=\"admonition-title\">Python 3!</p>\n<p>Αυτός ο οδηγός προϋποθέτει ότι χρησιμοποιείτε την Python 3. Κατεβάστε την τελευταία έκδοση στην <a class=\"reference external\" href=\"https://www.python.org/download/\">επίσημη σελίδα της Python</a> ή με τον αντίστοιχο διαχειριστή πακέτων (packet manager) του λειτουργικού σας συστήματος.</p>\n</aside>\n<aside class=\"admonition-for-windows-users admonition\" role=\"note\">\n<p class=\"admonition-title\">Για τους χρήστες Windows</p>\n<p>Κατά την εγκατάσταση της Python σε περιβάλλον Windows, σιγουρευτείτε ότι η επιλογή «Προσθήκη python.exe στο Path» είναι επιλεγμένη, ούτως ώστε οι εντολές που έχουν σχέση με την Python να είναι διαθέσιμες μέσω της γραμμής εντολών.</p>\n</aside>\n</section>\n</section>\n<section id=\"code-of-conduct\">\n<h2>Κώδικας δεοντολογίας<a class=\"heading-anchor\" href=\"#code-of-conduct\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Ως συνεισφέρων, μπορείτε να μας βοηθήσετε να διατηρήσουμε την Django κοινότητα ανοιχτή (open) και περιεκτική (inclusive). Παρακαλούμε διαβάστε και ακολουθήστε το δικό μας <a class=\"reference external\" href=\"https://www.djangoproject.com/conduct/\">Κώδικα Δεοντολογίας</a>.</p>\n</section>\n<section id=\"installing-git\">\n<h2>Εγκατάσταση Git<a class=\"heading-anchor\" href=\"#installing-git\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Για αυτόν τον οδηγό θα χρειαστεί να έχετε εγκατεστημένο το Git ούτως ώστε να κατεβάσετε την αναπτυξιακή έκδοση (development version) του Django και να δημιουργήσετε patch αρχεία για τις αλλαγές που κάνετε.</p>\n<p>Για να ελέγξετε αν έχετε εγκατεστημένο το Git, γράψτε στη κονσόλα (ή στη γραμμή εντολών αν έχετε Windows) τη λέξη <code class=\"docutils literal notranslate\">git</code>. Αν βλέπετε μηνύματα που λένε ότι αυτή η εντολή δεν υπάρχει, θα χρειαστεί να κατεβάσετε το Git και να το εγκαταστήσετε. Δείτε πως, στην <a class=\"reference external\" href=\"http://git-scm.com/download\">επίσημη σελίδα του Git</a>.</p>\n<aside class=\"admonition-for-windows-users admonition\" role=\"note\">\n<p class=\"admonition-title\">Για τους χρήστες Windows</p>\n<p>Κατά την διάρκεια της εγκατάστασης του Git σε λειτουργικό Windows, προτείνετε να τσεκάρετε την επιλογή «Git Bash» ούτως ώστε το Git να τρέχει σε δικό του κέλυφος (shell). Αυτός ο οδηγός προϋποθέτει ότι έχει εγκατασταθεί το Git με αυτόν τον τρόπο.</p>\n</aside>\n<p>Αν δεν είστε εξοικειωμένοι με το Git, μπορείτε να μάθετε περισσότερα σχετικά με τις εντολές του (αφού εγκατασταθεί) πληκτρολογώντας <code class=\"docutils literal notranslate\">git help</code> στην κονσόλα (ή στη γραμμή εντολών για χρήστες Windows).</p>\n</section>\n<section id=\"getting-a-copy-of-django-s-development-version\">\n<h2>Δημιουργία αντίγραφου της αναπτυξιακής έκδοσης του Django<a class=\"heading-anchor\" href=\"#getting-a-copy-of-django-s-development-version\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Το πρώτο βήμα για την συνεισφορά στο Django είναι να αποκτήσετε ένα αντίγραφο του πηγαίου κώδικα. Πρώτα, κάντε <a class=\"reference external\" href=\"https://github.com/django/django/fork\">fork το Django από το GitHub</a>. Από την γραμμή εντολών, χρησιμοποιείστε την εντολή <code class=\"docutils literal notranslate\">cd</code> για να μεταβείτε στον φάκελο στον οποίο θέλετε να αποθηκεύσετε τον πηγαίο κώδικα του Django. Αν δεν υπάρχει κάποιος φάκελος της αρεσκείας σας, τότε χρησιμοποιήστε την εντολή <code class=\"docutils literal notranslate\">mkdir</code> για να τον δημιουργήσετε και μετά την εντολή <code class=\"docutils literal notranslate\">cd επιθυμητός_φάκελος</code> για να αποθηκεύσετε εκεί τον πηγαίο κώδικα.</p>\n<p>Κατεβάστε το αποθετήριο (εφεξής repository ή repo) του πηγαίου κώδικα του Django χρησιμοποιώντας την ακόλουθη εντολή:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>git clone git@github.com:YourGitHubName/django.git\n</code></pre></div>\n<p>Τώρα που έχετε ένα τοπικό αντίγραφο του Django, μπορείτε να το εγκαταστήσετε, όπως ακριβώς ένα οποιοδήποτε πακέτο, με την χρήση της εντολής <code class=\"docutils literal notranslate\">pip</code>. Ο πιο βολικός και προτεινόμενος τρόπος να το κάνετε είναι μέσω ενός <em>εικονικού περιβάλλοντος</em> (εφεξής virtualenv, από τις λέξεις virtual environment) το οποίο είναι ένα προεγκατεστημένο χαρακτηριστικό (feature) της Python για την διαχείριση ξεχωριστών εγκαταστάσεων ανά εφαρμογή. Η φιλοσοφία είναι ότι κρατάτε σε ξεχωριστό φάκελο (περιβάλλον) τα πακέτα (π.χ Django 1.9 ή Django 1.10 ή κάποια third party εφαρμογή) που απαιτούνται για την εφαρμογή σας (π.χ Django app) και έτσι κάθε εφαρμογή δεν θα παρεμβαίνει με τις υπόλοιπες.</p>\n<p>Είναι καλή πρακτική να κρατάτε όλα τα virtualenvs σε ένα σημείο, για παράδειγμα στο φάκελο <code class=\"docutils literal notranslate\">.virtualenvs/</code> μέσα στο home φάκελο σας. Δημιουργήστε το, αν δεν υπάρχει ήδη:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>mkdir ~/.virtualenvs\n</code></pre></div>\n<p>Τώρα δημιουργήστε ένα καινούργιο virtualenv (π.χ με το όνομα djangoenv) τρέχοντας την εντολή:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>python3 -m venv ~/.virtualenvs/djangodev\n</code></pre></div>\n<p>Η διαδρομή (path) που εισαγάγατε αποτελεί και το καινούργιο virtualenv το οποίο θα αποθηκευτεί στον υπολογιστή σας.</p>\n<aside class=\"admonition-for-windows-users admonition\" role=\"note\">\n<p class=\"admonition-title\">Για τους χρήστες Windows</p>\n<p>Χρησιμοποιώντας τον τρόπο που αναφέρθηκε παραπάνω (<code class=\"docutils literal notranslate\">Εγκατάσταση Git</code>) για την εγκατάσταση του Git, η εντολή <code class=\"docutils literal notranslate\">venv</code> δεν θα δουλέψει, επειδή τα activation scripts δημιουργούνται μόνο στο κέλυφος συστήματος (<code class=\"docutils literal notranslate\">.bat</code>) και στο PowerShell (<code class=\"docutils literal notranslate\">.ps1</code>). Για να δουλέψει χρησιμοποιείστε το πακέτο <code class=\"docutils literal notranslate\">virtualenv</code>:</p>\n<div class=\"code-block\" data-language=\"none\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">None</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=\"None code\"><code>$ pip install virtualenv\n$ virtualenv ~/.virtualenvs/djangodev\n</code></pre></div>\n</aside>\n<aside class=\"admonition-for-ubuntu-users admonition\" role=\"note\">\n<p class=\"admonition-title\">Για τους χρήστες Ubuntu</p>\n<p>Σε κάποιες εκδόσεις του λειτουργικού Ubuntu, η εντολή <code class=\"docutils literal notranslate\">venv</code> ενδέχεται να μην δουλέψει. Χρησιμοποιείστε το πακέτο <code class=\"docutils literal notranslate\">virtualenv</code>, αφού πρώτα σιγουρευτείτε ότι έχετε εγκατεστημένο το <code class=\"docutils literal notranslate\">pip3</code>:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>sudo apt-get install python3-pip\n<span class=\"gp\">$ </span><span class=\"c1\"># Prefix the next command with sudo if it gives a permission denied error</span>\n<span class=\"gp\">$ </span>pip3 install virtualenv\n<span class=\"gp\">$ </span>virtualenv --python<span class=\"o\">=</span><span class=\"sb\">`</span>which python3<span class=\"sb\">`</span> ~/.virtualenvs/djangodev\n</code></pre></div>\n</aside>\n<p>Το τελευταίο βήμα σχετικά με την ολοκλήρωση του virtualenv είναι η ενεργοποίηση του:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span><span class=\"nb\">source</span> ~/.virtualenvs/djangodev/bin/activate\n</code></pre></div>\n<p>Αν η εντολή <code class=\"docutils literal notranslate\">source</code> δεν είναι διαθέσιμη, χρησιμοποιήστε την τελεία, όπως:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>. ~/.virtualenvs/djangodev/bin/activate\n</code></pre></div>\n<aside class=\"admonition-for-windows-users admonition\" role=\"note\">\n<p class=\"admonition-title\">Για τους χρήστες Windows</p>\n<p>Για να ενεργοποιήσετε το virtualenv σας σε λειτουργικό Windows, τρέξτε:</p>\n<div class=\"code-block\" data-language=\"none\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">None</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=\"None code\"><code>$ source ~/virtualenvs/djangodev/Scripts/activate\n</code></pre></div>\n</aside>\n<p>Κάθε φορά που ανοίγετε μια κονσόλα (γραμμή εντολών) και σκοπεύετε να αλληλεπιδράτε με την εφαρμογή σας, θα πρέπει σε κάθε κονσόλα να ενεργοποιείτε το virtualenv. Το εργαλείο <a class=\"reference external\" href=\"https://virtualenvwrapper.readthedocs.io/en/latest/\">virtualenvwrapper</a> θα σας φανεί πολύ χρήσιμο και βολικό για τέτοιου είδους καταστάσεις.</p>\n<p>Όταν ένα virtualenv ενεργοποιηθεί, το πρόθεμα στη γραμμή εντολών θα είναι το όνομα του virtualenv σας μέσα σε παρένθεση. Οποιοδήποτε πακέτο εγκαταστήσετε, από δω και στο εξής μέσω του <code class=\"docutils literal notranslate\">pip</code>, θα εγκατασταθεί στον φάκελο που αποθηκεύονται όλα τα virtualenvs (π.χ <code class=\"docutils literal notranslate\">.virtualenvs</code>) και πιο συγκεκριμένα μέσα στο φάκελο με την ονομασία του virtualenv σας (π.χ <code class=\"docutils literal notranslate\">.virtualenvs/djangoenv</code>). Με αυτό τον τρόπο κάθε virtualenv περιέχει τα δικά του πακέτα και έτσι επιτυγχάνεται η απομόνωση μεταξύ άλλων πακέτων άλλων virtualenvs και των πακέτων του συστήματος σας (global/system-wide). Εγκαταστήστε τώρα την έκδοση του Django που κατεβάσατε πριν μέσω του <code class=\"docutils literal notranslate\">git clone</code>:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>pip install -e /path/to/your/local/clone/django/\n</code></pre></div>\n<p>Η εγκατεστημένη έκδοση του Django είναι τώρα μέσα στο virtualenv σας και μπορείτε να κάνετε <code class=\"docutils literal notranslate\">import django</code> σε Python κονσόλα χωρίς να σας επιστρέψει σφάλμα (cannot import module django). Τώρα μπορείτε να δείτε απ’ ευθείας τις αλλαγές που κάνετε σε αυτό το πακέτο, το οποίο είναι εξαιρετικά χρήσιμο, ειδικά όταν θα γράψετε το πρώτο σας patch αρχείο.</p>\n</section>\n<section id=\"rolling-back-to-a-previous-revision-of-django\">\n<h2>Επαναφορά σε μια προγενέστερη έκδοση του Django<a class=\"heading-anchor\" href=\"#rolling-back-to-a-previous-revision-of-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Σε αυτό τον οδηγό, θα χρησιμοποιήσουμε το ticket <a class=\"extlink-ticket reference external\" href=\"https://code.djangoproject.com/ticket/24788\">#24788</a> ως αντικείμενο μελέτης. Γι’ αυτό το λόγο θα χρειαστεί να μεταβούμε σε μια προγενέστερη έκδοση του Django πριν εφαρμοστεί αυτό το patch. Με άλλα λόγια θέλουμε να αναπαράγουμε το σφάλμα που εμφανιζόταν πριν, να γράψουμε το patch και να διορθώσουμε το σφάλμα εφαρμόζοντας το, στην τότε έκδοση. Αυτό θα μας βοηθήσει να δούμε όλα τα εμπλεκόμενα βήματα τα οποία απαιτούνται για να γραφτεί από την αρχή ένα patch (συμπεριλαμβάνοντας και την σουίτα δοκιμών του Django).</p>\n<p><strong>Έχετε υπόψη σας ότι παρόλο που θα χρησιμοποιήσουμε μια παλιά έκδοση του Django σε αυτόν τον οδηγό, εσείς θα πρέπει πάντα να χρησιμοποιείτε την τρέχουσα αναπτυξιακή έκδοση (development version) του Django όταν πρόκειται να γράψετε ένα patch για κάποιο ticket</strong></p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Σημείωση</p>\n<p>Το patch, για αυτό το ticket, γράφτηκε από τον Paweł Marczewski και ενσωματώθηκε στον πηγαίο κώδικα του Django ως <a class=\"reference external\" href=\"https://github.com/django/django/commit/4df7e8483b2679fc1cba3410f08960bac6f51115\">commit 4df7e8483b2679fc1cba3410f08960bac6f51115</a>. Συνεπώς, θα χρησιμοποιήσουμε μια έκδοση του Django πριν το ανωτέρω commit, <a class=\"reference external\" href=\"https://github.com/django/django/commit/4ccfc4439a7add24f8db4ef3960d02ef8ae09887\">commit 4ccfc4439a7add24f8db4ef3960d02ef8ae09887</a>.</p>\n</aside>\n<p>Μεταβείτε στο root φάκελο του Django (είναι αυτός που περιέχει τους φακέλους <code class=\"docutils literal notranslate\">django</code>, <code class=\"docutils literal notranslate\">docs</code>, <code class=\"docutils literal notranslate\">tests</code>, <code class=\"docutils literal notranslate\">AUTHORS</code>, κλπ), ο οποίος βρίσκεται μέσα στο φάκελο με το όνομα του virtualenv σας. Αφού μεταβείτε εκεί, μπορείτε να κάνετε checkout (εντολή git) σε μια παλαιότερη έκδοση του Django, την οποία θα χρησιμοποιήσουμε σε αυτόν τον οδηγό:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>git checkout 4ccfc4439a7add24f8db4ef3960d02ef8ae09887\n</code></pre></div>\n</section>\n<section id=\"running-django-s-test-suite-for-the-first-time\">\n<h2>Εκτέλεση της σουίτας δοκιμών του Django για πρώτη φορά<a class=\"heading-anchor\" href=\"#running-django-s-test-suite-for-the-first-time\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Όταν συνεισφέρετε στο Django είναι πολύ σημαντικό ο κώδικας που γράφετε (π.χ για την επίλυση ενός ticket) να μην επιφέρει σφάλματα (bugs) σε άλλα σημεία του Django. Με άλλα λόγια όταν προσπαθείτε να διορθώσετε κάποια κομμάτια στον πηγαίο κώδικα του Django, να μην δημιουργούνται νέα σφάλματα σε άλλο σημείο του πηγαίου κώδικα. Ένας τρόπος για να γνωρίζετε ότι το Django τρέχει ορθά μετά τις αλλαγές σας, είναι τρέχοντας την σουίτα δοκιμών του Django (test suite). Αν όλα τα τεστ περάσουν, τότε μπορείτε εκ του ασφαλούς να ξέρετε ότι ο κώδικας σας δεν προκάλεσε σφάλματα αλλού. Αν δεν έχετε τρέξει ποτέ τη σουίτα δοκιμών του Django, μια καλή ιδέα είναι να την τρέξετε πριν ξεκινήσετε τη διαδικασία των αλλαγών (πριν την συγγραφή  του patch), ούτως ώστε να εξοικειωθείτε με την εμφάνιση των αποτελεσμάτων του (output results).</p>\n<p>Πριν τρέξετε την σουίτα, θα πρέπει να εγκαταστήσετε πρώτα κάποια πακέτα τα οποία είναι απαραίτητα για να ολοκληρωθούν τα τεστ. Μεταβείτε στον φάκελο <code class=\"docutils literal notranslate\">tests/</code> (με την εντολή <code class=\"docutils literal notranslate\">cd tests/</code>) και τρέξτε την εντολή:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>pip install -r requirements/py3.txt\n</code></pre></div>\n<p>Αν αντιμετωπίσατε κάποιο πρόβλημα κατά την εγκατάσταση, ίσως να λείπει απ” το σύστημα σας κάποιο dependency (τα dependencies είναι και αυτά με τη σειρά τους πακέτα) για ένα ή περισσότερα Python πακέτα. Συμβουλευτείτε το εγχειρίδιο των πακέτων που δεν εγκαταστάθηκαν ή αναζητήστε στο ίντερνετ το σφάλμα, όπως ακριβώς αυτό εμφανίστηκε όταν προέκυψε.</p>\n<p>Τώρα είμαστε έτοιμοι να τρέξουμε τη σουίτα δοκιμών του Django. Αν χρησιμοποιείτε GNU/Linux, Mac OS X ή κάποια άλλη Unix διανομή, τρέξτε:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>./runtests.py\n</code></pre></div>\n<p>Καθίστε αναπαυτικά και χαλαρώστε! Η σουίτα δοκιμών του Django περιλαμβάνει πάνω από 9,600 διαφορετικά τεστ. Αυτό σημαίνει ότι η διαδικασία ενδέχεται να διαρκέσει μεταξύ 5 – 15 λεπτά, ανάλογα την ισχύ του υπολογιστή σας.</p>\n<p>Όσο τα τεστ τρέχουν, θα παρατηρήσετε διάφορες ακολουθίες χαρακτήρων οι οποίες αναπαριστούν την κατάσταση (status) του κάθε τεστ. Το <code class=\"docutils literal notranslate\">E</code> υποδηλώνει ότι προέκυψε σφάλμα κατά την εκτέλεση του συγκεκριμένου τεστ. Το <code class=\"docutils literal notranslate\">F</code> ότι τα assertions του τεστ απέτυχαν. Οι δύο ανωτέρω καταστάσεις δηλώνουν ότι το τεστ απέτυχε. Επίσης, τα <code class=\"docutils literal notranslate\">x</code> και <code class=\"docutils literal notranslate\">s</code> υποδηλώνουν αναμενόμενες αποτυχίες (expected failures) και παραλειπόμενα τεστ (skipped tests), αντίστοιχα. Οι τελείες υποδηλώνουν επιτυχή τεστ.</p>\n<p>Τα παραλειπόμενα τεστ (τεστ που δεν έγιναν) προκύπτουν συνήθως λόγω έλλειψης κάποιων εξωτερικών βιβλιοθηκών (external libraries) οι οποίες χρειάζονται για να τρέξει το τεστ. Δείτε στο <a class=\"reference internal\" href=\"/el/1.10/internals/contributing/writing-code/unit-tests/#running-unit-tests-dependencies\"><span class=\"std std-ref\">Τρέχοντας όλα τα τεστ</span></a> για μια λίστα με όλα τα dependencies (εξαρτώμενα πακέτα – εξωτερικές βιβλιοθήκες). Επίσης σιγουρευτείτε ότι έχετε εγκαταστήσει τα απαραίτητα πακέτα (στα οποία εξαρτώνται τα τεστ) προτού τρέξετε κάποιο τεστ (δεν θα χρειαστούμε κάποιο από αυτά σε αυτόν τον οδηγό). Μερικά τεστ είναι γραμμένα και συνδέονται με μια συγκεκριμένη βάση δεδομένων και δεν θα τρέξουν αν δεν υπάρχει εγκατεστημένη η αντίστοιχη βάση δεδομένων καθώς και το πακέτο (βιβλιοθήκη) που συνδέει την database με το Django (π.χ για την PostgreSQL το πακέτο είναι το <code class=\"docutils literal notranslate\">psycopg2</code>). Η SQLite είναι η βάση δεδομένων που χρησιμοποιεί το Django ως προεπιλογή. Μπορείτε επίσης να <a class=\"reference internal\" href=\"/el/1.10/internals/contributing/writing-code/unit-tests/#running-unit-tests-settings\"><span class=\"std std-ref\">τρέξετε τα τεστ χρησιμοποιώντας μια διαφορετική βάση δεδομένων</span></a>.</p>\n<p>Όταν ολοκληρωθούν τα τεστ, θα σας εμφανιστεί κάποιο μήνυμα που θα σας ενημερώνει για την επιτυχή ή όχι εκτέλεση τους. Εφόσον δεν έχετε κάνει κάποια αλλαγή μέχρι τώρα στον πηγαίο κώδικα του Django, όλα τα τεστ θα <strong>πρέπει</strong> να έχουν επιτυχή έκβαση. Αν δείτε τυχόν σφάλματα ή αποτυχίες κάποιων τεστ, σιγουρευτείτε ότι έχετε ακολουθήσει κατάλληλα τα ανωτέρω βήματα. Δείτε στο <a class=\"reference internal\" href=\"/el/1.10/internals/contributing/writing-code/unit-tests/#running-unit-tests\"><span class=\"std std-ref\">τρέχοντας τα unit τεστ</span></a> για περισσότερες πληροφορίες. Αν χρησιμοποιείτε την Python 3.5+, θα υπάρξουν κάποιες αποτυχίες μερικών τεστ οι οποίες οφείλονται σε προειδοποιήσεις υποβάθμισης (deprecation warnings) στις οποίες μπορείτε να μην δώσετε σημασία. Αυτές οι αποτυχίες έχουν αποκατασταθεί στην τρέχουσα έκδοση του Django. Σας υπενθυμίζουμε ότι σε αυτόν τον οδηγό χρησιμοποιούμε μια παλιά έκδοση του Django.</p>\n<p>Υπογραμμίζεται ότι η τελευταία αναπτυξιακή έκδοση του Django ενδέχεται να μην είναι σταθερή (stable). Όταν δουλεύετε με τέτοιου είδους εκδόσεις, μπορείτε να ενημερώνεστε μέσω των <a class=\"reference external\" href=\"http://djangoci.com\">εκδόσεων συνεχούς ενσωμάτωσης του Django (Django’s continuous integration builds)</a> για να διαπιστώσετε αν οι αποτυχίες των τεστ οφείλονται στο σύστημα σας ή οι αποτυχίες συμβαίνουν και στις επίσημες αναπτυξιακές εκδόσεις του Django. Αν κλικάρετε για να δείτε μια συγκεκριμένη έκδοση, μπορείτε να δείτε το «Configuration Matrix» το οποίο δείχνει τις αποτυχίες (failures) αναλυτικά ανά έκδοση Python και βάση δεδομένων.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Σημείωση</p>\n<p>Για το συγκεκριμένο οδηγό και για το ticket πάνω στο οποίο δουλεύουμε, τα τεστ που αφορούν την SQLite είναι αρκετά, ωστόσο, είναι δυνατόν (και μερικές φορές απαραίτητο) να <a class=\"reference internal\" href=\"/el/1.10/internals/contributing/writing-code/unit-tests/#running-unit-tests-settings\"><span class=\"std std-ref\">τρέχουμε τεστ χρησιμοποιώντας διαφορετικές βάσεις δεδομένων</span></a>.</p>\n</aside>\n</section>\n<section id=\"creating-a-branch-for-your-patch\">\n<h2>Δημιουργία ενός τμήματος για το αρχείου σας<a class=\"heading-anchor\" href=\"#creating-a-branch-for-your-patch\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Πριν κάνετε αλλαγές, δημιουργήστε ένα νέο τμήμα για το εισητήριο</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>git checkout -b ticket_24788\n</code></pre></div>\n<p>Μπορείτε να επιλέξετε οποιοδήποτε όνομα θέλετε για το τμήμα, το «ticket_24788» είναι ένα παράδειγμα. Όλες οι αλλαγές που έγιναν σε αυτόν το τμήμα θα είναι ειδικά για το εισιτήριο και δεν θα επηρεάσουν το κύριο αντίγραφο του κώδικα που έχουμε κλωνοποιήσαμε νωρίτερα.</p>\n</section>\n<section id=\"writing-some-tests-for-your-ticket\">\n<h2>Γράφοντας μερικά τεστ για το ticket<a class=\"heading-anchor\" href=\"#writing-some-tests-for-your-ticket\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Στις περισσότερες περιπτώσεις, για να θεωρηθεί ένα patch αποδεκτό για την ενσωμάτωση του στο Django, θα πρέπει να περιέχει τεστ. Για περιπτώσεις που αφορούν κάποια επιδιόρθωση σφάλματος (bug fix), θα πρέπει να γραφτεί ένα τεστ οπισθοδρόμησης (regression test) του οποίου η σημασία είναι η βεβαίωση ότι το σφάλμα (που επρόκειτο να διορθωθεί) δεν θα ξαναεμφανιστεί σε μεταγενέστερη έκδοση του Django. Ένα regression τεστ θα πρέπει να γραφτεί με τέτοιο τρόπο ούτως ώστε θα αποτυγχάνει (fail) όσο το σφάλμα θα υπάρχει και θα επιτυγχάνει όταν το σφάλμα διορθωθεί. Για patches τα οποία περιέχουν καινούργιο κώδικα (δεν προσπαθούν, δηλαδή, να διορθώσουν υπάρχον κώδικα αλλά προσθέτουν νέα χαρακτηριστικά-λειτουργία), θα χρειαστεί να συμπεριλάβετε τεστ τα οποία εξασφαλίζουν ότι το καινούργιο χαρακτηριστικό λειτουργεί ορθά (π.χ δημιουργία ενός καινούργιου django.db.models.fields ή δημιουργία καινούργιου template tag). Τα τεστ αυτά, θα πρέπει να αποτυγχάνουν όταν τα καινούργια αυτά χαρακτηριστικά δεν υπάρχουν (π.χ σε παλαιότερες εκδόσεις του Django) και αντιθέτως να επιτυγχάνουν όταν αυτά (τα χαρακτηριστικά) εμφανιστούν.</p>\n<p>Μια καλή πρακτική για να επιτύχετε τα παραπάνω είναι να γράψετε πρώτα τα τεστ, προτού κάνετε οποιεσδήποτε αλλαγές στον πηγαίο κώδικα. Αυτού του είδους το development ονομάζεται <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Test-driven_development\">test-driven development</a> και μπορεί να εφαρμοστεί από απλά patches μέχρι ολόκληρα projects. Αφού γράψετε τα τεστ, μπορείτε να τα τρέξετε για να διαπιστώσετε ότι όντως αποτυγχάνουν (λογικό, αφού δεν έχετε γράψει ακόμη κώδικα που να διορθώνει το σφάλμα ή κώδικα που προσθέτει κάποιο καινούργιο χαρακτηριστικό στο Django). Αν τα τεστ σας δεν αποτυγχάνουν, θα πρέπει να φροντίσετε ώστε να το κάνουν. Αν ένα regression test περνά, ανεξαρτήτως αν το σφάλμα (bug) υπάρχει ή όχι, δεν βοηθάει καθόλου και θα δυσκολέψει το έργο (όχι μόνο το δικό σας) της αποσφαλμάτωσης (debugging) στο μέλλον.</p>\n<p>Ας εργαστούμε λοιπόν στο παράδειγμα μας.</p>\n<section id=\"writing-some-tests-for-ticket-24788\">\n<h3>Γράφοντας μερικά τεστ για το ticket #24788<a class=\"heading-anchor\" href=\"#writing-some-tests-for-ticket-24788\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Το ticket <a class=\"extlink-ticket reference external\" href=\"https://code.djangoproject.com/ticket/24788\">#24788</a> προτείνει μια μικρή προσθήκη ενός νέου χαρακτηριστικού: την δυνατότητα να προσδιοριστεί το class attribute με το όνομα <code class=\"docutils literal notranslate\">prefix</code> μέσα στις Form classes, ούτως ώστε:</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>[…] forms which ship with apps could effectively namespace themselves such\nthat N overlapping form fields could be POSTed at once and resolved to the\ncorrect form.\n</code></pre></div>\n<p>Για να επιλύσουμε αυτό το ticket, θα προσθέσουμε το <code class=\"docutils literal notranslate\">prefix</code> attribute στην <code class=\"docutils literal notranslate\">BaseForm</code> class. Έτσι, όταν θα δημιουργούμε instances από αυτή την class περνώντας ένα prefix όρισμα στην <code class=\"docutils literal notranslate\">__init__()</code> μέθοδο, το instance θα έχει καταχωρημένο αυτό το <code class=\"docutils literal notranslate\">prefix</code> attribute. Αλλά όταν δεν περνάμε (μέσω της <code class=\"docutils literal notranslate\">__init__()</code>) το prefix (ή περνάμε <code class=\"docutils literal notranslate\">None</code>) τότε θα χρησιμοποιηθεί το prefix σε επίπεδο class (το prefix attribute της class δηλαδή). Πριν γράψουμε αυτές τις αλλαγές όμως, θα γράψουμε μερικά τεστ τα οποία θα αντικατοπτρίζουν τις αλλαγές αυτές και θα ακολουθούν την ιδεολογία του Test Driven Development (TDD), όπως αναφέρθηκε παραπάνω.</p>\n<p>Μεταβείτε στον φάκελο <code class=\"docutils literal notranslate\">tests/forms_tests/tests/</code> και ανοίξτε το αρχείο <code class=\"docutils literal notranslate\">test_forms.py</code>. Προσθέστε τον ακόλουθο κώδικα στην γραμμή 1674, ακριβώς πριν την συνάρτηση <code class=\"docutils literal notranslate\">test_forms_with_null_boolean</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=\"k\">def</span> <span class=\"nf\">test_class_prefix</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Prefix can be also specified at the class level.</span>\n    <span class=\"k\">class</span> <span class=\"nc\">Person</span><span class=\"p\">(</span>Form<span class=\"p\">):</span>\n        first_name <span class=\"o\">=</span> CharField<span class=\"p\">()</span>\n        prefix <span class=\"o\">=</span> <span class=\"s1\">&#39;foo&#39;</span>\n\n    p <span class=\"o\">=</span> Person<span class=\"p\">()</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span>assertEqual<span class=\"p\">(</span>p<span class=\"o\">.</span>prefix<span class=\"p\">,</span> <span class=\"s1\">&#39;foo&#39;</span><span class=\"p\">)</span>\n\n    p <span class=\"o\">=</span> Person<span class=\"p\">(</span>prefix<span class=\"o\">=</span><span class=\"s1\">&#39;bar&#39;</span><span class=\"p\">)</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span>assertEqual<span class=\"p\">(</span>p<span class=\"o\">.</span>prefix<span class=\"p\">,</span> <span class=\"s1\">&#39;bar&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Αυτό το καινούργιο τεστ ελέγχει δύο πράγματα (τα οποία ήταν στις προδιαγραφές παραπάνω). Πρώτον, αν το instance δημιουργηθεί χωρίς prefix (δεν περαστεί στην <code class=\"docutils literal notranslate\">__init__</code>) τότε το <code class=\"docutils literal notranslate\">p.prefix</code> θα είναι ίσο με ένα προεπιλεγμένο prefix attribute που θα το ορίζει η εκάστοτε class. Δεύτερον, αν το instance δημιουργηθεί με κάποιο prefix attribute (πάντα μέσω της <code class=\"docutils literal notranslate\">__init__</code>) τότε το <code class=\"docutils literal notranslate\">p.prefix</code> θα ισούται με αυτό που πέρασε στην <code class=\"docutils literal notranslate\">__init__</code>.</p>\n<aside class=\"admonition-but-this-testing-thing-looks-kinda-hard admonition\" role=\"note\">\n<p class=\"admonition-title\">Μήπως σας φάνηκε δύσκολο αυτό το τεστ;</p>\n<p>Αν δεν έχετε γράψει ποτέ στο παρελθόν κάποιο τεστ και πρώτη φορά συναναστρέφεστε με αυτό, στην αρχή ίσως σας φανεί κάπως δύσκολο. Δεν υπάρχει όμως λόγος να ανησυχείτε καθώς η ενότητα testing είναι ένα <em>τεράστιο</em> κεφάλαιο στον προγραμματισμό, που σημαίνει ότι υπάρχει εκτενής και πολλή πληροφορία πάνω σε αυτό το θέμα:</p>\n<ul class=\"simple\">\n<li><p>Μια πρώτη ματιά για τη σύνταξη των τεστ για το Django μπορείτε να βρείτε στην ενότητα του εγχειριδίου (documentation) <a class=\"reference internal\" href=\"/el/1.10/topics/testing/overview/\"><span class=\"doc\">σύνταξη και εκτέλεση των τεστ</span></a>.</p></li>\n<li><p>Το βιβλίο Dive Into Python (δωρεάν για αρχάριους developers στην γλώσσα προγραμματισμού Python) περιέχει μια πολύ καλή <a class=\"reference external\" href=\"http://www.diveintopython.net/unit_testing/index.html\">εισαγωγή στο Unit Testing</a>.</p></li>\n<li><p>Αφού διαβάσετε τα ανωτέρω και επιθυμείτε να εμβαθύνετε τις γνώσεις σας περί του θέματος, υπάρχει πάντα το εγχειρίδιο <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#module-unittest\" title=\"(στη Python έκδοση 3.14)\"><code class=\"xref py py-mod docutils literal notranslate\">unittest</code></a> της Python.</p></li>\n</ul>\n</aside>\n</section>\n<section id=\"running-your-new-test\">\n<h3>Τρέχοντας το τεστ<a class=\"heading-anchor\" href=\"#running-your-new-test\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Θυμηθείτε ότι δεν έχουμε πειράξει (ακόμη) τον πηγαίο κώδικα του Django (παρεμβαίνοντας συγκεκριμένα στην <code class=\"docutils literal notranslate\">BaseForm</code>). Το μόνο που αλλάξαμε είναι η προσθήκη ενός ακόμη τεστ (το οποίο θα πρέπει να αποτυγχάνει). Ας τρέξουμε όλα τα τεστ στον φάκελο <code class=\"docutils literal notranslate\">forms_tests</code> ούτως ώστε να σιγουρευτούμε ότι το δικό μας αποτυγχάνει. Από τη γραμμή εντολών, χρησιμοποιώντας την εντολή <code class=\"docutils literal notranslate\">cd tests/</code> μεταβαίνετε στο φάκελο <code class=\"docutils literal notranslate\">tests/</code> και τρέχετε την εντολή:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>./runtests.py forms_tests\n</code></pre></div>\n<p>Αν τα τεστ εκτελεστούν με επιτυχία (προσοχή, αυτό δεν σημαίνει ότι πέρασαν, απλώς ότι εκτελέστηκαν επιτυχώς) τότε θα πρέπει να δείτε στο τεστ που γράψαμε πριν, αποτυχία (failure). Αν όλα τα τεστ πέρασαν, τότε κάτι δεν πήγε καλά και θα πρέπει να σιγουρευτείτε ότι προσθέσατε το παραπάνω τεστ στο σωστό φάκελο κάτω από τη σωστή class.</p>\n</section>\n</section>\n<section id=\"writing-the-code-for-your-ticket\">\n<h2>Γράφοντας κώδικα για το ticket<a class=\"heading-anchor\" href=\"#writing-the-code-for-your-ticket\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Παρακάτω θα γράψουμε τον κώδικα που απαιτείται για να επιλύσουμε το ticket <a class=\"extlink-ticket reference external\" href=\"https://code.djangoproject.com/ticket/24788\">#24788</a>.</p>\n<section id=\"writing-the-code-for-ticket-24788\">\n<h3>Γράφοντας κώδικα για το ticket #24788<a class=\"heading-anchor\" href=\"#writing-the-code-for-ticket-24788\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Μεταβείτε στο φάκελο <code class=\"docutils literal notranslate\">django/django/forms/</code> και ανοίξτε το αρχείο <code class=\"docutils literal notranslate\">forms.py</code>. Βρείτε την <code class=\"docutils literal notranslate\">BaseForm</code> class στη γραμμή 72 και προσθέστε το <code class=\"docutils literal notranslate\">prefix</code> class attribute ακριβώς κάτω από το <code class=\"docutils literal notranslate\">field_order</code> attribute:</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=\"k\">class</span> <span class=\"nc\">BaseForm</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"c1\"># This is the main implementation of all the Form logic. Note that this</span>\n    <span class=\"c1\"># class is different than Form. See the comments by the Form class for</span>\n    <span class=\"c1\"># more information. Any improvements to the form API should be made to</span>\n    <span class=\"c1\"># *this* class, not to the Form class.</span>\n    field_order <span class=\"o\">=</span> <span class=\"kc\">None</span>\n    prefix <span class=\"o\">=</span> <span class=\"kc\">None</span>\n</code></pre></div>\n</section>\n<section id=\"verifying-your-test-now-passes\">\n<h3>Επιβεβαίωση ότι το νέο τεστ περνά επιτυχώς<a class=\"heading-anchor\" href=\"#verifying-your-test-now-passes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Όταν τελειώσετε την τροποποίηση του πηγαίου κώδικα του Django, πρέπει να σιγουρευτούμε ότι τα τεστ που γράψαμε νωρίτερα περνούν επιτυχώς, κάτι το οποίο θα επιβεβαιώσει ότι ο κώδικας που γράψαμε (στην <code class=\"docutils literal notranslate\">BaseForm</code>) είναι σωστός. Για να τρέξουμε τα τεστ στο φάκελο <code class=\"docutils literal notranslate\">forms_tests</code>, πληκτρολογήστε <code class=\"docutils literal notranslate\">cd tests/</code> (για μετάβαση στον φάκελο <code class=\"docutils literal notranslate\">tests/</code>) και μετά:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>./runtests.py forms_tests\n</code></pre></div>\n<p>Oops, φαίνεται ότι κάναμε καλά και γράψαμε αυτό το τεστ νωρίτερα! Θα πρέπει να δείτε μια αποτυχία (failure) με το ακόλουθο exception:</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=\"ne\">AssertionError</span><span class=\"p\">:</span> <span class=\"kc\">None</span> <span class=\"o\">!=</span> <span class=\"s1\">&#39;foo&#39;</span>\n</code></pre></div>\n<p>Παραλείψαμε  να προσθέσουμε μια δομή ελέγχου (conditional statement) μέσα στην μέθοδο <code class=\"docutils literal notranslate\">__init__</code>. Πηγαίνετε λοιπόν και αλλάξτε το <code class=\"docutils literal notranslate\">self.prefix = prefix</code> που βρίσκεται στη γραμμή 87 του αρχείου <code class=\"docutils literal notranslate\">django/forms/forms.py</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=\"k\">if</span> prefix <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span>prefix <span class=\"o\">=</span> prefix\n</code></pre></div>\n<p>Ξανά-τρέξτε τα τεστ και πλέον όλα θα έχουν περάσει επιτυχώς. Αν όχι, σιγουρευτείτε ότι έχετε τροποποιήσει την <code class=\"docutils literal notranslate\">BaseForm</code> σωστά (όπως στο παράδειγμα) και επίσης έχετε γράψει το τεστ όπως στο παράδειγμα.</p>\n</section>\n</section>\n<section id=\"running-django-s-test-suite-for-the-second-time\">\n<h2>Εκτέλεση της σουίτας δοκιμών του Django για δεύτερη φορά<a class=\"heading-anchor\" href=\"#running-django-s-test-suite-for-the-second-time\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Όταν έχετε επιβεβαιώσει ότι το patch και το τεστ δουλεύουν ορθά, τότε είναι ώρα για ένα τελευταίο τεστ όλης της σουίτας του Django, ούτως ώστε να είστε σίγουροι ότι οι αλλαγές που κάνατε (στο συγκεκριμένο οδηγό, στην <code class=\"docutils literal notranslate\">BaseForm</code>) δεν επιφέρουν σφάλματα σε άλλα σημεία του Django. Ωστόσο, αν το patch περάσει επιτυχώς απ’ όλα τα τεστ, αυτό δεν εγγυάται ότι ο κώδικας σας δεν περιέχει σφάλματα (bug free). Βοηθάει, όμως, στην αναγνώριση πολλών σφαλμάτων που ειδάλλως θα περνούσαν απαρατήρητα.</p>\n<p>Για να τρέξετε ολόκληρη τη σουίτα δοκιμών του Django, πληκτρολογήστε <code class=\"docutils literal notranslate\">cd tests/</code> και τρέξτε:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>./runtests.py\n</code></pre></div>\n<p>Εφόσον δε δείτε κάποια αποτυχία (failure), είστε έτοιμοι!</p>\n</section>\n<section id=\"writing-documentation\">\n<h2>Γράφοντας το εγχειρίδιο (documentation)<a class=\"heading-anchor\" href=\"#writing-documentation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Το εγχειρίδιο είναι ένα νέο χαρακτηριστικό και θα πρέπει να σας απασχολήσει στον ίδιο βαθμό με τον κώδικα που γράφετε. Κάθε κομμάτι που γράφετε μέσα στο εγχειρίδιο, βοηθάτε όχι μόνο τον εαυτό σας αλλά και τους υπόλοιπους προγραμματιστές οι οποίοι θα διαβάσουν τον κώδικα σας. Προσθέστε το ακόλουθο κομμάτι στη γραμμή 1068, στο τέλος του αρχείου <code class=\"docutils literal notranslate\">django/docs/ref/forms/api.txt</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>The prefix can also be specified on the form class::\n\n    &gt;&gt;&gt; class PersonForm(forms.Form):\n    ...     ...\n    ...     prefix = &#39;person&#39;\n\n.. versionadded:: 1.9\n\n    The ability to specify ``prefix`` on the form class was added.\n</code></pre></div>\n<p>Εφόσον αυτό το νέο χαρακτηριστικό (<code class=\"docutils literal notranslate\">prefix</code>) θα είναι διαθέσιμο από την έκδοση 1.9 (και μετά) του Django, θα πρέπει να προστεθεί στις σημειώσεις έκδοσης (release notes) του Django 1.9. Το προσθέσαμε λοιπόν στη γραμμή 164 κάτω από την ενότητα «Forms» στο αρχείο <code class=\"docutils literal notranslate\">docs/releases/1.9.txt</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>* A form prefix can be specified inside a form class, not only when\n  instantiating a form. See :ref:`form-prefix` for details.\n</code></pre></div>\n<p>Για περισσότερες πληροφορίες σχετικά με οδηγίες σύνταξης του εγχειριδίου (περιέχει και την εξήγηση του <code class=\"docutils literal notranslate\">versionadded</code>), δείτε στο <a class=\"reference internal\" href=\"/el/1.10/internals/contributing/writing-documentation/\"><span class=\"doc\">γράφοντας το εγχειρίδιο</span></a>. Αυτή η σελίδα εξηγεί και το πως να δημιουργήσετε ένα αντίγραφο του εγχειριδίου σας τοπικά (στον υπολογιστή σας), ούτως ώστε να δείτε πως θα φαίνεται online στο επίσημο site του Django.</p>\n</section>\n<section id=\"previewing-your-changes\">\n<h2>Προβολή των αλλαγών σας<a class=\"heading-anchor\" href=\"#previewing-your-changes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Τώρα ήρθε η ώρα να περάσει μέσα από όλες τις αλλαγές που έγιναν στην ενημέρωσή μας. Για να εμφανίσετε τις διαφορές μεταξύ του τρέχοντος αντίγραφο σας του Django (με τις αλλαγές σας) και την αναθεώρηση που αρχικά ελέγξατε νωρίτερα στο σεμινάριο:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>git diff\n</code></pre></div>\n<p>Χρησιμοποιήστε τα βέλη για να κινηθείτε προς τα επάνω και προς τα κάτω.</p>\n<div class=\"code-block\" data-language=\"diff\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Diff</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=\"Diff code\"><code><span class=\"gh\">diff --git a/django/forms/forms.py b/django/forms/forms.py</span>\n<span class=\"gh\">index 509709f..d1370de 100644</span>\n<span class=\"gd\">--- a/django/forms/forms.py</span>\n<span class=\"gi\">+++ b/django/forms/forms.py</span>\n<span class=\"gu\">@@ -75,6 +75,7 @@ class BaseForm(object):</span>\n     # information. Any improvements to the form API should be made to *this*\n     # class, not to the Form class.\n     field_order = None\n<span class=\"gi\">+    prefix = None</span>\n\n     def __init__(self, data=None, files=None, auto_id=&#39;id_%s&#39;, prefix=None,\n                  initial=None, error_class=ErrorList, label_suffix=None,\n<span class=\"gu\">@@ -83,7 +84,8 @@ class BaseForm(object):</span>\n         self.data = data or {}\n         self.files = files or {}\n         self.auto_id = auto_id\n<span class=\"gd\">-        self.prefix = prefix</span>\n<span class=\"gi\">+        if prefix is not None:</span>\n<span class=\"gi\">+            self.prefix = prefix</span>\n         self.initial = initial or {}\n         self.error_class = error_class\n         # Translators: This is the default suffix added to form field labels\n<span class=\"gh\">diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt</span>\n<span class=\"gh\">index 3bc39cd..008170d 100644</span>\n<span class=\"gd\">--- a/docs/ref/forms/api.txt</span>\n<span class=\"gi\">+++ b/docs/ref/forms/api.txt</span>\n<span class=\"gu\">@@ -1065,3 +1065,13 @@ You can put several Django forms inside one ``&lt;form&gt;`` tag. To give each</span>\n     &gt;&gt;&gt; print(father.as_ul())\n     &lt;li&gt;&lt;label for=&quot;id_father-first_name&quot;&gt;First name:&lt;/label&gt; &lt;input type=&quot;text&quot; name=&quot;father-first_name&quot; id=&quot;id_father-first_name&quot; /&gt;&lt;/li&gt;\n     &lt;li&gt;&lt;label for=&quot;id_father-last_name&quot;&gt;Last name:&lt;/label&gt; &lt;input type=&quot;text&quot; name=&quot;father-last_name&quot; id=&quot;id_father-last_name&quot; /&gt;&lt;/li&gt;\n<span class=\"gi\">+</span>\n<span class=\"gi\">+The prefix can also be specified on the form class::</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+    &gt;&gt;&gt; class PersonForm(forms.Form):</span>\n<span class=\"gi\">+    ...     ...</span>\n<span class=\"gi\">+    ...     prefix = &#39;person&#39;</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+.. versionadded:: 1.9</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+    The ability to specify ``prefix`` on the form class was added.</span>\n<span class=\"gh\">diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt</span>\n<span class=\"gh\">index 5b58f79..f9bb9de 100644</span>\n<span class=\"gd\">--- a/docs/releases/1.9.txt</span>\n<span class=\"gi\">+++ b/docs/releases/1.9.txt</span>\n<span class=\"gu\">@@ -161,6 +161,9 @@ Forms</span>\n   :attr:`~django.forms.Form.field_order` attribute, the ``field_order``\n   constructor argument , or the :meth:`~django.forms.Form.order_fields` method.\n\n<span class=\"gi\">+* A form prefix can be specified inside a form class, not only when</span>\n<span class=\"gi\">+  instantiating a form. See :ref:`form-prefix` for details.</span>\n<span class=\"gi\">+</span>\n Generic Views\n ^^^^^^^^^^^^^\n\n<span class=\"gh\">diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py</span>\n<span class=\"gh\">index 690f205..e07fae2 100644</span>\n<span class=\"gd\">--- a/tests/forms_tests/tests/test_forms.py</span>\n<span class=\"gi\">+++ b/tests/forms_tests/tests/test_forms.py</span>\n<span class=\"gu\">@@ -1671,6 +1671,18 @@ class FormsTestCase(SimpleTestCase):</span>\n         self.assertEqual(p.cleaned_data[&#39;last_name&#39;], &#39;Lennon&#39;)\n         self.assertEqual(p.cleaned_data[&#39;birthday&#39;], datetime.date(1940, 10, 9))\n\n<span class=\"gi\">+    def test_class_prefix(self):</span>\n<span class=\"gi\">+        # Prefix can be also specified at the class level.</span>\n<span class=\"gi\">+        class Person(Form):</span>\n<span class=\"gi\">+            first_name = CharField()</span>\n<span class=\"gi\">+            prefix = &#39;foo&#39;</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+        p = Person()</span>\n<span class=\"gi\">+        self.assertEqual(p.prefix, &#39;foo&#39;)</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+        p = Person(prefix=&#39;bar&#39;)</span>\n<span class=\"gi\">+        self.assertEqual(p.prefix, &#39;bar&#39;)</span>\n<span class=\"gi\">+</span>\n     def test_forms_with_null_boolean(self):\n         # NullBooleanField is a bit of a special case because its presentation (widget)\n         # is different than its data. This is handled transparently, though.\n</code></pre></div>\n<p>Αφότου ρίξετε μια ματιά στο κείμενο, πιέστε το πλήκτρο <code class=\"docutils literal notranslate\">q</code> για να βρεθείτε πάλι στη γραμμή εντολών. Αν το περιεχόμενο του patch δείχνει σωστό, μπορείτε να κάνετε commit τις αλλαγές (υποτίθεται ότι βρίσκεστε στο root directory του project):</p>\n</section>\n<section id=\"committing-the-changes-in-the-patch\">\n<h2>Κάνοντας commit τις αλλαγές του patch<a class=\"heading-anchor\" href=\"#committing-the-changes-in-the-patch\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Για να κάνετε commit τις αλλαγές γράψτε:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>git commit -a\n</code></pre></div>\n<p>Η παραπάνω εντολή ανοίγει έναν επεξεργαστή κειμένου για να γράψετε το μήνυμα του commit. Ακολουθήστε τις <a class=\"reference internal\" href=\"/el/1.10/internals/contributing/committing-code/#committing-guidelines\"><span class=\"std std-ref\">οδηγίες για ένα σωστό μήνυμα commit</span></a> και γράψτε ένα μήνυμα όπως:</p>\n<div class=\"code-block\" data-language=\"text\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Text</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=\"Text code\"><code>Fixed #24788 -- Allowed Forms to specify a prefix at the class level.\n</code></pre></div>\n</section>\n<section id=\"pushing-the-commit-and-making-a-pull-request\">\n<h2>Κάνοντας push το commit καθώς και ένα pull request<a class=\"heading-anchor\" href=\"#pushing-the-commit-and-making-a-pull-request\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Αφού κάνατε commit το patch, στείλτε το στο fork που φτιάξατε στο GitHub (αντικαθιστώντας το «ticket_24788» με το όνομα του δικού σας branch, αν είναι διαφορετικό):</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code><span class=\"gp\">$ </span>git push origin ticket_24788\n</code></pre></div>\n<p>Μπορείτε να δημιουργήσετε ένα pull request πηγαίνοντας στην <a class=\"reference external\" href=\"https://github.com/django/django/\">επίσημη σελίδα του Django στο GitHub</a>. Εκεί θα δείτε το δικό σας branch κάτω από την ετικέτα «Your recently pushed branches». Κάντε κλικ στο «Compare &amp; pull request».</p>\n<p>Παρακαλούμε να μην το κάνετε για αυτό τον οδηγό, αλλά στην επόμενη σελίδα που θα εμφανιστεί μια προεπισκόπιση του patch σας,  θα κάνετε κλικ στο «Create pull request».</p>\n</section>\n<section id=\"next-steps\">\n<h2>Επόμενα βήματα<a class=\"heading-anchor\" href=\"#next-steps\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Συγχαρητήρια! Μόλις μάθατε πως να κάνετε pull requests στο Django! Λεπτομέρειες για περισσότερο ανεπτυγμένες τεχνικές, που ίσως χρειαστείτε, θα βρείτε στο <a class=\"reference internal\" href=\"/el/1.10/internals/contributing/writing-code/working-with-git/\"><span class=\"doc\">Working with Git and GitHub</span></a>.</p>\n<p>Τώρα μπορείτε να χρησιμοποιήσετε αυτές τις τεχνικές για καλό σκοπό βελτιώνοντας τον πηγαίο κώδικα του Django.</p>\n<section id=\"more-information-for-new-contributors\">\n<h3>Περισσότερες πληροφορίες για του νέους στην συνεισφορά<a class=\"heading-anchor\" href=\"#more-information-for-new-contributors\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Προτού ξεκινήσετε να γράφετε patches για το Django, υπάρχουν μερικές ακόμη πληροφορίες στις οποίες θα πρέπει να ρίξετε μια ματιά:</p>\n<ul class=\"simple\">\n<li><p>Θα πρέπει να διαβάσετε το εγχειρίδιο του Django σχετικά με <a class=\"reference internal\" href=\"/el/1.10/internals/contributing/writing-code/submitting-patches/\"><span class=\"doc\">κατάθεση patches και διεκδίκηση tickets</span></a>. Καλύπτει την δεοντολογία του Trac, πως να διεκδικήσετε tickets για τον εαυτό σας, προτεινόμενο στυλ γραφής κώδικα για patches και πολλές άλλες σημαντικές λεπτομέρειες.</p></li>\n<li><p>Όσοι από εσάς συνεισφέρουν για πρώτη φορά στο Django θα πρέπει να διαβάσουν <a class=\"reference internal\" href=\"/el/1.10/internals/contributing/new-contributors/\"><span class=\"doc\">το εγχειρίδιο του Django για τους νέους συνεισφέροντες</span></a>. Περιέχει πολλές και χρήσιμες συμβουλές για εκείνους που θέλουν να βοηθήσουν-υποστηρίξουν την Django κοινότητα.</p></li>\n<li><p>Κατόπιν των ανωτέρω, αν θέλετε να μάθετε ακόμη περισσότερα σχετικά με την συνεισφορά, μπορείτε πάντα να ανατρέχετε στην ενότητα του εγχειρίδίου <a class=\"reference internal\" href=\"/el/1.10/internals/contributing/\"><span class=\"doc\">του Django σχετικά με την συνεισφορά</span></a>. Περιέχει τόνους πληροφορίας και θα πρέπει να είναι η πρώτη πηγή που θα κοιτάξετε για τυχόν ερωτήσεις ή απορίες που μπορεί να προκύψουν.</p></li>\n</ul>\n</section>\n<section id=\"finding-your-first-real-ticket\">\n<h3>Εύρεση του πρώτου αληθινού ticket<a class=\"heading-anchor\" href=\"#finding-your-first-real-ticket\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Αφού διαβάσατε και κατανοήσατε τη λογική των patches και των συνεισφορών, πιθανόν να είστε έτοιμοι να αναζητήσετε κάποιο ticket προκειμένου να γράψετε το κατάλληλο patch. Δώστε μεγάλη προσοχή στα tickets με το κριτήριο «easy pickings». Αυτού του είδους τα tickets είναι αρκετά απλά στη φύση τους (όπως απλό ήταν και αυτό που γράψαμε σε αυτόν τον οδηγό) και είναι κομμένα και ραμμένα στα μέτρα των νέων προγραμματιστών που θέλουν να συνεισφέρουν. Όταν εξοικειωθείτε με την συνεισφορά στο Django, μπορείτε να συνεχίσετε και να γράφετε patches\nκαι για πιο δύσκολα-περίπλοκα tickets. Η λογική είναι να ξεκινήσετε την επίλυση απλών tickets και σιγά σιγά να επιλύετε ακόμη πιο δύσκολα. Αν πάλι θέλετε να παραμείνετε στην επίλυση απλών tickets κανένα πρόβλημα.</p>\n<p>Αν θέλετε να ξεκινήσετε άμεσα (και κανείς δε πρόκειται να σας κατηγορήσει γι” αυτό!), ρίξτε μια ματιά στη λίστα των <a class=\"reference external\" href=\"https://code.djangoproject.com/query?status=new&amp;status=reopened&amp;has_patch=0&amp;easy=1&amp;col=id&amp;col=summary&amp;col=status&amp;col=owner&amp;col=type&amp;col=milestone&amp;order=priority\">easy tickets που χρειάζονται patches</a> και στα <a class=\"reference external\" href=\"https://code.djangoproject.com/query?status=new&amp;status=reopened&amp;needs_better_patch=1&amp;easy=1&amp;col=id&amp;col=summary&amp;col=status&amp;col=owner&amp;col=type&amp;col=milestone&amp;order=priority\">easy tickets που έχουν patches αλλά χρειάζονται βελτίωση</a>. Αν έχετε εξοικειωθεί με την συγγραφή τεστ, μπορείτε επίσης να κοιτάξετε τη λίστα των <a class=\"reference external\" href=\"https://code.djangoproject.com/query?status=new&amp;status=reopened&amp;needs_tests=1&amp;easy=1&amp;col=id&amp;col=summary&amp;col=status&amp;col=owner&amp;col=type&amp;col=milestone&amp;order=priority\">easy tickets που χρειάζονται τεστ</a>. Θυμηθείτε μόνο τις κατευθηντήριες γραμμές (guidelines) σχετικά με την διεκδίκηση tickets οι οποίες αναφέρθηκαν στον σύνδεσμο του εγχειρίδίου του Django σχετικά με την :doc:` κατάθεση patches και διεκδίκηση tickets &lt;/internals/contributing/writing-code/submitting-patches&gt;`.</p>\n</section>\n<section id=\"what-s-next-after-creating-a-pull-request\">\n<h3>Τι γίνετε μετά, αφότου δημιουργήσω ένα pull request;<a class=\"heading-anchor\" href=\"#what-s-next-after-creating-a-pull-request\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Όταν ένα ticket συνοδεύεται από ένα patch, θα χρειαστεί να κοιταχτεί και από άλλους. Αφού κατατεθεί ένα pull request, θα πρέπει να ενημερώσετε τα metadata του ticket θέτοντας τα κατάλληλα flags πάνω σε αυτό, πχ «has patch», «doesn’t need tests» κλπ, ούτως ώστε άλλοι προγραμματιστές να μπορέσουν να το βρουν και να το κοιτάξουν και εκείνοι. Η συνεισφορά δεν σημαίνει πάντα να γράφετε ένα patch από το μηδέν. Αναθεωρώντας ήδη υπάρχοντα patches αποτελεί μια πολύ σημαντική συνεισφορά. Δείτε λεπτομέρειες στο <a class=\"reference internal\" href=\"/el/1.10/internals/contributing/triaging-tickets/\"><span class=\"doc\">Triaging tickets</span></a>.</p>\n</section>\n</section>","rootId":"writing-your-first-patch-for-django","toc":[{"title":"Εισαγωγή","anchor":"introduction","children":[{"title":"Σε ποιους απευθύνεται αυτό το tutorial","anchor":"who-s-this-tutorial-for","children":[]},{"title":"Τι καλύπτει αυτός ο οδηγός;","anchor":"what-does-this-tutorial-cover","children":[]}]},{"title":"Κώδικας δεοντολογίας","anchor":"code-of-conduct","children":[]},{"title":"Εγκατάσταση Git","anchor":"installing-git","children":[]},{"title":"Δημιουργία αντίγραφου της αναπτυξιακής έκδοσης του Django","anchor":"getting-a-copy-of-django-s-development-version","children":[]},{"title":"Επαναφορά σε μια προγενέστερη έκδοση του Django","anchor":"rolling-back-to-a-previous-revision-of-django","children":[]},{"title":"Εκτέλεση της σουίτας δοκιμών του Django για πρώτη φορά","anchor":"running-django-s-test-suite-for-the-first-time","children":[]},{"title":"Δημιουργία ενός τμήματος για το αρχείου σας","anchor":"creating-a-branch-for-your-patch","children":[]},{"title":"Γράφοντας μερικά τεστ για το ticket","anchor":"writing-some-tests-for-your-ticket","children":[{"title":"Γράφοντας μερικά τεστ για το ticket #24788","anchor":"writing-some-tests-for-ticket-24788","children":[]},{"title":"Τρέχοντας το τεστ","anchor":"running-your-new-test","children":[]}]},{"title":"Γράφοντας κώδικα για το ticket","anchor":"writing-the-code-for-your-ticket","children":[{"title":"Γράφοντας κώδικα για το ticket #24788","anchor":"writing-the-code-for-ticket-24788","children":[]},{"title":"Επιβεβαίωση ότι το νέο τεστ περνά επιτυχώς","anchor":"verifying-your-test-now-passes","children":[]}]},{"title":"Εκτέλεση της σουίτας δοκιμών του Django για δεύτερη φορά","anchor":"running-django-s-test-suite-for-the-second-time","children":[]},{"title":"Γράφοντας το εγχειρίδιο (documentation)","anchor":"writing-documentation","children":[]},{"title":"Προβολή των αλλαγών σας","anchor":"previewing-your-changes","children":[]},{"title":"Κάνοντας commit τις αλλαγές του patch","anchor":"committing-the-changes-in-the-patch","children":[]},{"title":"Κάνοντας push το commit καθώς και ένα pull request","anchor":"pushing-the-commit-and-making-a-pull-request","children":[]},{"title":"Επόμενα βήματα","anchor":"next-steps","children":[{"title":"Περισσότερες πληροφορίες για του νέους στην συνεισφορά","anchor":"more-information-for-new-contributors","children":[]},{"title":"Εύρεση του πρώτου αληθινού ticket","anchor":"finding-your-first-real-ticket","children":[]},{"title":"Τι γίνετε μετά, αφότου δημιουργήσω ένα pull request;","anchor":"what-s-next-after-creating-a-pull-request","children":[]}]}],"breadcrumbs":[{"docname":"intro/index","title":"Ξεκινώντας","url":"/el/1.10/intro/"}],"prev":{"docname":"intro/whatsnext","title":"Τι να διαβάσετε μετά","url":"/el/1.10/intro/whatsnext/"},"next":{"docname":"topics/index","title":"Using Django","url":"/el/1.10/topics/"},"formats":{"html":"/el/1.10/intro/contributing/","markdown":"/el/1.10/intro/contributing.md","json":"/el/1.10/intro/contributing.json"},"source":"https://github.com/django/django/blob/stable/1.10.x/docs/intro/contributing.txt","official":"https://docs.djangoproject.com/el/1.10/intro/contributing/","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","es","el","pl"]}