質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

2206閲覧

djangoにて日本語のcsvをインポートする方法

komatsuna

総合スコア7

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2017/09/07 05:54

編集2017/09/07 09:48

###前提・実現したいこと

実現したいこと: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」へと変更した所、
無事にファイルをインポートすることができるようになりました!

コメント欄、回答欄にて適切なご指摘を下さり誠にありがとうございました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2017/09/07 08:43

インポートしたCSVファイルも提示ください(先頭「ID」列にはどのような値が入っているか?)
komatsuna

2017/09/07 08:46 編集

質問をご確認いただきありがとうございます。 以下に、インポートしたCSVファイルの内容を記載いたします。 ======================================================= 1 2 3 4 3 4 5 6 4 2 3 4 あ い う え ======================================================= 最後の行の「あいうえ」の情報を入力した所、エラーが発生している状態です。
can110

2017/09/07 08:50

追記ありがとうございます。が、内容が確認しずらいため、CSVファイルをテキストエディタで開き全てコピーし、質問本文にコードで囲んで(貼付)追記ください。
komatsuna

2017/09/07 08:53

ご確認ありがとうございます。内容が確認しづらく、失礼いたしました。質問本文にcsvファイルの内容を追記いたしました。お手すきの際にご確認いただけますと幸いです。
can110

2017/09/07 09:00

修正ありがとうございます。先頭に「あ」が入っていますね。おおむねkacchan822さんの回答のとおりだと思います。
can110

2017/09/07 09:25

インポートしたCSVファイルの文字コードもテキストエディタなどで確認し追記ください(0x82なのでshift-jisだと思われますが)
komatsuna

2017/09/07 09:30 編集

ご指摘くださりありがとうございます!文字コードを確認した所、ANSIとなっておりました。utf-8を指定し再度アップしたところ、無事にファイルをアップロードすることができました。 文字コードに関しまして、とても初歩的な部分で躓いていたようです。 本件に関しまして、お時間を割いてくださりありがとうございました。
guest

回答1

0

ベストアンサー

post, _ = Post.objects.get_or_create(pk=line[0])

→ おそらくこの部分ではないかと思います。
pkは、modelで特に指定していないようなので、int型です。エラーから見ると
**lin[0]**に入っているのはintではないのではないでしょうか。
(エラーメッセージ的には、「あ」?)

旧:csv_importのrequest.FILES['csv'].file, encoding='utf-8')
新:request.FILES['csv'].file, encoding='shift-jis')

→ 最近のExcelなどで作成されたcsvであれば文字コードは、utf8だと
思われますので、shift-jisでなくてよいと思います。
→ Excelで作られた場合は、BOM付きUTF8というのになっているので、
utf_8_sigを指定するとよいと思います。

旧: 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

→ Python3.6を使用されているので、書き換えなくて問題ありません。

投稿2017/09/07 08:46

編集2017/09/07 08:48
kacchan822

総合スコア57

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

komatsuna

2017/09/07 09:03 編集

ご回答くださりありがとうございます。 models.pyに「pk」の指定をstr型で入れれば解決する、というようなことでしょうか。 python3.6の場合は、strとunicodeの部分の書き換えは不要とのことでしたので、models.pyは変更前の状態に修正致しました。 また、views.pyに関しましては、 旧:request.FILES['csv'].file, encoding='shift-jis') 新:request.FILES['csv'].file, encoding='utf_8_sig') というふうに記載を直し、再度日本語の含まれるファイルをアップロード致しました。 そうすると、 「'utf-8' codec can't decode byte 0x82 in position 27: invalid start byte」 というエラーが発生している状態です。 先程と同じく、日本語の部分で弾かれている状態かと考えておりますが、 models.pyを修正することで解決できるでしょうか。
komatsuna

2017/09/07 09:49 編集

上記修正の上、 文字コードの修正を行ったところ無事にファイルをインポートできました。 ファイルの文字コードを間違えて降りました。 この度は、丁寧にご回答くださりありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問