Начал делать изменение профиля

This commit is contained in:
Андрей Дувакин 2022-12-16 23:54:24 +05:00
parent 158409f158
commit 89bb80c73c
17 changed files with 1185 additions and 865 deletions

15
forms/edit_profile.py Normal file
View File

@ -0,0 +1,15 @@
from flask_wtf import FlaskForm
from flask_wtf.file import FileAllowed
from wtforms import EmailField, StringField, TextAreaField, FileField, SubmitField, DateField
from wtforms.validators import DataRequired
class EditProfileForm(FlaskForm):
email = EmailField('Почта', validators=[DataRequired()])
name = StringField('Имя', validators=[DataRequired()])
surname = StringField('Фамилия', )
about = TextAreaField('Расскажите о себе', default='')
birthday = DateField('Дата рождения')
photo = FileField('Фото', validators=[FileAllowed(['jpg', 'png', 'bmp'], 'Только фотографии!')])
del_photo = SubmitField('Удалить фотографию')
submit = SubmitField('Сохранить')

View File

@ -1,6 +1,6 @@
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from flask_wtf.file import FileAllowed from flask_wtf.file import FileAllowed
from wtforms import EmailField, StringField, PasswordField, SubmitField, FileField, DateField, TextAreaField from wtforms import EmailField, StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired from wtforms.validators import DataRequired

70
main.py
View File

@ -1,11 +1,14 @@
import datetime import datetime
import os
from flask import Flask, render_template, request, url_for from flask import Flask, render_template, request, url_for
from flask_login import login_user, current_user, LoginManager, logout_user, login_required from flask_login import login_user, current_user, LoginManager, logout_user, login_required
from werkzeug.datastructures import CombinedMultiDict
from werkzeug.utils import redirect from werkzeug.utils import redirect
from itsdangerous import URLSafeTimedSerializer, SignatureExpired from itsdangerous import URLSafeTimedSerializer, SignatureExpired
from functions import check_password, mail from functions import check_password, mail
from forms.edit_profile import EditProfileForm
from forms.login import LoginForm from forms.login import LoginForm
from forms.register import RegisterForm from forms.register import RegisterForm
from data.users import User from data.users import User
@ -22,7 +25,63 @@ login_manager.init_app(app)
@app.route('/') @app.route('/')
def base(): def base():
return render_template('main.html', title='Главная') if not current_user.is_authenticated:
return render_template('main.html', title='Главная')
else:
return redirect('/project')
@app.route('/project')
def project():
if current_user.is_authenticated:
return redirect(f'/profile')
else:
return redirect('/login')
@app.route('/profile', methods=['GET', 'POST'])
def profile():
if current_user.is_authenticated:
form = EditProfileForm(
CombinedMultiDict((request.files, request.form)),
email=current_user.email,
name=current_user.name,
surname=current_user.surname,
about=current_user.about,
birthday=current_user.birthday
)
if form.del_photo.data:
data_session = db_session.create_session()
user = data_session.query(User).filter(User.id == current_user.id).first()
if not user:
return render_template('profile.html', title='Профиль', form=form,
message='Ошибка, пользователь ненайден')
os.remove(current_user.photo)
user.photo = 'static/images/none_logo.png'
data_session.commit()
data_session.close()
if form.validate_on_submit():
data_session = db_session.create_session()
user = data_session.query(User).filter(User.id == current_user.id).first()
if not user:
return render_template('profile.html', title='Профиль', form=form,
message='Ошибка, пользователь ненайден')
if form.email.data != current_user.email:
pass
if form.photo.data:
with open(f'static/app_files/user_logo/{current_user.login}.png', 'wb') as file:
form.photo.data.save(file)
user.photo = f'static/app_files/user_logo/{current_user.login}.png'
user.name = form.name.data
user.surname = form.surname.data
user.about = form.about.data
user.birthday = form.birthday.data
data_session.commit()
data_session.close()
return redirect('/profile')
return render_template('profile.html', title='Профиль', form=form, message='')
else:
return redirect('/login')
@login_manager.user_loader @login_manager.user_loader
@ -56,7 +115,7 @@ def login():
return render_template('login.html', title='Авторизация', form=form, message=message, return render_template('login.html', title='Авторизация', form=form, message=message,
danger=danger) danger=danger)
else: else:
return redirect('/') return redirect('/project')
@app.route('/logout') @app.route('/logout')
@ -84,7 +143,10 @@ def register():
email=form.email.data, email=form.email.data,
name=form.name.data, name=form.name.data,
login=form.login.data, login=form.login.data,
activity=datetime.datetime.now() activity=datetime.datetime.now(),
data_reg=datetime.date.today(),
photo='static/images/none_logo.png',
role='user'
) )
user.set_password(form.password.data) user.set_password(form.password.data)
data_session.add(user) data_session.add(user)
@ -97,7 +159,7 @@ def register():
return redirect('/login?message=Мы выслали ссылку для подтверждения почты') return redirect('/login?message=Мы выслали ссылку для подтверждения почты')
return render_template('register.html', form=form, message='', title='Регистрация') return render_template('register.html', form=form, message='', title='Регистрация')
else: else:
return redirect('/') return redirect('/project')
@app.route('/confirmation/<token>') @app.route('/confirmation/<token>')

