Python 我的sqlalchemy.InterfaceError的原因是什么?如何使用url_for()访问存储为十六进制的图像(使用PIL pillow)?

Python 我的sqlalchemy.InterfaceError的原因是什么?如何使用url_for()访问存储为十六进制的图像(使用PIL pillow)?,python,flask,sqlalchemy,Python,Flask,Sqlalchemy,长期读者,第一次海报 我正在用python flask和sqlalchemy创建一个基本的社交网络。这包括个人资料照片、标题照片和帖子照片。我一直在遵循Corey Schafer的python Alchemy教程,使用PIL Pizz实现标题和个人资料照片功能。这是相当简单的,工作如预期。问题是试图在Post模型中复制这一点,而不是在用户模型中 下面是我成功实现的profile\u img和header\u img功能 routes.py def save_profile_img(form_pr

长期读者,第一次海报

我正在用python flask和sqlalchemy创建一个基本的社交网络。这包括个人资料照片、标题照片和帖子照片。我一直在遵循Corey Schafer的python Alchemy教程,使用PIL Pizz实现标题和个人资料照片功能。这是相当简单的,工作如预期。问题是试图在Post模型中复制这一点,而不是在用户模型中

下面是我成功实现的profile\u img和header\u img功能

routes.py

def save_profile_img(form_profile_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_profile_img.filename)
    profile_img_fn = random_hex + f_ext
    profile_img_path = os.path.join(app.root_path, "static/profile_pics", profile_img_fn)

    output_size = (225, 225)
    i = Image.open(form_profile_img)
    i.thumbnail(output_size)
    i.save(profile_img_path)

    return profile_img_fn

def save_header_img(form_header_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_header_img.filename)
    header_img_fn = random_hex + f_ext
    header_img_path = os.path.join(app.root_path, "static/profile_pics", header_img_fn)
    form_header_img.save(header_img_path)

    output_size = (700, 700)
    i = Image.open(form_header_img)
    i.thumbnail(output_size)
    i.save(header_img_path)

    return header_img_fn

@app.route('/profile/<id>-<firstname>', methods=['GET', 'POST'])
@login_required
def profile(id, firstname):
    user = User.query.filter_by(id=id).first_or_404()
    firstname = User.query.filter_by(firstname=firstname).first_or_404()
    # edit profile form
    form = EditProfile()
    if form.validate_on_submit():
        if form.profile_img.data:
            profile_img_file = save_profile_img(form.profile_img.data)
            current_user.profile_img = profile_img_file
        if form.header_img.data:
            header_img_file = save_header_img(form.header_img.data)
            current_user.header_img = header_img_file
        current_user.firstname = form.firstname.data
        current_user.lastname = form.lastname.data
        current_user.email = form.email.data
        current_user.city = form.city.data
        db.session.commit()
        flash('Your account has been updated', 'success')
        return redirect(url_for('profile', id=current_user.id, firstname=current_user.firstname))
    elif request.method == 'GET':
        form.firstname.data = current_user.firstname
        form.lastname.data = current_user.lastname
        form.email.data = current_user.email
        form.city.data = current_user.city
    profile_img = url_for('static', filename='profile_pics/' + user.profile_img)
    header_img = url_for('static', filename='profile_pics/' + user.header_img)
    return render_template('profile.html', title='Profile', profile=profile, posts=posts, user=user, firstname=firstname, profile_img=profile_img, header_img=header_img, form=form)
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(20), nullable=False)
    lastname = db.Column(db.String(20), nullable=False)
    profile_img = db.Column(db.String(50), nullable=False, default="default.png")
    header_img = db.Column(db.String(50), nullable=False, default="default_bg5.jpg")
    email = db.Column(db.String(50), nullable=False)
    password = db.Column(db.String(60), nullable=False)
    city = db.Column(db.String(50), nullable=False)
    posts = db.relationship('Post', backref='author', lazy=True)
    work_history = db.relationship('Employment', backref='author', lazy=True)
    education = db.relationship('Education', backref='author', lazy=True)
    about = db.relationship('About', backref='author', lazy=True)

    def __repr__(self):
        return f"User('{self.id}', '{self.firstname}', '{self.lastname}', '{self.email}', '{self.city}', '{self.profile_img}', '{self.header_img}')" 
