132
158

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DjangoAdvent Calendar 2018

Day 16

Djangoよくあるエラー集

Posted at

djangoで発生するエラー(例外)とその原因です.
エラーの9割くらいはtypoが原因ですので,原因箇所の文字列に打ち間違えがないかよくチェックしましょう.
レアなケースですが,特殊文字が挟まっていて原因がわからない(わかりにくい)ことがあるので,
editorは特殊文字を表示できるものを使いましょう.

tl;dr

  • 原因はほぼtypo(タイプミス,打ち間違い)
  • エラーの場所と原因は(ほとんどの場合)ちゃんと教えてくれてる → 英語だけどがんばって読め
  • ロジックのミスはエラーじゃないです.プログラムは書いた通りに動きます

エラー表示と友達になろう

「なんか動かないんだけど!」「エラーが発生しました!」
原因はちゃんと書いてくれるので,読んでみましょう.
大体は英語ですが, 「どこで」「なにを」間違えているか読み取れれば十分です.

something_happend.jpeg
わかりやすいエラー表示の例

ターミナルに表示されるエラーの読み方

$ python manage.py runserver と打った時に発生するエラーはdjangoというよりもpythonのエラーがほとんどのはずです.
manage.pyは初期化時に urls.pymodels.py を読み込みます.
また, urls.pyviews.py を importして使用します.
この中のファイルに構文エラーなどがあればターミナルに英語が大量に表示され,動作が停止します.

$ python manage.py runserver
Performing system checks...

Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x102037d08>
Traceback (most recent call last):
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/utils/autoreload.py", line 225, in wrapper
    fn(*args, **kwargs)
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/core/management/commands/runserver.py", line 117, in inner_run
    self.check(display_num_errors=True)
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/core/management/base.py", line 379, in check
    include_deployment_checks=include_deployment_checks,
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/core/management/base.py", line 366, in _run_checks
    return checks.run_checks(**kwargs)
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/core/checks/registry.py", line 71, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/core/checks/urls.py", line 13, in check_url_config
    return check_resolver(resolver)
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/core/checks/urls.py", line 23, in check_resolver
    return check_method()
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/urls/resolvers.py", line 396, in check
    for pattern in self.url_patterns:
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/utils/functional.py", line 37, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/urls/resolvers.py", line 533, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/utils/functional.py", line 37, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/urls/resolvers.py", line 526, in urlconf_module
    return import_module(self.urlconf_name)
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/shimomura/elv/tutorial/tutorial/urls.py", line 33, in <module>
    url(r'^polls/', include('polls.urls', namespace='polls')),
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/site-packages/django/urls/conf.py", line 34, in include
    urlconf_module = import_module(urlconf_module)
  File "/Users/shimomura/.virtualenvs/tutorial/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/shimomura/elv/tutorial/polls/urls.py", line 8, in <module>
    url(r'^$', views.idex, name='index'),
AttributeError: module 'polls.views' has no attribute 'idex'

ずらずら表示されているものは スタックトレース(Stack Trace) というもので,プログラムの呼び出し順序が記録されてものです.
pythonではこの表示に traceback という標準ライブラリが使用されるため,最初のほうに
Traceback (most recent call last):
と表示されています.

上から順番に,どのファイルの,何行目の,どの関数(メソッド)から呼び出されたかが書いてますが,
必要なのは 最終的にどこでエラーが発生したかどういう内容か だけなので
一番下のこの2行以外見る必要ありません.

場合によってはライブラリがエラーの発生元になっており,自分が書いたコードではない場合があります.
その場合は File に自分が編集したファイルが出てくるまで数行さかのぼりましょう.
後述しますが,ブラウザでエラーが見える場合は自分のコードはハイライトされます.

  File "/Users/shimomura/elv/tutorial/polls/urls.py", line 8, in <module>
    url(r'^$', views.idex, name='index'),
AttributeError: module 'polls.views' has no attribute 'idex'