View File

@ -49,3 +49,43 @@ body {
width: 85%; width: 85%;
text-align: center; text-align: center;
} }
.nav_panel {
width: 100%;
display: inline-flex;
justify-content: center;
}
.nav_user {
display: flex;
flex-direction: row;
justify-content: center;
height: 100%;
align-items: center;
}
.nav_user_name {
margin-left: 10px;
align-self: center;
}
.nav_chapter_text {
height: 100%;
font-family: Georgia, 'Times New Roman', Times, serif;
font-style: bold;
color: #946137;
font-size: 2vw;
transition: color 0.3s ease-in;
}
.nav_chapter_text:hover {
color: #f3d5be;
}
.nav_chapter {
text-align: center;
width: 30%;
border-bottom: 0.2vw solid #d49d51;
transition: border-bottom 0.3s ease-in;
}
.nav_chapter:hover {
text-decoration: none;
border-bottom: 0.2vw solid #face7d;
}
.nav_user_name_div {
height: 100%;
}

View File

@ -256,3 +256,16 @@ main, html {
border-bottom: 3px solid #f3c79e; border-bottom: 3px solid #f3c79e;
text-decoration: none; text-decoration: none;
} }
.scroll_button {
position: fixed;
width: 50px;
height: 50px;
background-color: #e5e5e5;
border-radius: 2vw;
margin-left: 95%;
margin-top: 45%;
transition: background-color 0.5s ease-in;
}
.scroll_button:hover {
background-color: #1c59fe;
}

95
static/css/profile.css Normal file
View File