class EditProfile(FlaskForm):
    firstname = StringField('First Name', validators=[DataRequired(), Length(min=2, max=20)])
    lastname = StringField('Last Name',  validators=[DataRequired(), Length(min=2, max=20)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    profile_img = FileField(validators=[FileAllowed(['jpg', 'png'])])
    header_img = FileField(validators=[FileAllowed(['jpg', 'png'])])
    city = SelectField('City', choices = [('Brampton', 'Brampton'), ('Etobicoke', 'Etobicoke'), ('Brampton', 'Brampton'), ('Markham', 'Markham'), ('Mississauga', 'Mississauga'), ('North York', 'North York'), ('Oakville', 'Oakville'), ('Ottawa', 'Ottawa'), ('Pickering', 'Pickering'), ('Scarborough', 'Scarborough'), ('Toronto', 'Toronto'), ('Vaughn', 'Vaughn')])
    submit = SubmitField('Update Account')

    def validate_email(self, email):
        if email.data != current_user.email:    
            user = User.query.filter_by(email=email.data).first()
            if user:
                raise ValidationError('Email is already in use.')
def save_post_img(form_post_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_post_img.filename)
    post_img_fn = random_hex + f_ext
    post_img_path = os.path.join(app.root_path, "static/post_pics", post_img_fn)
    form_post_img.save(post_img_path)

    output_size = (700, 700)
    i = Image.open(form_post_img)
    i.thumbnail(output_size)
    i.save(post_img_path)

    return post_img_fn

@app.route('/')
@app.route('/index', methods=['GET', 'POST'])
def home():
    if current_user.is_authenticated == False:
        return redirect(url_for('register'))
    user = current_user
    profile_img = url_for('static', filename='profile_pics/' + user.profile_img)
    form = PostForm()
    if form.validate_on_submit():
        post = Post(content=form.content.data, post_img=form.post_img.data, author=current_user)
        if form.post_img.data:
            post_img_file = save_post_img(form.post_img.data)
            post_img = post_img_file
        db.session.add(post)
        db.session.commit()
        flash('Post Successful!', 'success')
        return redirect(url_for('profile', id=current_user.id, firstname=current_user.firstname))
    post_img = url_for('static', filename='post_pics/post_img.jpg')
    posts = Post.query.order_by(Post.date_posted.desc()).all()
    return render_template('index.html', posts=posts, profile_img=profile_img, form=form, user=user, post_img=post_img)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(1000), nullable=False)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)  
    post_img = db.Column(db.String(50), nullable=True) 
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    def __repr__(self):
        return f"Post('{self.content}', '{self.post_img}', '{self.date_posted}')" 
class PostForm(FlaskForm):
    content = TextAreaField('Content', validators=[DataRequired()])
    post_img= FileField(validators=[FileAllowed(['jpg', 'png'])])
    submit = SubmitField('Post')
forms.py

def save_profile_img(form_profile_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_profile_img.filename)
    profile_img_fn = random_hex + f_ext
    profile_img_path = os.path.join(app.root_path, "static/profile_pics", profile_img_fn)

    output_size = (225, 225)
    i = Image.open(form_profile_img)
    i.thumbnail(output_size)
    i.save(profile_img_path)

    return profile_img_fn

def save_header_img(form_header_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_header_img.filename)
    header_img_fn = random_hex + f_ext
    header_img_path = os.path.join(app.root_path, "static/profile_pics", header_img_fn)
    form_header_img.save(header_img_path)

    output_size = (700, 700)
    i = Image.open(form_header_img)
    i.thumbnail(output_size)
    i.save(header_img_path)

    return header_img_fn

