User Tools

Site Tools


doc:appunti:prog:django

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
doc:appunti:prog:django [2011/02/20 16:42] – [L'applicazione admin] niccolodoc:appunti:prog:django [2011/06/28 09:15] (current) – [Mettere i dati nella vista] niccolo
Line 9: Line 9:
  
 ===== Progetto e applicazioni ===== ===== Progetto e applicazioni =====
 +
 +  * **Progetto**
 +  * **Applicazione**: Contenitore di viste (pagine web) e modelli di dati (tabelle del database).
  
 Per creare un **nuovo progetto**: Per creare un **nuovo progetto**:
Line 143: Line 146:
  
 admin.site.register(Expense, ExpenseAdmin) admin.site.register(Expense, ExpenseAdmin)
 +</code>
 +
 +===== Creare una nuova pagina =====
 +
 +==== Vista ====
 +
 +Nel file **''my_app/views.py''** si definisce una funzione Python che restituisce una pagina web, questa sarà una **vista** della nostra applicazione:
 +
 +<code python>
 +from django.http import HttpResponse
 +
 +def my_view(request):
 +    output = u'''
 +        <html>
 +        <body>
 +        <h1>%s</h1>
 +        </body>       
 +        </html>
 +    ''' % (
 +        u'Titolo della vista'
 +    )
 +    return HttpResponse(output)
 +</code>
 +
 +==== URL ====
 +
 +Nel file **''urls.py''** contenuto alla radice del progetto si mappa un nuovo URL sulla vista, cioè sulla funzione Python definita in precedenza nel modulo ''my_project.views''. L'URL viene aggiunto nell'array **''urlpatterns''**, oltre agli altri eventualmente esistenti:
 +
 +<code python>
 +from my_app.views import *
 +
 +urlpatterns = patterns('',
 +    (r'^my_url/', my_view),
 +)
 +</code>
 +
 +La pagina sarà visibile all'URL **''/my_url/''** (vedere più avanti come configurare l'URL base del progetto).
 +==== Mettere i dati nella vista ====
 +
 +Invece di includere il codice HTML direttamente nella vista (funzione Python) si utilizza il sistema dei **template**.
 +
 +Nella directory radice del progetto si crea la sottodirectory **''templates''** e nel file **''settings.py''** si definisce la **''TEMPLATE_DIRS''** (controllare se il modulo os.path è già incluso):
 +
 +<code python>
 +import os.path
 +
 +TEMPLATE_DIRS = (
 +    os.path.join(os.path.dirname(__file__), 'templates),
 +)
 +</code>
 +
 +Quindi si crea il file **''templates/my_view.html''** che conterrà dei segnaposto del tipo **''%%{{nome}}%%''** che verranno sostituiti a runtime:
 +
 +<code html>
 +<html>
 +<body>
 +  <h1>{{page_title}}</h1>
 +  <p>{{page_body}}</p>
 +</body>
 +</html>
 +</code>
 +
 +Infine si modifica il codice della vista:
 +
 +<code python>
 +from django.http import HttpResponse
 +from django.template import Context
 +from django.template.loader import get_template
 +
 +def my_view(request):
 +    template = get_template('my_view.html')
 +    variables = Context({
 +        'page_title': u'Titolo della vista',
 +        'page_body':  u'Contenuto della pagina'
 +    })
 +    output = template.render(variables)
 +    return HttpResponse(output)
 +</code>
 +
 +==== Visualizzazione e aggregazione dei dati ====
 +
 +Nel codice della **view** è possibile accedere ai dati (i **model**) sfruttando anche le relazioni tra essi (le //foreign key// delle tabelle del database). È possibile anche usare funzioni di aggregazione.
 +
 +Ecco un esempio di una vista dell'applicazione **spese** (**''my_project/spese/views.py''**), che accede ai dati del modello **''User''** e del modello correlato **''Expense''** (sono tabelle correlate). Nella vista si aggiunge un attributo al modello ''User'', aggregando per ogni ''User'' il campo ''amount'' del modello ''Expense'', calcolando la **''Sum''** e il **''Count''**:
 +
 +<code python>
 +from django.http import HttpResponse
 +from django.template import Context
 +from django.template.loader import get_template
 +
 +from django.db.models import Sum, Count
 +
 +from django.contrib.auth.models import User
 +#from spese.models import Expense
 +
 +def balance(request):
 +
 +    users = User.objects.all()
 +
 +    max_expense = 0
 +    for user in users:
 +        user.aggr = user.expense_set.aggregate(Count('amount'), Sum('amount'))
 +        if user.aggr['amount__sum'] > max_expense:
 +            max_expense = user.aggr['amount__sum']
 +    for user in users:
 +        user.balance = user.aggr['amount__sum'] - max_expense
 +
 +    template = get_template('balance.html')
 +    variables = Context({
 +        'page_title':    u'Bilancio spese',
 +        'users':         users,
 +        'max_expense':   max_expense
 +    })
 +    output = template.render(variables)
 +    return HttpResponse(output)
 +</code>
 +
 +Ecco infine il template **''my_project/templates/balance.html''** che provvede ad impaginare i dati:
 +
 +<code html>
 +<html>
 +<body>
 +  <h1>{{page_title}}</h1>
 +  {% if users %}
 +    <table border="1" cellspacing="0">
 +      <tr>
 +        <th>Persona</th>
 +        <th>Numero spese</th>
 +        <th>Somma spesa</th>
 +        <th>Bilancio</th>
 +      </tr>
 +      {% for user in users %}
 +        <tr>
 +          <td>{{user.username}}</td>
 +          <td>{{user.aggr.amount__count}}</td>
 +          <td>{{user.aggr.amount__sum}}</td>
 +          <td>{{user.balance}}</td></tr>
 +      {% endfor %}
 +    </table>
 +  {% else %}
 +    <p>No users found.</p>
 +  {% endif %}
 +</body>
 +</html>
 </code> </code>
 ===== Webserver di test ===== ===== Webserver di test =====
doc/appunti/prog/django.1298216570.txt.gz · Last modified: 2011/02/20 16:42 by niccolo