<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 第五節:生成CSV文件 # 生成CSV文件: 有時候我們做的網站,需要將一些數據,生成有一個`CSV`文件給瀏覽器,并且是作為附件的形式下載下來。以下將講解如何生成`CSV`文件。 ## 生成小的CSV文件: 這里將用一個生成小的`CSV`文件為例,來把生成`CSV`文件的技術要點講到位。我們用`Python`內置的`csv`模塊來處理`csv`文件,并且使用`HttpResponse`來將`csv`文件返回回去。示例代碼如下: ``` <pre class="calibre12">``` <span class="hljs-keyword">import</span> csv <span class="hljs-keyword">from</span> django.http <span class="hljs-keyword">import</span> HttpResponse <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">csv_view</span><span class="hljs-params">(request)</span>:</span> response = HttpResponse(content_type=<span class="hljs-string">'text/csv'</span>) response[<span class="hljs-string">'Content-Disposition'</span>] = <span class="hljs-string">'attachment; filename="somefilename.csv"'</span> writer = csv.writer(response) writer.writerow([<span class="hljs-string">'username'</span>, <span class="hljs-string">'age'</span>, <span class="hljs-string">'height'</span>, <span class="hljs-string">'weight'</span>]) writer.writerow([<span class="hljs-string">'zhiliao'</span>, <span class="hljs-string">'18'</span>, <span class="hljs-string">'180'</span>, <span class="hljs-string">'110'</span>]) <span class="hljs-keyword">return</span> response ``` ``` 這里再來對每個部分的代碼進行解釋: 1. 我們在初始化`HttpResponse`的時候,指定了`Content-Type`為`text/csv`,這將告訴瀏覽器,這是一個`csv`格式的文件而不是一個`HTML`格式的文件,如果用默認值,默認值就是`html`,那么瀏覽器將把`csv`格式的文件按照`html`格式輸出,這肯定不是我們想要的。 2. 第二個我們還在`response`中添加一個`Content-Disposition`頭,這個東西是用來告訴瀏覽器該如何處理這個文件,我們給這個頭的值設置為`attachment;`,那么瀏覽器將不會對這個文件進行顯示,而是作為附件的形式下載,第二個`filename="somefilename.csv"`是用來指定這個`csv`文件的名字。 3. 我們使用`csv`模塊的`writer`方法,將相應的數據寫入到`response`中。 ## 將`csv`文件定義成模板: 我們還可以將`csv`格式的文件定義成模板,然后使用`Django`內置的模板系統,并給這個模板傳入一個`Context`對象,這樣模板系統就會根據傳入的`Context`對象,生成具體的`csv`文件。示例代碼如下: 模板文件: ``` <pre class="calibre12">``` {% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}" {% endfor %} ``` ``` 視圖函數: ``` <pre class="calibre12">``` <span class="hljs-keyword">from</span> django.http <span class="hljs-keyword">import</span> HttpResponse <span class="hljs-keyword">from</span> django.template <span class="hljs-keyword">import</span> loader, Context <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">some_view</span><span class="hljs-params">(request)</span>:</span> response = HttpResponse(content_type=<span class="hljs-string">'text/csv'</span>) response[<span class="hljs-string">'Content-Disposition'</span>] = <span class="hljs-string">'attachment; filename="somefilename.csv"'</span> csv_data = ( (<span class="hljs-string">'First row'</span>, <span class="hljs-string">'Foo'</span>, <span class="hljs-string">'Bar'</span>, <span class="hljs-string">'Baz'</span>), (<span class="hljs-string">'Second row'</span>, <span class="hljs-string">'A'</span>, <span class="hljs-string">'B'</span>, <span class="hljs-string">'C'</span>, <span class="hljs-string">'"Testing"'</span>, <span class="hljs-string">"Here's a quote"</span>), ) t = loader.get_template(<span class="hljs-string">'my_template_name.txt'</span>) response.write(t.render({<span class="hljs-string">"data"</span>: csv_data})) <span class="hljs-keyword">return</span> response ``` ``` ## 生成大的CSV文件: 以上的例子是生成的一個小的`csv`文件,如果想要生成大型的`csv`文件,那么以上方式將有可能會發生超時的情況(服務器要生成一個大型csv文件,需要的時間可能會超過瀏覽器默認的超時時間)。這時候我們可以借助另外一個類,叫做`StreamingHttpResponse`對象,這個對象是將響應的數據作為一個流返回給客戶端,而不是作為一個整體返回。示例代碼如下: ``` <pre class="calibre12">``` <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Echo</span>:</span> <span class="hljs-string">""" 定義一個可以執行寫操作的類,以后調用csv.writer的時候,就會執行這個方法 """</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">write</span><span class="hljs-params">(self, value)</span>:</span> <span class="hljs-keyword">return</span> value <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">large_csv</span><span class="hljs-params">(request)</span>:</span> rows = ([<span class="hljs-string">"Row {}"</span>.format(idx), str(idx)] <span class="hljs-keyword">for</span> idx <span class="hljs-keyword">in</span> range(<span class="hljs-params">655360</span>)) pseudo_buffer = Echo() writer = csv.writer(pseudo_buffer) response = StreamingHttpResponse((writer.writerow(row) <span class="hljs-keyword">for</span> row <span class="hljs-keyword">in</span> rows),content_type=<span class="hljs-string">"text/csv"</span>) response[<span class="hljs-string">'Content-Disposition'</span>] = <span class="hljs-string">'attachment; filename="somefilename.csv"'</span> <span class="hljs-keyword">return</span> response ``` ``` 這里我們構建了一個非常大的數據集`rows`,并且將其變成一個迭代器。然后因為`StreamingHttpResponse`的第一個參數只能是一個生成器,因此我們使用圓括號`(writer.writerow(row) for row in rows)`,并且因為我們要寫的文件是`csv`格式的文件,因此需要調用`writer.writerow`將`row`變成一個`csv`格式的字符串。而調用`writer.writerow`又需要一個中間的容器,因此這里我們定義了一個非常簡單的類`Echo`,這個類只實現一個`write`方法,以后在執行`csv.writer(pseudo_buffer)`的時候,就會調用`Echo.writer`方法。 注意:`StreamingHttpResponse`會啟動一個進程來和客戶端保持長連接,所以會很消耗資源。所以如果不是特殊要求,盡量少用這種方法。 ## 關于StreamingHttpResponse: 這個類是專門用來處理流數據的。使得在處理一些大型文件的時候,不會因為服務器處理時間過長而到時連接超時。這個類不是繼承自`HttpResponse`,并且跟`HttpResponse`對比有以下幾點區別: 1. 這個類沒有屬性`content`,相反是`streaming_content`。 2. 這個類的`streaming_content`必須是一個可以迭代的對象。 3. 這個類沒有`write`方法,如果給這個類的對象寫入數據將會報錯。 注意:`StreamingHttpResponse`會啟動一個進程來和客戶端保持長連接,所以會很消耗資源。所以如果不是特殊要求,盡量少用這種方法。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看