@app.route('/profile/<id>-<firstname>', methods=['GET', 'POST'])
@login_required
def profile(id, firstname):
    user = User.query.filter_by(id=id).first_or_404()
    firstname = User.query.filter_by(firstname=firstname).first_or_404()
    # edit profile form
    form = EditProfile()
    if form.validate_on_submit():
        if form.profile_img.data:
            profile_img_file = save_profile_img(form.profile_img.data)
            current_user.profile_img = profile_img_file
        if form.header_img.data:
            header_img_file = save_header_img(form.header_img.data)
            current_user.header_img = header_img_file
        current_user.firstname = form.firstname.data
        current_user.lastname = form.lastname.data
        current_user.email = form.email.data
        current_user.city = form.city.data
        db.session.commit()
        flash('Your account has been updated', 'success')
        return redirect(url_for('profile', id=current_user.id, firstname=current_user.firstname))
    elif request.method == 'GET':
        form.firstname.data = current_user.firstname
        form.lastname.data = current_user.lastname
        form.email.data = current_user.email
        form.city.data = current_user.city
    profile_img = url_for('static', filename='profile_pics/' + user.profile_img)
    header_img = url_for('static', filename='profile_pics/' + user.header_img)
    return render_template('profile.html', title='Profile', profile=profile, posts=posts, user=user, firstname=firstname, profile_img=profile_img, header_img=header_img, form=form)
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(20), nullable=False)
    lastname = db.Column(db.String(20), nullable=False)
    profile_img = db.Column(db.String(50), nullable=False, default="default.png")
    header_img = db.Column(db.String(50), nullable=False, default="default_bg5.jpg")
    email = db.Column(db.String(50), nullable=False)
    password = db.Column(db.String(60), nullable=False)
    city = db.Column(db.String(50), nullable=False)
    posts = db.relationship('Post', backref='author', lazy=True)
    work_history = db.relationship('Employment', backref='author', lazy=True)
    education = db.relationship('Education', backref='author', lazy=True)
    about = db.relationship('About', backref='author', lazy=True)

    def __repr__(self):
        return f"User('{self.id}', '{self.firstname}', '{self.lastname}', '{self.email}', '{self.city}', '{self.profile_img}', '{self.header_img}')" 
class EditProfile(FlaskForm):
    firstname = StringField('First Name', validators=[DataRequired(), Length(min=2, max=20)])
    lastname = StringField('Last Name',  validators=[DataRequired(), Length(min=2, max=20)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    profile_img = FileField(validators=[FileAllowed(['jpg', 'png'])])
    header_img = FileField(validators=[FileAllowed(['jpg', 'png'])])
    city = SelectField('City', choices = [('Brampton', 'Brampton'), ('Etobicoke', 'Etobicoke'), ('Brampton', 'Brampton'), ('Markham', 'Markham'), ('Mississauga', 'Mississauga'), ('North York', 'North York'), ('Oakville', 'Oakville'), ('Ottawa', 'Ottawa'), ('Pickering', 'Pickering'), ('Scarborough', 'Scarborough'), ('Toronto', 'Toronto'), ('Vaughn', 'Vaughn')])
    submit = SubmitField('Update Account')

    def validate_email(self, email):
        if email.data != current_user.email:    
            user = User.query.filter_by(email=email.data).first()
            if user:
                raise ValidationError('Email is already in use.')
def save_post_img(form_post_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_post_img.filename)
    post_img_fn = random_hex + f_ext
    post_img_path = os.path.join(app.root_path, "static/post_pics", post_img_fn)
    form_post_img.save(post_img_path)

    output_size = (700, 700)
    i = Image.open(form_post_img)
    i.thumbnail(output_size)
    i.save(post_img_path)

    return post_img_fn

@app.route('/')
@app.route('/index', methods=['GET', 'POST'])
def home():
    if current_user.is_authenticated == False:
        return redirect(url_for('register'))
    user = current_user
    profile_img = url_for('static', filename='profile_pics/' + user.profile_img)
    form = PostForm()
    if form.validate_on_submit():
        post = Post(content=form.content.data, post_img=form.post_img.data, author=current_user)
        if form.post_img.data:
            post_img_file = save_post_img(form.post_img.data)
            post_img = post_img_file
        db.session.add(post)
        db.session.commit()
        flash('Post Successful!', 'success')
        return redirect(url_for('profile', id=current_user.id, firstname=current_user.firstname))
    post_img = url_for('static', filename='post_pics/post_img.jpg')
    posts = Post.query.order_by(Post.date_posted.desc()).all()
    return render_template('index.html', posts=posts, profile_img=profile_img, form=form, user=user, post_img=post_img)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(1000), nullable=False)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)  
    post_img = db.Column(db.String(50), nullable=True) 
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    def __repr__(self):
        return f"Post('{self.content}', '{self.post_img}', '{self.date_posted}')" 
class PostForm(FlaskForm):
    content = TextAreaField('Content', validators=[DataRequired()])
    post_img= FileField(validators=[FileAllowed(['jpg', 'png'])])
    submit = SubmitField('Post')
使用此功能,用户可以单击上载文件按钮,选择JPG或PNG文件,查看提交前显示的文件,然后单击提交。然后将每个图像存储为给定静态文件中的十六进制。我可以使用下面的
url\u for()
语句访问
user.profile\u img
user.header\u img
,这些语句位于路径的底部,就在
呈现模板
语句之前

user = User.query.filter_by(id=id).first_or_404()
profile_img = url_for('static', filename='profile_pics/' + user.profile_img)
header_img = url_for('static', filename='profile_pics/' + user.header_img)
然后,我可以使用一个简单的jinja2语句
src=“{{profile\u img}}”
src=“{{header\u img}}”