上の行が最終的にエラーが発生した場所,下の行がエラーの種類とその詳細です.

エラー画面の読み方

$ python manage.py runserver 実行後,
ブラウザでページを開いた時にエラーが発生した場合は専用のエラー画面が表示されます.
ターミナル上にも先程のようにスタックトレースとエラー内容が表示されますが,
ブラウザ上ではより多くの情報が見やすく表示されているので, runserver が成功しているのであれば
この画面から確認するほうがいいでしょう.
とはいえ,見るべきポイントは先程と同じくスタックトレース(Traceback)の一番下と,エラーの種類くらいです.

スクリーンショット 2018-12-15 12.56.36.png

'Local varsをクリックするとその関数(メソッド)内で使用している変数の内容が表示されるので,ranse Exception` などとコードを書いてわざと例外を発生させることで
所謂printfデバッグ的なこともできます.

Python組み込みのエラー

Python公式ドキュメント

下記のように条件分岐の中で定義した変数は条件を通らない場合使えないので注意してください.

if False:
    x = 10
print(x)  # NameErrorが発生

AttributeError

pythonではクラスやモジュールの属性に . で繋いでアクセスしますが,指定した属性を持っていない時にこのエラーが発生します.

モジュールの属性とはファイル内にインデントなしで記述した変数,関数,クラスなどのことです.

hoge.py
a = 10
def my_func():
    pass
class MyClass(object):
    pass
fuga.py
import hoge

hoge.a  # ok
hoge.my_func() # ok
hoge.MyClass() # ok

hoge.b # <-- AttributeError

urls.pyで発生することが多いと思います.
. の後ろの文字がtypoしているので,関数名などが間違えていないか確認しましょう.

エラー例

  File "/Users/shimomura/elv/tutorial/polls/urls.py", line 8, in <module>
    url(r'^$', views.idex, name='index'),
AttributeError: module 'polls.views' has no attribute 'idex'
polls.views.py
from . import views
...
    url(r'^$', views.idex, name='index'),
                 #   ↑ indexのtypo

ImportError

その名の通り,importできなかった,というエラーです.
モジュール名(=ファイル名)をtypoしてます.
ファイルやディレクトリ名をもう一度確認しましょう.

エラー例

  File "/Users/shimomura/elv/tutorial/polls/urls.py", line 3, in <module>
    from . import view
ImportError: cannot import name 'view' from 'polls' (/Users/shimomura/elv/tutorial/polls/__init__.py)

この場合は viewsview になってます.


Traceback (most recent call last):
  File "./manage.py", line 8, in <module>
    from django.core.management import execute_from_command_line
ImportError: No module named django.core.management

こんな感じで django がないって言われたら仮想環境へ入れてないか,まだインストールしていないのが原因です.

循環importのエラー(ImportError / AttributeError)

ソースとしては特に問題がなさそうでも,循環importしている場合は名前解決ができないので発生します.

  File "/Users/shimomura/elv/tutorial/polls/models.py", line 5, in <module>
    from . import views
  File "/Users/shimomura/elv/tutorial/polls/views.py", line 10, in <module>
    from .forms import MyForm
  File "/Users/shimomura/elv/tutorial/polls/forms.py", line 3, in <module>
    from .models import Question
ImportError: cannot import name 'Question' from 'polls.models' (/Users/shimomura/elv/tutorial/polls/models.py)

views.py から models.py を importし, さらに models.py から views.py をimportした場合,上記のようになります.
使っている箇所によってImportErrorになったりAttributeErrorになったりします.
typoが無さそうなのにエラーになっている場合は相互にimportしていないか確認してみてください.

-参考: Pythonで循環インポートするとどうなるのか

SyntaxError

構文エラーです.
pythonの基本的な構文を間違えてます.
エラーが出ている箇所をよく見てみましょう.
実際の原因は前の行の場合もよくあるので,エラーが見つからなければ少し前の行も見てみましょう.

エラー例

  File "/Users/shimomura/elv/tutorial/polls/views.py", line 24
    if True
          ^
