Version 4 (modified by Nicola Larosa <nico@…>, 17 years ago) ( diff )

Removed some defacement

..
  =====================================
  Writing your first Django app, part 1
  =====================================

.. 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 `<paolo@php3.it>`
  
  Aggiornato alla revisione: 3481 (release 0.95)

.. contents:: **Contenuti del capitolo**

======================================================
Realizzare la prima applicazione con Django, parte uno
======================================================

.. _Writing your first Django app, part 1: http://www.djangoproject.com/documentation/tutorial1/

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()
    [<Poll: Poll object>]

..
  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()
      [<Poll: Poll object>]

Un momento. ``<Poll: Poll object>`` è 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. ``<Poll: Poll object>`` 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()
    [<Poll: What's up?>]

    # Django mette a disposizione un ricco set di API per risalire ai dati,
    # dove puoi specificare argomenti.
    >>> Poll.objects.filter(id=1)
    [<Poll: What's up?>]
    >>> Poll.objects.filter(question__startswith='What')
    [<Poll: What's up?>]

    # 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: What's up?>

    >>> 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)
    <Poll: What's up?>

    # 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)
    <Choice: Not much>
    >>> p.choice_set.create(choice='The sky', votes=0)
    <Choice: The sky>
    >>> 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
    <Poll: What's up?>

    # Vice versa: gli oggetti Poll hanno accesso agli oggetti Choice.
    >>> p.choice_set.all()
    [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
    >>> 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)
    [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]

    # 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()
      [<Poll: What's up?>]
  
      # Django provides a rich database lookup API that's entirely driven by
      # keyword arguments.
      >>> Poll.objects.filter(id=1)
      [<Poll: What's up?>]
      >>> Poll.objects.filter(question__startswith='What')
      [<Poll: What's up?>]
  
      # 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: What's up?>
  
      >>> 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)
      <Poll: What's up?>
  
      # 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)
      <Choice: Not much>
      >>> p.choice_set.create(choice='The sky', votes=0)
      <Choice: The sky>
      >>> c = p.choice_set.create(choice='Just hacking again', votes=0)
  
      # Choice objects have API access to their related Poll objects.
      >>> c.poll
      <Poll: What's up?>
  
      # And vice versa: Poll objects get access to Choice objects.
      >>> p.choice_set.all()
      [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
      >>> 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)
      [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
  
      # 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


Note: See TracWiki for help on using the wiki.
Back to Top