【问题标题】:How can I add images to my posts using flask framework?如何使用烧瓶框架将图像添加到我的帖子中?
【发布时间】:2020-08-10 08:29:37
【问题描述】:

我目前正在努力将图片添加到我的烧瓶博客中的帖子中

这是我的 routes.py 导入和 new_post 函数和路由

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')

这是我的 forms.py 导入和 PostForm 类

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')

这是我的 models.py 文件和 Post 类

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}')"

这是我的 post.html 文件

{% 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">&times;</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 %}

这是我的 create_post.html 文件

{% 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 %}

我的问题是点击这里时出现以下错误:

另外,如果我将 post_image=post_image 更改为 post_image=image_post,我会收到以下错误

【问题讨论】:

    标签: python flask flask-sqlalchemy flask-wtforms


    【解决方案1】:

    在你的 new_post 方法中你需要通过

    return render_template('create_post.html', title='New Post', post_image=image_post,
                               form=form, legend='New Post')
    

    通过以非常相似的方式命名不同的变量,您的生活变得有点困难:image_post、post_image、post_picture 这很可能让您在代码中混淆它们。

    【讨论】:

    • 如果我执行 post_image=image_post,我会收到“UnboundLocalError: local variable 'image_post' referenced before assignment”错误
    • 这意味着你的 form.post_picture.data 是 None。检查您的请求中是否实际提交了图片。
    【解决方案2】:

    image_post 变量在 return redirect(url_for('home')) 的 if 语句中赋值。

    所以如果你没有分配它

    return render_template('create_post.html', title='New Post', post_image=post_image,
                               form=form, legend='New Post')
    

    请记住,方法一次只返回一件事。

    【讨论】:

    • 我认为这是根本原因。
    【解决方案3】:

    我知道这是一年后的事,但我遇到了这个错误,我弄明白了 你需要编辑这个:

    <div class="content-section">
    <form method="POST" action="">
    

    到这里:

    <div class="content-section">
    <form method="POST" action="" enctype="multipart/form-data">
    

    就是这样

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      • 2013-11-01
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多