init
This commit is contained in:
commit
5309e0593b
22 changed files with 722 additions and 0 deletions
blog
11
blog/__init__.py
Normal file
11
blog/__init__.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
from flask import Flask
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_migrate import Migrate
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config.from_object('blog.config')
|
||||
db = SQLAlchemy(app)
|
||||
migrate = Migrate(app, db)
|
||||
migrate.init_app(app, db)
|
||||
|
||||
from blog.views import auth, entries
|
6
blog/config.py
Normal file
6
blog/config.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
SQLALCHEMY_DATABASE_URI = 'sqlite:///blog.db'
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = True
|
||||
DEBUG = True
|
||||
USERNAME = 'john'
|
||||
PASSWORD = 'due123'
|
||||
SECRET_KEY = 'secret key'
|
17
blog/models/entries.py
Normal file
17
blog/models/entries.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
from blog import db
|
||||
from datetime import datetime
|
||||
|
||||
class Entry(db.Model):
|
||||
__tablename__ = 'entries'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
title = db.Column(db.String(50), unique=True, nullable=False)
|
||||
text = db.Column(db.Text, nullable=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
def __init__(self, title, text):
|
||||
self.title = title
|
||||
self.text = text
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Entry id:{self.id} title:{self.title} text:{self.text}>'
|
10
blog/templates/entries/edit.html
Normal file
10
blog/templates/entries/edit.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
<form action="{{ url_for('update_entry', id=entry.id) }}" method="post">
|
||||
<label for="title">タイトル</label>
|
||||
<input type="text" id="title" name=title value={{ entry.title }}>
|
||||
<label for="text">本文</label>
|
||||
<textarea id="text" name=text rows="3">{{ entry.text | safe }}</textarea>
|
||||
<button type="submit">更新</button>
|
||||
</form>
|
||||
{% endblock %}
|
13
blog/templates/entries/index.html
Normal file
13
blog/templates/entries/index.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
<ul>
|
||||
{% for entry in entries %}
|
||||
<li>
|
||||
<h5>{{ entry.title }}</h5>
|
||||
<a href="{{ url_for('show_entry', id=entry.id) }}">続きを読む</a>
|
||||
</li>
|
||||
{% else %}
|
||||
投稿がありません
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
10
blog/templates/entries/new.html
Normal file
10
blog/templates/entries/new.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
<form action="{{ url_for('add_entry') }}" method="post">
|
||||
<label for="title">タイトル</label>
|
||||
<input type="text" id="title" name="title">
|
||||
<label for="text">本文</label>
|
||||
<textarea id="text" name="text" rows="3"></textarea>
|
||||
<button type="submit">作成</button>
|
||||
</form>
|
||||
{% endblock %}
|
14
blog/templates/entries/show.html
Normal file
14
blog/templates/entries/show.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
<h2>{{ entry.title }}</h2>
|
||||
<br>
|
||||
{{ entry.text }}
|
||||
<br><br>
|
||||
投稿日時 {{ entry.created_at }}
|
||||
<form action="{{ url_for('edit_entry', id=entry.id) }}" method="GET">
|
||||
<button type="submit">編集</button>
|
||||
</form>
|
||||
<form action="{{ url_for('delete_entry', id=entry.id) }}" method="POST">
|
||||
<button type="submit">削除</button>
|
||||
</form>
|
||||
{% endblock %}
|
30
blog/templates/layout.html
Normal file
30
blog/templates/layout.html
Normal file
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Flask Blog</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
|
||||
</head>
|
||||
<body class="container">
|
||||
<header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="/">Flask Blog</a></li>
|
||||
</ul>
|
||||
<ul>
|
||||
{% if not session.logged_in %}
|
||||
<li><a href="{{ url_for('login')}}">ログイン</a></li>
|
||||
{% else %}
|
||||
<li><a href="{{ url_for('new_entry')}}">新規投稿</a></li>
|
||||
<li><a href="{{ url_for('logout')}}">ログアウト</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
{% for message in get_flashed_messages() %}
|
||||
<p>{{ message }}</p>
|
||||
{% endfor %}
|
||||
<main>
|
||||
{% block body %}{% endblock %}
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
10
blog/templates/login.html
Normal file
10
blog/templates/login.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
<form action="{{ url_for('login')}}" method="post">
|
||||
<label for="username">ユーザ名</label>
|
||||
<input type="text" id="username" name="username">
|
||||
<label for="password">パスワード</label>
|
||||
<input type="password" id="password" name="password">
|
||||
<button type="submit">ログイン</button>
|
||||
</form>
|
||||
{% endblock %}
|
31
blog/views/auth.py
Normal file
31
blog/views/auth.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
from flask import render_template, request, redirect, session, flash, url_for
|
||||
from blog import app
|
||||
from functools import wraps
|
||||
|
||||
def login_required(view):
|
||||
@wraps(view)
|
||||
def inner(*args, **kwargs):
|
||||
if not session.get('logged_in'):
|
||||
return redirect(url_for('login'))
|
||||
return view(*args, **kwargs)
|
||||
return inner
|
||||
|
||||
@app.route("/login", methods=['GET', 'POST'])
|
||||
def login():
|
||||
error = None
|
||||
if request.method == 'POST':
|
||||
if request.form['username'] != app.config['USERNAME']:
|
||||
flash("ユーザー名が異なります")
|
||||
elif request.form['password'] != app.config['PASSWORD']:
|
||||
flash("パスワードが異なります")
|
||||
else:
|
||||
session['logged_in'] = True
|
||||
flash("ログインしました")
|
||||
return redirect(url_for("show_entries"))
|
||||
return render_template("login.html")
|
||||
|
||||
@app.route("/logout")
|
||||
def logout():
|
||||
session.pop('logged_in', None)
|
||||
flash("ログアウトしました")
|
||||
return redirect(url_for("show_entries"))
|
59
blog/views/entries.py
Normal file
59
blog/views/entries.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
from flask import render_template, redirect, url_for, request, flash
|
||||
from blog import app, db
|
||||
from blog.models.entries import Entry
|
||||
from blog.views.auth import login_required
|
||||
|
||||
@app.route("/")
|
||||
@login_required
|
||||
def show_entries():
|
||||
entries = Entry.query.order_by(Entry.id.desc()).all()
|
||||
return render_template('entries/index.html', entries=entries)
|
||||
|
||||
@app.route("/entries/new", methods=['GET'])
|
||||
@login_required
|
||||
def new_entry():
|
||||
return render_template('entries/new.html')
|
||||
|
||||
@app.route("/entries", methods=["POST"])
|
||||
@login_required
|
||||
def add_entry():
|
||||
entry = Entry(
|
||||
title=request.form['title'],
|
||||
text=request.form['text']
|
||||
)
|
||||
db.session.add(entry)
|
||||
db.session.commit()
|
||||
flash('新しく記事が作成されました')
|
||||
return redirect(url_for("show_entries"))
|
||||
|
||||
@app.route("/entries/<int:id>", methods=["GET"])
|
||||
@login_required
|
||||
def show_entry(id):
|
||||
entry = Entry.query.get(id)
|
||||
return render_template("entries/show.html", entry=entry)
|
||||
|
||||
@app.route('/entries/<int:id>/edit', methods=['GET'])
|
||||
@login_required
|
||||
def edit_entry(id):
|
||||
entry = Entry.query.get(id)
|
||||
return render_template('entries/edit.html', entry=entry)
|
||||
|
||||
@app.route("/entries/<int:id>/update", methods=['POST'])
|
||||
@login_required
|
||||
def update_entry(id):
|
||||
entry = Entry.query.get(id)
|
||||
entry.title = request.form['title']
|
||||
entry.text = request.form['text']
|
||||
db.session.merge(entry)
|
||||
db.session.commit()
|
||||
flash('記事が更新されました')
|
||||
return redirect(url_for('show_entries'))
|
||||
|
||||
@app.route("/entries/<int:id>/delete", methods=["POST"])
|
||||
@login_required
|
||||
def delete_entry(id):
|
||||
entry = Entry.query.get(id)
|
||||
db.session.delete(entry)
|
||||
db.session.commit()
|
||||
flash('記事が削除されました')
|
||||
return redirect(url_for("show_entries"))
|
Loading…
Add table
Add a link
Reference in a new issue