Application - User Account & Profil Picture

dev
nico 5 days ago
parent 8690e401f2
commit 904a880886

Binary file not shown.

@ -13,6 +13,6 @@ db = SQLAlchemy(app)
bcrypt = Bcrypt(app) bcrypt = Bcrypt(app)
login_manager = LoginManager(app) login_manager = LoginManager(app)
login_manager.login_view = 'login' login_manager.login_view = 'login'
# login_manager.login_message_category = 'info' bootstrap class
from blogapp import routes from blogapp import routes

@ -1,4 +1,6 @@
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed
from flask_login import current_user #type: ignore
from wtforms import StringField, PasswordField, SubmitField, BooleanField from wtforms import StringField, PasswordField, SubmitField, BooleanField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from blogapp.models import User from blogapp.models import User
@ -6,7 +8,7 @@ from blogapp.models import User
class RegistrationForm(FlaskForm): class RegistrationForm(FlaskForm):
username = StringField('Username', username = StringField('Username',
validators=[DataRequired(), Length(min=2, max=20)]) validators=[DataRequired(), Length(min=4, max=20)])
email = StringField('Email', email = StringField('Email',
validators=[DataRequired(), Email()]) validators=[DataRequired(), Email()])
@ -31,4 +33,25 @@ class LoginForm(FlaskForm):
password = PasswordField('Password' , validators=[DataRequired()]) password = PasswordField('Password' , validators=[DataRequired()])
remember = BooleanField('Remember Me') remember = BooleanField('Remember Me')
submit =SubmitField('Login') submit =SubmitField('Login')
class UpdateAccountForm(FlaskForm):
username = StringField('Username',
validators=[DataRequired(), Length(min=4, max=20)])
email = StringField('Email',
validators=[DataRequired(), Email()])
picture = FileField('Update Profile Picture', validators=[FileAllowed(['jpg','png','jpeg'])])
submit =SubmitField('Update')
def validate_username(self, username):
if username.data != current_user.username:
user = User.query.filter_by(username=username.data).first()
if user:
raise ValidationError('That username is taken. Please choose a different one')
def validate_email(self, email):
if email.data != current_user.email:
user = User.query.filter_by(email=email.data).first()
if user:
raise ValidationError('That email is taken. Please choose a different one')

@ -11,7 +11,7 @@ class User(db.Model, UserMixin):
username = db.Column(db.String(20), unique=True, nullable=False) username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False, image_file = db.Column(db.String(20), nullable=False,
default='default.jpg') default='default.svg')
password = db.Column(db.String(60), nullable=False) password = db.Column(db.String(60), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True) posts = db.relationship('Post', backref='author', lazy=True)

@ -1,6 +1,9 @@
import os
import secrets
from PIL import Image #type: ignore
from flask import render_template, url_for, flash, redirect, request from flask import render_template, url_for, flash, redirect, request
from blogapp import app, db, bcrypt from blogapp import app, db, bcrypt
from blogapp.forms import RegistrationForm, LoginForm from blogapp.forms import RegistrationForm, LoginForm, UpdateAccountForm
from blogapp.models import User, Post from blogapp.models import User, Post
from flask_login import login_user, current_user, logout_user, login_required # type: ignore from flask_login import login_user, current_user, logout_user, login_required # type: ignore
@ -65,7 +68,33 @@ def logout():
logout_user() logout_user()
return redirect(url_for('home')) return redirect(url_for('home'))
@app.route("/account") def save_picture(form_picture):
random_hex = secrets.token_hex(8)
_, f_ext = os.path.splitext(form_picture.filename)
picture_fn = random_hex + f_ext
picture_path = os.path.join(app.root_path, 'static/profil_pics', picture_fn)
output_size = (125,125)
i = Image.open(form_picture)
i.thumbnail(output_size)
i.save(picture_path)
return picture_fn
@app.route("/account", methods=['GET', 'POST'])
@login_required @login_required
def account(): def account():
return render_template('account.html', title='account', pagetitle=pagetitle) form = UpdateAccountForm()
if form.validate_on_submit():
if form.picture.data:
picture_file = save_picture(form.picture.data)
current_user.image_file = picture_file
current_user.username = form.username.data
current_user.email = form.email.data
db.session.commit()
flash('Your account has been updated')
return redirect(url_for('account'))
elif request.method == 'GET':
form.username.data = current_user.username
form.email.data = current_user.email
image_file = url_for('static', filename='profil_pics/' + current_user.image_file)
return render_template('account.html', title='account', pagetitle=pagetitle,
image_file=image_file, form=form)

@ -1,3 +1,9 @@
.invalid { .invalid {
color:red; color:red;
}
.round-image{
width: 100px;
height:100px;
border-radius: 50%;
} }

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M399 384.2C376.9 345.8 335.4 320 288 320l-64 0c-47.4 0-88.9 25.8-111 64.2c35.2 39.2 86.2 63.8 143 63.8s107.8-24.7 143-63.8zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm256 16a72 72 0 1 0 0-144 72 72 0 1 0 0 144z"/></svg>

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

@ -2,6 +2,59 @@
{% block content %} {% block content %}
<img src="{{ image_file }}" class="round-image" alt="">
<h2> Welcome {{ current_user.username }} </h2> <h2> Welcome {{ current_user.username }} </h2>
<div>
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<br>
<fieldset>
<legend>Account Info</legend>
<div>
{{ form.username.label() }}
{% if form.username.errors %}
{{ form.username()}}
<div class="invalid">
{% for error in form.username.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.username() }}
{% endif %}
</div>
<br>
<div>
{{ form.email.label() }}
{% if form.email.errors %}
{{ form.email() }}
<div class="invalid">
{% for error in form.email.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.email() }}
{% endif %}
</div>
<br>
<div>
{{ form.picture.label() }}
{{ form.picture() }}
{% if form.picture.errors %}
{% for error in form.picture.errors %}
<br><span class="invalid">{{ error }}</span><br>
{% endfor %}
{% endif %}
</div>
</fieldset>
<div>
{{ form.submit() }}
</div>
</form>
</div>
{% endblock content %} {% endblock content %}

@ -5,6 +5,7 @@
<div> <div>
<form method="POST" action=""> <form method="POST" action="">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<br>
<fieldset> <fieldset>
<legend>Login</legend> <legend>Login</legend>
<div> <div>

@ -5,6 +5,7 @@
<div> <div>
<form method="POST" action=""> <form method="POST" action="">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<br>
<fieldset> <fieldset>
<legend>Join Today</legend> <legend>Join Today</legend>
<div> <div>

Binary file not shown.
Loading…
Cancel
Save