问题 至于实现
post\img
功能,我遇到了一系列问题。在这一点上,我不知道如何通过url_for语句访问图像,并且在提交时遇到了sqlalchemyInterface错误。但是,该文件确实被重命名为十六进制,并存储在相应的静态文件中。我的问题有两个?为什么我会得到sqlalchemy.exc.InterfaceError?我如何通过一个带有post_ID的url_访问图像,这样如果用户确实将图像上传到他们的帖子中,它就会出现, 下面是form.py、routes.py、model.py和_postform.html

routes.py

def save_profile_img(form_profile_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_profile_img.filename)
    profile_img_fn = random_hex + f_ext
    profile_img_path = os.path.join(app.root_path, "static/profile_pics", profile_img_fn)

    output_size = (225, 225)
    i = Image.open(form_profile_img)
    i.thumbnail(output_size)
    i.save(profile_img_path)

    return profile_img_fn

def save_header_img(form_header_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_header_img.filename)
    header_img_fn = random_hex + f_ext
    header_img_path = os.path.join(app.root_path, "static/profile_pics", header_img_fn)
    form_header_img.save(header_img_path)

    output_size = (700, 700)
    i = Image.open(form_header_img)
    i.thumbnail(output_size)
    i.save(header_img_path)

    return header_img_fn

@app.route('/profile/<id>-<firstname>', methods=['GET', 'POST'])
@login_required
def profile(id, firstname):
    user = User.query.filter_by(id=id).first_or_404()
    firstname = User.query.filter_by(firstname=firstname).first_or_404()
    # edit profile form
    form = EditProfile()
    if form.validate_on_submit():
        if form.profile_img.data:
            profile_img_file = save_profile_img(form.profile_img.data)
            current_user.profile_img = profile_img_file
        if form.header_img.data:
            header_img_file = save_header_img(form.header_img.data)
            current_user.header_img = header_img_file
        current_user.firstname = form.firstname.data
        current_user.lastname = form.lastname.data
        current_user.email = form.email.data
        current_user.city = form.city.data
        db.session.commit()
        flash('Your account has been updated', 'success')
        return redirect(url_for('profile', id=current_user.id, firstname=current_user.firstname))
    elif request.method == 'GET':
        form.firstname.data = current_user.firstname
        form.lastname.data = current_user.lastname
        form.email.data = current_user.email
        form.city.data = current_user.city
    profile_img = url_for('static', filename='profile_pics/' + user.profile_img)
    header_img = url_for('static', filename='profile_pics/' + user.header_img)
    return render_template('profile.html', title='Profile', profile=profile, posts=posts, user=user, firstname=firstname, profile_img=profile_img, header_img=header_img, form=form)
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(20), nullable=False)
    lastname = db.Column(db.String(20), nullable=False)
    profile_img = db.Column(db.String(50), nullable=False, default="default.png")
    header_img = db.Column(db.String(50), nullable=False, default="default_bg5.jpg")
    email = db.Column(db.String(50), nullable=False)
    password = db.Column(db.String(60), nullable=False)
    city = db.Column(db.String(50), nullable=False)
    posts = db.relationship('Post', backref='author', lazy=True)
    work_history = db.relationship('Employment', backref='author', lazy=True)
    education = db.relationship('Education', backref='author', lazy=True)
    about = db.relationship('About', backref='author', lazy=True)

    def __repr__(self):
        return f"User('{self.id}', '{self.firstname}', '{self.lastname}', '{self.email}', '{self.city}', '{self.profile_img}', '{self.header_img}')" 
