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

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

ただいまの
回答率

87.48%

Flaskを用いた開発中の404エラー

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 196

score 1

Python+Flask+sqlalchemyでのプログラム作成

現在、上の3つを使ってブログのようなwebアプリを作ろうとしています。
Lolipopを使って運用しようとして、ディレクトリの配置を変えて作成したところ、
突如404エラーで詰まってしまいました。

素人が入門書のプログラムを改造したためこうなったのだと思います。
うまく動くような解決策を提示していただけるとありがたいです。

ソースコードをどこまで貼ればいいのか分からなかったので全部貼らせていただきます。
(順番が滅茶苦茶ですみません)

エラーメッセージ

127.0.0.1 - - [17/Aug/2021 11:53:55] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [17/Aug/2021 11:53:55] "GET /favicon.ico HTTP/1.1" 404 -

ソースコード

#views.py
from flask import request,redirect,url_for,render_template,flash,session
from __init__ import app
from models.entries import Entry ,SESSION
from sqlalchemy.engine import base

@app.route('/')
def show_entries():
    if not session.get('logged_in'):
        return redirect(url_for('login')) 
    entrie = SESSION.query(Entry).all()
    return render_template('home.html',entries = entrie)

@app.route('/login',methods=['GET','POST'])
def login():
    error = None
    if request.method == 'POST':
        if request.form['username'] != app.config['USERNAME']:
            flash('error:username')
        elif request.form['password'] != app.config['PASSWORD']:
            flash('error:password')
        else:
            session['logged_in']=True
            flash('logged in')
            return redirect(url_for('show_entries')) 
    return render_template('login.html')

@app.route('/logout')
def logout():
    session.pop('logged_in',None)
    flash('logged out')
    return redirect(url_for('show_entries')) 

@app.route('/entries',methods=['POST'])
def add_entry():
    if not session.get('logged_in'):
        return redirect(url_for('login')) 
    entry = Entry(
        long = request.form['long'],
        subject = request.form['subject'],
        now = request.form['now'],
        comment = request.form['comment']
    )
    SESSION.add(entry)
    SESSION.commit()
    flash('created')
    return redirect(url_for('show_entries')) 

@app.route('/entries/new')
def new_entry():
    if not session.get('logged_in'):
        return redirect(url_for('login')) 
    return render_template('new.html')
#server.py
from __init__ import app

if __name__ =='__main__': 
    app.run()
#config.py
DEBUG=True
USERNAME='admin'
PASSWORD='admin'
SECRET_KEY = 'f47wyhdfa8387hadfja3798293uhda83jk'
SQLALCHEMY_DATABASE_URI = 'sqlite:///coco.db'
SQLALCHEMY_TRACK_MODIFICATIONS = True
#__init__.py
from flask import Flask

app=Flask(__name__)
app.config.from_object('config')

import views
#entries.py
from sqlalchemy.sql.sqltypes import DateTime, Time
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///coco.db', echo=True)
Base = declarative_base()

class Entry(Base):
    __tablename__ = 'entries'
    id = Column(Integer,primary_key=True)
    long = Column(Time)
    subject = Column(String)
    now = Column(DateTime)
    comment = Column(String(50))

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    password = Column(String)

Session = sessionmaker(bind=engine)
SESSION = Session()

Base.metadata.create_all(engine)
<!--home.html-->
{% extends "layout.html" %}
{% block content %}
<ul class="list-group list-group-flush">

    {% for entry in entries %}
    <div class="card">
        <div class="card-body">
            <h5 class="card-title">{{ entry.subject }}</h5>
        </div>
    </div>
    {% else %}
    noarticle
    {% endfor %}

</ul>
{% endblock %}
<!--layout.html-->
<!DOCTYPE html>
<title>coco study</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>


<div class="container">
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <a class="navbar-brand" href="{{url_for('show_entries')}}">Coco study</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="nav navbar-nav navbar-right">
                {% if not session.logged_in %}
                <li class="nav-item">
                    <a class="nav-link" href="{{url_for('login')}}">login</a>
                </li>
                {% else %}
                <li class="nav-item">
                    <a class="nav-link" href="{{url_for('new_entry')}}">new entry</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="{{url_for('logout')}}">logout</a>
                </li>
                {% endif %}
            </ul>
        </div>
    </nav>
    {% for message in get_flashed_messages() %}
        <div class="alert alert-info" role="alert">
            {{ message }}
        </div>
    {% endfor %}

    <div class="blog-body">
        {% block content %}
        {% endblock %}
    </div>

</div>
<!--login.html-->
{% extends "layout.html" %}
{% block content %}
<form action="/login" method="POST">
    <div class="form-group">
        <label for="InputTitle">username</label>
        <input type="text" class="form-control" id="InputTitle" name="username">
    </div>

    <div class="form-group">
        <label for="InputPassword">password</label>
        <input type="password" class="form-control" id="InputPassword" name="password">
    </div>
    <button type="submit" class="btn btn-primary">login</button>
</form>
{% endblock %}
<!--new.html-->
{% extends "layout.html" %}
{% block content %}
<form action="{{url_for('add_entry')}}" method="POST" class="add-entry">
    <div class="form-group">
        <label for="InputSubject">Subject</label>
        <input type="text" class="form-control" id="InputSubject" name="title">
    </div>
    <div class="form-group">
        <label for="Inputlong">long</label>
        <input type="time" class="form-control" id="Inputlong" name="long">
    </div>
    <div class="form-group">
        <label for="Inputnow">now</label>
        <input type="time" class="form-control" id="Inputnow" name="now">
    </div>
    <div class="form-group">
        <label for="inputcomment">comment</label>
        <input type="text" class="form-control" id="Inputcomment" name="comment">
    </div>
    <button type="submit" class="btn btn-primary">create</button>
</form>
{% endblock %}

補足1

ディレクトリの構造です

/application|
            |-/models 
                   |-__init__.py(空)
                   |-entries.py
            |-/templates
                   |-home.html
                   |-layout.html
                   |-login.html
                   |-new.html
            |-__init__.py
            |-coco.db
            |-config.py
            |-server.py
            |-views.py

補足2

まだlolipopでは試さず、ローカルで動かしています

cd application
python server.py

https://github.com/chaingng/flask_tutorial

こちらのプログラムを元にしました

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mather

    2021/08/17 14:53

    Lolipop での flask の起動方法を提示してください。 (flask run コマンドなど)
    参考にしたページなどがあれば質問に記載してください。

    キャンセル

  • kou-pen

    2021/08/17 14:58

    編集させていただきました

    キャンセル

回答 1

checkベストアンサー

+1

まず、 通常 __init__.py にはモジュールシステムの解決のための記述を行います。今回はひとまずファイルだけ置いて、中には何も記述しないのが良いと思います。
URLにあるチュートリアルの場合は flask_blog ディレクトリをモジュールとして扱うために __init__.py に記述しています。
参考 : https://qiita.com/msi/items/d91ea3900373ff8b09d7

また、__init__.py と views.py で循環参照しています。(お互いを import している)
これによってエラーが起こるわけではないですが、あまりよろしくないです。

最小限のコードを書いてみたところ普通に動きました。

# views.py
from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "Hello"
# server.py
from views import app

if __name__ =='__main__':
    app.run()
# __init__.py (空ファイル)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/08/17 15:48 編集

    一発で直りました!!
    僕の勉強不足でした。。。
    ありがとうございました(ToT)

    キャンセル

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

  • ただいまの回答率 87.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る