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

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

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

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Django

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1354閲覧

例外ValueErorrのキャッチ場所

kwmr8416

総合スコア6

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Django

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2020/11/02 02:42

DjangoにてCSVインポート時の例外処理を実装しています。Django及びPython初心者になります。
この度、型の不一致時(IntegerFieldの項目に全角文字を取り込む等)の例外種類であるValueErorrを
キャッチして画面にエラーメッセージ('データに誤りがあります。')を表示させるため、try-except文を記述していますが、
エラー発生箇所が特定できない及びtry-except文の記述が無効な場所として逆に例外(ValidationError)がスローされてしまう
状況に陥っています。

forms.py

import io import csv from django import forms from setting.models import worktypemaster class CSVUploadForm(forms.Form): file = forms.FileField(label='CSVファイル', help_text='※拡張子csvのファイルをアップロードしてください。') def clean_file(self): file = self.cleaned_data['file'] # ファイル名が.csvかどうかの確認 if not file.name.endswith('.csv'): raise forms.ValidationError('拡張子がcsvのファイルをアップロードしてください。') # csv.readerに渡すため、TextIOWrapperでテキストモードなファイルに変換 csv_file = io.TextIOWrapper(file, encoding='cp932') reader = csv.reader(csv_file) # 各行から作った保存前のモデルインスタンスを保管するリスト self._instances = [] try: # 一旦データベースを削除する worktypemaster.objects.all().delete() # idの値として挿入するカウンター i = 1 for row in reader: worktypemaster_db = worktypemaster(id=i, worktypecd=row[0], workcontents=row[1]) self._instances.append(worktypemaster_db) i += 1 except UnicodeDecodeError: raise forms.ValidationError('ファイルのエンコーディングや、正しいCSVファイルか確認ください。') except IndexError: raise forms.ValidationError('項目数が足りないレコード(行)があります。') #↓ここではValuErorrは拾わない except ValueError: raise forms.ValidationError('データに誤りがあります。') return file def save(self): for worktypemaster_db in self._instances: #↓このtry-except文でValidationErrorが発生する try: worktypemaster_db.save() except ValueError: raise forms.ValidationError('データに誤りがあります。')

views.py

class PostImport(generic.FormView): template_name = 'setting/import.html' success_url = reverse_lazy('setting:index') form_class = CSVUploadForm def form_valid(self, form): form.save() return redirect('setting:index')

以上が現状の問題です。CSVインポート時のValueErorrの例外処理の記述方法について、
アドバイス等頂けますでしょうか、よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

自己解決

この度はCSVインポート時に例外ValueErorrをキャッチしようと試みましたが、少し考えるとValueErorrが発生する前に正規表現で当該データの妥当性を確認し、妥当ではない場合はraiseで処理を中断することで実装方法を変更してみることにしました。ただ当初の実装方法であるtry-except文ではないため、あらかじめ対象の列を指定しなければなりません。よって恒久処置にはなりえません。
下記コードでは、その対象列として1列目(row[0])がIntegerFieldで定義してあるものとします。

forms.py(※修正後)

import csv import io from django import forms from setting_worktypemaster.models import worktypemaster # ※修正後:追加モジュール import re class CSVUploadForm(forms.Form): file = forms.FileField(label='CSVファイル', help_text='※拡張子csvのファイルをアップロードしてください。') def clean_file(self): file = self.cleaned_data['file'] # ファイル名が.csvかどうかの確認 if not file.name.endswith('.csv'): raise forms.ValidationError('拡張子がcsvのファイルをアップロードしてください') # csv.readerに渡すため、TextIOWrapperでテキストモードなファイルに変換 csv_file = io.TextIOWrapper(file, encoding='cp932') reader = csv.reader(csv_file) # 各行から作った保存前のモデルインスタンスを保管するリスト self._instances = [] try: # 一旦データベースを削除する worktypemaster.objects.all().delete() # idの値として挿入するカウンター i = 1 for row in reader: post = worktypemaster(id=i, worktypecd=row[0], workcontents=row[1]) # ※修正後:追加箇所ここから pattern = r'[0-9]+' text = row[0] result = re.match(pattern, text) if not(result): raise forms.ValidationError('データに誤りがあります。') # ※修正後:追加箇所ここまで self._instances.append(post) i += 1 except UnicodeDecodeError: raise forms.ValidationError('ファイルのエンコーディングや、正しいCSVファイルか確認ください。') except IndexError: raise forms.ValidationError('項目数が足りないレコード(行)があります。') return file def save(self): for post in self._instances: post.save()

投稿2020/11/03 11:37

編集2020/11/03 11:43
kwmr8416

総合スコア6

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問