class EditProfile(FlaskForm):
    firstname = StringField('First Name', validators=[DataRequired(), Length(min=2, max=20)])
    lastname = StringField('Last Name',  validators=[DataRequired(), Length(min=2, max=20)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    profile_img = FileField(validators=[FileAllowed(['jpg', 'png'])])
    header_img = FileField(validators=[FileAllowed(['jpg', 'png'])])
    city = SelectField('City', choices = [('Brampton', 'Brampton'), ('Etobicoke', 'Etobicoke'), ('Brampton', 'Brampton'), ('Markham', 'Markham'), ('Mississauga', 'Mississauga'), ('North York', 'North York'), ('Oakville', 'Oakville'), ('Ottawa', 'Ottawa'), ('Pickering', 'Pickering'), ('Scarborough', 'Scarborough'), ('Toronto', 'Toronto'), ('Vaughn', 'Vaughn')])
    submit = SubmitField('Update Account')

    def validate_email(self, email):
        if email.data != current_user.email:    
            user = User.query.filter_by(email=email.data).first()
            if user:
                raise ValidationError('Email is already in use.')
def save_post_img(form_post_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_post_img.filename)
    post_img_fn = random_hex + f_ext
    post_img_path = os.path.join(app.root_path, "static/post_pics", post_img_fn)
    form_post_img.save(post_img_path)

    output_size = (700, 700)
    i = Image.open(form_post_img)
    i.thumbnail(output_size)
    i.save(post_img_path)

    return post_img_fn

@app.route('/')
@app.route('/index', methods=['GET', 'POST'])
def home():
    if current_user.is_authenticated == False:
        return redirect(url_for('register'))
    user = current_user
    profile_img = url_for('static', filename='profile_pics/' + user.profile_img)
    form = PostForm()
    if form.validate_on_submit():
        post = Post(content=form.content.data, post_img=form.post_img.data, author=current_user)
        if form.post_img.data:
            post_img_file = save_post_img(form.post_img.data)
            post_img = post_img_file
        db.session.add(post)
        db.session.commit()
        flash('Post Successful!', 'success')
        return redirect(url_for('profile', id=current_user.id, firstname=current_user.firstname))
    post_img = url_for('static', filename='post_pics/post_img.jpg')
    posts = Post.query.order_by(Post.date_posted.desc()).all()
    return render_template('index.html', posts=posts, profile_img=profile_img, form=form, user=user, post_img=post_img)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(1000), nullable=False)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)  
    post_img = db.Column(db.String(50), nullable=True) 
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    def __repr__(self):
        return f"Post('{self.content}', '{self.post_img}', '{self.date_posted}')" 
class PostForm(FlaskForm):
    content = TextAreaField('Content', validators=[DataRequired()])
    post_img= FileField(validators=[FileAllowed(['jpg', 'png'])])
    submit = SubmitField('Post')
型号.py

def save_profile_img(form_profile_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_profile_img.filename)
    profile_img_fn = random_hex + f_ext
    profile_img_path = os.path.join(app.root_path, "static/profile_pics", profile_img_fn)

    output_size = (225, 225)
    i = Image.open(form_profile_img)
    i.thumbnail(output_size)
    i.save(profile_img_path)

    return profile_img_fn

def save_header_img(form_header_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_header_img.filename)
    header_img_fn = random_hex + f_ext
    header_img_path = os.path.join(app.root_path, "static/profile_pics", header_img_fn)
    form_header_img.save(header_img_path)

    output_size = (700, 700)
    i = Image.open(form_header_img)
    i.thumbnail(output_size)
    i.save(header_img_path)

    return header_img_fn

@app.route('/profile/<id>-<firstname>', methods=['GET', 'POST'])
@login_required
def profile(id, firstname):
    user = User.query.filter_by(id=id).first_or_404()
    firstname = User.query.filter_by(firstname=firstname).first_or_404()
    # edit profile form
    form = EditProfile()
    if form.validate_on_submit():
        if form.profile_img.data:
            profile_img_file = save_profile_img(form.profile_img.data)
            current_user.profile_img = profile_img_file
        if form.header_img.data:
            header_img_file = save_header_img(form.header_img.data)
            current_user.header_img = header_img_file
        current_user.firstname = form.firstname.data
        current_user.lastname = form.lastname.data
        current_user.email = form.email.data
        current_user.city = form.city.data
        db.session.commit()
        flash('Your account has been updated', 'success')
        return redirect(url_for('profile', id=current_user.id, firstname=current_user.firstname))
    elif request.method == 'GET':
        form.firstname.data = current_user.firstname
        form.lastname.data = current_user.lastname
        form.email.data = current_user.email
        form.city.data = current_user.city
    profile_img = url_for('static', filename='profile_pics/' + user.profile_img)
    header_img = url_for('static', filename='profile_pics/' + user.header_img)
    return render_template('profile.html', title='Profile', profile=profile, posts=posts, user=user, firstname=firstname, profile_img=profile_img, header_img=header_img, form=form)
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(20), nullable=False)
    lastname = db.Column(db.String(20), nullable=False)
    profile_img = db.Column(db.String(50), nullable=False, default="default.png")
    header_img = db.Column(db.String(50), nullable=False, default="default_bg5.jpg")
    email = db.Column(db.String(50), nullable=False)
    password = db.Column(db.String(60), nullable=False)
    city = db.Column(db.String(50), nullable=False)
    posts = db.relationship('Post', backref='author', lazy=True)
    work_history = db.relationship('Employment', backref='author', lazy=True)
    education = db.relationship('Education', backref='author', lazy=True)
    about = db.relationship('About', backref='author', lazy=True)

    def __repr__(self):
        return f"User('{self.id}', '{self.firstname}', '{self.lastname}', '{self.email}', '{self.city}', '{self.profile_img}', '{self.header_img}')" 
