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)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
# login_manager.login_message_category = 'info' bootstrap class
from blogapp import routes

@ -1,4 +1,6 @@
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.validators import DataRequired, Length, Email, EqualTo, ValidationError
from blogapp.models import User
@ -6,7 +8,7 @@ from blogapp.models import User
class RegistrationForm(FlaskForm):
username = StringField('Username',
validators=[DataRequired(), Length(min=2, max=20)])
validators=[DataRequired(), Length(min=4, max=20)])
email = StringField('Email',
validators=[DataRequired(), Email()])
@ -31,4 +33,25 @@ class LoginForm(FlaskForm):
password = PasswordField('Password' , validators=[DataRequired()])
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)
email = db.Column(db.String(120), unique=True, 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)
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 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 flask_login import login_user, current_user, logout_user, login_required # type: ignore
@ -65,7 +68,33 @@ def logout():
logout_user()
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
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 {
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 %}
<img src="{{ image_file }}" class="round-image" alt="">
<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 %}

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

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

Binary file not shown.
Loading…
Cancel
Save