🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Django

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

Python 3.x

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

Python

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

Q&A

解決済

2回答

1557閲覧

pythonのフォーム入力の際にエラーメッセージを表示させたい

hisa_eng

総合スコア3

Django

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

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2021/01/30 07:31

編集2021/01/30 08:44

前提・実現したいこと

python3の初学者です。python3を用いて簡易的なスクレイピングのアプリを作成しています。現在は、ブラウザ上でビューファイルは問題なく表示され、urlを用いたスクレイピングも行えています。しかし、例外のurlで抽出すると、(IndexError: list index out of range)が発生するため、例外時に画面上にフォームエラーのメッセージを表示させたいのですが、表示されなくて困っております。

エラーメッセージの表示方法は以下のURLのサイトを参考にしました
参考URL

実際に実装を進めると、以下の様な(TemplateDoesNotExist at /path/to/form-alert.html)のエラーが発生している状況です。

発生している問題・エラーメッセージ

python

1Traceback (most recent call last): 2 File "/Users/hoge/.pyenv/versions/3.7.0/lib/python3.7/site-packages/django/core/handlers/exception.py", line 47, in inner 3 response = get_response(request) 4 File "/Users/hoge/.pyenv/versions/3.7.0/lib/python3.7/site-packages/django/core/handlers/base.py", line 202, in _get_response 5 response = response.render() 6 File "/Users/hoge/.pyenv/versions/3.7.0/lib/python3.7/site-packages/django/template/response.py", line 105, in render 7 self.content = self.rendered_content 8 File "/Users/hoge/.pyenv/versions/3.7.0/lib/python3.7/site-packages/django/template/response.py", line 83, in rendered_content 9 return template.render(context, self._request) 10 File "/Users/hoge/.pyenv/versions/3.7.0/lib/python3.7/site-packages/django/template/backends/django.py", line 63, in render 11 reraise(exc, self.backend) 12 File "/Users/hoge/.pyenv/versions/3.7.0/lib/python3.7/site-packages/django/template/backends/django.py", line 84, in reraise 13 raise new from exc 14django.template.exceptions.TemplateDoesNotExist: path/to/form-alert.html

該当のソースコード

以下にエラーメッセージに関連するコードを記述します
form-alart.html

python

1{% if form.non_field_errors %} 2<ul class="alert alert-danger list-unstyled"> 3 <li style="list-style-type: none;"> 4<ul class="alert alert-danger list-unstyled">{% for error in form.non_field_errors %} 5 <li>{{ error }}</li> 6</ul> 7 </li> 8</ul> 9{% endfor %} 10 11{% endif %}

home.html

python

1{% extends 'base.html' %} 2 3{% block header %} 4<div class="jumbotron"> 5 <div class="container"> 6 <h1 class="display-4">News</h1> 7 <p class="lead">NewsのURLを記述してください</p> 8 </div> 9 </div> 10{% endblock header %} 11 12{% block content %} 13<div class="container"> 14{% include 'path/to/form-alert.html' %}    #エラーを表示させたい箇所 15<form action='' method='POST'>{% csrf_token %} 16<p>URL: <input type="text" name='url'></p> 17<input type="submit" value="取得する"> 18</form> 19</div> 20{% endblock content %}

settings.pyのテンプレートの部分のコード

python

1TEMPLATES = [ 2 { 3 'BACKEND': 'django.template.backends.django.DjangoTemplates', 4 'DIRS': [BASE_DIR, 'templates'], 5 'APP_DIRS': True, 6 'OPTIONS': { 7 'context_processors': [ 8 'django.template.context_processors.debug', 9 'django.template.context_processors.request', 10 'django.contrib.auth.context_processors.auth', 11 'django.contrib.messages.context_processors.messages', 12 ], 13 }, 14 }, 15]

view.pyのコード

python

1from django.shortcuts import render 2from .models import News 3from django.views.generic import CreateView 4from django.urls import reverse_lazy 5import urllib.request 6import requests 7from bs4 import BeautifulSoup 8 9 10class Create(CreateView): 11 template_name = 'home.html' 12 model = News 13 fields = ('url',) 14 success_url = reverse_lazy('list') 15 16 17def listfunc(request): 18 for post in News.objects.all(): 19 url = post.url 20 list = [] 21 response = requests.get(url) 22 bs = BeautifulSoup(response.text, "html.parser") 23 ul_tag = bs.find_all(class_="yjnSubTopics_list") 24 for tag in ul_tag[0]: 25 title = tag.a.getText() 26 url2 = tag.a.get("href") 27 list.append([title, url2]) 28 context = {'list': list,} 29 return render(request, 'list.html', context)