class EditProfile(FlaskForm):
    firstname = StringField('First Name', validators=[DataRequired(), Length(min=2, max=20)])
    lastname = StringField('Last Name',  validators=[DataRequired(), Length(min=2, max=20)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    profile_img = FileField(validators=[FileAllowed(['jpg', 'png'])])
    header_img = FileField(validators=[FileAllowed(['jpg', 'png'])])
    city = SelectField('City', choices = [('Brampton', 'Brampton'), ('Etobicoke', 'Etobicoke'), ('Brampton', 'Brampton'), ('Markham', 'Markham'), ('Mississauga', 'Mississauga'), ('North York', 'North York'), ('Oakville', 'Oakville'), ('Ottawa', 'Ottawa'), ('Pickering', 'Pickering'), ('Scarborough', 'Scarborough'), ('Toronto', 'Toronto'), ('Vaughn', 'Vaughn')])
    submit = SubmitField('Update Account')

    def validate_email(self, email):
        if email.data != current_user.email:    
            user = User.query.filter_by(email=email.data).first()
            if user:
                raise ValidationError('Email is already in use.')
def save_post_img(form_post_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_post_img.filename)
    post_img_fn = random_hex + f_ext
    post_img_path = os.path.join(app.root_path, "static/post_pics", post_img_fn)
    form_post_img.save(post_img_path)

    output_size = (700, 700)
    i = Image.open(form_post_img)
    i.thumbnail(output_size)
    i.save(post_img_path)

    return post_img_fn

@app.route('/')
@app.route('/index', methods=['GET', 'POST'])
def home():
    if current_user.is_authenticated == False:
        return redirect(url_for('register'))
    user = current_user
    profile_img = url_for('static', filename='profile_pics/' + user.profile_img)
    form = PostForm()
    if form.validate_on_submit():
        post = Post(content=form.content.data, post_img=form.post_img.data, author=current_user)
        if form.post_img.data:
            post_img_file = save_post_img(form.post_img.data)
            post_img = post_img_file
        db.session.add(post)
        db.session.commit()
        flash('Post Successful!', 'success')
        return redirect(url_for('profile', id=current_user.id, firstname=current_user.firstname))
    post_img = url_for('static', filename='post_pics/post_img.jpg')
    posts = Post.query.order_by(Post.date_posted.desc()).all()
    return render_template('index.html', posts=posts, profile_img=profile_img, form=form, user=user, post_img=post_img)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(1000), nullable=False)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)  
    post_img = db.Column(db.String(50), nullable=True) 
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    def __repr__(self):
        return f"Post('{self.content}', '{self.post_img}', '{self.date_posted}')" 
class PostForm(FlaskForm):
    content = TextAreaField('Content', validators=[DataRequired()])
    post_img= FileField(validators=[FileAllowed(['jpg', 'png'])])
    submit = SubmitField('Post')
forms.py

def save_profile_img(form_profile_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_profile_img.filename)
    profile_img_fn = random_hex + f_ext
    profile_img_path = os.path.join(app.root_path, "static/profile_pics", profile_img_fn)

    output_size = (225, 225)
    i = Image.open(form_profile_img)
    i.thumbnail(output_size)
    i.save(profile_img_path)

    return profile_img_fn

def save_header_img(form_header_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_header_img.filename)
    header_img_fn = random_hex + f_ext
    header_img_path = os.path.join(app.root_path, "static/profile_pics", header_img_fn)
    form_header_img.save(header_img_path)

    output_size = (700, 700)
    i = Image.open(form_header_img)
    i.thumbnail(output_size)
    i.save(header_img_path)

    return header_img_fn

