Browse Source

Chapter 11: Blog posts (11a)

master
T. Meissner 6 years ago
parent
commit
9f056eb85b
7 changed files with 114 additions and 7 deletions
  1. +5
    -0
      app/main/forms.py
  2. +12
    -4
      app/main/views.py
  3. +9
    -0
      app/models.py
  4. +26
    -0
      app/static/styles.css
  5. +23
    -1
      app/templates/index.html
  6. +2
    -2
      flasky.py
  7. +37
    -0
      migrations/versions/c16f3d665442_.py

+ 5
- 0
app/main/forms.py View File

@ -48,3 +48,8 @@ class EditProfileAdminForm(FlaskForm):
if field.data != self.user.username and \
User.query.filter_by(username=field.data).first():
raise ValidationError('Username already in use.')
class PostForm(FlaskForm):
body = TextAreaField("What's on your mind?", validators=[DataRequired()])
submit = SubmitField('Submit')

+ 12
- 4
app/main/views.py View File

@ -1,15 +1,23 @@
from flask import render_template, redirect, url_for, flash
from flask_login import login_required, current_user
from . import main
from .forms import EditProfileForm, EditProfileAdminForm
from .forms import EditProfileForm, EditProfileAdminForm, PostForm
from .. import db
from ..models import User, Role
from ..models import User, Role, Permission, Post
from ..decorators import admin_required
@main.route('/')
@main.route('/', methods=['GET', 'POST'])
def index():
return render_template('index.html')
form = PostForm()
if current_user.can(Permission.WRITE) and form.validate_on_submit():
post = Post(body=form.body.data,
author=current_user._get_current_object())
db.session.add(post)
db.session.commit()
return redirect(url_for('.index'))
posts = Post.query.order_by(Post.timestamp.desc()).all()
return render_template('index.html', form=form, posts=posts)
@main.route('/user/<username>')


+ 9
- 0
app/models.py View File

@ -83,6 +83,7 @@ class User(UserMixin, db.Model):
member_since = db.Column(db.DateTime(), default=datetime.utcnow)
last_seen = db.Column(db.DateTime(), default=datetime.utcnow)
avatar_hash = db.Column(db.String(32))
posts = db.relationship('Post', backref='author', lazy='dynamic')
def __init__(self, **kwargs):
super(User, self).__init__(**kwargs)
@ -186,6 +187,14 @@ class User(UserMixin, db.Model):
return '<User %r>' % self.username
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.Text)
timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
class AnonymousUser(AnonymousUserMixin):
def can(self, perm):
return False


+ 26
- 0
app/static/styles.css View File

@ -5,3 +5,29 @@
min-height: 260px;
margin-left: 280px;
}
ul.posts {
list-style-type: none;
padding: 0px;
margin: 16px 0px 0px 0px;
border-top: 1px solid #e0e0e0;
}
ul.posts li.post {
padding: 8px;
border-bottom: 1px solid #e0e0e0;
}
ul.posts li.post:hover {
background-color: #f0f0f0;
}
div.post-date {
float: right;
}
div.post-author {
font-weight: bold;
}
div.post-thumbnail {
position: absolute;
}
div.post-content {
margin-left: 48px;
min-height: 48px;
}

+ 23
- 1
app/templates/index.html View File

@ -1,4 +1,5 @@
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Flasky{% endblock %}
@ -8,4 +9,25 @@
Hello, {% if current_user.is_authenticated %}{{ current_user.username }}{% else %}Stranger{% endif %}!
</h1>
</div>
{% endblock %}
<div>
{% if current_user.can(Permission.WRITE) %}
{{ wtf.quick_form(form) }}
{% endif %}
</div>
<ul class="posts">
{% for post in posts %}
<li class="post">
<div class="post-thumbnail">
<a href="{{ url_for('.user', username=post.author.username) }}">
<img class="img-rounded profile-thumbnail" src="{{ post.author.gravatar(size=40) }}">
</a>
</div>
<div class="post-content">
<div class="post-date">{{ moment(post.timestamp).fromNow() }}</div>
<div class="post-author"><a href="{{ url_for('.user', username=post.author.username) }}">{{ post.author.username }}</a></div>
<div class="post-body">{{ post.body }}</div>
</div>
</li>
{% endfor %}
</ul>
{% endblock %}

+ 2
- 2
flasky.py View File

@ -1,7 +1,7 @@
import os
from flask_migrate import Migrate
from app import create_app, db
from app.models import User, Role, Permission
from app.models import User, Role, Permission, Post
app = create_app(os.getenv('FLASK_CONFIG') or 'default')
@ -10,7 +10,7 @@ migrate = Migrate(app, db)
@app.shell_context_processor
def make_shell_context():
return dict(db=db, User=User, Role=Role, Permission=Permission)
return dict(db=db, User=User, Role=Role, Permission=Permission, Post=Post)
@app.cli.command()


+ 37
- 0
migrations/versions/c16f3d665442_.py View File

@ -0,0 +1,37 @@
"""empty message
Revision ID: c16f3d665442
Revises: 5cffb9b6fccd
Create Date: 2018-11-15 22:46:16.787868
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'c16f3d665442'
down_revision = '5cffb9b6fccd'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('posts',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('body', sa.Text(), nullable=True),
sa.Column('timestamp', sa.DateTime(), nullable=True),
sa.Column('author_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['author_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_posts_timestamp'), 'posts', ['timestamp'], unique=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_posts_timestamp'), table_name='posts')
op.drop_table('posts')
# ### end Alembic commands ###

Loading…
Cancel
Save