###前提・実現したいこと
実現したいこと:djangoにて、日本語で記入されたcsvをインポートできるようにしたい
使用言語:python3.6
フレームワーク:「Django1.11」
以下のサイトを参照に、djangoにてcsvアップローダーを作成しました。
【参照サイト】
https://torina.top/detail/324/
日本語にて記載されたcsvをインポートできるようにしたいのですが、
試しにcsvに「あいうえお」と入力しインポートした所、以下のエラーが発生してしまいました。
ValueError at /import/csv_import/
invalid literal for int() with base 10: 'あ'
こちらのバグを修正し、日本語のcsvをインポートできるようにするためには、
どこを修正したら良いでしょうか。
###該当のソースコード
以下に、views.pyとmodels.pyのソースコードを記載いたします。
①views.py
___________________________
python
1import csv 2from io import TextIOWrapper, StringIO 3from django.http import HttpResponse 4from django.shortcuts import redirect 5from django.views import generic 6from .models import Post, Category 7 8 9class IndexView(generic.ListView): 10 model = Post 11 12 13def csv_import(request): 14 form_data = TextIOWrapper( 15 request.FILES['csv'].file, encoding='utf-8') 16 if form_data: 17 csv_file = csv.reader(form_data) 18 for line in csv_file: 19 post, _ = Post.objects.get_or_create(pk=line[0]) 20 post.title = line[1] 21 post.text = line[2] 22 category, _ = Category.objects.get_or_create(name=line[3]) 23 post.category = category 24 post.save() 25 26 return redirect('app:index') 27 28 29def csv_export(request): 30 memory_file = StringIO() 31 writer = csv.writer(memory_file) 32 for post in Post.objects.all(): 33 row = [post.pk, post.title, post.text, post.category.name] 34 writer.writerow(row) 35 response = HttpResponse( 36 memory_file.getvalue(), content_type='text/csv') 37 response['Content-Disposition'] = 'attachment; filename=db.csv' 38 return response
②models.py
python
1from datetime import datetime 2from django.db import models 3 4 5class Category(models.Model): 6 7 name = models.CharField('カテゴリ名', max_length=255) 8 9 def __str__(self): 10 return self.name 11 12 13class Post(models.Model): 14 15 title = models.CharField('タイトル', max_length=255) 16 text = models.TextField('本文', max_length=255) 17 category = models.ForeignKey(Category, verbose_name='カテゴリ', null=True) 18 19 def __str__(self): 20 return self.title
③CSVファイルの内容
csv
11 2 3 4 23 4 5 6 34 2 3 4 4あ い う え 5
###試したこと
①以下のサイトを参考に、views.pyを変更
【参考にしたサイト】
http://qiita.com/niwaringo/items/d2a30e04e08da8eaa643
【書き換え内容】
書き換えた関数:csv_import
旧:csv_importのrequest.FILES['csv'].file, encoding='utf-8')
新:request.FILES['csv'].file, encoding='shift-jis')
②以下のサイトを参考に、models.pyを変更
【参考にしたサイト】
http://docs.djangoproject.jp/en/latest/ref/unicode.html
http://www.metareal.org/2008/04/11/django-unicode-encode-error/
【書き換え内容】
書き換えたクラス:Category
旧: def str(self):
return self.name
新: def unicode(self):
return self.name
書き換えたクラス:Post
旧:def str(self):
return self.title
新:def unicode(self):
return self.title
上記のように、views.pyとmodels.pyを書き換え、再度確認してみましたが、
同様のエラーが発生する状態です。
int()の引数に対し書式が違うというエラーのようですが、
int関数を指定しておらず、どこを変更すればcsvファイルにて日本語を読み込めるのか、分からない状態です。
pythonもdjangoも初心者のため、不足している情報等ありましたら申し訳ございません。
どうぞ宜しくお願い致します。
【追記】
回答欄にてご指摘いただき、以下の修正を行いました。
①views.pyの関数の文字コードをutf_8_sigに指定
python
1def csv_import(request): 2 form_data = TextIOWrapper( 3#文字コードをutf_8_sigに指定 4 request.FILES['csv'].file, encoding='utf_8_sig') 5 if form_data: 6 csv_file = csv.reader(form_data) 7 for line in csv_file: 8 post, _ = Post.objects.get_or_create(pk=line[0]) 9 post.title = line[1] 10 post.text = line[2] 11 category, _ = Category.objects.get_or_create(name=line[3]) 12 post.category = category 13 post.save()
②models.py上の不要な変更点を元に戻す
※試したこと の項目の、②の変更点を変更前(冒頭に貼ったmodels.pyのコードの状態)に戻しました
再度ファイルをアップロードしてみた所、
以下のエラーが発生いたしました。
'utf-8' codec can't decode byte 0x82 in position 27: invalid start byte
csvファイル冒頭の「ID」の部分に日本語の入力をしているのがおかしいのかと考え、
「ID」は数字、ほかは日本語の状態にしアップロードしましたが、エラー内容は変わりませんでした。
1 2 3 4 3 4 5 6 4 2 3 4 5 あ い う
models.pyにてpyという変数を定義し、
views.pyのpost, _ = Post.objects.get_or_create(pk=line[0])の箇所を修正することで、
上記のエラーは解消できるでしょうか。
【追記②】
kacchan822様にご回答いただいたとおりにviewとmodelを修正し、
can110様にご指摘いただいたとおりにファイルの文字コードを「utf-8」へと変更した所、
無事にファイルをインポートすることができるようになりました!
コメント欄、回答欄にて適切なご指摘を下さり誠にありがとうございました。

回答1件
あなたの回答
tips
プレビュー