Python 我的sqlalchemy.InterfaceError的原因是什么?如何使用url_for()访问存储为十六进制的图像(使用PIL pillow)?
长期读者,第一次海报 我正在用python flask和sqlalchemy创建一个基本的社交网络。这包括个人资料照片、标题照片和帖子照片。我一直在遵循Corey Schafer的python Alchemy教程,使用PIL Pizz实现标题和个人资料照片功能。这是相当简单的,工作如预期。问题是试图在Post模型中复制这一点,而不是在用户模型中 下面是我成功实现的profile\u img和header\u img功能 routes.pyPython 我的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
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文件。我需要找到一种说“当前帖子”的方式,而不是说“当前用户”,我不知道该怎么做