| 1 | {{{ |
| 2 | #!rst |
| 3 | |
| 4 | ======================================================== |
| 5 | Realizzare la prima applicazione con Django, prima parte |
| 6 | ======================================================== |
| 7 | |
| 8 | .. sidebar:: Realizzare la prima applicazione con Django, parte uno |
| 9 | :subtitle: traduzione in lingua italiana. |
| 10 | |
| 11 | Documento originale: `Writing your first Django app, part 1`_ |
| 12 | |
| 13 | Traduzione: paolo `<paolo@php3.it>` |
| 14 | |
| 15 | Aggiornato alla revisione: 3481 (release 0.95) |
| 16 | |
| 17 | .. _Writing your first Django app, part 1: http://www.djangoproject.com/documentation/tutorial1/ |
| 18 | |
| 19 | .. contents:: **Contenuti del capitolo** |
| 20 | |
| 21 | .. |
| 22 | ===================================== |
| 23 | Writing your first Django app, part 1 |
| 24 | ===================================== |
| 25 | |
| 26 | In questo tutorial imparerai Django per esempi. Ti condurremo nella |
| 27 | realizzazione di una semplice applicazione per sondaggi. |
| 28 | |
| 29 | .. |
| 30 | Let's learn by example. |
| 31 | |
| 32 | Throughout this tutorial, we'll walk you through the creation of a basic |
| 33 | poll application. |
| 34 | |
| 35 | L'applicazione si articola in due parti: |
| 36 | |
| 37 | * un sito pubblico dove l'utente visualizza i sondaggi e vota. |
| 38 | * un sito di amministrazione dove puoi aggiungere, modificare e rimuovere |
| 39 | sondaggi. |
| 40 | |
| 41 | .. It'll consist of two parts: |
| 42 | |
| 43 | * A public site that lets people view polls and vote in them. |
| 44 | * An admin site that lets you add, change and delete poll. |
| 45 | |
| 46 | Supporremo che `Django sia già installato`. Puoi verificare che ciò sia vero |
| 47 | digitando ``import django`` dall'interprete interattivo di Python. Se il |
| 48 | comando non produce errori Django è installato. |
| 49 | |
| 50 | .. |
| 51 | We'll assume you have `Django installed`_ already. You can tell Django is |
| 52 | installed by running the Python interactive interpreter and typing |
| 53 | ``import django``. If that command runs successfully, with no errors, Django is |
| 54 | installed. |
| 55 | |
| 56 | .. |
| 57 | .. _`Django installed`: http://www.djangoproject.com/documentation/install/ |
| 58 | |
| 59 | .. `Django sia già installato`: http://www.djangoproject.com/documentation/install/ |
| 60 | |
| 61 | Creare il progetto |
| 62 | ================== |
| 63 | |
| 64 | .. |
| 65 | Creating a project |
| 66 | ================== |
| 67 | |
| 68 | Se questa è la prima volta che usi Django dovrai prenderti cura di effettuare |
| 69 | una minima configurazione iniziale. Più precisamente devi far sì che venga |
| 70 | generato automaticamente il codice necessario per creare un *progetto*, inteso |
| 71 | come una collezione di impostazioni associate ad un'istanza di Django in cui |
| 72 | verranno precisate la informazioni relative al database, le opzioni specifiche |
| 73 | di Django e quelle dell'applicazione. |
| 74 | |
| 75 | .. |
| 76 | If this is your first time using Django, you'll have to take care of some |
| 77 | initial setup. Namely, you'll need to auto-generate some code that establishes |
| 78 | a Django *project* -- a collection of settings for an instance of Django, |
| 79 | including database configuration, Django-specific options and |
| 80 | application-specific settings. |
| 81 | |
| 82 | Dalla linea di comando cambia la directory corrente posizionandoti dove |
| 83 | memorizzerai il codice ed esegui il comando ``django-admin.py startproject |
| 84 | mysite``. Verrà creata la directory ``mysite``. |
| 85 | |
| 86 | .. |
| 87 | From the command line, ``cd`` into a directory where you'd like to store your |
| 88 | code, then run the command ``django-admin.py startproject mysite``. This |
| 89 | will create a ``mysite`` directory in your current directory. |
| 90 | |
| 91 | (Se hai installato Django tramite ``python setup.py``, il file |
| 92 | ``django-admin.py`` dovrebbe trovarsi nel path di sistema. Se così non fosse lo |
| 93 | troverai in ``site-packages/django/bin``, dove ``site-packages`` è una |
| 94 | directory creata in fase di installazione di Python. Considera di creare un |
| 95 | link a questo file, ad esempio in ``/usr/local/bin``.) |
| 96 | |
| 97 | .. |
| 98 | (``django-admin.py`` should be on your system path if you installed Django via |
| 99 | ``python setup.py``. If it's not on your path, you can find it in |
| 100 | ``site-packages/django/bin``, where ``site-packages`` is a directory within |
| 101 | your Python installation. Consider symlinking to ``django-admin.py`` from some |
| 102 | place on your path, such as ``/usr/local/bin``.) |
| 103 | |
| 104 | .. admonition:: Dove mettere questo codice? |
| 105 | |
| 106 | Se in passato hai avuto a che fare con PHP probabilmente sei abituato a |
| 107 | collocare il codice delle tue applicazioni sotto la document root del Web |
| 108 | server (ad esempio in ``/var/www``). Con Django non devi seguire questa |
| 109 | pratica. Non è un buon posto per memorizzare il tuo codice Python, perché |
| 110 | come minimo rischi che qualcuno possa leggere i tuoi sorgenti sul Web, e ciò |
| 111 | non è un vantaggio in termini di sicurezza. |
| 112 | |
| 113 | Una buona scelta è di mantenere il codice **al di fuori** della document |
| 114 | root, ad esempio in ``/home/mycode``. |
| 115 | |
| 116 | .. |
| 117 | .. admonition:: Where should this code live? |
| 118 | |
| 119 | If your background is in PHP, you're probably used to putting code under the |
| 120 | Web server's document root (in a place such as ``/var/www``). With Django, |
| 121 | you don't do that. It's not a good idea to put any of this Python code within |
| 122 | your Web server's document root, because it risks the possibility that |
| 123 | people may be able to view your code over the Web. That's not good for |
| 124 | security. |
| 125 | |
| 126 | Put your code in some directory **outside** of the document root, such as |
| 127 | ``/home/mycode``. |
| 128 | |
| 129 | Vediamo che cosa è stato creato da ``startproject``:: |
| 130 | |
| 131 | mysite/ |
| 132 | __init__.py |
| 133 | manage.py |
| 134 | settings.py |
| 135 | urls.py |
| 136 | |
| 137 | .. Let's look at what ``startproject`` created:: |
| 138 | |
| 139 | mysite/ |
| 140 | __init__.py |
| 141 | manage.py |
| 142 | settings.py |
| 143 | urls.py |
| 144 | |
| 145 | Questi file sono: |
| 146 | |
| 147 | * ``__init__.py``: un file vuoto il cui scopo è di indicare a Python che la |
| 148 | directory che lo contiene è da considerarsi un pacchetto Python. (Se sei |
| 149 | alle prime armi con Python puoi trovare `ulteriori informazioni sui |
| 150 | pacchetti` nella documentazione ufficiale); |
| 151 | * ``manage.py``: un'utility utilizzabile da riga di comando con cui |
| 152 | interagire con il progetto in vari modi; |
| 153 | * ``settings.py``: contiene le impostazioni per questo progetto; |
| 154 | * ``urls.py``: è la dichiarazione degli URL per questo progetto. |
| 155 | Consideralo come un "indice" del tuo sito realizzato con Django. |
| 156 | |
| 157 | .. |
| 158 | These files are: |
| 159 | |
| 160 | * ``__init__.py``: An empty file that tells Python that this directory |
| 161 | should be considered a Python package. (Read `more about packages`_ in the |
| 162 | official Python docs if you're a Python beginner.) |
| 163 | * ``manage.py``: A command-line utility that lets you interact with this |
| 164 | Django project in various ways. |
| 165 | * ``settings.py``: Settings/configuration for this Django project. |
| 166 | * ``urls.py``: The URL declarations for this Django project; a "table of |
| 167 | contents" of your Django-powered site. |
| 168 | |
| 169 | .. |
| 170 | .. _more about packages: http://docs.python.org/tut/node8.html#packages |
| 171 | |
| 172 | .. _ulteriori informazioni sui pacchetti: http://docs.python.org/tut/node8.html#packages |
| 173 | |
| 174 | Il server di sviluppo |
| 175 | --------------------- |
| 176 | |
| 177 | .. |
| 178 | The development server |
| 179 | ---------------------- |
| 180 | |
| 181 | Verifichiamo che il nostro progetto sia funzionante. Cambia la directory |
| 182 | corrente in ``mysite`` ed esegui il comando ``python manage.py runserver``. |
| 183 | Ti apparirà un output simile a:: |
| 184 | |
| 185 | Validating models... |
| 186 | 0 errors found. |
| 187 | |
| 188 | Django version 0.95, using settings 'mysite.settings' |
| 189 | Development server is running at http://127.0.0.1:8000/ |
| 190 | Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows). |
| 191 | |
| 192 | .. |
| 193 | Let's verify this worked. Change into the ``mysite`` directory, if you |
| 194 | haven't already, and run the command ``python manage.py runserver``. You'll see |
| 195 | the following output on the command line:: |
| 196 | |
| 197 | Validating models... |
| 198 | 0 errors found. |
| 199 | |
| 200 | Django version 0.95, using settings 'mysite.settings' |
| 201 | Development server is running at http://127.0.0.1:8000/ |
| 202 | Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows). |
| 203 | |
| 204 | Hai avviato il server Web di sviluppo scritto in Python a corredo con Django. |
| 205 | E' stato incluso per darti la possibilità di sviluppare rapidamente senza dover |
| 206 | configurare subito un server di produzione come Apache, dandoti la possibilità di |
| 207 | posticipare questo momento a quando dovrai andare in produzione. |
| 208 | |
| 209 | .. |
| 210 | You've started the Django development server, a lightweight Web server written |
| 211 | purely in Python. We've included this with Django so you can develop things |
| 212 | rapidly, without having to deal with configuring a production server -- such as |
| 213 | Apache -- until you're ready for production. |
| 214 | |
| 215 | E' una buona occasione per dirti di NON usare questo server in nessuna |
| 216 | situazione che possa assomigliare vagamente a uno scenario di produzione. E' |
| 217 | stato concepito unicamente per essere usato in fase di sviluppo. (In effetti il |
| 218 | nostro impegno è orientato al campo dei framework Web, noi dei Web server). |
| 219 | |
| 220 | .. |
| 221 | Now's a good time to note: DON'T use this server in anything resembling a |
| 222 | production environment. It's intended only for use while developing. (We're in |
| 223 | the business of making Web frameworks, not Web servers.) |
| 224 | |
| 225 | Ora che il server è in funzione, accedi all'indirizzo http://127.0.0.1:8000/. |
| 226 | Vedrai una pagina di benvenuto di un gradevole color blu pastello. Funziona! |
| 227 | |
| 228 | .. |
| 229 | Now that the server's running, visit http://127.0.0.1:8000/ with your Web |
| 230 | browser. You'll see a "Welcome to Django" page, in pleasant, light-blue pastel. |
| 231 | It worked! |
| 232 | |
| 233 | .. admonition:: Cambiare la porta |
| 234 | |
| 235 | Di default, il comando ``runserver`` pone in ascolto il server di sviluppo |
| 236 | sulla porta 8000. Se vuoi cambiare questo parametro, passa il nuovo valore |
| 237 | dalla riga di comando. Ad esempio, se vuoi che il server resti in |
| 238 | esecuzione sulla porta 8080:: |
| 239 | |
| 240 | python manage.py runserver 8080 |
| 241 | |
| 242 | Informazioni dettagliate sul server di sviluppo sono disponibili nella |
| 243 | `documentazione di django-admin.py`_. |
| 244 | |
| 245 | .. |
| 246 | .. admonition:: Changing the port |
| 247 | |
| 248 | By default, the ``runserver`` command starts the development server on port |
| 249 | 8000. If you want to change the server's port, pass it as a command-line |
| 250 | argument. For instance, this command starts the server on port 8080:: |
| 251 | |
| 252 | python manage.py runserver 8080 |
| 253 | |
| 254 | Full docs for the development server are at `django-admin documentation`_. |
| 255 | |
| 256 | .. |
| 257 | .. _django-admin documentation: http://www.djangoproject.com/documentation/django_admin/ |
| 258 | |
| 259 | .. _documentazione di django-admin.py: http://www.djangoproject.com/documentation/django_admin/ |
| 260 | |
| 261 | Configurare il database |
| 262 | ----------------------- |
| 263 | |
| 264 | .. |
| 265 | Database setup |
| 266 | -------------- |
| 267 | |
| 268 | Ora modifica il file ``settings.py``. Si tratta di un normale modulo Python |
| 269 | contenente variabili a livello di modulo usate per la configurazione di |
| 270 | Django. Le impostazioni sul database avvengono mediante questi parametri: |
| 271 | |
| 272 | * ``DATABASE_ENGINE`` -- 'postgresql', 'mysql' or 'sqlite3'. Ne sono |
| 273 | previsti altri per il futuro. |
| 274 | * ``DATABASE_NAME`` -- è il nome del databse o il percorso completo |
| 275 | (assoluto) del file che contiene i dati se stai usando SQLite. |
| 276 | * ``DATABASE_USER`` -- è il nome dell'utente che gestisce il database (non |
| 277 | usato con SQLite). |
| 278 | * ``DATABASE_PASSWORD`` -- è la password relativa all'utente del punto |
| 279 | precedente (non usato con SQLite). |
| 280 | * ``DATABASE_HOST`` -- è l'host su cui risiede il database. Se il database |
| 281 | è ospitato sulla stessa macchina che fa girare Django lascia una stringa |
| 282 | vuota (non usato con SQLite). |
| 283 | |
| 284 | .. |
| 285 | Now, edit ``settings.py``. It's a normal Python module with module-level |
| 286 | variables representing Django settings. Change these settings to match your |
| 287 | database's connection parameters: |
| 288 | |
| 289 | * ``DATABASE_ENGINE`` -- Either 'postgresql', 'mysql' or 'sqlite3'. |
| 290 | More coming soon. |
| 291 | * ``DATABASE_NAME`` -- The name of your database, or the full (absolute) |
| 292 | path to the database file if you're using SQLite. |
| 293 | * ``DATABASE_USER`` -- Your database username (not used for SQLite). |
| 294 | * ``DATABASE_PASSWORD`` -- Your database password (not used for SQLite). |
| 295 | * ``DATABASE_HOST`` -- The host your database is on. Leave this as an |
| 296 | empty string if your database server is on the same physical machine |
| 297 | (not used for SQLite). |
| 298 | |
| 299 | .. admonition:: Note |
| 300 | |
| 301 | Se stai usando PostgreSQL o MySQL assicurati di aver creato un database. |
| 302 | In caso contrario fallo ora usando la sintassi "``CREATE DATABASE |
| 303 | database_name;``" dal prompt interattivo del database in uso. |
| 304 | |
| 305 | .. |
| 306 | .. admonition:: Note |
| 307 | |
| 308 | If you're using PostgreSQL or MySQL, make sure you've created a database by |
| 309 | this point. Do that with "``CREATE DATABASE database_name;``" within your |
| 310 | database's interactive prompt. |
| 311 | |
| 312 | Modificando ``settings.py`` probabilmente avrai notato l'impostazione |
| 313 | ``INSTALLED_APPS`` verso la fine del file. Questa variabile contiene i nomi di |
| 314 | tutte le applicazioni Django attive in questa istanza di Django. Ogni |
| 315 | applicazione può essere usata in più di un progetto, e se sei interessato puoi |
| 316 | pacchettizzarle e distribuirle ad altre persone affinché le usino nei loro |
| 317 | progetti. |
| 318 | |
| 319 | .. |
| 320 | While you're editing ``settings.py``, take note of the ``INSTALLED_APPS`` |
| 321 | setting towards the bottom of the file. That variable holds the names of all |
| 322 | Django applications that are activated in this Django instance. Apps can be |
| 323 | used in multiple projects, and you can package and distribute them for use |
| 324 | by others in their projects. |
| 325 | |
| 326 | Le applicazioni predefinite in ``INSTALLED_APPS`` sono: |
| 327 | |
| 328 | * ``django.contrib.auth``: un sistema di autenticazione. |
| 329 | * ``django.contrib.contenttypes``: un framework per i tipi di contenuto. |
| 330 | * ``django.contrib.sessions``: un framework per le sessioni. |
| 331 | * ``django.contrib.sites``: un framework per gestire più di un sito con una |
| 332 | sola installazione di Django. |
| 333 | |
| 334 | .. |
| 335 | By default, ``INSTALLED_APPS`` contains the following apps, all of which come |
| 336 | with Django: |
| 337 | |
| 338 | * ``django.contrib.auth`` -- An authentication system. |
| 339 | * ``django.contrib.contenttypes`` -- A framework for content types. |
| 340 | * ``django.contrib.sessions`` -- A session framework. |
| 341 | * ``django.contrib.sites`` -- A framework for managing multiple sites |
| 342 | with one Django installation. |
| 343 | |
| 344 | Queste applicazioni sono incluse per convenienza e si adattano ai casi d'uso |
| 345 | più comuni. |
| 346 | |
| 347 | .. |
| 348 | These applications are included by default as a convenience for the common |
| 349 | case. |
| 350 | |
| 351 | Ognuna di esse richiede almeno una tabella del database, quindi prima di |
| 352 | poterne fare uso è necessario creare le tabelle necessarie. A questo scopo |
| 353 | esiste il comando:: |
| 354 | |
| 355 | python manage.py syncdb |
| 356 | |
| 357 | .. |
| 358 | Each of these applications makes use of at least one database table, though, |
| 359 | so we need to create the tables in the database before we can use them. To do |
| 360 | that, run the following command:: |
| 361 | |
| 362 | python manage.py syncdb |
| 363 | |
| 364 | ``syncdb`` crea le tabelle necessarie alle applicazioni elencate in |
| 365 | ``INSTALLED_APPS`` usando i parametri relativi al database che hai specificato |
| 366 | in ``settings.py``. Per ogni tabella che viene creata comparirà un messaggio, |
| 367 | ed inoltre ti verrà chiesto se intendi creare un account come superutente per |
| 368 | il sistema di autenticazione. Procedi creandolo. |
| 369 | |
| 370 | .. |
| 371 | The ``syncdb`` command looks at the ``INSTALLED_APPS`` setting and creates any |
| 372 | necessary database tables according to the database settings in your |
| 373 | ``settings.py`` file. You'll see a message for each database table it creates, |
| 374 | and you'll get a prompt asking you if you'd like to create a superuser account |
| 375 | for the authentication system. Go ahead and do that. |
| 376 | |
| 377 | Se sei interessato a sapere quali tabelle sono state create puoi usare il |
| 378 | client interattivo a corredo con il database che stai usando e scrivere``\dt`` |
| 379 | (PostgreSQL), ``SHOW TABLES;`` (MySQL), oppure ``.schema`` (SQLite). |
| 380 | |
| 381 | .. |
| 382 | If you're interested, run the command-line client for your database and type |
| 383 | ``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), or ``.schema`` (SQLite) to |
| 384 | display the tables Django created. |
| 385 | |
| 386 | .. admonition:: Per i minimalisti |
| 387 | |
| 388 | Come abbiamo detto in precedenza, le applicazioni predefinite sono adeguate |
| 389 | nei casi di utilizzo più comuni, non in tutti. Se non ti serve nessuna di |
| 390 | queste applicazioni puoi commentare o eliminare senza problemi la riga |
| 391 | corrispondente a ciò che non sei interessatoin ``INSTALLED_APPS``, purché |
| 392 | questo avvenga prima di eseguire ``syncdb``. ``syncdb`` crea soltanto le |
| 393 | tabelle per le applicazioni elencate in ``INSTALLED_APPS``. |
| 394 | |
| 395 | .. |
| 396 | .. admonition:: For the minimalists |
| 397 | |
| 398 | Like we said above, the default applications are included for the common |
| 399 | case, but not everybody needs them. If you don't need any or all of them, |
| 400 | feel free to comment-out or delete the appropriate line(s) from |
| 401 | ``INSTALLED_APPS`` before running ``syncdb``. The ``syncdb`` command will |
| 402 | only create tables for apps in ``INSTALLED_APPS``. |
| 403 | |
| 404 | Creare i modelli |
| 405 | ================ |
| 406 | |
| 407 | .. |
| 408 | Creating models |
| 409 | =============== |
| 410 | |
| 411 | Ora l'environment lavorativo - il "progetto" - è stato configurato, sei pronto |
| 412 | per cominciare lo sviluppo vero e proprio. |
| 413 | |
| 414 | .. |
| 415 | Now that your environment -- a "project" -- is set up, you're set to start |
| 416 | doing work. |
| 417 | |
| 418 | Ogni applicazione che scrivi per Django consiste in un pacchetto Python posto |
| 419 | da qualche parte nel `Python path`_, scritto seguendo alcune convenzioni. |
| 420 | Django fornisce un'utility che genera automaticamente la struttura base delle |
| 421 | directory di un'applicazione, così potrai focalizzare l'attenzione sul codice |
| 422 | che scriverai invece che creare directory. |
| 423 | |
| 424 | .. |
| 425 | Each application you write in Django consists of a Python package, somewhere |
| 426 | on your `Python path`_, that follows a certain convention. Django comes with a |
| 427 | utility that automatically generates the basic directory structure of an app, |
| 428 | so you can focus on writing code rather than creating directories. |
| 429 | |
| 430 | .. admonition: Progetti e applicazioni |
| 431 | |
| 432 | Qual è la differenza tra un progetto e un'applicazione? Quest'ultima è |
| 433 | un'applicazione Web con una finalità di utilizzo pratica, ad esempio può |
| 434 | essere un sistema per la gestione di blog, una base di dati pubblicamente |
| 435 | consultabile oppure una semplice applicazione per sondaggi. Un progetto è |
| 436 | l'insieme di configurazione e applicazioni relativo a un particolare sito |
| 437 | Web. Un progetto può contenere più di una applicazione. Un'applicazione può |
| 438 | comparire in più di un progetto. |
| 439 | |
| 440 | .. |
| 441 | .. admonition:: Projects vs. apps |
| 442 | |
| 443 | What's the difference between a project and an app? An app is a Web |
| 444 | application that does something -- e.g., a weblog system, a database of |
| 445 | public records or a simple poll app. A project is a collection of |
| 446 | configuration and apps for a particular Web site. A project can contain |
| 447 | multiple apps. An app can be in multiple projects. |
| 448 | |
| 449 | In questo tutorial l'applicazione verrà creata nella directory ``mysite``, per |
| 450 | semplicità. Come conseguenza, l'applicazione sarà vincolata al progetto, e il |
| 451 | codice Python all'interno dell'applicazione farà riferimento a |
| 452 | ``mysite.polls``. Nel seguito di questo tutorial discuteremo come slegare |
| 453 | le applicazioni per poterle distribuire. |
| 454 | |
| 455 | .. |
| 456 | In this tutorial, we'll create our poll app in the ``mysite`` directory, |
| 457 | for simplicity. As a consequence, the app will be coupled to the project -- |
| 458 | that is, Python code within the poll app will refer to ``mysite.polls``. |
| 459 | Later in this tutorial, we'll discuss decoupling your apps for distribution. |
| 460 | |
| 461 | Per creare l'applicazione assicurati di essere nella directory ``mysite`` e |
| 462 | digita:: |
| 463 | |
| 464 | python manage.py startapp polls |
| 465 | |
| 466 | .. |
| 467 | To create your app, make sure you're in the ``mysite`` directory and type |
| 468 | this command:: |
| 469 | |
| 470 | python manage.py startapp polls |
| 471 | |
| 472 | Verrà creata una directory ``polls`` così organizzata:: |
| 473 | |
| 474 | polls/ |
| 475 | __init__.py |
| 476 | models.py |
| 477 | views.py |
| 478 | |
| 479 | .. |
| 480 | That'll create a directory ``polls``, which is laid out like this:: |
| 481 | |
| 482 | polls/ |
| 483 | __init__.py |
| 484 | models.py |
| 485 | views.py |
| 486 | |
| 487 | Questa struttura ospiterà l'applicazione. |
| 488 | |
| 489 | .. This directory structure will house the poll application. |
| 490 | |
| 491 | Il primo passo nella scrittura di un'applicazione Web con Django consiste nel |
| 492 | definirne i modelli, ovvero sostanzialmente lo schema del database ed alcuni |
| 493 | metadati aggiuntivi. |
| 494 | |
| 495 | .. |
| 496 | The first step in writing a database Web app in Django is to define your models |
| 497 | -- essentially, your database layout, with additional metadata. |
| 498 | |
| 499 | .. admonition:: Philosophy |
| 500 | |
| 501 | Un modello è l'unica e definitiva sorgente di accesso ai tuoi dati. |
| 502 | Contiene i campi essenziali e i principali comportamenti in merito ai dati |
| 503 | che stai memorizzando. Django segue il `principio DRY`_. L'obiettivo è |
| 504 | quello di definire il modello dei dati in un posto ben definito ed |
| 505 | automaticamente derivare ciò che serve esattamente da lì. |
| 506 | |
| 507 | .. |
| 508 | .. admonition:: Philosophy |
| 509 | |
| 510 | A model is the single, definitive source of data about your |
| 511 | data. It contains the essential fields and behaviors of the data you're |
| 512 | storing. Django follows the `DRY Principle`_. The goal is to define your |
| 513 | data model in one place and automatically derive things from it. |
| 514 | |
| 515 | Nella nostra semplice applicazione creeremo due modelli: polls (sondaggi) e |
| 516 | choices (scelte). Un sondaggio è caratterizzato da una domanda e da una data di |
| 517 | pubblicazione. Una scelta invece da un testo e un contatore di voti. Ogni |
| 518 | scelta è associata ad un sondaggio. |
| 519 | |
| 520 | .. |
| 521 | In our simple poll app, we'll create two models: polls and choices. A poll has |
| 522 | a question and a publication date. A choice has two fields: the text of the |
| 523 | choice and a vote tally. Each choice is associated with a poll. |
| 524 | |
| 525 | Questi concetti sono tradotti in semplici classi Python. |
| 526 | Modifica il file ``polls/models.py`` in modo che il contenuto sia:: |
| 527 | |
| 528 | from django.db import models |
| 529 | |
| 530 | class Poll(models.Model): |
| 531 | question = models.CharField(maxlength=200) |
| 532 | pub_date = models.DateTimeField('date published') |
| 533 | |
| 534 | class Choice(models.Model): |
| 535 | poll = models.ForeignKey(Poll) |
| 536 | choice = models.CharField(maxlength=200) |
| 537 | votes = models.IntegerField() |
| 538 | |
| 539 | .. |
| 540 | These concepts are represented by simple Python classes. Edit the |
| 541 | ``polls/models.py`` file so it looks like this:: |
| 542 | |
| 543 | from django.db import models |
| 544 | |
| 545 | class Poll(models.Model): |
| 546 | question = models.CharField(maxlength=200) |
| 547 | pub_date = models.DateTimeField('date published') |
| 548 | |
| 549 | class Choice(models.Model): |
| 550 | poll = models.ForeignKey(Poll) |
| 551 | choice = models.CharField(maxlength=200) |
| 552 | votes = models.IntegerField() |
| 553 | |
| 554 | Il codice è facilmente comprensibile. Ogni modello è espresso da una |
| 555 | sottoclasse di ``django.db.models.Model``. Per ogni modello sono specificate |
| 556 | alcune variabili di classe, ognuna delle quali rappresenta, all'interno del |
| 557 | modello, un campo del database. |
| 558 | |
| 559 | .. |
| 560 | The code is straightforward. Each model is represented by a class that |
| 561 | subclasses ``django.db.models.Model``. Each model has a number of class |
| 562 | variables, each of which represents a database field in the model. |
| 563 | |
| 564 | Ogni campo è rappresentato da un'istanza della classe ``models.*Field``, ad |
| 565 | esempio ``models.CharField`` per campi contenenti caratteri e |
| 566 | ``models.DateTimeField`` per date e orari. In questo modo Django può risalire ai |
| 567 | tipi di dato che vengono mantenuti nei diversi campi. |
| 568 | |
| 569 | .. |
| 570 | Each field is represented by an instance of a ``models.*Field`` class -- e.g., |
| 571 | ``models.CharField`` for character fields and ``models.DateTimeField`` for |
| 572 | datetimes. This tells Django what type of data each field holds. |
| 573 | |
| 574 | Il nome di ciascuna istanza ``models.*Field`` (ad esempio, ``question`` o |
| 575 | ``pub_date``) è il nome del campo in formato machine-readable (riconoscibile |
| 576 | dalla macchina). Questo nome verrà usato da te per scrivere il codice Python e |
| 577 | dal database per assegnare un nome alla colonna. |
| 578 | |
| 579 | .. |
| 580 | The name of each ``models.*Field`` instance (e.g. ``question`` or ``pub_date`` ) |
| 581 | is the field's name, in machine-friendly format. You'll use this value in your |
| 582 | Python code, and your database will use it as the column name. |
| 583 | |
| 584 | Per specificare un nome human-readable (riconoscibile dagli esseri umani) puoi |
| 585 | dichiarare, per i vari campi, un primo argomento posizionale facoltativo. |
| 586 | Questo valore viene usato anche in un paio di situazioni orientate |
| 587 | all'introspezione, ed ha il vantaggio di migliorare la documentazione. Quando |
| 588 | non è precisato un nome human-readable Django userà il nome machine-readable. |
| 589 | In questo esempio abbiamo definito solamente un nome human-readable: in |
| 590 | ``Poll.pub_date``. Per tutti gli altri campi di questo modello verrà usato il |
| 591 | nome machine-readable. |
| 592 | |
| 593 | .. |
| 594 | You can use an optional first positional argument to a ``Field`` to designate a |
| 595 | human-readable name. That's used in a couple of introspective parts of Django, |
| 596 | and it doubles as documentation. If this field isn't provided, Django will use |
| 597 | the machine-readable name. In this example, we've only defined a human-readable |
| 598 | name for ``Poll.pub_date``. For all other fields in this model, the field's |
| 599 | machine-readable name will suffice as its human-readable name. |
| 600 | |
| 601 | Alcune classi ``Field`` richiedono obbligatoriamente alcune informazioni |
| 602 | aggiuntive. Ad esempio ``CharField`` richiede che venga precisata la lunghezza |
| 603 | massima di caratteri, ``maxlength``. Questo valore non viene usato soltanto |
| 604 | nello schema del database, ma anche nella validazione, come vedremo tra poco. |
| 605 | |
| 606 | .. |
| 607 | Some ``Field`` classes have required elements. ``CharField``, for example, |
| 608 | requires that you give it a ``maxlength``. That's used not only in the database |
| 609 | schema, but in validation, as we'll soon see. |
| 610 | |
| 611 | A questo punto puoi osservare come usando ``models.ForeignKey`` viene definita |
| 612 | una relazione. In questo modo Django viene informato che ogni scelta (Choice) è |
| 613 | associata ad un singolo sondaggio (Poll). Django riconosce le relazioni più |
| 614 | comunemente utilizzate: molti-a-uno, molti-a-molti, uno-a-uno. |
| 615 | |
| 616 | .. |
| 617 | Finally, note a relationship is defined, using ``models.ForeignKey``. That tells |
| 618 | Django each Choice is related to a single Poll. Django supports all the common |
| 619 | database relationships: many-to-ones, many-to-manys and one-to-ones. |
| 620 | |
| 621 | .. _`Python path`: http://docs.python.org/tut/node8.html#SECTION008110000000000000000 |
| 622 | .. _principio DRY: http://c2.com/cgi/wiki?DontRepeatYourself |
| 623 | |
| 624 | .. |
| 625 | .. _`Python path`: http://docs.python.org/tut/node8.html#SECTION008110000000000000000 |
| 626 | .. _DRY Principle: http://c2.com/cgi/wiki?DontRepeatYourself |
| 627 | |
| 628 | Attivare i modelli |
| 629 | ================== |
| 630 | |
| 631 | .. |
| 632 | Activating models |
| 633 | ================= |
| 634 | |
| 635 | Il breve frammento di codice che hai appena scritto fornisce molte |
| 636 | informazioni, che Django utilizza per: |
| 637 | |
| 638 | * creare lo schema del database (i comandi ``CREATE TABLE``) per |
| 639 | l'applicazione corrente; |
| 640 | * creare un insieme di API Python per accedere agli oggetti Poll e Choice. |
| 641 | |
| 642 | .. |
| 643 | That small bit of model code gives Django a lot of information. With it, Django |
| 644 | is able to: |
| 645 | |
| 646 | * Create a database schema (``CREATE TABLE`` statements) for this app. |
| 647 | * Create a Python database-access API for accessing Poll and Choice objects. |
| 648 | |
| 649 | Prima che Django possa procedere però è necessario informare il progetto che |
| 650 | l'applicazione ``polls`` è installata. |
| 651 | |
| 652 | .. But first we need to tell our project that the ``polls`` app is installed. |
| 653 | |
| 654 | .. admonition:: Philosophy |
| 655 | |
| 656 | Le applicazioni per Django sono modulari: puoi installarle in più progetti |
| 657 | e, poiché non risultano legate ad un particolare progetto, puoi |
| 658 | distribuirle. |
| 659 | |
| 660 | .. |
| 661 | .. admonition:: Philosophy |
| 662 | |
| 663 | Django apps are "pluggable": You can use an app in multiple projects, and |
| 664 | you can distribute apps, because they don't have to be tied to a given |
| 665 | Django installation. |
| 666 | |
| 667 | Modifica nuovamente il file ``settings.py`` e aggiungi la stringa |
| 668 | ``'mysite.polls'`` a ``INSTALLED_APPS``. Questo il risultato:: |
| 669 | |
| 670 | INSTALLED_APPS = ( |
| 671 | 'django.contrib.auth', |
| 672 | 'django.contrib.contenttypes', |
| 673 | 'django.contrib.sessions', |
| 674 | 'django.contrib.sites', |
| 675 | 'mysite.polls' |
| 676 | ) |
| 677 | |
| 678 | .. |
| 679 | Edit the ``settings.py`` file again, and change the ``INSTALLED_APPS`` setting |
| 680 | to include the string ``'mysite.polls'``. So it'll look like this:: |
| 681 | |
| 682 | INSTALLED_APPS = ( |
| 683 | 'django.contrib.auth', |
| 684 | 'django.contrib.contenttypes', |
| 685 | 'django.contrib.sessions', |
| 686 | 'django.contrib.sites', |
| 687 | 'mysite.polls' |
| 688 | ) |
| 689 | |
| 690 | Ora Django è consapevole che ``mysite`` contiene l'applicazione ``polls`` e tu |
| 691 | puoi ottenere informazioni sull'SQL con questo comando:: |
| 692 | |
| 693 | python manage.py sql polls |
| 694 | |
| 695 | .. |
| 696 | Now Django knows ``mysite`` includes the ``polls`` app. Let's run another command:: |
| 697 | |
| 698 | python manage.py sql polls |
| 699 | |
| 700 | Dovrebbero comparirti le istruzioni SQL CREATE TABLE relative all'applicazione |
| 701 | polls:: |
| 702 | |
| 703 | BEGIN; |
| 704 | CREATE TABLE "polls_poll" ( |
| 705 | "id" serial NOT NULL PRIMARY KEY, |
| 706 | "question" varchar(200) NOT NULL, |
| 707 | "pub_date" timestamp with time zone NOT NULL |
| 708 | ); |
| 709 | CREATE TABLE "polls_choice" ( |
| 710 | "id" serial NOT NULL PRIMARY KEY, |
| 711 | "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"), |
| 712 | "choice" varchar(200) NOT NULL, |
| 713 | "votes" integer NOT NULL |
| 714 | ); |
| 715 | COMMIT; |
| 716 | |
| 717 | .. |
| 718 | You should see the following (the CREATE TABLE SQL statements for the polls app):: |
| 719 | |
| 720 | BEGIN; |
| 721 | CREATE TABLE "polls_poll" ( |
| 722 | "id" serial NOT NULL PRIMARY KEY, |
| 723 | "question" varchar(200) NOT NULL, |
| 724 | "pub_date" timestamp with time zone NOT NULL |
| 725 | ); |
| 726 | CREATE TABLE "polls_choice" ( |
| 727 | "id" serial NOT NULL PRIMARY KEY, |
| 728 | "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"), |
| 729 | "choice" varchar(200) NOT NULL, |
| 730 | "votes" integer NOT NULL |
| 731 | ); |
| 732 | COMMIT; |
| 733 | |
| 734 | Dovresti osservare che: |
| 735 | |
| 736 | * i nomi delle tabelle vengono generati automaticamente combinando il nome |
| 737 | dell'applicazione (``polls``) ed il nome del modello in lettere |
| 738 | minuscole, ``poll`` e ``choice``. (Puoi personalizzare questa |
| 739 | impostazione). |
| 740 | |
| 741 | * le chiavi primarie (gli ID) sono inserite automaticamente. (Puoi |
| 742 | personalizzare anche questa impostazione). |
| 743 | |
| 744 | * come convenzione, al nome delle chiavi esterne viene accodato il suffisso |
| 745 | ``"_id"``. Naturalmente puoi personalizzare anche questo. |
| 746 | |
| 747 | * la sintassi per la relazione di chiave esterna è coerente con il database |
| 748 | in uso, perciò automaticamente verrà scelto ``auto_increment`` (MySQL), |
| 749 | ``serial`` (PostgreSQL) o ``integer primary key`` (SQLite). Lo stesso |
| 750 | principio viene adottato per quotare il nome dei campi, ad esempio, |
| 751 | usando i doppi apici o i singoli apici. L'autore di questo documento usa |
| 752 | PostgreSQL, perciò il risultato degli esempi è espresso con la sintassi |
| 753 | di PostgreSQL. |
| 754 | |
| 755 | * il comando `sql` non esegue il codice SQL sul database, ma si limita a |
| 756 | presentarlo a video mostrando come Django ha costruito i comandi per la |
| 757 | creazione del database. Se ti dovesse servire potrai copiare questo |
| 758 | output ed incollarlo dal programma client di accesso al database. |
| 759 | Tuttavia, come vedrai tra poco Django offre un metodo molto più semplice |
| 760 | per l'esecuzione dei comandi SQL sul database. |
| 761 | |
| 762 | .. |
| 763 | Note the following: |
| 764 | |
| 765 | * Table names are automatically generated by combining the name of the app |
| 766 | (``polls``) and the lowercase name of the model -- ``poll`` and |
| 767 | ``choice``. (You can override this behavior.) |
| 768 | |
| 769 | * Primary keys (IDs) are added automatically. (You can override this, too.) |
| 770 | |
| 771 | * By convention, Django appends ``"_id"`` to the foreign key field name. |
| 772 | Yes, you can override this, as well. |
| 773 | |
| 774 | * The foreign key relationship is made explicit by a ``REFERENCES`` statement. |
| 775 | |
| 776 | * It's tailored to the database you're using, so database-specific field |
| 777 | types such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or |
| 778 | ``integer primary key`` (SQLite) are handled for you automatically. Same |
| 779 | goes for quoting of field names -- e.g., using double quotes or single |
| 780 | quotes. The author of this tutorial runs PostgreSQL, so the example |
| 781 | output is in PostgreSQL syntax. |
| 782 | |
| 783 | * The `sql` command doesn't actually run the SQL in your database - it just |
| 784 | prints it to the screen so that you can see what SQL Django thinks is required. |
| 785 | If you wanted to, you could copy and paste this SQL into your database prompt. |
| 786 | However, as we will see shortly, Django provides an easier way of committing |
| 787 | the SQL to the database. |
| 788 | |
| 789 | Questi sono altri comandi che puoi eseguire: |
| 790 | * ``python manage.py validate polls``: verifica la presenza di errori nei |
| 791 | modelli. |
| 792 | |
| 793 | * ``python manage.py sqlinitialdata polls``: mostra i dati iniziali |
| 794 | richiesti per il framework di amministrazione di Django e per i tuoi |
| 795 | modelli. |
| 796 | |
| 797 | * ``python manage.py sqlclear polls``: mostra i comandi ``DROP TABLE`` |
| 798 | per questa applicazione, sulla base delle tabelle già esistenti nel |
| 799 | database (se ve ne fossero). |
| 800 | |
| 801 | * ``python manage.py sqlindexes polls``: mostra i comandi ``CREATE INDEX`` |
| 802 | per questa applicazione. |
| 803 | |
| 804 | * ``python manage.py sqlall polls``: è la combinazione dei comandi 'sql', |
| 805 | 'sqlinitialdata' e 'sqlindexes'. |
| 806 | |
| 807 | .. |
| 808 | If you're interested, also run the following commands: |
| 809 | * ``python manage.py validate polls`` -- Checks for any errors in the |
| 810 | construction of your models. |
| 811 | |
| 812 | * ``python manage.py sqlinitialdata polls`` -- Outputs any initial data |
| 813 | required for Django's admin framework and your models. |
| 814 | |
| 815 | * ``python manage.py sqlclear polls`` -- Outputs the necessary ``DROP |
| 816 | TABLE`` statements for this app, according to which tables already exist |
| 817 | in your database (if any). |
| 818 | |
| 819 | * ``python manage.py sqlindexes polls`` -- Outputs the ``CREATE INDEX`` |
| 820 | statements for this app. |
| 821 | |
| 822 | * ``python manage.py sqlall polls`` -- A combination of all the SQL from |
| 823 | the 'sql', 'sqlinitialdata', and 'sqlindexes' commands. |
| 824 | |
| 825 | L'analisi dell'output di questi comandi può aiutarti a capire che cosa |
| 826 | succederà dietro le quinte. |
| 827 | |
| 828 | .. |
| 829 | Looking at the output of those commands can help you understand what's actually |
| 830 | happening under the hood. |
| 831 | |
| 832 | Ora crea le tabelle relative ai modelli dell'applicazione eseguendo ancora una |
| 833 | volta ``syncdb``:: |
| 834 | |
| 835 | python manage.py syncdb |
| 836 | |
| 837 | .. |
| 838 | Now, run ``syncdb`` again to create those model tables in your database:: |
| 839 | |
| 840 | python manage.py syncdb |
| 841 | |
| 842 | Il comando ``syncdb`` manda in esecuzione i comandi sql generati da 'sqlall' |
| 843 | relativamente a tutte le applicazioni in ``INSTALLED_APPS`` che già non siano |
| 844 | esistenti nel database. Il risultato è la creazione di tutte le tabelle, dei |
| 845 | dati iniziali e degli indici di tutte le applicazioni che hai aggiunto al |
| 846 | progetto dall'ultima volta che syncdb è stato lanciato. Puoi invocare |
| 847 | ``syncdb`` tutte le volte che vuoi, e soltanto le tabelle che ancora non |
| 848 | esistono verranno create. |
| 849 | |
| 850 | .. |
| 851 | The ``syncdb`` command runs the sql from 'sqlall' on your database for all apps |
| 852 | in ``INSTALLED_APPS`` that don't already exist in your database. This creates |
| 853 | all the tables, initial data and indexes for any apps you have added to your |
| 854 | project since the last time you ran syncdb. ``syncdb`` can be called as often |
| 855 | as you like, and it will only ever create the tables that don't exist. |
| 856 | |
| 857 | Per avere informazioni complete sulle possibilità offerte dall'utility |
| 858 | ``manage.py`` consulta la `documentazione su django-admin.py`_. |
| 859 | |
| 860 | .. |
| 861 | Read the `django-admin.py documentation`_ for full information on what the |
| 862 | ``manage.py`` utility can do. |
| 863 | |
| 864 | .. |
| 865 | .. _django-admin.py documentation: http://www.djangoproject.com/documentation/django_admin/ |
| 866 | |
| 867 | .. _documentazione su django-admin.py: http://www.djangoproject.com/documentation/django_admin/ |
| 868 | |
| 869 | Esperimenti con le API |
| 870 | ====================== |
| 871 | |
| 872 | .. |
| 873 | Playing with the API |
| 874 | ==================== |
| 875 | |
| 876 | Ora avvia la shell Python interattiva e fai qualche prova con l'insieme di API |
| 877 | che Django mette a disposizione. Per invocare la shell usa questo comando:: |
| 878 | |
| 879 | python manage.py shell |
| 880 | |
| 881 | .. |
| 882 | Now, let's hop into the interactive Python shell and play around with the free |
| 883 | API Django gives you. To invoke the Python shell, use this command:: |
| 884 | |
| 885 | python manage.py shell |
| 886 | |
| 887 | Ti proponiamo questa sintassi invece di digitare semplicemente "python" perché |
| 888 | usando ``manage.py`` le impostazioni di environment del progetto verrà impostato |
| 889 | senza che tu debba fare nessuna operazione. "Impostare l'environment del progetto" |
| 890 | coinvolge due operazioni: |
| 891 | |
| 892 | * aggiungere ``mysite`` a ``sys.path``. Per migliorare la flessibilità, |
| 893 | diverse parti di Django usano la notazione puntata (dotted notation) |
| 894 | quando si riferiscono a progetti (ad esempio, ``'mysite.polls.models'``). |
| 895 | Generalmente, perché questo approccio funzioni, il pacchetto ``mysite`` |
| 896 | deve essere elencato in ``sys.path``. |
| 897 | |
| 898 | * impostare la variabile di environment ``DJANGO_SETTINGS_MODULE`` affinché |
| 899 | Django sia in grado di accedere al file ``settings.py``. |
| 900 | |
| 901 | .. |
| 902 | We're using this instead of simply typing "python", because ``manage.py`` sets |
| 903 | up the project's environment for you. "Setting up the environment" involves two |
| 904 | things: |
| 905 | |
| 906 | * Putting ``mysite`` on ``sys.path``. For flexibility, several pieces of |
| 907 | Django refer to projects in Python dotted-path notation (e.g. |
| 908 | ``'mysite.polls.models'``). In order for this to work, the |
| 909 | ``mysite`` package has to be on ``sys.path``. |
| 910 | |
| 911 | We've already seen one example of this: the ``INSTALLED_APPS`` setting is |
| 912 | a list of packages in dotted-path notation. |
| 913 | |
| 914 | * Setting the ``DJANGO_SETTINGS_MODULE`` environment variable, which gives |
| 915 | Django the path to your ``settings.py`` file. |
| 916 | |
| 917 | .. admonition:: Bypassare manage.py |
| 918 | |
| 919 | Se non intendi usare ``manage.py`` puoi decidere di farlo senza problemi. |
| 920 | Assicurati però che ``mysite`` sia al livello più alto del Python path |
| 921 | (verifica che il comando ``import mysite`` non dia errori) e imposta il |
| 922 | valore ``mysite.settings`` per la variabile ``DJANGO_SETTINGS_MODULE``. |
| 923 | |
| 924 | Per ulteriori informazioni su quanto detto consulta la `documentazione su |
| 925 | django-admin.py`_. |
| 926 | |
| 927 | .. |
| 928 | .. admonition:: Bypassing manage.py |
| 929 | |
| 930 | If you'd rather not use ``manage.py``, no problem. Just make sure |
| 931 | ``mysite`` is at the root level on the Python path (i.e., |
| 932 | ``import mysite`` works) and set the ``DJANGO_SETTINGS_MODULE`` |
| 933 | environment variable to ``mysite.settings``. |
| 934 | |
| 935 | For more information on all of this, see the `django-admin.py documentation`_. |
| 936 | |
| 937 | Una volta invocata la shell esplora le API relative al database:: |
| 938 | |
| 939 | # Importa le classi dei modelli che hai appena scritto. |
| 940 | >>> from mysite.polls.models import Poll, Choice |
| 941 | |
| 942 | # Non esistono ancora sondaggi. |
| 943 | >>> Poll.objects.all() |
| 944 | [] |
| 945 | |
| 946 | # Crea un nuovo oggetto Poll. |
| 947 | >>> from datetime import datetime |
| 948 | >>> p = Poll(question="What's up?", pub_date=datetime.now()) |
| 949 | |
| 950 | # Salva l'oggetto nel database. Devi invocare save() esplicitamente. |
| 951 | >>> p.save() |
| 952 | |
| 953 | # Ora p ha un ID. Nota che il suo valore può essere "1L" invece di "1". |
| 954 | # Dipende dal database che stai usando. Non è nulla di preoccupante, |
| 955 | # significa soltanto che il backend preferisce restituire i numeri interi |
| 956 | # sottoforma di oggetti Python interi lunghi. |
| 957 | >>> p.id |
| 958 | 1 |
| 959 | |
| 960 | # Accedi alle colonne del database come attributi Python. |
| 961 | >>> p.question |
| 962 | "What's up?" |
| 963 | >>> p.pub_date |
| 964 | datetime.datetime(2005, 7, 15, 12, 00, 53) |
| 965 | |
| 966 | # Cambia i valori agendo sugli attributi e salvando le modifiche con |
| 967 | # save(). |
| 968 | >>> p.pub_date = datetime(2005, 4, 1, 0, 0) |
| 969 | >>> p.save() |
| 970 | |
| 971 | # objects.all() mostra tutti i sondaggi nel database. |
| 972 | >>> Poll.objects.all() |
| 973 | [<Poll: Poll object>] |
| 974 | |
| 975 | .. |
| 976 | Once you're in the shell, explore the database API:: |
| 977 | |
| 978 | # Import the model classes we just wrote. |
| 979 | >>> from mysite.polls.models import Poll, Choice |
| 980 | |
| 981 | # No polls are in the system yet. |
| 982 | >>> Poll.objects.all() |
| 983 | [] |
| 984 | |
| 985 | # Create a new Poll. |
| 986 | >>> from datetime import datetime |
| 987 | >>> p = Poll(question="What's up?", pub_date=datetime.now()) |
| 988 | |
| 989 | # Save the object into the database. You have to call save() explicitly. |
| 990 | >>> p.save() |
| 991 | |
| 992 | # Now it has an ID. Note that this might say "1L" instead of "1", depending |
| 993 | # on which database you're using. That's no biggie; it just means your |
| 994 | # database backend prefers to return integers as Python long integer |
| 995 | # objects. |
| 996 | >>> p.id |
| 997 | 1 |
| 998 | |
| 999 | # Access database columns via Python attributes. |
| 1000 | >>> p.question |
| 1001 | "What's up?" |
| 1002 | >>> p.pub_date |
| 1003 | datetime.datetime(2005, 7, 15, 12, 00, 53) |
| 1004 | |
| 1005 | # Change values by changing the attributes, then calling save(). |
| 1006 | >>> p.pub_date = datetime(2005, 4, 1, 0, 0) |
| 1007 | >>> p.save() |
| 1008 | |
| 1009 | # objects.all() displays all the polls in the database. |
| 1010 | >>> Poll.objects.all() |
| 1011 | [<Poll: Poll object>] |
| 1012 | |
| 1013 | Un momento. ``<Poll: Poll object>`` è una rappresentazione dell'oggetto |
| 1014 | totalmente priva di utilità. Puoi sistemare questo aggiungendo il metodo |
| 1015 | ``__str__()`` alle classi ``Poll`` e ``Choice`` contenute nel file dei modelli |
| 1016 | ``polls/models.py``:: |
| 1017 | |
| 1018 | class Poll(models.Model): |
| 1019 | # ... |
| 1020 | def __str__(self): |
| 1021 | return self.question |
| 1022 | |
| 1023 | class Choice(models.Model): |
| 1024 | # ... |
| 1025 | def __str__(self): |
| 1026 | return self.choice |
| 1027 | |
| 1028 | .. |
| 1029 | Wait a minute. ``<Poll: Poll object>`` is, utterly, an unhelpful |
| 1030 | representation of this object. Let's fix that by editing the polls model (in |
| 1031 | the ``polls/models.py`` file) and adding a ``__str__()`` method to both |
| 1032 | ``Poll`` and ``Choice``:: |
| 1033 | |
| 1034 | class Poll(models.Model): |
| 1035 | # ... |
| 1036 | def __str__(self): |
| 1037 | return self.question |
| 1038 | |
| 1039 | class Choice(models.Model): |
| 1040 | # ... |
| 1041 | def __str__(self): |
| 1042 | return self.choice |
| 1043 | |
| 1044 | E' importante aggiungere i metodi ``__str__()`` non solo per una |
| 1045 | tua comodità durante le sessioni interattive, ma anche perché la |
| 1046 | rappresentazione testuale degli oggetti viene usata nell'interfaccia di |
| 1047 | amministrazione che Django genera in modo automatico. |
| 1048 | |
| 1049 | .. |
| 1050 | It's important to add ``__str__()`` methods to your models, not only for your |
| 1051 | own sanity when dealing with the interactive prompt, but also because objects' |
| 1052 | representations are used throughout Django's automatically-generated admin. |
| 1053 | |
| 1054 | Prova a farci caso, fino ad ora abbiamo usato normali metodi Python. |
| 1055 | Come controprova proviamo ad aggiungere un metodo personalizzato:: |
| 1056 | |
| 1057 | import datetime |
| 1058 | # ... |
| 1059 | class Poll(models.Model): |
| 1060 | # ... |
| 1061 | def was_published_today(self): |
| 1062 | return self.pub_date.date() == datetime.date.today() |
| 1063 | |
| 1064 | .. |
| 1065 | Note these are normal Python methods. Let's add a custom method, just for |
| 1066 | demonstration:: |
| 1067 | |
| 1068 | import datetime |
| 1069 | # ... |
| 1070 | class Poll(models.Model): |
| 1071 | # ... |
| 1072 | def was_published_today(self): |
| 1073 | return self.pub_date.date() == datetime.date.today() |
| 1074 | |
| 1075 | ``import datetime`` è stato aggiunto facendo riferimento alla libreria standard |
| 1076 | di Python. |
| 1077 | |
| 1078 | .. |
| 1079 | Note the addition of ``import datetime`` to reference Python's standard |
| 1080 | ``datetime`` module. |
| 1081 | |
| 1082 | Torniamo alla shell interattiva invocando di nuovo ``python manage.py shell``:: |
| 1083 | |
| 1084 | >>> from mysite.polls.models import Poll, Choice |
| 1085 | |
| 1086 | # Assicurati che il metodo __str__() che hai appena aggiunto sia |
| 1087 | # funzionante. |
| 1088 | >>> Poll.objects.all() |
| 1089 | [<Poll: What's up?>] |
| 1090 | |
| 1091 | # Django mette a disposizione un ricco set di API per risalire ai dati, |
| 1092 | # dove puoi specificare argomenti. |
| 1093 | >>> Poll.objects.filter(id=1) |
| 1094 | [<Poll: What's up?>] |
| 1095 | >>> Poll.objects.filter(question__startswith='What') |
| 1096 | [<Poll: What's up?>] |
| 1097 | |
| 1098 | # Ottiene tutti i sondaggi dell'anno 2005. E' sottointeso che se stai |
| 1099 | # seguendo questo tutorial in un anno diverso dal 2005 devi cambiare il |
| 1100 | # parametro di ricerca in modo appropriato. |
| 1101 | >>> Poll.objects.get(pub_date__year=2005) |
| 1102 | <Poll: What's up?> |
| 1103 | |
| 1104 | >>> Poll.objects.get(id=2) |
| 1105 | Traceback (most recent call last): |
| 1106 | ... |
| 1107 | DoesNotExist: Poll matching query does not exist. |
| 1108 | |
| 1109 | # Frequentemente ti capiterà di usare la chiave primaria per risalire ai |
| 1110 | # dati. Per questo Django offre una scorciatoia. La seguente sintassi è |
| 1111 | # identica a Poll.objects.get(id=1). |
| 1112 | >>> Poll.objects.get(pk=1) |
| 1113 | <Poll: What's up?> |
| 1114 | |
| 1115 | # Assicurati che il metodo che hai personalizzato funzioni. |
| 1116 | >>> p = Poll.objects.get(pk=1) |
| 1117 | >>> p.was_published_today() |
| 1118 | False |
| 1119 | |
| 1120 | # Associa qualche scelta (Choice) al sondaggio (Poll). La chiamata a create |
| 1121 | # costruisce un nuovo oggetto di scelta, tramite una operazione di INSERT |
| 1122 | # lo inserisce, aggiunge la scelta all'insieme delle scelte disponibili e |
| 1123 | # restituisce un nuovo oggetto Choice. |
| 1124 | >>> p = Poll.objects.get(pk=1) |
| 1125 | >>> p.choice_set.create(choice='Not much', votes=0) |
| 1126 | <Choice: Not much> |
| 1127 | >>> p.choice_set.create(choice='The sky', votes=0) |
| 1128 | <Choice: The sky> |
| 1129 | >>> c = p.choice_set.create(choice='Just hacking again', votes=0) |
| 1130 | |
| 1131 | # Gli oggetti Choice mettono a disposizione un insieme di API per accedere |
| 1132 | # all'oggetto Poll a cui sono associati. |
| 1133 | >>> c.poll |
| 1134 | <Poll: What's up?> |
| 1135 | |
| 1136 | # Vice versa: gli oggetti Poll hanno accesso agli oggetti Choice. |
| 1137 | >>> p.choice_set.all() |
| 1138 | [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] |
| 1139 | >>> p.choice_set.count() |
| 1140 | 3 |
| 1141 | |
| 1142 | # Le API seguono le relazioni automaticamente sulla base delle tue |
| 1143 | # necessità. Per separare le relazioni usa il doppio underscore. Questo |
| 1144 | # funziona a qualsiasi livello tu voglia, non c'è limite. |
| 1145 | # Trova tutte le scelte per qualsiasi sondaggio il cui attributo pub_date |
| 1146 | # sia 2005. |
| 1147 | >>> Choice.objects.filter(poll__pub_date__year=2005) |
| 1148 | [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] |
| 1149 | |
| 1150 | # Cancella una delle scelte. Usa delete(). |
| 1151 | >>> c.choice_set.filter(choice__startswith='Just hacking') |
| 1152 | >>> c.delete() |
| 1153 | |
| 1154 | .. |
| 1155 | Let's jump back into the Python interactive shell by running |
| 1156 | ``python manage.py shell`` again:: |
| 1157 | |
| 1158 | >>> from mysite.polls.models import Poll, Choice |
| 1159 | |
| 1160 | # Make sure our __str__() addition worked. |
| 1161 | >>> Poll.objects.all() |
| 1162 | [<Poll: What's up?>] |
| 1163 | |
| 1164 | # Django provides a rich database lookup API that's entirely driven by |
| 1165 | # keyword arguments. |
| 1166 | >>> Poll.objects.filter(id=1) |
| 1167 | [<Poll: What's up?>] |
| 1168 | >>> Poll.objects.filter(question__startswith='What') |
| 1169 | [<Poll: What's up?>] |
| 1170 | |
| 1171 | # Get the poll whose year is 2005. Of course, if you're going through this |
| 1172 | # tutorial in another year, change as appropriate. |
| 1173 | >>> Poll.objects.get(pub_date__year=2005) |
| 1174 | <Poll: What's up?> |
| 1175 | |
| 1176 | >>> Poll.objects.get(id=2) |
| 1177 | Traceback (most recent call last): |
| 1178 | ... |
| 1179 | DoesNotExist: Poll matching query does not exist. |
| 1180 | |
| 1181 | # Lookup by a primary key is the most common case, so Django provides a |
| 1182 | # shortcut for primary-key exact lookups. |
| 1183 | # The following is identical to Poll.objects.get(id=1). |
| 1184 | >>> Poll.objects.get(pk=1) |
| 1185 | <Poll: What's up?> |
| 1186 | |
| 1187 | # Make sure our custom method worked. |
| 1188 | >>> p = Poll.objects.get(pk=1) |
| 1189 | >>> p.was_published_today() |
| 1190 | False |
| 1191 | |
| 1192 | # Give the Poll a couple of Choices. The create call constructs a new |
| 1193 | # choice object, does the INSERT statement, adds the choice to the set |
| 1194 | # of available choices and returns the new Choice object. |
| 1195 | >>> p = Poll.objects.get(pk=1) |
| 1196 | >>> p.choice_set.create(choice='Not much', votes=0) |
| 1197 | <Choice: Not much> |
| 1198 | >>> p.choice_set.create(choice='The sky', votes=0) |
| 1199 | <Choice: The sky> |
| 1200 | >>> c = p.choice_set.create(choice='Just hacking again', votes=0) |
| 1201 | |
| 1202 | # Choice objects have API access to their related Poll objects. |
| 1203 | >>> c.poll |
| 1204 | <Poll: What's up?> |
| 1205 | |
| 1206 | # And vice versa: Poll objects get access to Choice objects. |
| 1207 | >>> p.choice_set.all() |
| 1208 | [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] |
| 1209 | >>> p.choice_set.count() |
| 1210 | 3 |
| 1211 | |
| 1212 | # The API automatically follows relationships as far as you need. |
| 1213 | # Use double underscores to separate relationships. |
| 1214 | # This works as many levels deep as you want. There's no limit. |
| 1215 | # Find all Choices for any poll whose pub_date is in 2005. |
| 1216 | >>> Choice.objects.filter(poll__pub_date__year=2005) |
| 1217 | [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] |
| 1218 | |
| 1219 | # Let's delete one of the choices. Use delete() for that. |
| 1220 | >>> c = p.choice_set.filter(choice__startswith='Just hacking') |
| 1221 | >>> c.delete() |
| 1222 | |
| 1223 | Per i dettagli completi sulle API di accesso al database consulta il `reference |
| 1224 | delle API di accesso al database`_ |
| 1225 | |
| 1226 | .. For full details on the database API, see our `Database API reference`_. |
| 1227 | |
| 1228 | Quando ti accorgi di avere una certa dimestichezza con queste API leggi la |
| 1229 | `seconda parte del tutarial`_ per mettere in funzione l'interfaccia di |
| 1230 | amministrazione di Django. |
| 1231 | |
| 1232 | .. |
| 1233 | When you're comfortable with the API, read `part 2 of this tutorial`_ to get |
| 1234 | Django's automatic admin working. |
| 1235 | |
| 1236 | .. |
| 1237 | .. _Database API reference: http://www.djangoproject.com/documentation/db_api/ |
| 1238 | .. _part 2 of this tutorial: http://www.djangoproject.com/documentation/tutorial2/ |
| 1239 | |
| 1240 | .. _reference delle API di accesso al database: http://www.djangoproject.com/documentation/db_api/ |
| 1241 | .. _seconda parte del tutarial: DocItTutorial02 |
| 1242 | |
| 1243 | |
| 1244 | }}} |