SyntaxError: invalid syntax

if文の最後に : がないです.


  File "/Users/shimomura/elv/tutorial/polls/views.py", line 24
    x = 10
         ^
SyntaxError: invalid character in identifier

全角スペースが入っていると invalid character in identifier とメッセージが変わります.
最初のうちは見つけるのがなかなか大変ですが,pythonは明示的にメッセージを出してくれるので割とわかりやすいです.
全角スペースを明示してくれるエディタを使いましょう.

ブラウザのせいかqiitaのせいかわからないですが,全角スペースがコピペできなかったです

IndentationError

これも一種のSyntaxErrorですが,より具体的です.
インデントが揃ってなかったり,下げすぎてたりすると発生します.

  File "/Users/shimomura/elv/tutorial/polls/views.py", line 25
     return render(request, 'polls/index.html', {
    ^
IndentationError: unexpected indent
エラーが出たソースコード
def index(request):
   x = 10
    return render(request, 'polls/index.html', {
        'questions': Question.objects.all(),
    })

この場合は x = 10 の行とその次の return の行のindentが揃ってないです.
エラーが出ているのはreturn の行ですが, x = 10 の行はスペースが3つしなかいので,実はこの行が原因です.


  File "/Users/shimomura/elv/tutorial/polls/views.py", line 25
    return render(request, 'polls/index.html', {
                                               ^
IndentationError: unindent does not match any outer indentation level
エラーが出たソースコード
def index(request):
        x = 10
    return render(request, 'polls/index.html', {
        'questions': Question.objects.all(),
    })

indentを8個にするとエラーメッセージが変わります.

TabError

  File "/Users/shimomura/elv/tutorial/polls/views.py", line 26
    Question.objects.get(pk=100)
                               ^
TabError: inconsistent use of tabs and spaces in indentation

indentがスペースじゃなくtabになっている場合に発生します.

NameError

定義していない名前の変数を代入しようとしたり,引数で指定すると発生します.
引数で受け取った request を使おうとして reqest などとtypoして発生します.

  File "/Users/shimomura/elv/tutorial/polls/views.py", line 21, in index
    x = y
NameError: name 'y' is not defined

KeyError

辞書を参照する際に,存在しないkeyを触ると発生します.

d = {}
x = d['hoge']  # KeyError

KeyErrorを発生させたくない場合は in で存在確認するか, get を使います.

if 'hoge' in d:
    x = d['hoge']
# もしくは
x = d.get('hoge')

UnicodeDecodeError

bytes 型を str 型に変換する際に,変換できない文字が含まれていると発生します.
uft8 だと思ったら sjis だった,というふうにファイル読み込み時に文字コードを間違えると発生します.

UnicodeEncodeError

str 型から bytes 型に変換する際に,変換できない文字が含まれていると発生します.
csvの出力を作る際は文字コードをexcelで開けるようにsjisで出力することがよくありましたが,
梯子高(高の旧字体)の高橋さんなど,機種依存文字が入っていると発生します.
ちなみに変換時に第2引数をつけることでエラーを発生させなくできます.

スクリーンショット 2018-12-16 0.37.42.png

djgnao初期化時のエラー

# 色々書こうとしたけど結局ほとんどAttributeErrorやImportErrorだった…
# 何かわけわからないエラーが出たって人は教えてください

RuntimeError("populate() isn't reentrant")

初期化が正常に終了しなかった場合に発生します.
初期化途中に発生した例外をdjangoが握りつぶした上で発生するので,とても見つけにくいです.
独自のFieldクラス等を定義して,そのコードに不備があった場合に発生した気がしますが,
発生条件覚えてないので発生した人教えてください.

Viewやテンプレートのエラー

./manage.py runserver 成功後,

ランタイムエラーって書こうとしたけどスクリプト言語だと全部ランタイムでまさかられそうだったので…

TemplateDoesNotExist

render関数などに渡したtemplateのパスが間違っている場合に発生します.
指定した文字列をtypoしている場合と,設定の問題で正しくファイルを探せていない場合があります.
特に manage.py runserver を実行したまま新しくテンプレート用のディレクトリを作成した場合は読み込めていない場合があるので
コマンドを再実行してみましょう.
エラー内容の中にどこからファイルを探したかが出ているので,そこを確認すれば大丈夫です.

スクリーンショット 2018-12-15 19.05.34.png

render関数の呼び出しは複数行になることが多いと思いますが,
その場合スタックトレースの呼び出し元が微妙にずれて表示されることがあります.
クリックすれば前後の内容が表示されます.

スクリーンショット 2018-12-15 19.09.01.png

NoReverseMatch

template内で使用している {% url %} タグや django.shortcuts.redirect 関数に渡した名前を解決出来ない時に発生します.

  • 指定した名前をtypoしている
  • urls.pyの name=の部分をtypoしている
  • namespaceがない
    などが原因です.
スクリーンショット 2018-12-15 19.57.46.png

モデル操作時のエラー

Modelクラスを操作する際に発生するエラー

DoesNotExist

Managerクラス(QuerySet)の get メソッドを使用した際に,条件に一致するデータがDBにない場合に発生します.
URL等でユーザから入力される数値を元に検索している場合はチュートリアル通りキャッチして http404 を投げるようにしましょう.

スクリーンショット 2018-12-15 19.35.01.png

MultipleObjectsReturned

DoesNotExist と似てますが,今度は複数のデータが見つかった場合に発生します.
画像の例では6個みつかっています.
getメソッドでは複数のデータを扱うことができないので,条件にはpkのようなunique制約のあるフィールドを使うようにしましょう.

pkは primary key の略で,DBで主キーとして使用されるフィールドです.
djangoではデフォルトで id という名前のフィールドで作成されますが, get(pk=1) のように使うことも出来ます.

スクリーンショット 2018-12-15 19.43.53.png

FieldError

getやfilterで指定したフィールド名が間違っています.
エラーの詳細に指定可能なフィールド名も書かれているので見比べてみましょう.

スクリーンショット 2018-12-15 19.47.01.png

httpエラー

今まではhttp的にはステータスコード500を返す,サーバエラーでした.
この節では400番代のステータスコードに対応する例外と,発生した場合の原因について説明します.
djangoでは特殊な例外が内部で発生した場合,
django.core.handler.exception.response_for_exception の中で捕まえて,
専用のエラーページを表示しています.

ほとんどのケースでは自分で設定するものなのでurls.pyの指定ミスによる404以外では困ることはないと思います.
例外の紹介だけで詳細は省きます.

Http404

urlに対応するviewがない場合に発生する例外です.
原因はurlの設定もしくはブラウザに指定したURLのtypoです.

スクリーンショット 2018-12-15 19.01.44.png

url的には正しくても,データの都合でこの例外を発生させることもあります.
詳細ページなどではURLでデータのpkを指定しますが,対応するデータがない場合はこの例外を出します.
その他にも403(権限なしエラー)の代わりに,ページの存在を知らせない意味で404にする場合もあります.

スクリーンショット 2018-12-15 23.43.45.png

PermissionDenied

権限なしエラーです.
httpステータスコードとしては403になります.

400系

Bad Reuqestを表す400ですが,内部的には原因により例外が分かれています.

DisallowedHost

debugモードではない時に settings.pyALLOWED_HOSTS の値が正しく設定されていないと発生.

TooManyFieldsSent

getやpostで送付するフィールド数が一定数エラーの場合に発生.
デフォルトは1000.

RequestDataTooBig

送付するデータが一定以上のサイズの場合に発生するエラー.
デフォルトは2.5MB.
ファイルアップロードではなくパラメータとして送付したデータのサイズ数

MultiPartParserError

その名の通りマルチパートでpostした際のパースエラーです.
jsなどで自前でデータを生成すると遭遇するかもしれません.

132
158
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
132
158

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?