@app.route('/profile/<id>-<firstname>', methods=['GET', 'POST'])
@login_required
def profile(id, firstname):
    user = User.query.filter_by(id=id).first_or_404()
    firstname = User.query.filter_by(firstname=firstname).first_or_404()
    # edit profile form
    form = EditProfile()
    if form.validate_on_submit():
        if form.profile_img.data:
            profile_img_file = save_profile_img(form.profile_img.data)
            current_user.profile_img = profile_img_file
        if form.header_img.data:
            header_img_file = save_header_img(form.header_img.data)
            current_user.header_img = header_img_file
        current_user.firstname = form.firstname.data
        current_user.lastname = form.lastname.data
        current_user.email = form.email.data
        current_user.city = form.city.data
        db.session.commit()
        flash('Your account has been updated', 'success')
        return redirect(url_for('profile', id=current_user.id, firstname=current_user.firstname))
    elif request.method == 'GET':
        form.firstname.data = current_user.firstname
        form.lastname.data = current_user.lastname
        form.email.data = current_user.email
        form.city.data = current_user.city
    profile_img = url_for('static', filename='profile_pics/' + user.profile_img)
    header_img = url_for('static', filename='profile_pics/' + user.header_img)
    return render_template('profile.html', title='Profile', profile=profile, posts=posts, user=user, firstname=firstname, profile_img=profile_img, header_img=header_img, form=form)
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(20), nullable=False)
    lastname = db.Column(db.String(20), nullable=False)
    profile_img = db.Column(db.String(50), nullable=False, default="default.png")
    header_img = db.Column(db.String(50), nullable=False, default="default_bg5.jpg")
    email = db.Column(db.String(50), nullable=False)
    password = db.Column(db.String(60), nullable=False)
    city = db.Column(db.String(50), nullable=False)
    posts = db.relationship('Post', backref='author', lazy=True)
    work_history = db.relationship('Employment', backref='author', lazy=True)
    education = db.relationship('Education', backref='author', lazy=True)
    about = db.relationship('About', backref='author', lazy=True)

    def __repr__(self):
        return f"User('{self.id}', '{self.firstname}', '{self.lastname}', '{self.email}', '{self.city}', '{self.profile_img}', '{self.header_img}')" 
class EditProfile(FlaskForm):
    firstname = StringField('First Name', validators=[DataRequired(), Length(min=2, max=20)])
    lastname = StringField('Last Name',  validators=[DataRequired(), Length(min=2, max=20)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    profile_img = FileField(validators=[FileAllowed(['jpg', 'png'])])
    header_img = FileField(validators=[FileAllowed(['jpg', 'png'])])
    city = SelectField('City', choices = [('Brampton', 'Brampton'), ('Etobicoke', 'Etobicoke'), ('Brampton', 'Brampton'), ('Markham', 'Markham'), ('Mississauga', 'Mississauga'), ('North York', 'North York'), ('Oakville', 'Oakville'), ('Ottawa', 'Ottawa'), ('Pickering', 'Pickering'), ('Scarborough', 'Scarborough'), ('Toronto', 'Toronto'), ('Vaughn', 'Vaughn')])
    submit = SubmitField('Update Account')

    def validate_email(self, email):
        if email.data != current_user.email:    
            user = User.query.filter_by(email=email.data).first()
            if user:
                raise ValidationError('Email is already in use.')
def save_post_img(form_post_img):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_post_img.filename)
    post_img_fn = random_hex + f_ext
    post_img_path = os.path.join(app.root_path, "static/post_pics", post_img_fn)
    form_post_img.save(post_img_path)

    output_size = (700, 700)
    i = Image.open(form_post_img)
    i.thumbnail(output_size)
    i.save(post_img_path)

    return post_img_fn

@app.route('/')
@app.route('/index', methods=['GET', 'POST'])
def home():
    if current_user.is_authenticated == False:
        return redirect(url_for('register'))
    user = current_user
    profile_img = url_for('static', filename='profile_pics/' + user.profile_img)
    form = PostForm()
    if form.validate_on_submit():
        post = Post(content=form.content.data, post_img=form.post_img.data, author=current_user)
        if form.post_img.data:
            post_img_file = save_post_img(form.post_img.data)
            post_img = post_img_file
        db.session.add(post)
        db.session.commit()
        flash('Post Successful!', 'success')
        return redirect(url_for('profile', id=current_user.id, firstname=current_user.firstname))
    post_img = url_for('static', filename='post_pics/post_img.jpg')
    posts = Post.query.order_by(Post.date_posted.desc()).all()
    return render_template('index.html', posts=posts, profile_img=profile_img, form=form, user=user, post_img=post_img)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(1000), nullable=False)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)  
    post_img = db.Column(db.String(50), nullable=True) 
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    def __repr__(self):
        return f"Post('{self.content}', '{self.post_img}', '{self.date_posted}')" 
