sabato 25 ottobre 2025

Corso di Python: 13 Codice completo del sito

Configurazione progetto Django
Codice completo del sito

  1. Creazione ambiente virtuale e installazione pacchetti

python -m venv venv
source venv/bin/activate      # Linux/Mac
venv\Scripts\activate         # Windows

pip install django pandas numpy yfinance plotly matplotlib djangorestframework
  1. Creazione progetto e app principali

django-admin startproject financeadvisor
cd financeadvisor

python manage.py startapp users
python manage.py startapp portfolios
python manage.py startapp market
  1. Aggiornamento settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'users',
    'portfolios',
    'market
    1️⃣ Modello utenti personalizzato (users/models.py)

from django.contrib.auth.models import AbstractUser

from django.db import models class CustomUser(AbstractUser): is_consulente = models.BooleanField(default=False) is_cliente = models.BooleanField(default=True) telefono = models.CharField(max_length=20, blank=True, null=True) indirizzo = models.TextField(blank=True, null=True) def __str__(self): return self.username

2️⃣ Configurazione settings.py

AUTH_USER_MODEL = 'users.CustomUser'

LOGIN_REDIRECT_URL = 'dashboard' LOGOUT_REDIRECT_URL = 'login'

3️⃣ Forms per registrazione (users/forms.py)

from django import forms

from django.contrib.auth.forms import UserCreationForm from .models import CustomUser class CustomUserCreationForm(UserCreationForm): class Meta: model = CustomUser fields = ('username', 'email', 'telefono', 'indirizzo', 'is_consulente', 'is_cliente')

4️⃣ Views per registrazione e dashboard (users/views.py)

from django.shortcuts import render, redirect

from django.contrib.auth import login from django.contrib.auth.decorators import login_required from .forms import CustomUserCreationForm def register(request): if request.method == 'POST': form = CustomUserCreationForm(request.POST) if form.is_valid(): user = form.save() login(request, user) return redirect('dashboard') else: form = CustomUserCreationForm() return render(request, 'users/register.html', {'form': form}) @login_required def dashboard(request): return render(request, 'users/dashboard.html')

5️⃣ URL Routing (users/urls.py)

from django.urls import path