@ -0,0 +1,95 @@
.profile_page {
display: flex;
flex-direction: column;
height: 70vw;
width: 100%;
background: linear-gradient( rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0.8) ), url(../images/back_profile_one.jpg);background-repeat: repeat; background-position: center;
}
.profile_block {
height: 80%;
width: 85%;
margin-left: 7.5%;
margin-top: 10%;
background: linear-gradient( rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3) ), url(../images/back_profile_two.jpg);background-repeat: repeat; background-position: center;
display: flex;
flex-direction: column;
}
.header_profile {
display: inline;
flex-direction: column;
width: 15vw;
height: 15vw;
margin-top: 50px;
align-self: center;
}
.user_photo {
width: 15vw;
height: 15vw;
border: 0.2vw solid #ffffff;
border-radius: 2vw;
}
.edit_form {
align-self: center;
margin-top: 20px;
width: 80%;
}
form {
display: flex;
flex-direction: column;
}
.form_data_button {
align-self: center;
}
.form_blocks {
width: 100%;
margin-top: 50px;
display: inline-flex;
justify-content: space-evenly;
}
.form_data, .form_data_button {
display: flex;
flex-direction: column;
margin-left: 2%;
margin-left: 2%;
}
.form_data_button {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.input_data {
color: #000000;
border: 0.1vw solid #595008;
height: 4.5vw;
width: 20vw;
background-color: #dbc3af;
border-radius: 5vw;
font-size: 1.3vw;
display: inline-flex;
align-items: center;
}
.input_button {
width: 10vw;
height: 5vw;
border-radius: 5vw;
vertical-align: middle;
}
.form-label {
font-size: 1.3vw;
color: #ffffff;
font-weight: bold;
}
.profile_button {
margin-top: 15px;
width: 20vw;
height: 5vw;
background-color: #000000;
color: #ffffff;
border-radius: 5vw;
vertical-align: middle;
font-size: 1.5vw;
}
#delete_button {
margin-top: 45px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

BIN
static/images/none_logo.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,45 +1,58 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ru"> <html lang="ru">
<head> <head>
<meta charset="UTF-8"/> <meta charset="UTF-8" />
<link rel="stylesheet" href="../static/css/base.css"/> <link rel="stylesheet" href="../static/css/base.css" />
<link <link
rel="stylesheet" rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous" crossorigin="anonymous"
/> />
<link rel="icon" href="../static/images/logo_b.ico" type="image/x-icon"/> <link rel="icon" href="../static/images/logo_b.ico" type="image/x-icon" />
<title>{{title}}</title> <title>{{title}}</title>
</head> </head>
<body> <body>
<script <script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js" src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8" integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8"
crossorigin="anonymous" crossorigin="anonymous"
></script> ></script>
<nav class="navbar" id="navbar"> {% if current_user.is_authenticated %}
<div class="container-fluid"> <nav class="navbar">
<a class="navbar-brand" href="/"> <div class="nav_panel">
<img <a class="nav_chapter" href="/profile">
src="../static/images/logo_b.png" <div class="nav_user">
class="nav_logo" <div class="nav_user_name_div"><p class="nav_user_name nav_chapter_text">{{current_user.name}}</p></div>
/> </div>
</a>
<a class="nav_chapter" href="/projects">
<p class="nav_chapter_text">Проекты</p>
</a>
<a class="nav_chapter" href="/messages">
<p class="nav_chapter_text">Сообщения</p>
</a>
</div>
</nav>
{% else %}
<nav class="navbar" id="navbar">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<img src="../static/images/logo_b.png" class="nav_logo" />
</a> </a>
{% if current_user.is_authenticated %}
<a class="auth_button" href="/logout">Выход</a>
{% else %}
<a class="auth_button" href="/login">Авторизация</a> <a class="auth_button" href="/login">Авторизация</a>
{% endif %} </div>
</div> </nav>
</nav> {% endif %}
<!-- Begin page content --> <!-- Begin page content -->
<main role="main">{% block content %}{% endblock %}</main> <main role="main">{% block content %}{% endblock %}</main>
<footer class="footer"> <footer class="footer">
<div class="footer_block"> <div class="footer_block">
<a href="/#header_block"><img class="footer_logo" src="../static/images/logo_w.png"></a> <a href="/#header_block"
><img class="footer_logo" src="../static/images/logo_w.png"
/></a>
<strong class="footer_rights">© All rights reserved</strong> <strong class="footer_rights">© All rights reserved</strong>
</div> </div>
</footer> </footer>
</body> </body>
</html> </html>

View File

@ -2,6 +2,9 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<rect class="scroll_button">
<img class="scroll_image" src="">
</rect>
<div class="header_block"> <div class="header_block">
<div id="header_block"></div> <div id="header_block"></div>
<div class="header_text"> <div class="header_text">

79
templates/profile.html Normal file
View File

@ -0,0 +1,79 @@
<link rel="stylesheet" href="../static/css/profile.css"/>
{% extends "base.html" %} {% block content %}
<div class="profile_page">
<div class="profile_block">
<div class="header_profile">
<img class="user_photo" src="../{{current_user.photo}}">
</div>
<div class="edit_form">
<form action="" method="post" class="register_form" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<div class="form_blocks">
<div class="data_block">
<div class="form_data">
<label class="form-label">{{ form.email.label }}</label>
{{ form.email(class="input_data", type="email", placeholder='example@mail.ex') }} {% for
error in form.email.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
</div>
<div class="form_data">
<label class="form-label">{{ form.name.label }}</label>
{{ form.name(class="input_data", type="name", placeholder='name') }} {%
for error in form.name.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
</div>
<div class="form_data">
<label class="form-label">{{ form.surname.label }}</label>
{{ form.surname(class="input_data", type="surname", placeholder='surname') }}
{% for error in form.surname.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
</div>
</div>
<div class="data_block">
<div class="form_data">
<label class="form-label">{{ form.birthday.label }}</label>
{{ form.birthday(class="input_data", type="date") }}
{% for error in form.birthday.errors %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% endfor %}
</div>
<div class="form_data">
<label class="form-label">{{ form.about.label }}</label>
{{ form.about(class="input_data", type="name", placeholder='about') }} {%
for error in form.about.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
</div>
{% if 'none' in current_user.photo %}
<div class="form_data">
<label class="form-label">{{ form.photo.label }}</label>
{{ form.photo(class="input_data", type="file") }}
{% for error in form.photo.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
</div>
{% else %}
<div class="form_data_button">
{{ form.del_photo(type="submit", class="profile_button", id="delete_button") }}
</div>
{% endif %}
<div class="message_block">
{% if message != '' %}
<div class="alert alert-danger message" role="alert">{{ message }}</div>
{% endif %}
</div>
</div>
</div>
<div class="form_data_button">
{{ form.submit(type="submit", class="profile_button") }}
</div>
</form>
</div>
</div>
</div>
{% endblock %}