blog/
├── app/
│ ├── __init__.py
│ ├── models.py
│ ├── routes.py
│ ├── forms.py
│ └── templates/
│ ├── base.html
│ ├── index.html
│ └── post.html
├── config.py
└── run.py
# models.py
from app import db
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
posts = db.relationship('Post', backref='author')
# forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField
from wtforms.validators import DataRequired
class PostForm(FlaskForm):
title = StringField('Titre', validators=[DataRequired()])
content = TextAreaField('Contenu', validators=[DataRequired()])
# routes.py
@app.route('/')
def index():
posts = Post.query.order_by(Post.created_at.desc()).all()
return render_template('index.html', posts=posts)
@app.route('/post/new', methods=['GET', 'POST'])
@login_required
def new_post():
form = PostForm()
if form.validate_on_submit():
post = Post(title=form.title.data,
content=form.content.data,
author=current_user)
db.session.add(post)
db.session.commit()
return redirect(url_for('index'))
return render_template('post_form.html', form=form)
# api.py
from flask import Blueprint, jsonify
from flask_restful import Resource, Api
api_bp = Blueprint('api', __name__)
api = Api(api_bp)
class PostAPI(Resource):
def get(self, post_id):
post = Post.query.get_or_404(post_id)
return {
'id': post.id,
'title': post.title,
'content': post.content,
'author': post.author.username
}
api.add_resource(PostAPI, '/posts/')
# test_api.py
def test_get_post():
response = client.get('/api/posts/1')
assert response.status_code == 200
data = response.get_json()
assert 'title' in data
assert 'content' in data
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
{% extends "base.html" %}
{% block title %}{{ post.title }}{% endblock %}
{% block content %}
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
<small>Par {{ post.author.username }}</small>
{% endblock %}
from flask_login import login_user
@app.route('/login', methods=['POST'])
def login():
user = User.query.filter_by(
username=form.username.data).first()
if user and user.check_password(form.password.data):
login_user(user)
return redirect(url_for('index'))
from flask_migrate import Migrate
migrate = Migrate(app, db)
# Dans le terminal:
# flask db init
# flask db migrate
# flask db upgrade