{"title":"Come creare un output su CSV","version":"4.1","locale":"it","docname":"howto/outputting-csv","url":"/it/4.1/howto/outputting-csv/","canonical":"https://djangodocs.dev/it/4.1/howto/outputting-csv/","summary":"Questo documento spiega come fare output di CSV (Comma Separated Values) in modo dinamico usando Django. Per fare ciò, puoi sia usare la libreria CSV di Python che…","html":"<h1>Come creare un output su CSV<a class=\"heading-anchor\" href=\"#how-to-create-csv-output\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Questo documento spiega come fare output di CSV (Comma Separated Values) in modo dinamico usando Django. Per fare ciò, puoi sia usare la libreria CSV di Python che il sistema di template di Django.</p>\n<section id=\"using-the-python-csv-library\">\n<h2>Utilizzando la libreria CSV di Python<a class=\"heading-anchor\" href=\"#using-the-python-csv-library\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Python è dotato di una libreria CSV, <a class=\"reference external\" href=\"https://docs.python.org/3/library/csv.html#module-csv\" title=\"(in Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">csv</span></code></a>. La chiave dell’usarla con Django è che le capacità di creazione di CSV del modulo <a class=\"reference external\" href=\"https://docs.python.org/3/library/csv.html#module-csv\" title=\"(in Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">csv</span></code></a> agiscono su oggetti file-like e gli oggetti di Django <a class=\"reference internal\" href=\"/it/4.1/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> sono oggetti file-like.</p>\n<p>Qui un esempio:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">csv</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">some_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Create the HttpResponse object with the appropriate CSV header.</span>\n    <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span>\n        <span class=\"n\">content_type</span><span class=\"o\">=</span><span class=\"s1\">&#39;text/csv&#39;</span><span class=\"p\">,</span>\n        <span class=\"n\">headers</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;Content-Disposition&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;attachment; filename=&quot;somefilename.csv&quot;&#39;</span><span class=\"p\">},</span>\n    <span class=\"p\">)</span>\n\n    <span class=\"n\">writer</span> <span class=\"o\">=</span> <span class=\"n\">csv</span><span class=\"o\">.</span><span class=\"n\">writer</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"p\">)</span>\n    <span class=\"n\">writer</span><span class=\"o\">.</span><span class=\"n\">writerow</span><span class=\"p\">([</span><span class=\"s1\">&#39;First row&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Foo&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Bar&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Baz&#39;</span><span class=\"p\">])</span>\n    <span class=\"n\">writer</span><span class=\"o\">.</span><span class=\"n\">writerow</span><span class=\"p\">([</span><span class=\"s1\">&#39;Second row&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;A&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;B&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;C&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;&quot;Testing&quot;&#39;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Here&#39;s a quote&quot;</span><span class=\"p\">])</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">response</span>\n</code></pre></div>\n<p>Il codice ed i commenti dovrebbero essere auto esplicativi, ma alcuni dettagli meritano un approfondimento:</p>\n<ul class=\"simple\">\n<li><p>La response ottiene un MIME type speciale, <em class=\"mimetype\">text/csv</em>. Questo dice ai browser che il documento è un file CSV, piuttosto che un file HTML. Se non lo specifichi, i browser probabilmente intepreteranno l’output come HTML, che risulterà in un brutto e spaventoso nonsense nella finestra del browser.</p></li>\n<li><p>La risposta ottine un header <code class=\"docutils literal notranslate\"><span class=\"pre\">Content-Disposition</span></code> aggiuntivo, che contiene il nome del file CSV. Questo nome è arbitrario; chiamalo come vuoi. Sarà usato dai browser nel dialogo «Salva come…» ecc…</p></li>\n<li><p>Puoi agganciarti alla API per la generazione di CSV passando <code class=\"docutils literal notranslate\"><span class=\"pre\">response</span></code> come primo argomento a <code class=\"docutils literal notranslate\"><span class=\"pre\">csv.writer</span></code>. La funzione <code class=\"docutils literal notranslate\"><span class=\"pre\">csv.writer</span></code> si aspetta un oggetto file-like e <a class=\"reference internal\" href=\"/it/4.1/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> fa al caso suo.</p></li>\n<li><p>Per ogni riga del tuo CSV, chiama <code class=\"docutils literal notranslate\"><span class=\"pre\">writer.writerow</span></code>, passando un <a class=\"reference external\" href=\"https://docs.python.org/3/glossary.html#term-iterable\" title=\"(in Python v3.14)\"><span class=\"xref std std-term\">iterable</span></a>.</p></li>\n<li><p>Il modulo CSV si occupa del quoting per te, quindi non devi preoccuparti di fare escape delle stringhe con quote o virgole. Passa a <code class=\"docutils literal notranslate\"><span class=\"pre\">writerow()</span></code> le tue stringhe grezze e farà la cosa giusta.</p></li>\n</ul>\n<section id=\"streaming-large-csv-files\">\n<span id=\"streaming-csv-files\"></span><h3>Streaming di grossi file CSV<a class=\"heading-anchor\" href=\"#streaming-large-csv-files\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Quando hai a che fare con view che generano response molto grandi, potresti voler considerare <a class=\"reference internal\" href=\"/it/4.1/ref/request-response/#django.http.StreamingHttpResponse\" title=\"django.http.StreamingHttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">StreamingHttpResponse</span></code></a> di Django, invece. Per esempio, facendo streaming di un file che ci mette tanto ad essere generato puoi evitare che il load balancer interrompa una connessione che sarebbe andata fuori tempo massimo mentre il server generava la risposta.</p>\n<p>In questo esempio, utilizziamo i generatori Python per gestire in modo efficiente la composizione e la trasmissione di un file CSV di grandi dimensioni:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">csv</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">StreamingHttpResponse</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Echo</span><span class=\"p\">:</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;An object that implements just the write method of the file-like</span>\n<span class=\"sd\">    interface.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">write</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">value</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;Write the value by returning it, instead of storing in a buffer.&quot;&quot;&quot;</span>\n        <span class=\"k\">return</span> <span class=\"n\">value</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">some_streaming_csv_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;A view that streams a large CSV file.&quot;&quot;&quot;</span>\n    <span class=\"c1\"># Generate a sequence of rows. The range is based on the maximum number of</span>\n    <span class=\"c1\"># rows that can be handled by a single sheet in most spreadsheet</span>\n    <span class=\"c1\"># applications.</span>\n    <span class=\"n\">rows</span> <span class=\"o\">=</span> <span class=\"p\">([</span><span class=\"s2\">&quot;Row </span><span class=\"si\">{}</span><span class=\"s2\">&quot;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"n\">idx</span><span class=\"p\">),</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">idx</span><span class=\"p\">)]</span> <span class=\"k\">for</span> <span class=\"n\">idx</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">65536</span><span class=\"p\">))</span>\n    <span class=\"n\">pseudo_buffer</span> <span class=\"o\">=</span> <span class=\"n\">Echo</span><span class=\"p\">()</span>\n    <span class=\"n\">writer</span> <span class=\"o\">=</span> <span class=\"n\">csv</span><span class=\"o\">.</span><span class=\"n\">writer</span><span class=\"p\">(</span><span class=\"n\">pseudo_buffer</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">StreamingHttpResponse</span><span class=\"p\">(</span>\n        <span class=\"p\">(</span><span class=\"n\">writer</span><span class=\"o\">.</span><span class=\"n\">writerow</span><span class=\"p\">(</span><span class=\"n\">row</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">row</span> <span class=\"ow\">in</span> <span class=\"n\">rows</span><span class=\"p\">),</span>\n        <span class=\"n\">content_type</span><span class=\"o\">=</span><span class=\"s2\">&quot;text/csv&quot;</span><span class=\"p\">,</span>\n        <span class=\"n\">headers</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;Content-Disposition&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;attachment; filename=&quot;somefilename.csv&quot;&#39;</span><span class=\"p\">},</span>\n    <span class=\"p\">)</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"using-the-template-system\">\n<h2>Utilizzare il template system<a class=\"heading-anchor\" href=\"#using-the-template-system\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Alternativamente, puoi usare il <a class=\"reference internal\" href=\"/it/4.1/topics/templates/\"><span class=\"doc\">sistema di template di Django</span></a> per generare CSV.\nQuesto è più low-level rispetto all’utilizzo del conveniente modulo <a class=\"reference external\" href=\"https://docs.python.org/3/library/csv.html#module-csv\" title=\"(in Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">csv</span></code></a> ma la soluzione viene qui proposta per completezza.</p>\n<p>L’idea è di passare una lista di oggetti al tuo template, e lasciare che il template crei le virgole nel ciclo <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatetag-for\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">for</span></code></a></p>\n<p>Qui c’è un esempio, che genera lo stesso file CSV visto in precedenza:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.template</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">loader</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">some_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Create the HttpResponse object with the appropriate CSV header.</span>\n    <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span>\n        <span class=\"n\">content_type</span><span class=\"o\">=</span><span class=\"s1\">&#39;text/csv&#39;</span><span class=\"p\">,</span>\n        <span class=\"n\">headers</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;Content-Disposition&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;attachment; filename=&quot;somefilename.csv&quot;&#39;</span><span class=\"p\">},</span>\n    <span class=\"p\">)</span>\n\n    <span class=\"c1\"># The data is hard-coded here, but you could load it from a database or</span>\n    <span class=\"c1\"># some other source.</span>\n    <span class=\"n\">csv_data</span> <span class=\"o\">=</span> <span class=\"p\">(</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;First row&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Foo&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Bar&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Baz&#39;</span><span class=\"p\">),</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;Second row&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;A&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;B&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;C&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;&quot;Testing&quot;&#39;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Here&#39;s a quote&quot;</span><span class=\"p\">),</span>\n    <span class=\"p\">)</span>\n\n    <span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"n\">loader</span><span class=\"o\">.</span><span class=\"n\">get_template</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_template_name.txt&#39;</span><span class=\"p\">)</span>\n    <span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s1\">&#39;data&#39;</span><span class=\"p\">:</span> <span class=\"n\">csv_data</span><span class=\"p\">}</span>\n    <span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">write</span><span class=\"p\">(</span><span class=\"n\">t</span><span class=\"o\">.</span><span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">c</span><span class=\"p\">))</span>\n    <span class=\"k\">return</span> <span class=\"n\">response</span>\n</code></pre></div>\n<p>La sola differenza tra questo esempio e quello precedente è che questo usa il caricamento del template invece del modulo CSV. Il resto del codice – come <code class=\"docutils literal notranslate\"><span class=\"pre\">content_type='text/csv'</span></code> – è lo stesso.</p>\n<p>Quindi, crea il template <code class=\"docutils literal notranslate\"><span class=\"pre\">my_template_name.txt</span></code>, con questo codice:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">row</span> <span class=\"k\">in</span> <span class=\"nv\">data</span> <span class=\"cp\">%}</span>&quot;<span class=\"cp\">{{</span> <span class=\"nv\">row.0</span><span class=\"o\">|</span><span class=\"nf\">addslashes</span> <span class=\"cp\">}}</span>&quot;, &quot;<span class=\"cp\">{{</span> <span class=\"nv\">row.1</span><span class=\"o\">|</span><span class=\"nf\">addslashes</span> <span class=\"cp\">}}</span>&quot;, &quot;<span class=\"cp\">{{</span> <span class=\"nv\">row.2</span><span class=\"o\">|</span><span class=\"nf\">addslashes</span> <span class=\"cp\">}}</span>&quot;, &quot;<span class=\"cp\">{{</span> <span class=\"nv\">row.3</span><span class=\"o\">|</span><span class=\"nf\">addslashes</span> <span class=\"cp\">}}</span>&quot;, &quot;<span class=\"cp\">{{</span> <span class=\"nv\">row.4</span><span class=\"o\">|</span><span class=\"nf\">addslashes</span> <span class=\"cp\">}}</span>&quot;\n<span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Questo breve template itera i dati e mostra una riga del CSV alla volta. Utilizza il filtro template <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatefilter-addslashes\"><code class=\"xref std std-tfilter docutils literal notranslate\"><span class=\"pre\">addslashes</span></code></a> per essere sicuro che non ci siano problemi con gli apici.</p>\n</section>\n<section id=\"other-text-based-formats\">\n<h2>Altri formati basati sul testo<a class=\"heading-anchor\" href=\"#other-text-based-formats\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Nota che non c’è niente di molto specifico di CSV qui – solo il formato di output. Puoi usare entrambe queste tecniche per fare output di qualsiasi file in formato testo che vuoi. Puoi anche utilizzare una tecnica simile per generare dati binari arbitrari; vedi <a class=\"reference internal\" href=\"/it/4.1/howto/outputting-pdf/\"><span class=\"doc\">Come creare file PDF</span></a> per avere un esempio.</p>\n</section>","rootId":"how-to-create-csv-output","toc":[{"title":"Utilizzando la libreria CSV di Python","anchor":"using-the-python-csv-library","children":[{"title":"Streaming di grossi file CSV","anchor":"streaming-large-csv-files","children":[]}]},{"title":"Utilizzare il template system","anchor":"using-the-template-system","children":[]},{"title":"Altri formati basati sul testo","anchor":"other-text-based-formats","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"guide «How-to»","url":"/it/4.1/howto/"}],"prev":{"docname":"howto/logging","title":"Come configurare ed utilizzare i log","url":"/it/4.1/howto/logging/"},"next":{"docname":"howto/outputting-pdf","title":"Come creare file PDF","url":"/it/4.1/howto/outputting-pdf/"},"formats":{"html":"/it/4.1/howto/outputting-csv/","markdown":"/it/4.1/howto/outputting-csv.md","json":"/it/4.1/howto/outputting-csv.json"},"source":"https://github.com/django/django/blob/stable/4.1.x/docs/howto/outputting-csv.txt","official":"https://docs.djangoproject.com/it/4.1/howto/outputting-csv/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}