class PostForm(FlaskForm):
    content = TextAreaField('Content', validators=[DataRequired()])
    post_img= FileField(validators=[FileAllowed(['jpg', 'png'])])
    submit = SubmitField('Post')
\u postform.html

<div class="content-section bg-light">
    <form novalidate action="" method="POST" enctype="multipart/form-data">
        {{ form.hidden_tag() }}
            <div class="form-group">
                    {% if form.content.errors %}
                    {{ form.content(placeholder="What's on your mind?", 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(placeholder="What's on your mind?", class="form-control form-control-lg") }} 
                    {% endif %}    
            </div>
            <div class="container">
            <div class="row">
                <label for="file-upload" class="post-file-upload">
                    <i class='far fa-image fa-2x'></i>
                </label>
                    {{ form.post_img(placeholder='JPG or PNG', id="file-upload", type="file") }}
                {% if form.post_img.errors %}
                {% for error in form.post_img.errors %}
                    <span class='text-danger'>{{ error }}</span><br>
                {% endfor %}
                {% endif %}

            <div class="form-group">
                {{ form.submit(class="btn custom-btn") }}
            </div>
        </div>

        </div>

    </form>
</div> 
变动后

form = PostForm()
    if form.validate_on_submit():
        post = Post(content=form.content.data, author=current_user)
        db.session.add(post)
        db.session.commit()
        flash('Post Successful!', 'success')
        return redirect(url_for('profile', id=current_user.id, firstname=current_user.firstname))
任何帮助和见解都将不胜感激

一目了然(因为这里有很多东西)

[参数:('我希望这是一张照片','2020-01-07 21:02:46.223754',2)]

请注意,您实际上是将
post\u img
设置为
FileStorage
对象,而不是我怀疑您需要的字符串,或者在前面的示例中,
save\u post\u img()
的返回值

我怀疑在后一种
routes.py中,您需要更改:

post = Post(content=form.content.data, post_img=form.post_img.data, author=current_user)
if form.post_img.data:
    post_img_file = save_post_img(form.post_img.data)
    post_img = post_img_file
db.session.add(post)
更像是:

if form.post_img.data:
    post_img_file = save_post_img(form.post_img.data)
    post_img = post_img_file
post = Post(content=form.content.data, post_img=post_img_file, author=current_user)
db.session.add(post)
这样,您就可以在从
save\u post\u img()
获得返回后创建
post


那是猜测。希望这至少能帮你找到正确的方向。

我解决了!感谢您提供有关文件存储对象的提示。首先,我得到了实际保存到后期模型的图像。我是这样说的
post.post\u img=post\u img\u文件
我确认它是用 p=Posts.query.all()
一旦我发现我遇到了一个错误“无法连接'str'和'NoneType'对象” 因此,我删除了路由中的url,并在我的html
{{post.post\u img}
中简单地做了以下jinja2语句,然后返回十六进制文件。因此,我编写了url_,用于说明数据库中存储的None类型。 我用我的表格写了这个:

form = PostForm()
    if form.validate_on_submit():
        post = Post(content=form.content.data, post_img=form.post_img.data, author=current_user)
        if form.post_img.data:
            post_img_file = save_post_img(form.post_img.data)
            post.post_img = post_img_file
        db.session.add(post)
        db.session.commit()
        flash('Post Successful!', 'success')
        return redirect(url_for('home'))
    # list of posts by descending time
    posts = Post.query.order_by(Post.date_posted.desc()).all()
    for post in posts:
        if post.post_img != None:
            post_img = url_for('static', filename='post_pics/' + post.post_img)
    return render_template('index.html', posts=posts, post_img=post_img, profile_img=profile_img, form=form, user=user)

这在路由中没有错误,但jinja2仍然向我抛出了“无法连接非类型”错误,因此我也必须在html中解释它,并使用以下方法:

 {% if post.post_img != None %}
      <img class='img-fluid mx-auto post-img' src="{{ url_for('static', filename='post_pics/' + post.post_img) }}"> 
        {% endif %}
{%if post.post\u img!=None%}
{%endif%}

尝试过,但仍然出现接口错误。我想知道为什么它适用于用户模型而不是post模型?我想我找到了问题所在。在post\u img表单路由中,我有post\u img=post\u img\u文件。对于头文件和profile\u img,我有当前的\u user.profile\u img=profile\u img\u文件。我需要找到一种说“当前帖子”的方式,而不是说“当前用户”,我不知道该怎么做