otkken2のプログラミング備忘録

学習の備忘録。自分向け

Django備忘録:DEBUG = Falseの時でもエラー内容の詳細を知りたい時、settings.pyにDEBUG_PROPAGATE_EXCEPTIONS = Trueを追記すると良い件について

タイトルのまんまです。

追記する前は、DEBUG = Falseの状態だと、Server Error(500)になっていても具体的にどんな点がよくなくてエラーになってるのかよくわかりませんでした。

そこでタイトルにも書いた設定を、settings.pyに追記してみましょう。

えいっ

settings.py

DEBUG_PROPAGATE_EXCEPTIONS = True

僕は今herokuへのデプロイを試みてるのでエラーが出てる状態で

heroku logs

コマンドを叩いてみます。

結果がこちら↓

2020-03-14T15:05:55.765734+00:00 app[web.1]: raise ValueError("Missing staticfiles manifest entry for '%s'" % clean_name)
2020-03-14T15:05:55.765778+00:00 app[web.1]: ValueError: Missing staticfiles manifest entry for 'css/style.css'
2020-03-14T15:05:55.766491+00:00 app[web.1]: 10.16.250.243 - - [15/Mar/2020:00:05:55 +0900] "GET / HTTP/1.1" 500 0 "-" "-"


親切に教えてくれるので、スタティックファイルに関してなんかおかしいんだなーってひとめで分かり大変ありがたいです!

便利!

備忘録:ローカル環境ではpython manage.py migrate がきちんと反映されるのに、heroku run python manage.py migrateでは反映されなかった件

現象:
タイトルの通り、heroku上で

$ heroku run python manage.py migrate

すると、

Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
.
.
.
.

と言った感じで、一見きちんと動いているようでいて、showmigrations コマンドで確認してみると

[  ] 0001_initial
 [  ] 0002_alter_permission_name_max_length
 [  ] 0003_alter_user_email_max_length
.
.
.
.

↑こんな表示であり、明らかにmigrationされていない。


試したこと:
ローカル上で全てのmigrationファイルを削除してmakemigrationsし直した。すると、きちんとmigrationファイルは作られるし、migrate した後にshowmigrations すると、

[X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
.
.
.
.

うん、きちんと反映されている。


つまり、herokuではうまくいかず、herokuでない状態だとうまく行く。
したがって、「herokuであるか否か」に起因する「何か」によってこの不具合は引き起こされていると考えられる。

では、その「何か」とはなにか?
settings.pyが怪しい。
だって↓こんな設定してるんだから

if not DEBUG:
    import django_heroku
    django_heroku.settings(locals())

DEBUG=Falseの場合のみdjango_herokuをimportしている。


なんだ。

そりゃそうだ。

もともと、本番環境ではDEBUG=Falseにしないとだめだよ〜ってのは知っていたし、実際最初はそうしていたのだが。
Falseの状態でheroku open しても Server Error(500)がドンっと表示されるだけの真っ白なブラウザに嫌気がさして、エラーの原因を詳しく教えてくれるDEBUG=False状態に戻していたのだった。


というわけで

解決策:
自分の場合、settings.pyのDEBUGの値をTrueにしていたことが原因だったのでDEBUG=Falseに設定し直してgit add ,commit ,push heroku master をした。
その後 heroku run python manage.py migrate したところ、showmigrations で確認してもきちんとXマークが表示されるようになりましたとさ。

めでたしめでたし。

備忘録:migrationsを削除してから再度makemigrationsする流れについて

事情がありmigrationファイルを全て消してイチから出直したくなった。
プロジェクトのあるディレクトリで下記コマンドを打てば__init__.py以外削除してくれる、とのことで実行

find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
find . -path "*/migrations/*.pyc"  -delete

そして再度migration ファイルを作ればよいとのこだが…

python manage.py makemigrations

エラーになってしまった。

ModuleNotFoundError: No module named 'django.db.migrations.migration'

何か俺は取り返しなつかないことをしてしまったのでは、という脇汗が吹き出す中、必死に気を落ち着かせてぐぐる

stackoverflow.com

pip3 uninstall Django
pip3 install Django

djangoを一度アンインストールしてから再度インストールしろ、ということらしい。素直に従う。


そして再度

python manage.py makemigrations

無事migrationファイルが作成されました!!
良かったー…(脇汗でTシャツがビシャビシャ)

Django エラー備忘録:複数のManyToManyFieldを持った検索フォームの実装でOR検索をしたら同じ記事が何十個も重複表示された件

バンドメンバー募集サイトを作成中です。メン募記事の検索機能を作ろうとしています。

活動エリア(都道府県)[active_area]、投稿者のパート[mypart]、募集するパート[recruite_part]、ジャンル[genre]という4つのManyToManyフィールドを記事は持っており、それらいづれかを含む記事を抽出して表示したい、という状況です。

 views.py

from django.db.models import Q
from .forms import *

def search(request):
    if request.method == "POST":
        form = PostContentForm(request.POST)
  #各ManyToManyフィールドの選択結果をリスト形式で取得 
        m2m_search_active_area = request.POST.getlist('active_area')
        m2m_search_mypart = request.POST.getlist('mypart')
        m2m_search_recruite_part = request.POST.getlist('recruite_part')
        m2m_search_genre = request.POST.getlist('genre')

        #以下のOR検索だと同じ記事が何回も重複して表示されてしまう。 
        postcontents = PostContent.objects.filter(Q(active_area__in = m2m_search_active_area) | Q(mypart__in = m2m_search_mypart) \
            |Q(recruite_part__in = m2m_search_recruite_part) |Q(genre__in = m2m_search_genre))
これやったら解決した
postcontents = PostContent.objects.filter(Q(active_area__in = m2m_search_active_area) | Q(mypart__in = m2m_search_mypart) \
            |Q(recruite_part__in = m2m_search_recruite_part) |Q(genre__in = m2m_search_genre)).distinct() #←末尾にdistinct()を追記


あじゃす