{{{ #!rstafancul ======================================================== Realizzare la prima applicazione con Django, prima parte ======================================================== .. sidebar:: Realizzare la prima applicazione con Django, parte uno :subtitle: traduzione in lingua italiana. Documento originale: `Writing your first Django app, part 1`_ Traduzione: paolo `` Aggiornato alla revisione: 3481 (release 0.95) .. _Writing your first Django app, part 1: http://www.djangoproject.com/documentation/tutorial1/ .. contents:: **Contenuti del capitolo** .. ===================================== Writing your first Django app, part 1 ===================================== In questo tutorial imparerai Django per esempi. Ti condurremo nella realizzazione di una semplice applicazione per sondaggi. .. Let's learn by example. Throughout this tutorial, we'll walk you through the creation of a basic poll application. L'applicazione si articola in due parti: * un sito pubblico dove l'utente visualizza i sondaggi e vota. * un sito di amministrazione dove puoi aggiungere, modificare e rimuovere sondaggi. .. It'll consist of two parts: * A public site that lets people view polls and vote in them. * An admin site that lets you add, change and delete poll. Supporremo che `Django sia già installato`. Puoi verificare che ciò sia vero digitando ``import django`` dall'interprete interattivo di Python. Se il comando non produce errori Django è installato. .. We'll assume you have `Django installed`_ already. You can tell Django is installed by running the Python interactive interpreter and typing ``import django``. If that command runs successfully, with no errors, Django is installed. .. .. _`Django installed`: http://www.djangoproject.com/documentation/install/ .. `Django sia già installato`: http://www.djangoproject.com/documentation/install/ Creare il progetto ================== .. Creating a project ================== Se questa è la prima volta che usi Django dovrai prenderti cura di effettuare una minima configurazione iniziale. Più precisamente devi far sì che venga generato automaticamente il codice necessario per creare un *progetto*, inteso come una collezione di impostazioni associate ad un'istanza di Django in cui verranno precisate la informazioni relative al database, le opzioni specifiche di Django e quelle dell'applicazione. .. If this is your first time using Django, you'll have to take care of some initial setup. Namely, you'll need to auto-generate some code that establishes a Django *project* -- a collection of settings for an instance of Django, including database configuration, Django-specific options and application-specific settings. Dalla linea di comando cambia la directory corrente posizionandoti dove memorizzerai il codice ed esegui il comando ``django-admin.py startproject mysite``. Verrà creata la directory ``mysite``. .. From the command line, ``cd`` into a directory where you'd like to store your code, then run the command ``django-admin.py startproject mysite``. This will create a ``mysite`` directory in your current directory. (Se hai installato Django tramite ``python setup.py``, il file ``django-admin.py`` dovrebbe trovarsi nel path di sistema. Se così non fosse lo troverai in ``site-packages/django/bin``, dove ``site-packages`` è una directory creata in fase di installazione di Python. Considera di creare un link a questo file, ad esempio in ``/usr/local/bin``.) .. (``django-admin.py`` should be on your system path if you installed Django via ``python setup.py``. If it's not on your path, you can find it in ``site-packages/django/bin``, where ``site-packages`` is a directory within your Python installation. Consider symlinking to ``django-admin.py`` from some place on your path, such as ``/usr/local/bin``.) .. admonition:: Dove mettere questo codice? Se in passato hai avuto a che fare con PHP probabilmente sei abituato a collocare il codice delle tue applicazioni sotto la document root del Web server (ad esempio in ``/var/www``). Con Django non devi seguire questa pratica. Non è un buon posto per memorizzare il tuo codice Python, perché come minimo rischi che qualcuno possa leggere i tuoi sorgenti sul Web, e ciò non è un vantaggio in termini di sicurezza. Una buona scelta è di mantenere il codice **al di fuori** della document root, ad esempio in ``/home/mycode``. .. .. admonition:: Where should this code live? If your background is in PHP, you're probably used to putting code under the Web server's document root (in a place such as ``/var/www``). With Django, you don't do that. It's not a good idea to put any of this Python code within your Web server's document root, because it risks the possibility that people may be able to view your code over the Web. That's not good for security. Put your code in some directory **outside** of the document root, such as ``/home/mycode``. Vediamo che cosa è stato creato da ``startproject``:: mysite/ __init__.py manage.py settings.py urls.py .. Let's look at what ``startproject`` created:: mysite/ __init__.py manage.py settings.py urls.py Questi file sono: * ``__init__.py``: un file vuoto il cui scopo è di indicare a Python che la directory che lo contiene è da considerarsi un pacchetto Python. (Se sei alle prime armi con Python puoi trovare `ulteriori informazioni sui pacchetti` nella documentazione ufficiale); * ``manage.py``: un'utility utilizzabile da riga di comando con cui interagire con il progetto in vari modi; * ``settings.py``: contiene le impostazioni per questo progetto; * ``urls.py``: è la dichiarazione degli URL per questo progetto. Consideralo come un "indice" del tuo sito realizzato con Django. .. These files are: * ``__init__.py``: An empty file that tells Python that this directory should be considered a Python package. (Read `more about packages`_ in the official Python docs if you're a Python beginner.) * ``manage.py``: A command-line utility that lets you interact with this Django project in various ways. * ``settings.py``: Settings/configuration for this Django project. * ``urls.py``: The URL declarations for this Django project; a "table of contents" of your Django-powered site. .. .. _more about packages: http://docs.python.org/tut/node8.html#packages .. _ulteriori informazioni sui pacchetti: http://docs.python.org/tut/node8.html#packages Il server di sviluppo --------------------- .. The development server ---------------------- Verifichiamo che il nostro progetto sia funzionante. Cambia la directory corrente in ``mysite`` ed esegui il comando ``python manage.py runserver``. Ti apparirà un output simile a:: Validating models... 0 errors found. Django version 0.95, using settings 'mysite.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows). .. Let's verify this worked. Change into the ``mysite`` directory, if you haven't already, and run the command ``python manage.py runserver``. You'll see the following output on the command line:: Validating models... 0 errors found. Django version 0.95, using settings 'mysite.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows). Hai avviato il server Web di sviluppo scritto in Python a corredo con Django. E' stato incluso per darti la possibilità di sviluppare rapidamente senza dover configurare subito un server di produzione come Apache, dandoti la possibilità di posticipare questo momento a quando dovrai andare in produzione. .. You've started the Django development server, a lightweight Web server written purely in Python. We've included this with Django so you can develop things rapidly, without having to deal with configuring a production server -- such as Apache -- until you're ready for production. E' una buona occasione per dirti di NON usare questo server in nessuna situazione che possa assomigliare vagamente a uno scenario di produzione. E' stato concepito unicamente per essere usato in fase di sviluppo. (In effetti il nostro impegno è orientato al campo dei framework Web, noi dei Web server). .. Now's a good time to note: DON'T use this server in anything resembling a production environment. It's intended only for use while developing. (We're in the business of making Web frameworks, not Web servers.) Ora che il server è in funzione, accedi all'indirizzo http://127.0.0.1:8000/. Vedrai una pagina di benvenuto di un gradevole color blu pastello. Funziona! .. Now that the server's running, visit http://127.0.0.1:8000/ with your Web browser. You'll see a "Welcome to Django" page, in pleasant, light-blue pastel. It worked! .. admonition:: Cambiare la porta Di default, il comando ``runserver`` pone in ascolto il server di sviluppo sulla porta 8000. Se vuoi cambiare questo parametro, passa il nuovo valore dalla riga di comando. Ad esempio, se vuoi che il server resti in esecuzione sulla porta 8080:: python manage.py runserver 8080 Informazioni dettagliate sul server di sviluppo sono disponibili nella `documentazione di django-admin.py`_. .. .. admonition:: Changing the port By default, the ``runserver`` command starts the development server on port 8000. If you want to change the server's port, pass it as a command-line argument. For instance, this command starts the server on port 8080:: python manage.py runserver 8080 Full docs for the development server are at `django-admin documentation`_. .. .. _django-admin documentation: http://www.djangoproject.com/documentation/django_admin/ .. _documentazione di django-admin.py: http://www.djangoproject.com/documentation/django_admin/ Configurare il database ----------------------- .. Database setup -------------- Ora modifica il file ``settings.py``. Si tratta di un normale modulo Python contenente variabili a livello di modulo usate per la configurazione di Django. Le impostazioni sul database avvengono mediante questi parametri: * ``DATABASE_ENGINE`` -- 'postgresql', 'mysql' or 'sqlite3'. Ne sono previsti altri per il futuro. * ``DATABASE_NAME`` -- è il nome del databse o il percorso completo (assoluto) del file che contiene i dati se stai usando SQLite. * ``DATABASE_USER`` -- è il nome dell'utente che gestisce il database (non usato con SQLite). * ``DATABASE_PASSWORD`` -- è la password relativa all'utente del punto precedente (non usato con SQLite). * ``DATABASE_HOST`` -- è l'host su cui risiede il database. Se il database è ospitato sulla stessa macchina che fa girare Django lascia una stringa vuota (non usato con SQLite). .. Now, edit ``settings.py``. It's a normal Python module with module-level variables representing Django settings. Change these settings to match your database's connection parameters: * ``DATABASE_ENGINE`` -- Either 'postgresql', 'mysql' or 'sqlite3'. More coming soon. * ``DATABASE_NAME`` -- The name of your database, or the full (absolute) path to the database file if you're using SQLite. * ``DATABASE_USER`` -- Your database username (not used for SQLite). * ``DATABASE_PASSWORD`` -- Your database password (not used for SQLite). * ``DATABASE_HOST`` -- The host your database is on. Leave this as an empty string if your database server is on the same physical machine (not used for SQLite). .. admonition:: Note Se stai usando PostgreSQL o MySQL assicurati di aver creato un database. In caso contrario fallo ora usando la sintassi "``CREATE DATABASE database_name;``" dal prompt interattivo del database in uso. .. .. admonition:: Note If you're using PostgreSQL or MySQL, make sure you've created a database by this point. Do that with "``CREATE DATABASE database_name;``" within your database's interactive prompt. Modificando ``settings.py`` probabilmente avrai notato l'impostazione ``INSTALLED_APPS`` verso la fine del file. Questa variabile contiene i nomi di tutte le applicazioni Django attive in questa istanza di Django. Ogni applicazione può essere usata in più di un progetto, e se sei interessato puoi pacchettizzarle e distribuirle ad altre persone affinché le usino nei loro progetti. .. While you're editing ``settings.py``, take note of the ``INSTALLED_APPS`` setting towards the bottom of the file. That variable holds the names of all Django applications that are activated in this Django instance. Apps can be used in multiple projects, and you can package and distribute them for use by others in their projects. Le applicazioni predefinite in ``INSTALLED_APPS`` sono: * ``django.contrib.auth``: un sistema di autenticazione. * ``django.contrib.contenttypes``: un framework per i tipi di contenuto. * ``django.contrib.sessions``: un framework per le sessioni. * ``django.contrib.sites``: un framework per gestire più di un sito con una sola installazione di Django. .. By default, ``INSTALLED_APPS`` contains the following apps, all of which come with Django: * ``django.contrib.auth`` -- An authentication system. * ``django.contrib.contenttypes`` -- A framework for content types. * ``django.contrib.sessions`` -- A session framework. * ``django.contrib.sites`` -- A framework for managing multiple sites with one Django installation. Queste applicazioni sono incluse per convenienza e si adattano ai casi d'uso più comuni. .. These applications are included by default as a convenience for the common case. Ognuna di esse richiede almeno una tabella del database, quindi prima di poterne fare uso è necessario creare le tabelle necessarie. A questo scopo esiste il comando:: python manage.py syncdb .. Each of these applications makes use of at least one database table, though, so we need to create the tables in the database before we can use them. To do that, run the following command:: python manage.py syncdb ``syncdb`` crea le tabelle necessarie alle applicazioni elencate in ``INSTALLED_APPS`` usando i parametri relativi al database che hai specificato in ``settings.py``. Per ogni tabella che viene creata comparirà un messaggio, ed inoltre ti verrà chiesto se intendi creare un account come superutente per il sistema di autenticazione. Procedi creandolo. .. The ``syncdb`` command looks at the ``INSTALLED_APPS`` setting and creates any necessary database tables according to the database settings in your ``settings.py`` file. You'll see a message for each database table it creates, and you'll get a prompt asking you if you'd like to create a superuser account for the authentication system. Go ahead and do that. Se sei interessato a sapere quali tabelle sono state create puoi usare il client interattivo a corredo con il database che stai usando e scrivere``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), oppure ``.schema`` (SQLite). .. If you're interested, run the command-line client for your database and type ``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), or ``.schema`` (SQLite) to display the tables Django created. .. admonition:: Per i minimalisti Come abbiamo detto in precedenza, le applicazioni predefinite sono adeguate nei casi di utilizzo più comuni, non in tutti. Se non ti serve nessuna di queste applicazioni puoi commentare o eliminare senza problemi la riga corrispondente a ciò che non sei interessatoin ``INSTALLED_APPS``, purché questo avvenga prima di eseguire ``syncdb``. ``syncdb`` crea soltanto le tabelle per le applicazioni elencate in ``INSTALLED_APPS``. .. .. admonition:: For the minimalists Like we said above, the default applications are included for the common case, but not everybody needs them. If you don't need any or all of them, feel free to comment-out or delete the appropriate line(s) from ``INSTALLED_APPS`` before running ``syncdb``. The ``syncdb`` command will only create tables for apps in ``INSTALLED_APPS``. Creare i modelli ================ .. Creating models =============== Ora l'environment lavorativo - il "progetto" - è stato configurato, sei pronto per cominciare lo sviluppo vero e proprio. .. Now that your environment -- a "project" -- is set up, you're set to start doing work. Ogni applicazione che scrivi per Django consiste in un pacchetto Python posto da qualche parte nel `Python path`_, scritto seguendo alcune convenzioni. Django fornisce un'utility che genera automaticamente la struttura base delle directory di un'applicazione, così potrai focalizzare l'attenzione sul codice che scriverai invece che creare directory. .. Each application you write in Django consists of a Python package, somewhere on your `Python path`_, that follows a certain convention. Django comes with a utility that automatically generates the basic directory structure of an app, so you can focus on writing code rather than creating directories. .. admonition: Progetti e applicazioni Qual è la differenza tra un progetto e un'applicazione? Quest'ultima è un'applicazione Web con una finalità di utilizzo pratica, ad esempio può essere un sistema per la gestione di blog, una base di dati pubblicamente consultabile oppure una semplice applicazione per sondaggi. Un progetto è l'insieme di configurazione e applicazioni relativo a un particolare sito Web. Un progetto può contenere più di una applicazione. Un'applicazione può comparire in più di un progetto. .. .. admonition:: Projects vs. apps What's the difference between a project and an app? An app is a Web application that does something -- e.g., a weblog system, a database of public records or a simple poll app. A project is a collection of configuration and apps for a particular Web site. A project can contain multiple apps. An app can be in multiple projects. In questo tutorial l'applicazione verrà creata nella directory ``mysite``, per semplicità. Come conseguenza, l'applicazione sarà vincolata al progetto, e il codice Python all'interno dell'applicazione farà riferimento a ``mysite.polls``. Nel seguito di questo tutorial discuteremo come slegare le applicazioni per poterle distribuire. .. In this tutorial, we'll create our poll app in the ``mysite`` directory, for simplicity. As a consequence, the app will be coupled to the project -- that is, Python code within the poll app will refer to ``mysite.polls``. Later in this tutorial, we'll discuss decoupling your apps for distribution. Per creare l'applicazione assicurati di essere nella directory ``mysite`` e digita:: python manage.py startapp polls .. To create your app, make sure you're in the ``mysite`` directory and type this command:: python manage.py startapp polls Verrà creata una directory ``polls`` così organizzata:: polls/ __init__.py models.py views.py .. That'll create a directory ``polls``, which is laid out like this:: polls/ __init__.py models.py views.py Questa struttura ospiterà l'applicazione. .. This directory structure will house the poll application. Il primo passo nella scrittura di un'applicazione Web con Django consiste nel definirne i modelli, ovvero sostanzialmente lo schema del database ed alcuni metadati aggiuntivi. .. The first step in writing a database Web app in Django is to define your models -- essentially, your database layout, with additional metadata. .. admonition:: Philosophy Un modello è l'unica e definitiva sorgente di accesso ai tuoi dati. Contiene i campi essenziali e i principali comportamenti in merito ai dati che stai memorizzando. Django segue il `principio DRY`_. L'obiettivo è quello di definire il modello dei dati in un posto ben definito ed automaticamente derivare ciò che serve esattamente da lì. .. .. admonition:: Philosophy A model is the single, definitive source of data about your data. It contains the essential fields and behaviors of the data you're storing. Django follows the `DRY Principle`_. The goal is to define your data model in one place and automatically derive things from it. Nella nostra semplice applicazione creeremo due modelli: polls (sondaggi) e choices (scelte). Un sondaggio è caratterizzato da una domanda e da una data di pubblicazione. Una scelta invece da un testo e un contatore di voti. Ogni scelta è associata ad un sondaggio. .. In our simple poll app, we'll create two models: polls and choices. A poll has a question and a publication date. A choice has two fields: the text of the choice and a vote tally. Each choice is associated with a poll. Questi concetti sono tradotti in semplici classi Python. Modifica il file ``polls/models.py`` in modo che il contenuto sia:: from django.db import models class Poll(models.Model): question = models.CharField(maxlength=200) pub_date = models.DateTimeField('date published') class Choice(models.Model): poll = models.ForeignKey(Poll) choice = models.CharField(maxlength=200) votes = models.IntegerField() .. These concepts are represented by simple Python classes. Edit the ``polls/models.py`` file so it looks like this:: from django.db import models class Poll(models.Model): question = models.CharField(maxlength=200) pub_date = models.DateTimeField('date published') class Choice(models.Model): poll = models.ForeignKey(Poll) choice = models.CharField(maxlength=200) votes = models.IntegerField() Il codice è facilmente comprensibile. Ogni modello è espresso da una sottoclasse di ``django.db.models.Model``. Per ogni modello sono specificate alcune variabili di classe, ognuna delle quali rappresenta, all'interno del modello, un campo del database. .. The code is straightforward. Each model is represented by a class that subclasses ``django.db.models.Model``. Each model has a number of class variables, each of which represents a database field in the model. Ogni campo è rappresentato da un'istanza della classe ``models.*Field``, ad esempio ``models.CharField`` per campi contenenti caratteri e ``models.DateTimeField`` per date e orari. In questo modo Django può risalire ai tipi di dato che vengono mantenuti nei diversi campi. .. Each field is represented by an instance of a ``models.*Field`` class -- e.g., ``models.CharField`` for character fields and ``models.DateTimeField`` for datetimes. This tells Django what type of data each field holds. Il nome di ciascuna istanza ``models.*Field`` (ad esempio, ``question`` o ``pub_date``) è il nome del campo in formato machine-readable (riconoscibile dalla macchina). Questo nome verrà usato da te per scrivere il codice Python e dal database per assegnare un nome alla colonna. .. The name of each ``models.*Field`` instance (e.g. ``question`` or ``pub_date`` ) is the field's name, in machine-friendly format. You'll use this value in your Python code, and your database will use it as the column name. Per specificare un nome human-readable (riconoscibile dagli esseri umani) puoi dichiarare, per i vari campi, un primo argomento posizionale facoltativo. Questo valore viene usato anche in un paio di situazioni orientate all'introspezione, ed ha il vantaggio di migliorare la documentazione. Quando non è precisato un nome human-readable Django userà il nome machine-readable. In questo esempio abbiamo definito solamente un nome human-readable: in ``Poll.pub_date``. Per tutti gli altri campi di questo modello verrà usato il nome machine-readable. .. You can use an optional first positional argument to a ``Field`` to designate a human-readable name. That's used in a couple of introspective parts of Django, and it doubles as documentation. If this field isn't provided, Django will use the machine-readable name. In this example, we've only defined a human-readable name for ``Poll.pub_date``. For all other fields in this model, the field's machine-readable name will suffice as its human-readable name. Alcune classi ``Field`` richiedono obbligatoriamente alcune informazioni aggiuntive. Ad esempio ``CharField`` richiede che venga precisata la lunghezza massima di caratteri, ``maxlength``. Questo valore non viene usato soltanto nello schema del database, ma anche nella validazione, come vedremo tra poco. .. Some ``Field`` classes have required elements. ``CharField``, for example, requires that you give it a ``maxlength``. That's used not only in the database schema, but in validation, as we'll soon see. A questo punto puoi osservare come usando ``models.ForeignKey`` viene definita una relazione. In questo modo Django viene informato che ogni scelta (Choice) è associata ad un singolo sondaggio (Poll). Django riconosce le relazioni più comunemente utilizzate: molti-a-uno, molti-a-molti, uno-a-uno. .. Finally, note a relationship is defined, using ``models.ForeignKey``. That tells Django each Choice is related to a single Poll. Django supports all the common database relationships: many-to-ones, many-to-manys and one-to-ones. .. _`Python path`: http://docs.python.org/tut/node8.html#SECTION008110000000000000000 .. _principio DRY: http://c2.com/cgi/wiki?DontRepeatYourself .. .. _`Python path`: http://docs.python.org/tut/node8.html#SECTION008110000000000000000 .. _DRY Principle: http://c2.com/cgi/wiki?DontRepeatYourself Attivare i modelli ================== .. Activating models ================= Il breve frammento di codice che hai appena scritto fornisce molte informazioni, che Django utilizza per: * creare lo schema del database (i comandi ``CREATE TABLE``) per l'applicazione corrente; * creare un insieme di API Python per accedere agli oggetti Poll e Choice. .. That small bit of model code gives Django a lot of information. With it, Django is able to: * Create a database schema (``CREATE TABLE`` statements) for this app. * Create a Python database-access API for accessing Poll and Choice objects. Prima che Django possa procedere però è necessario informare il progetto che l'applicazione ``polls`` è installata. .. But first we need to tell our project that the ``polls`` app is installed. .. admonition:: Philosophy Le applicazioni per Django sono modulari: puoi installarle in più progetti e, poiché non risultano legate ad un particolare progetto, puoi distribuirle. .. .. admonition:: Philosophy Django apps are "pluggable": You can use an app in multiple projects, and you can distribute apps, because they don't have to be tied to a given Django installation. Modifica nuovamente il file ``settings.py`` e aggiungi la stringa ``'mysite.polls'`` a ``INSTALLED_APPS``. Questo il risultato:: INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'mysite.polls' ) .. Edit the ``settings.py`` file again, and change the ``INSTALLED_APPS`` setting to include the string ``'mysite.polls'``. So it'll look like this:: INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'mysite.polls' ) Ora Django è consapevole che ``mysite`` contiene l'applicazione ``polls`` e tu puoi ottenere informazioni sull'SQL con questo comando:: python manage.py sql polls .. Now Django knows ``mysite`` includes the ``polls`` app. Let's run another command:: python manage.py sql polls Dovrebbero comparirti le istruzioni SQL CREATE TABLE relative all'applicazione polls:: BEGIN; CREATE TABLE "polls_poll" ( "id" serial NOT NULL PRIMARY KEY, "question" varchar(200) NOT NULL, "pub_date" timestamp with time zone NOT NULL ); CREATE TABLE "polls_choice" ( "id" serial NOT NULL PRIMARY KEY, "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"), "choice" varchar(200) NOT NULL, "votes" integer NOT NULL ); COMMIT; .. You should see the following (the CREATE TABLE SQL statements for the polls app):: BEGIN; CREATE TABLE "polls_poll" ( "id" serial NOT NULL PRIMARY KEY, "question" varchar(200) NOT NULL, "pub_date" timestamp with time zone NOT NULL ); CREATE TABLE "polls_choice" ( "id" serial NOT NULL PRIMARY KEY, "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"), "choice" varchar(200) NOT NULL, "votes" integer NOT NULL ); COMMIT; Dovresti osservare che: * i nomi delle tabelle vengono generati automaticamente combinando il nome dell'applicazione (``polls``) ed il nome del modello in lettere minuscole, ``poll`` e ``choice``. (Puoi personalizzare questa impostazione). * le chiavi primarie (gli ID) sono inserite automaticamente. (Puoi personalizzare anche questa impostazione). * come convenzione, al nome delle chiavi esterne viene accodato il suffisso ``"_id"``. Naturalmente puoi personalizzare anche questo. * la sintassi per la relazione di chiave esterna è coerente con il database in uso, perciò automaticamente verrà scelto ``auto_increment`` (MySQL), ``serial`` (PostgreSQL) o ``integer primary key`` (SQLite). Lo stesso principio viene adottato per quotare il nome dei campi, ad esempio, usando i doppi apici o i singoli apici. L'autore di questo documento usa PostgreSQL, perciò il risultato degli esempi è espresso con la sintassi di PostgreSQL. * il comando `sql` non esegue il codice SQL sul database, ma si limita a presentarlo a video mostrando come Django ha costruito i comandi per la creazione del database. Se ti dovesse servire potrai copiare questo output ed incollarlo dal programma client di accesso al database. Tuttavia, come vedrai tra poco Django offre un metodo molto più semplice per l'esecuzione dei comandi SQL sul database. .. Note the following: * Table names are automatically generated by combining the name of the app (``polls``) and the lowercase name of the model -- ``poll`` and ``choice``. (You can override this behavior.) * Primary keys (IDs) are added automatically. (You can override this, too.) * By convention, Django appends ``"_id"`` to the foreign key field name. Yes, you can override this, as well. * The foreign key relationship is made explicit by a ``REFERENCES`` statement. * It's tailored to the database you're using, so database-specific field types such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or ``integer primary key`` (SQLite) are handled for you automatically. Same goes for quoting of field names -- e.g., using double quotes or single quotes. The author of this tutorial runs PostgreSQL, so the example output is in PostgreSQL syntax. * The `sql` command doesn't actually run the SQL in your database - it just prints it to the screen so that you can see what SQL Django thinks is required. If you wanted to, you could copy and paste this SQL into your database prompt. However, as we will see shortly, Django provides an easier way of committing the SQL to the database. Questi sono altri comandi che puoi eseguire: * ``python manage.py validate polls``: verifica la presenza di errori nei modelli. * ``python manage.py sqlinitialdata polls``: mostra i dati iniziali richiesti per il framework di amministrazione di Django e per i tuoi modelli. * ``python manage.py sqlclear polls``: mostra i comandi ``DROP TABLE`` per questa applicazione, sulla base delle tabelle già esistenti nel database (se ve ne fossero). * ``python manage.py sqlindexes polls``: mostra i comandi ``CREATE INDEX`` per questa applicazione. * ``python manage.py sqlall polls``: è la combinazione dei comandi 'sql', 'sqlinitialdata' e 'sqlindexes'. .. If you're interested, also run the following commands: * ``python manage.py validate polls`` -- Checks for any errors in the construction of your models. * ``python manage.py sqlinitialdata polls`` -- Outputs any initial data required for Django's admin framework and your models. * ``python manage.py sqlclear polls`` -- Outputs the necessary ``DROP TABLE`` statements for this app, according to which tables already exist in your database (if any). * ``python manage.py sqlindexes polls`` -- Outputs the ``CREATE INDEX`` statements for this app. * ``python manage.py sqlall polls`` -- A combination of all the SQL from the 'sql', 'sqlinitialdata', and 'sqlindexes' commands. L'analisi dell'output di questi comandi può aiutarti a capire che cosa succederà dietro le quinte. .. Looking at the output of those commands can help you understand what's actually happening under the hood. Ora crea le tabelle relative ai modelli dell'applicazione eseguendo ancora una volta ``syncdb``:: python manage.py syncdb .. Now, run ``syncdb`` again to create those model tables in your database:: python manage.py syncdb Il comando ``syncdb`` manda in esecuzione i comandi sql generati da 'sqlall' relativamente a tutte le applicazioni in ``INSTALLED_APPS`` che già non siano esistenti nel database. Il risultato è la creazione di tutte le tabelle, dei dati iniziali e degli indici di tutte le applicazioni che hai aggiunto al progetto dall'ultima volta che syncdb è stato lanciato. Puoi invocare ``syncdb`` tutte le volte che vuoi, e soltanto le tabelle che ancora non esistono verranno create. .. The ``syncdb`` command runs the sql from 'sqlall' on your database for all apps in ``INSTALLED_APPS`` that don't already exist in your database. This creates all the tables, initial data and indexes for any apps you have added to your project since the last time you ran syncdb. ``syncdb`` can be called as often as you like, and it will only ever create the tables that don't exist. Per avere informazioni complete sulle possibilità offerte dall'utility ``manage.py`` consulta la `documentazione su django-admin.py`_. .. Read the `django-admin.py documentation`_ for full information on what the ``manage.py`` utility can do. .. .. _django-admin.py documentation: http://www.djangoproject.com/documentation/django_admin/ .. _documentazione su django-admin.py: http://www.djangoproject.com/documentation/django_admin/ Esperimenti con le API ====================== .. Playing with the API ==================== Ora avvia la shell Python interattiva e fai qualche prova con l'insieme di API che Django mette a disposizione. Per invocare la shell usa questo comando:: python manage.py shell .. Now, let's hop into the interactive Python shell and play around with the free API Django gives you. To invoke the Python shell, use this command:: python manage.py shell Ti proponiamo questa sintassi invece di digitare semplicemente "python" perché usando ``manage.py`` le impostazioni di environment del progetto verrà impostato senza che tu debba fare nessuna operazione. "Impostare l'environment del progetto" coinvolge due operazioni: * aggiungere ``mysite`` a ``sys.path``. Per migliorare la flessibilità, diverse parti di Django usano la notazione puntata (dotted notation) quando si riferiscono a progetti (ad esempio, ``'mysite.polls.models'``). Generalmente, perché questo approccio funzioni, il pacchetto ``mysite`` deve essere elencato in ``sys.path``. * impostare la variabile di environment ``DJANGO_SETTINGS_MODULE`` affinché Django sia in grado di accedere al file ``settings.py``. .. We're using this instead of simply typing "python", because ``manage.py`` sets up the project's environment for you. "Setting up the environment" involves two things: * Putting ``mysite`` on ``sys.path``. For flexibility, several pieces of Django refer to projects in Python dotted-path notation (e.g. ``'mysite.polls.models'``). In order for this to work, the ``mysite`` package has to be on ``sys.path``. We've already seen one example of this: the ``INSTALLED_APPS`` setting is a list of packages in dotted-path notation. * Setting the ``DJANGO_SETTINGS_MODULE`` environment variable, which gives Django the path to your ``settings.py`` file. .. admonition:: Bypassare manage.py Se non intendi usare ``manage.py`` puoi decidere di farlo senza problemi. Assicurati però che ``mysite`` sia al livello più alto del Python path (verifica che il comando ``import mysite`` non dia errori) e imposta il valore ``mysite.settings`` per la variabile ``DJANGO_SETTINGS_MODULE``. Per ulteriori informazioni su quanto detto consulta la `documentazione su django-admin.py`_. .. .. admonition:: Bypassing manage.py If you'd rather not use ``manage.py``, no problem. Just make sure ``mysite`` is at the root level on the Python path (i.e., ``import mysite`` works) and set the ``DJANGO_SETTINGS_MODULE`` environment variable to ``mysite.settings``. For more information on all of this, see the `django-admin.py documentation`_. Una volta invocata la shell esplora le API relative al database:: # Importa le classi dei modelli che hai appena scritto. >>> from mysite.polls.models import Poll, Choice # Non esistono ancora sondaggi. >>> Poll.objects.all() [] # Crea un nuovo oggetto Poll. >>> from datetime import datetime >>> p = Poll(question="What's up?", pub_date=datetime.now()) # Salva l'oggetto nel database. Devi invocare save() esplicitamente. >>> p.save() # Ora p ha un ID. Nota che il suo valore può essere "1L" invece di "1". # Dipende dal database che stai usando. Non è nulla di preoccupante, # significa soltanto che il backend preferisce restituire i numeri interi # sottoforma di oggetti Python interi lunghi. >>> p.id 1 # Accedi alle colonne del database come attributi Python. >>> p.question "What's up?" >>> p.pub_date datetime.datetime(2005, 7, 15, 12, 00, 53) # Cambia i valori agendo sugli attributi e salvando le modifiche con # save(). >>> p.pub_date = datetime(2005, 4, 1, 0, 0) >>> p.save() # objects.all() mostra tutti i sondaggi nel database. >>> Poll.objects.all() [] .. Once you're in the shell, explore the database API:: # Import the model classes we just wrote. >>> from mysite.polls.models import Poll, Choice # No polls are in the system yet. >>> Poll.objects.all() [] # Create a new Poll. >>> from datetime import datetime >>> p = Poll(question="What's up?", pub_date=datetime.now()) # Save the object into the database. You have to call save() explicitly. >>> p.save() # Now it has an ID. Note that this might say "1L" instead of "1", depending # on which database you're using. That's no biggie; it just means your # database backend prefers to return integers as Python long integer # objects. >>> p.id 1 # Access database columns via Python attributes. >>> p.question "What's up?" >>> p.pub_date datetime.datetime(2005, 7, 15, 12, 00, 53) # Change values by changing the attributes, then calling save(). >>> p.pub_date = datetime(2005, 4, 1, 0, 0) >>> p.save() # objects.all() displays all the polls in the database. >>> Poll.objects.all() [] Un momento. ```` è una rappresentazione dell'oggetto totalmente priva di utilità. Puoi sistemare questo aggiungendo il metodo ``__str__()`` alle classi ``Poll`` e ``Choice`` contenute nel file dei modelli ``polls/models.py``:: class Poll(models.Model): # ... def __str__(self): return self.question class Choice(models.Model): # ... def __str__(self): return self.choice .. Wait a minute. ```` is, utterly, an unhelpful representation of this object. Let's fix that by editing the polls model (in the ``polls/models.py`` file) and adding a ``__str__()`` method to both ``Poll`` and ``Choice``:: class Poll(models.Model): # ... def __str__(self): return self.question class Choice(models.Model): # ... def __str__(self): return self.choice E' importante aggiungere i metodi ``__str__()`` non solo per una tua comodità durante le sessioni interattive, ma anche perché la rappresentazione testuale degli oggetti viene usata nell'interfaccia di amministrazione che Django genera in modo automatico. .. It's important to add ``__str__()`` methods to your models, not only for your own sanity when dealing with the interactive prompt, but also because objects' representations are used throughout Django's automatically-generated admin. Prova a farci caso, fino ad ora abbiamo usato normali metodi Python. Come controprova proviamo ad aggiungere un metodo personalizzato:: import datetime # ... class Poll(models.Model): # ... def was_published_today(self): return self.pub_date.date() == datetime.date.today() .. Note these are normal Python methods. Let's add a custom method, just for demonstration:: import datetime # ... class Poll(models.Model): # ... def was_published_today(self): return self.pub_date.date() == datetime.date.today() ``import datetime`` è stato aggiunto facendo riferimento alla libreria standard di Python. .. Note the addition of ``import datetime`` to reference Python's standard ``datetime`` module. Torniamo alla shell interattiva invocando di nuovo ``python manage.py shell``:: >>> from mysite.polls.models import Poll, Choice # Assicurati che il metodo __str__() che hai appena aggiunto sia # funzionante. >>> Poll.objects.all() [] # Django mette a disposizione un ricco set di API per risalire ai dati, # dove puoi specificare argomenti. >>> Poll.objects.filter(id=1) [] >>> Poll.objects.filter(question__startswith='What') [] # Ottiene tutti i sondaggi dell'anno 2005. E' sottointeso che se stai # seguendo questo tutorial in un anno diverso dal 2005 devi cambiare il # parametro di ricerca in modo appropriato. >>> Poll.objects.get(pub_date__year=2005) >>> Poll.objects.get(id=2) Traceback (most recent call last): ... DoesNotExist: Poll matching query does not exist. # Frequentemente ti capiterà di usare la chiave primaria per risalire ai # dati. Per questo Django offre una scorciatoia. La seguente sintassi è # identica a Poll.objects.get(id=1). >>> Poll.objects.get(pk=1) # Assicurati che il metodo che hai personalizzato funzioni. >>> p = Poll.objects.get(pk=1) >>> p.was_published_today() False # Associa qualche scelta (Choice) al sondaggio (Poll). La chiamata a create # costruisce un nuovo oggetto di scelta, tramite una operazione di INSERT # lo inserisce, aggiunge la scelta all'insieme delle scelte disponibili e # restituisce un nuovo oggetto Choice. >>> p = Poll.objects.get(pk=1) >>> p.choice_set.create(choice='Not much', votes=0) >>> p.choice_set.create(choice='The sky', votes=0) >>> c = p.choice_set.create(choice='Just hacking again', votes=0) # Gli oggetti Choice mettono a disposizione un insieme di API per accedere # all'oggetto Poll a cui sono associati. >>> c.poll # Vice versa: gli oggetti Poll hanno accesso agli oggetti Choice. >>> p.choice_set.all() [, , ] >>> p.choice_set.count() 3 # Le API seguono le relazioni automaticamente sulla base delle tue # necessità. Per separare le relazioni usa il doppio underscore. Questo # funziona a qualsiasi livello tu voglia, non c'è limite. # Trova tutte le scelte per qualsiasi sondaggio il cui attributo pub_date # sia 2005. >>> Choice.objects.filter(poll__pub_date__year=2005) [, , ] # Cancella una delle scelte. Usa delete(). >>> c.choice_set.filter(choice__startswith='Just hacking') >>> c.delete() .. Let's jump back into the Python interactive shell by running ``python manage.py shell`` again:: >>> from mysite.polls.models import Poll, Choice # Make sure our __str__() addition worked. >>> Poll.objects.all() [] # Django provides a rich database lookup API that's entirely driven by # keyword arguments. >>> Poll.objects.filter(id=1) [] >>> Poll.objects.filter(question__startswith='What') [] # Get the poll whose year is 2005. Of course, if you're going through this # tutorial in another year, change as appropriate. >>> Poll.objects.get(pub_date__year=2005) >>> Poll.objects.get(id=2) Traceback (most recent call last): ... DoesNotExist: Poll matching query does not exist. # Lookup by a primary key is the most common case, so Django provides a # shortcut for primary-key exact lookups. # The following is identical to Poll.objects.get(id=1). >>> Poll.objects.get(pk=1) # Make sure our custom method worked. >>> p = Poll.objects.get(pk=1) >>> p.was_published_today() False # Give the Poll a couple of Choices. The create call constructs a new # choice object, does the INSERT statement, adds the choice to the set # of available choices and returns the new Choice object. >>> p = Poll.objects.get(pk=1) >>> p.choice_set.create(choice='Not much', votes=0) >>> p.choice_set.create(choice='The sky', votes=0) >>> c = p.choice_set.create(choice='Just hacking again', votes=0) # Choice objects have API access to their related Poll objects. >>> c.poll # And vice versa: Poll objects get access to Choice objects. >>> p.choice_set.all() [, , ] >>> p.choice_set.count() 3 # The API automatically follows relationships as far as you need. # Use double underscores to separate relationships. # This works as many levels deep as you want. There's no limit. # Find all Choices for any poll whose pub_date is in 2005. >>> Choice.objects.filter(poll__pub_date__year=2005) [, , ] # Let's delete one of the choices. Use delete() for that. >>> c = p.choice_set.filter(choice__startswith='Just hacking') >>> c.delete() Per i dettagli completi sulle API di accesso al database consulta il `reference delle API di accesso al database`_ .. For full details on the database API, see our `Database API reference`_. Quando ti accorgi di avere una certa dimestichezza con queste API leggi la `seconda parte del tutarial`_ per mettere in funzione l'interfaccia di amministrazione di Django. .. When you're comfortable with the API, read `part 2 of this tutorial`_ to get Django's automatic admin working. .. .. _Database API reference: http://www.djangoproject.com/documentation/db_api/ .. _part 2 of this tutorial: http://www.djangoproject.com/documentation/tutorial2/ .. _reference delle API di accesso al database: http://www.djangoproject.com/documentation/db_api/ .. _seconda parte del tutarial: DocItTutorial02 }}}