試したこと

①エラーメッセージを表示させる記述「{% include 'path/to/form-alert.html' %} 」の配置する場所がおかしいのでは?と考え、ファイルの先頭や別ファイルなどに移動させてみたが、特に変化なし。

②settings.pyにて誤表記があるのでは?と考えたが、自分が見た中では、誤表記は見つけられなかった。

補足情報(FW/ツールのバージョンなど)

コードエディター VSコード
Python 3.7.0
Django 3.1.4
requests 2.25.1
beautifulsoup4 4.9.3

ディレクトリとファイルの構成
https://gyazo.com/434a1275b9db6c0e147dd6c18fd1b1c1

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

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

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

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

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

errormaker74

2021/01/30 08:08

`IndexError: list index out of range`はviews.pyで起きているのでしょうか? もし差し支えなければviews.py内のソースコードを載せられますか? `TemplateDoesNotExist`はDjangoがテンプレートのファイルを見つけることができなかった場合に表示されるエラーです。 十中八九、テンプレートファイルの置き場所を間違えているのでディレクトリ・ファイル構成を載せたほうがいいかもしれません。
hisa_eng

2021/01/30 08:19 編集

コメントありがとうございます! views.pyのコードを追記いたしました。 また、ディレクトリとファイル構成をスクショしたGyazoのURLも追記しました。 ご確認よろしくお願いします。
_whitecat_22

2021/01/30 09:00

テンプレが無い件は、パス指定の変更で解消したようですね!^^ 次は、IndexErrorですか…
guest

回答2

0

ベストアンサー

テンプレートのパスを確認してください

{% include 'path/to/form-alert.html' %} # この記述どおりのパスにhtmlファイルが存在しますか?

【追記】

パス変更後のIndexErrorについて。

例外のURLをフォームに入力した際に、該当するclassが取得できないために、下記内のfor文で、"IndexError: list index out of range" となっていると思われます。

python

1 ul_tag = bs.find_all(class_="yjnSubTopics_list") 2 for tag in ul_tag[0]: # ↑このclassが取得できないとき、ul_tagは空になるため、ココで "index out of range" になります。 3 title = tag.a.getText() 4 url2 = tag.a.get("href") 5 list.append([title, url2])

 
例外となるURLを入力した際は、try/except エラー表示して逃げましょうか。

python

1 ul_tag = bs.find_all(class_="yjnSubTopics_list") 2 try: 3 for tag in ul_tag[0]: 4 title = tag.a.getText() 5 url2 = tag.a.get("href") 6 list.append([title, url2]) 7 except Exception as e: 8 print("例外が発生しました")

投稿2021/01/30 09:16

_whitecat_22

総合スコア1305

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

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

hisa_eng

2021/01/30 09:53

丁寧にありがとうございます。 try/exceptに関しては考えていませんでしたので、大変勉強になりました。 ご指摘いただいた通りに実施しました所、メッセージはブラウザ上ではなくターミナルのみで表示されています。しかし、例外のURLで抽出を試みた際に、エラーは全く発生しなくなりましたので、ベストアンサーとさせていただきます! 残りは私の方で、実装を進めていきたいと思います。
_whitecat_22

2021/01/30 10:01

どういたしまして!^^ お役に立てて嬉しく思います。 たしかに、、exceptの場合にprint文にしたため、ターミナル上にエラーが表示されますね。。 print文ではなく、別の手法を使うことでWEBページ上にも表示できるはずです。 まずは、調べて実装してみてください。 お互いにpython/djangoの習得に向けてがんばりましょう!
guest

0

{% include 'path/to/form-alert.html' %}

の箇所を

{% include 'form-alert.html' %}

に修正はしてみるとどうでしょうか?

投稿2021/01/30 08:27

errormaker74

総合スコア230

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

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

hisa_eng

2021/01/30 08:44 編集

先ほど修正して確認しました。結果、TemplateDoesNotExistは解消されましたが、例外のurlをフォームに入力した際に、再び"IndexError: list index out of range"が表示されました。 ひとまず、1歩進むことができました。ありがとうございます。
errormaker74

2021/01/30 08:54

あとは`listfunc`メソッド内でprintしてみてどこでIndexErrorが起きているか確認すればよいかと思います。 printの一例。 ``` ul_tag = bs.find_all(class_="yjnSubTopics_list") print(ul_tag) ``` 値がとれていれば`python manage.py runserver`しているところで確認できます。
_whitecat_22

2021/01/30 09:17 編集

例外のURLをフォームに入力した際に、該当するclassが取得できないために、下記内のfor文で、"IndexError: list index out of range" となっていると思われます。 詳細は、回答として追記しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問