I am currently struggling with adding image to my posts in my flaskblog
this is my routes.py imports and new_post function and route
import os
import secrets
from PIL import Image
from flask import render_template, url_for, flash, redirect, request, abort
from flaskblog import app, db, bcrypt
from flaskblog.forms import RegistrationForm, LoginForm, UpdateAccountForm, PostForm
from flaskblog.models import User, Post
from flask_login import login_user, current_user, logout_user, login_required
@app.route("/post/new", methods=['GET', 'POST'])
@login_required
def new_post():
form = PostForm()
if form.validate_on_submit():
if form.post_picture.data:
image_post = form.post_picture.data
post = Post(title=form.title.data, content=form.content.data, author=current_user, post_image=image_post)
db.session.add(post)
db.session.commit()
flash('Your post has been created!', 'success')
return redirect(url_for('home'))
return render_template('create_post.html', title='New Post', post_image=post_image,
form=form, legend='New Post')
This is my forms.py imports and PostForm class
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed
from flask_login import current_user
from wtforms import StringField, PasswordField, SubmitField, BooleanField, TextAreaField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from flaskblog.models import User
class PostForm(FlaskForm):
title = StringField('Title', validators=[DataRequired()])
content = TextAreaField('Content', validators=[DataRequired()])
post_picture = FileField('Add image to your post', validators=[FileAllowed(['jpg', 'png'])])
submit = SubmitField('Post')
This is my models.py file and Post class
from datetime import datetime
from flaskblog import db, login_manager
from flask_login import UserMixin
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
post_image = db.Column(db.String(20), nullable=True)
def __repr__(self):
return f"Post('{self.title}', '{self.date_posted}')"
This is my post.html file
{% extends "layout.html" %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ url_for('static', filename='profile_pics/' + post.author.image_file) }}">
{% if post.image %}
<img class="rounded-circle account-img" src="{{ post_image }}">
{% endif %}
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="#">{{ post.author.username }}</a>
<small class="text-muted">{{ post.date_posted.strftime('on %d-%m-%Y at %H:%M:%S %p') }}</small>
{% if post.author == current_user %}
<div>
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{{ url_for('update_post', post_id=post.id) }}">Update</a>
<button type="button" class="btn btn-danger btn-sm m-1" data-toggle="modal" data-target="#deleteModal">Delete</button>
</div>
{% endif %}
</div>
<h2 class="article-title">{{ post.title }}</h2>
<p class="article-content">{{ post.content }}</p>
</div>
</article>
<!-- Modal -->
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteModalLabel">Delete Post?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Do you want to delete this post?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<form action="{{ url_for('delete_post', post_id=post.id) }}" method="POST">
<input class="btn btn-danger " type="submit" value="Delete">
</form>
</div>
</div>
</div>
</div>
{% endblock content %}
This is my create_post.html file
{% extends "layout.html" %}
{% block content %}
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">{{ legend }}</legend>
<div class="form-group">
{{ form.title.label(class="form-control-label") }}
{% if form.title.errors %}
{{ form.title(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.title.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.title(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.content.label(class="form-control-label") }}
{% if form.content.errors %}
{{ form.content(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.content.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.content(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.post_picture.label() }}
{{ form.post_picture(class="form-control-file") }}
{% if form.post_picture.errors %}
{% for error in form.post_picture.errors %}
<span class="text-danger">{{ error }}</span></br>
{% endfor %}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}
My problem is the following error when I click on here:
Also, if I change post_image=post_image as post_image=image_post, I receive the following error
in your new_post method you need to pass
return render_template('create_post.html', title='New Post', post_image=image_post,
form=form, legend='New Post')
You are making your life a bit difficult by naming different variables in a very similar way: image_post, post_image, post_picture This makes it very likely that you get them confused in your code.
Your image_post
variable is assigned within the if statement that return redirect(url_for('home'))
.
So it is not being assigned if you
return render_template('create_post.html', title='New Post', post_image=post_image,
form=form, legend='New Post')
Remember, a method only returns one thing at a time.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.