【django】csvのダウンロード・アップロードの方法

Django

djangoでcsvの取り扱いについて紹介します。

主にdjangoでcsvをダウンロードするコードと
アップロードするコードを紹介して
その後に実際に動かしたサンプルを紹介します。

djangoでcsvをダウンロードする部分

djangoでcsvを出力させるには
views.pyにこのコードを書けばOKです。

import csv
from django.http import HttpResponse

def csv_export(request):
    # csvファイルを作るコード
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment;  filename="filename.csv"'
    writer = csv.writer(response)

  # ここからcsvの内容を編集コード
    writer.writerow(['1', 'い'])
    writer.writerow(['2', 'ろ'])
    writer.writerow(['3', 'は'])

    return response

各部分の詳細を説明します。

    # csvファイルを作るコード
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment;  filename="filename.csv"'
    writer = csv.writer(response)

この部分はあまり変えないお約束のコードだと思っておいてください。

1行目の response = HttpResponse(content_type=’text/csv’) では
「csvを出力させるよ」とレスポンスに指令をします。

2行目response[‘Content-Disposition’] = ‘attachment; filename=”filename.csv”‘
「ダウンロード(attachment)、ファイル名は”filename.csv”」
と指定しています。ここでファイル名は好きに変えてください。

3行目writer = csv.writer(response)は
responseにcsv形式で書き込んでいくための記述です。

  # ここからcsvの内容を編集コード
    writer.writerow(['1', 'い'])
    writer.writerow(['2', 'ろ'])
    writer.writerow(['3', 'は'])

    return response

writer.writerow ([ ])でcsvに書く値を
1行ずつリスト形式で記入します。

最後にreturn responseで返値とすればOKです。

djangoでcsvをアップロードする部分

ここではHTMLとdjango のviews.pyの2つのファイルが必要です。

<form action="{% url 'csv_import' %}" method='POST' enctype="multipart/form-data">
  {% csrf_token %}
  <input type="file" name="csv">
  <button type="submit">送信</button>
</form>

HTMLでは<form>でcsvをアップロード後のURLとPOSTリクエスト
enctypeでファイルを送るためのお約束の”multipart/form-data”を書きます。

{% csrf_token %} はdjangoでお約束の形式ですね。
そのあと、<input>でtype=fileとして<button>で送信します。

そんなに難しいことはしてないですね。いつものHTML形式です。

import csv
import oi

def csv_import(request):
    if 'csv' in request.FILES:
        data = io.TextIOWrapper(request.FILES['csv'].file, encoding='utf-8')
        csv_content = csv.reader(data)
        for i in csv_content:
            print(i)
 # 出力結果
 ['1', 'い']
 ['2', 'ろ']
 ['3', 'は']

HTMLで送られてきた先のviews.pyを記述します。

if 'csv' in request.FILES:
    data = io.TextIOWrapper(request.FILES['csv'].file, encoding='utf-8')
    csv_content = csv.reader(data)

1行目ではrequestの中にFILESがあり、
それがHTMLの<input>のname=’csv’から来たかを判断してます。

2行目data = io.TextIOWrapper(request.FILES[‘csv’].file, encoding=’utf-8′)
name=’csv’で送られてきたファイルであれば
ファイル内を読めるようにutf-8へ変更し、dataとします。

3行目csv_content = csv.reader(data)では
utf-8へ変更したファイルをcsv形式にさらに変更します。

これでcsvファイルを読み込みが終わり、書き換えなどができるようになります。

ここからはdjangoでcsvを扱った簡単な実例のコードを紹介します。

djangoでcsvを扱う実例コード

こんな感じの動きをするコードです。
データベース内の値をcsvで出力。反対に、入力したcsvをデータベースに反映させます。

データベース内の値を一覧表示させています。
その下のcsv出力で、データを出力します。

出力したcsvにデータを追加。

変更したcsvをファイルを選択で取り入れて、送信をポチ。

すると、取り入れたcsvファイルのデータをデータベースに反映します。

各コードはこんな感じです。
urls.py

from . import views
from django.urls import path

urlpatterns = [
    path('', views.list, name='list'),
    path('import/', views.csvimport, name='csvimport'),
    path('export/', views.csvexport, name='csvexport'),
]

models.py

from django.db import models

class Hiragana(models.Model):
    moji = models.CharField('平文字', max_length=50)

    def __str__(self):
        return self.moji

views.py

from django.shortcuts import render, redirect
from .models import Hiragana
from django.http import HttpResponse
import csv, io

def list(request):
    hiragana_list = Hiragana.objects.all()
    return render(request, 'list.html', {'hiragana':hiragana_list})

def csvexport(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment;  filename="somefilename.csv"'

    writer = csv.writer(response)
    for moji in Hiragana.objects.all():
        writer.writerow([moji.pk, moji.moji])
    return response

def csvimport(request):
    if 'csv' in request.FILES:
        data = io.TextIOWrapper(request.FILES['csv'].file, encoding='utf-8')
        print(data)
        csv_content = csv.reader(data)
        print(csv_content)
        for i in csv_content:
            hiragana, created = Hiragana.objects.get_or_create(moji = i[1])
            hiragana.pk = i[0]
            hiragana.moji = i[1]
            hiragana.save()
        return redirect('list')
    else:
        return redirect('list')

最後にHTML

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    <title>list</title>
  </head>
  <body>
    <table class="table">
        <thead>
          <tr>
            <th>pk</th>
            <th>ひらがな</th>
          </tr>
        </thead>
        <tbody>
          {% for hira in hiragana %}
            <tr>
              <td>{{ hira.pk }}</td>
              <td>{{ hira.moji }}</td>
            </tr>
          {% endfor %}
        </tbody>
      </table>
    
      <a href="{% url 'csvexport' %}" class="btn btn-primary">csv出力</a>
      <form action="{% url 'csvimport' %}" method='POST' enctype="multipart/form-data">
        {% csrf_token %}
        <input type="file" name="csv">
        <button type="submit">送信</button>
      </form>
  </body>
</html>

以上です。

最後に

ここまでお付き合いいただきありがとうございました。

まだ余力があるので、私のDjango勉強本を紹介します。

djangoの基礎から細かな箇所まで書いてあり
実際にコードを書く上でも非常に参考になります。

タイトルとURLをコピーしました