from django.contrib.auth import views as auth_views from . import views urlpatterns = [ path('register/', views.register, name='register'), path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'), path('logout/', auth_views.LogoutView.as_view(), name='logout'), path('dashboard/', views.dashboard, name='dashboard'), ]

6️⃣ Template Login (users/templates/users/login.html)

<h2>Login</h2>

<form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Accedi</button> </form> <p>Non hai un account? <a href="{% url 'register' %}">Registrati</a></p>

7️⃣ Template Registrazione (users/templates/users/register.html)

<h2>Registrazione</h2>

<form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Registrati</button> </form>

8️⃣ Dashboard area riservata (users/templates/users/dashboard.html)

<h2>Benvenuto, {{ user.username }}</h2>

{% if user.is_consulente %} <p>Area Consulente: gestione portafogli e clienti</p> {% elif user.is_cliente %} <p>Area Cliente: visualizza il tuo portafoglio e analisi finanziaria</p> {% endif %} <a href="{% url 'logout' %}">Logout</a>

    1️⃣ Modello Portafoglio e Asset (portfolio/models.py)

    from django.db import models from django.conf import settings class Asset(models.Model): nome = models.CharField(max_length=100) simbolo = models.CharField(max_length=10) tipo = models.CharField(max_length=50, choices=[('azioni','Azioni'), ('bond','Bond'), ('crypto','Crypto'), ('ETF','ETF')]) def __str__(self): return f"{self.nome} ({self.simbolo})" class Portfolio(models.Model): cliente = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) nome_portafoglio = models.CharField(max_length=100) assets = models.ManyToManyField(Asset, through='PortfolioAsset') data_creazione = models.DateField(auto_now_add=True) def __str__(self): return f"{self.nome_portafoglio} - {self.cliente.username}" class PortfolioAsset(models.Model): portfolio = models.ForeignKey(Portfolio, on_delete=models.CASCADE) asset = models.ForeignKey(Asset, on_delete=models.CASCADE) quantita = models.FloatField() prezzo_acquisto = models.FloatField() def valore_attuale(self, prezzo_corrente): return self.quantita * prezzo_corrente

    2️⃣ Views di gestione portafogli (portfolio/views.py)

    from django.shortcuts import render, get_object_or_404 from django.contrib.auth.decorators import login_required from .models import Portfolio, Asset, PortfolioAsset import pandas as pd import plotly.express as px import yfinance as yf # Libreria per dati finanziari @login_required def portfolio_list(request): portfolios = Portfolio.objects.filter(cliente=request.user) return render(request, 'portfolio/portfolio_list.html', {'portfolios': portfolios}) @login_required def portfolio_detail(request, pk): portfolio = get_object_or_404(Portfolio, pk=pk, cliente=request.user) assets = PortfolioAsset.objects.filter(portfolio=portfolio) # Creazione DataFrame per analisi data = [] for pa in assets: ticker = yf.Ticker(pa.asset.simbolo) prezzo_corrente = ticker.history(period="1d")['Close'].iloc[-1] data.append({ 'Asset': pa.asset.nome, 'Quantità': pa.quantita, 'Prezzo Acquisto': pa.prezzo_acquisto, 'Prezzo Attuale': prezzo_corrente, 'Valore Attuale': pa.valore_attuale(prezzo_corrente) }) df = pd.DataFrame(data) # Grafico interattivo fig = px.pie(df, names='Asset', values='Valore Attuale', title='Distribuzione Portafoglio') grafico_html = fig.to_html(full_html=False) return render(request, 'portfolio/portfolio_detail.html', {'portfolio': portfolio, 'df': df.to_dict(orient='records'), 'grafico': grafico_html})

    3️⃣ URL Routing (portfolio/urls.py)

    from django.urls import path from . import views urlpatterns = [ path('', views.portfolio_list, name='portfolio_list'), path('<int:pk>/', views.portfolio_detail, name='portfolio_detail'), ]

    4️⃣ Template Lista Portafogli (portfolio/templates/portfolio/portfolio_list.html)

    <h2>I tuoi portafogli</h2> <ul> {% for p in portfolios %} <li> <a href="{% url 'portfolio_detail' p.pk %}">{{ p.nome_portafoglio }}</a> </li> {% empty %} <li>Nessun portafoglio disponibile.</li> {% endfor %} </ul>

    5️⃣ Template Dettaglio Portafoglio (portfolio/templates/portfolio/portfolio_detail.html)

    <h2>Portafoglio: {{ portfolio.nome_portafoglio }}</h2> <p>Cliente: {{ portfolio.cliente.username }}</p> <h3>Dettaglio Asset</h3> <table border="1"> <tr> <th>Asset</th> <th>Quantità</th> <th>Prezzo Acquisto</th> <th>Prezzo Attuale</th> <th>Valore Attuale</th> </tr> {% for asset in df %} <tr> <td>{{ asset.Asset }}</td> <td>{{ asset.Quantità }}</td> <td>{{ asset.Prezzo Acquisto }}</td> <td>{{ asset.Prezzo Attuale }}</td> <td>{{ asset.Valore Attuale }}</td> </tr> {% endfor %} </table> <h3>Grafico Distribuzione Portafoglio</h3> <div> {{ grafico|safe }} </div>

      ✅ Librerie Python principali utilizzate

      • Django → backend e gestione utenti/portafogli

      • pandas → analisi dei dati

      • plotly → grafici interattivi

      • yfinance → dati finanziari storici e correnti

      • Celery (opzionale) → aggiornamento dati periodico

    1️⃣ Modello dei portafogli

    portfolio/models.py

    from django.db import models from django.contrib.auth.models import User class Portfolio(models.Model): cliente = models.ForeignKey(User, on_delete=models.CASCADE) nome_portafoglio = models.CharField(max_length=100) data_creazione = models.DateField(auto_now_add=True) def __str__(self): return f"{self.nome_portafoglio} - {self.cliente.username}" class Investimento(models.Model): portfolio = models.ForeignKey(Portfolio, on_delete=models.CASCADE, related_name='investimenti') nome_asset = models.CharField(max_length=100) tipo_asset = models.CharField(max_length=50) # azioni, obbligazioni, ETF, ecc. quantita = models.FloatField() valore_unitario = models.FloatField() data_inserimento = models.DateField(auto_now_add=True) @property def valore_totale(self): return self.quantita * self.valore_unitario def __str__(self): return f"{self.nome_asset} ({self.tipo_asset})"

    2️⃣ Form per creare portafogli e investimenti

    portfolio/forms.py

    from django import forms from .models import Portfolio, Investimento class PortfolioForm(forms.ModelForm): class Meta: model = Portfolio fields = ['nome_portafoglio'] class InvestimentoForm(forms.ModelForm): class Meta: model = Investimento fields = ['nome_asset', 'tipo_asset', 'quantita', 'valore_unitario']

    3️⃣ Views per portafogli e investimenti

    portfolio/views.py

    from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth.decorators import login_required from .models import Portfolio, Investimento from .forms import PortfolioForm, InvestimentoForm @login_required def crea_portafoglio(request): if request.method == 'POST': form = PortfolioForm(request.POST) if form.is_valid(): portfolio = form.save(commit=False) portfolio.cliente = request.user portfolio.save() return redirect('dashboard') else: form = PortfolioForm() return render(request, 'portfolio/crea_portafoglio.html', {'form': form}) @login_required def dettaglio_portafoglio(request, portfolio_id): portfolio = get_object_or_404(Portfolio, id=portfolio_id) investimenti = portfolio.investimenti.all() if request.method == 'POST': form = InvestimentoForm(request.POST) if form.is_valid(): investimento = form.save(commit=False) investimento.portfolio = portfolio investimento.save() return redirect('dettaglio_portafoglio', portfolio_id=portfolio.id) else: form = InvestimentoForm() return render(request, 'portfolio/dettaglio_portafoglio.html', { 'portfolio': portfolio, 'investimenti': investimenti, 'form': form })

    4️⃣ URL routing

    portfolio/urls.py

    from django.urls import path from . import views urlpatterns = [ path('dashboard/', views.dashboard, name='dashboard'), path('crea_portafoglio/', views.crea_portafoglio, name='crea_portafoglio'), path('portafoglio/<int:portfolio_id>/', views.dettaglio_portafoglio, name='dettaglio_portafoglio'), ]

    5️⃣ Template per la gestione dei portafogli

    crea_portafoglio.html

    <h2>Crea Nuovo Portafoglio</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Crea</button> </form> <a href="{% url 'dashboard' %}">Torna alla Dashboard</a>

    dettaglio_portafoglio.html

    <h2>{{ portfolio.nome_portafoglio }}</h2> <h3>Investimenti</h3> <ul> {% for i in investimenti %} <li>{{ i.nome_asset }} - {{ i.tipo_asset }} - Quantità: {{ i.quantita }} - Valore unitario: {{ i.valore_unitario }} - Totale: {{ i.valore_totale }}</li> {% empty %} <li>Nessun investimento presente.</li> {% endfor %} </ul> <h3>Aggiungi nuovo investimento</h3> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Aggiungi</button> </form> <a href="{% url 'dashboard' %}">Torna alla Dashboard</a>

    1️⃣ Aggiornamento automatico dei dati finanziari

    Per aggiornare i prezzi degli asset in tempo reale, possiamo utilizzare API pubbliche (ad esempio Yahoo Finance tramite la libreria yfinance).

    portfolio/utils.py

    import yfinance as yf def aggiorna_valori_investimenti(portfolio): for investimento in portfolio.investimenti.all(): try: ticker = investimento.nome_asset dati = yf.Ticker(ticker) prezzo = dati.history(period="1d")['Close'].iloc[-1] investimento.valore_unitario = prezzo investimento.save() except Exception as e: print(f"Errore aggiornamento {investimento.nome_asset}: {e}")

    2️⃣ Grafici dei portafogli

    Usiamo Plotly per grafici interattivi.

    portfolio/views.py (aggiunta)

    import plotly.express as px from django.http import JsonResponse @login_required def grafico_portafoglio(request, portfolio_id): portfolio = get_object_or_404(Portfolio, id=portfolio_id) investimenti = portfolio.investimenti.all() nomi = [i.nome_asset for i in investimenti] valori = [i.valore_totale for i in investimenti] fig = px.pie(names=nomi, values=valori, title=f"Composizione Portafoglio: {portfolio.nome_portafoglio}") grafico_json = fig.to_json() return JsonResponse(grafico_json, safe=False)

    Template dettaglio_portafoglio.html aggiornato

    <h3>Grafico Portafoglio</h3> <div id="grafico"></div> <script src="https://cdn.plot.ly/plotly-latest.min.js"></script> <script> fetch("{% url 'grafico_portafoglio' portfolio.id %}") .then(response => response.json()) .then(data => { Plotly.newPlot('grafico', data.data, data.layout); }); </script>

    3️⃣ Report PDF

    Utilizziamo WeasyPrint per generare PDF dai template HTML.

    portfolio/views.py (aggiunta)

    from django.template.loader import render_to_string from django.http import HttpResponse import weasyprint @login_required def report_pdf(request, portfolio_id): portfolio = get_object_or_404(Portfolio, id=portfolio_id) investimenti = portfolio.investimenti.all() html_string = render_to_string('portfolio/report_pdf.html', { 'portfolio': portfolio, 'investimenti': investimenti }) response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = f'inline; filename="report_{portfolio.nome_portafoglio}.pdf"' weasyprint.HTML(string=html_string).write_pdf(response) return response

    Template report_pdf.html

    <h2>Report Portafoglio: {{ portfolio.nome_portafoglio }}</h2> <p>Cliente: {{ portfolio.cliente.username }}</p> <p>Data: {{ portfolio.data_creazione }}</p> <table border="1" cellspacing="0" cellpadding="5"> <tr> <th>Asset</th> <th>Tipo</th> <th>Quantità</th> <th>Valore Unitario</th> <th>Valore Totale</th> </tr> {% for i in investimenti %} <tr> <td>{{ i.nome_asset }}</td> <td>{{ i.tipo_asset }}</td> <td>{{ i.quantita }}</td> <td>{{ i.valore_unitario }}</td> <td>{{ i.valore_totale }}</td> </tr> {% endfor %} </table>

    4️⃣ Report Excel

    Usiamo pandas e openpyxl per esportare dati Excel.

    portfolio/views.py (aggiunta)

    import pandas as pd from django.http import HttpResponse @login_required def report_excel(request, portfolio_id): portfolio = get_object_or_404(Portfolio, id=portfolio_id) investimenti = portfolio.investimenti.all() data = [{ 'Asset': i.nome_asset, 'Tipo': i.tipo_asset, 'Quantità': i.quantita, 'Valore Unitario': i.valore_unitario, 'Valore Totale': i.valore_totale } for i in investimenti] df = pd.DataFrame(data) response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') response['Content-Disposition'] = f'attachment; filename=report_{portfolio.nome_portafoglio}.xlsx' df.to_excel(response, index=False) return response

    5️⃣ URL routing

    portfolio/urls.py aggiornato

    urlpatterns = [ path('dashboard/', views.dashboard, name='dashboard'), path('crea_portafoglio/', views.crea_portafoglio, name='crea_portafoglio'), path('portafoglio/<int:portfolio_id>/', views.dettaglio_portafoglio, name='dettaglio_portafoglio'), path('portafoglio/<int:portfolio_id>/grafico/', views.grafico_portafoglio, name='grafico_portafoglio'), path('portafoglio/<int:portfolio_id>/report/pdf/', views.report_pdf, name='report_pdf'), path('portafoglio/<int:portfolio_id>/report/excel/', views.report_excel, name='report_excel'), ]

    Nessun commento:

    Posta un commento

    Corso Fondamenti di Informatica e Reti: 6 Reti di computer e Internet

    Reti di computer e Internet Introduzione Prova a pensare alla vita quotidiana senza reti informatiche: niente messaggi WhatsApp, niente m...