Compare commits

...

1 Commits
master ... Dev

Author SHA1 Message Date
Wang Keyi
28c6d27461 表单传回数据 2023-04-28 11:34:55 +08:00
12 changed files with 490 additions and 22 deletions

20
app.py
View File

@ -1,8 +1,15 @@
from flask import Flask, render_template
from blueprint.Login import bp_login
from blueprint.error import bp_error
# 创建Flask应用程序实例
app = Flask(__name__)
app.register_blueprint(bp_login)
app.register_blueprint(bp_login, url_prefix='/login')
app.register_blueprint(bp_error)
# 配置Flask应用程序实例
app.config['SECRET_KEY'] = 'Myth wky'
@app.route('/')
@ -10,15 +17,6 @@ def index():
return render_template('index.html')
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@app.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500
if __name__ == '__main__':
DEBUG = True
app.run()

View File

@ -9,11 +9,15 @@
@Comment : 登录功能的蓝图
"""
from flask import Blueprint, render_template
from blueprint.model import LoginForm
# 创建蓝图对象
bp_login = Blueprint('bp_login', __name__)
@bp_login.route('/login')
@bp_login.route('/', methods=['GET', 'POST'])
def login():
return render_template('login.html')
form = LoginForm()
if form.validate_on_submit():
print(form.account.data)
print(form.password.data)
return render_template('login.html', form=form)

24
blueprint/error.py Normal file
View File

@ -0,0 +1,24 @@
# -*- coding: UTF-8 -*-
"""
@Project : FlaskProject
@File : error.py
@IDE : PyCharm
@Author : 爱写屎山的王可奕
@Email : 1933658780@qq.com
@Date : 2023/4/28 9:31
@Comment : errorhandler的蓝图
"""
from flask import Blueprint, render_template
# 创建蓝图对象
bp_error = Blueprint('bp_error', __name__)
@bp_error.app_errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@bp_error.app_errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500

25
blueprint/model.py Normal file
View File

@ -0,0 +1,25 @@
# -*- coding: UTF-8 -*-
"""
@Project : FlaskProject
@File : model.py
@IDE : PyCharm
@Author : 爱写屎山的王可奕
@Email : 1933658780@qq.com
@Date : 2023/4/28 10:01
@Comment : 存放各种类
"""
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField
from wtforms.validators import DataRequired
from werkzeug.security import generate_password_hash, check_password_hash
class LoginForm(FlaskForm):
account = StringField(label='account', validators=[DataRequired('用户名不能为空')],
render_kw={'class': "form-control", 'type': "text",
'id': "account", 'placeholder': "账号",
'required': ""})
password = PasswordField(label='password', validators=[DataRequired('密码不能为空')],
render_kw={'class': "form-control", 'type': "password", 'id': "password",
'placeholder': "密码", 'required': ""})
submit = SubmitField(label='login', render_kw={'class': "btn btn-primary d-block w-100", 'type': "submit"})

View File

@ -1 +1,2 @@
Flask~=2.2.3
Flask~=2.2.3
WTForms~=3.0.1

View File

@ -0,0 +1,34 @@
{% block doc -%}
<!DOCTYPE html>
<html{% block html_attribs %}{% endblock html_attribs %}>
{%- block html %}
<head>
{%- block head %}
<title>{% block title %}{{title|default}}{% endblock title %}</title>
{%- block metas %}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{%- endblock metas %}
{%- block styles %}
<!-- Bootstrap -->
<link href="{{bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')}}" rel="stylesheet">
{%- endblock styles %}
{%- endblock head %}
</head>
<body{% block body_attribs %}{% endblock body_attribs %}>
{% block body -%}
{% block navbar %}
{%- endblock navbar %}
{% block content -%}
{%- endblock content %}
{% block scripts %}
<script src="{{bootstrap_find_resource('jquery.js', cdn='jquery')}}"></script>
<script src="{{bootstrap_find_resource('js/bootstrap.js', cdn='bootstrap')}}"></script>
{%- endblock scripts %}
{%- endblock body %}
</body>
{%- endblock html %}
</html>
{% endblock doc -%}

View File

@ -0,0 +1,6 @@
{% macro ie8() %}
<!--[if lt IE 9]>
<script src="{{bootstrap_find_resource('html5shiv.js', cdn='html5shiv', local=False)}}"></script>
<script src="{{bootstrap_find_resource('respond.js', cdn='respond.js', local=False)}}"></script>
<![endif]-->
{% endmacro %}

View File

@ -0,0 +1,38 @@
{% macro analytics(account) -%}
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '{{account}}']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
{% endmacro %}
{% macro uanalytics(id, options='auto', domain=None) %}
{# The uanalytics macro currently contains a hack to support legacy code.
The old signature was ``uanalytics(id, domain)`` when domain was a required
parameter that was passed on to the ga() function.
To preserve old behavior, if options is not a dictionary, it is passed on
unchanged. The ``domain`` parameter is added to not break calls with named
parameters, it will override any other value for options.
More modern code can simply pass any desired option to the analytics
function as desired.
#}
{%- if domain != None %}
{%- set options = domain %}
{%- endif %}
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', {{id|tojson|safe}}, {{options|tojson|safe}});
ga('send', 'pageview');
</script>
{% endmacro %}

View File

@ -0,0 +1,51 @@
{% macro _arg_url_for(endpoint, base) %}
{# calls url_for() with a given endpoint and **base as the parameters,
additionally passing on all keyword_arguments (may overwrite existing ones)
#}
{%- with kargs = base.copy() -%}
{%- do kargs.update(kwargs) -%}
{{url_for(endpoint, **kargs)}}
{%- endwith %}
{%- endmacro %}
{% macro render_pagination(pagination,
endpoint=None,
prev=('&laquo;')|safe,
next=('&raquo;')|safe,
size=None,
ellipses='…',
args={}
)
-%}
{% with url_args = {} %}
{%- do url_args.update(request.view_args if not endpoint else {}),
url_args.update(request.args if not endpoint else {}),
url_args.update(args) -%}
{% with endpoint = endpoint or request.endpoint %}
<nav>
<ul class="pagination{% if size %} pagination-{{size}}{% endif %}"{{kwargs|xmlattr}}>
{# prev and next are only show if a symbol has been passed. #}
{% if prev != None -%}
<li{% if not pagination.has_prev %} class="disabled"{% endif %}><a href="{{_arg_url_for(endpoint, url_args, page=pagination.prev_num) if pagination.has_prev else '#'}}">{{prev}}</a></li>
{%- endif -%}
{%- for page in pagination.iter_pages() %}
{% if page %}
{% if page != pagination.page %}
<li><a href="{{_arg_url_for(endpoint, url_args, page=page)}}">{{page}}</a></li>
{% else %}
<li class="active"><a href="#">{{page}} <span class="sr-only">(current)</span></a></li>
{% endif %}
{% elif ellipses != None %}
<li class="disabled"><a href="#">{{ellipses}}</a></li>
{% endif %}
{%- endfor %}
{% if next != None -%}
<li{% if not pagination.has_next %} class="disabled"{% endif %}><a href="{{_arg_url_for(endpoint, url_args, page=pagination.next_num) if pagination.has_next else '#'}}">{{next}}</a></li>
{%- endif -%}
</ul>
</nav>
{% endwith %}
{% endwith %}
{% endmacro %}

View File

@ -0,0 +1,45 @@
{% macro flashed_messages(messages=None, container=True, transform={
'critical': 'danger',
'error': 'danger',
'info': 'info',
'warning': 'warning',
'debug': 'info',
'notset': 'info',
'message': 'info',
}, default_category=None, dismissible=False) -%}
{% with messages = messages or get_flashed_messages(with_categories=True) -%}
{% if messages -%} {# don't output anything if there are no messages #}
{% if container -%}
<!-- begin message block -->
<div class="container flashed-messages">
<div class="row">
<div class="col-md-12">
{% endif -%}
{% for cat, msg in messages %} <div class="alert alert-{{transform.get(cat.lower(), default_category or cat)}}{% if dismissible %} alert-dismissible{% endif %}" role="alert">
{% if dismissible %} <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>{% endif %}
{{msg}}
</div>
{%- endfor -%}
{% if container %}
</div>
</div>
</div>
<!-- end message block -->
{% endif -%}
{% endif -%}
{% endwith -%}
{% endmacro -%}
{% macro icon(type=None, extra_classes=[]) -%}
<span{{ ({'class': (['glyphicon', 'glyphicon-' + type] + extra_classes)|join(' ')})|xmlattr}}{{kwargs|xmlattr}}></span>
{%- endmacro %}
{% macro form_button(url, content, method='post', class='btn-link') -%}
<form style="display: inline;" action='{{url}}' method='{{method}}'><button class="{{class|safe}}">{{content}}</button></form>
{%- endmacro %}

View File

@ -0,0 +1,213 @@
{% macro form_errors(form, hiddens=True) %}
{%- if form.errors %}
{%- for fieldname, errors in form.errors.items() %}
{%- if bootstrap_is_hidden_field(form[fieldname]) and hiddens or
not bootstrap_is_hidden_field(form[fieldname]) and hiddens != 'only' %}
{%- for error in errors %}
<p class="error">{{error}}</p>
{%- endfor %}
{%- endif %}
{%- endfor %}
{%- endif %}
{%- endmacro %}
{% macro _hz_form_wrap(horizontal_columns, form_type, add_group=False, required=False) %}
{% if form_type == "horizontal" %}
{% if add_group %}<div class="form-group{% if required %} required{% endif %}">{% endif %}
<div class="col-{{horizontal_columns[0]}}-offset-{{horizontal_columns[1]}}
col-{{horizontal_columns[0]}}-{{horizontal_columns[2]}}
">
{% endif %}
{{caller()}}
{% if form_type == "horizontal" %}
{% if add_group %}</div>{% endif %}
</div>
{% endif %}
{% endmacro %}
{% macro form_field(field,
form_type="basic",
horizontal_columns=('lg', 2, 10),
button_map={}) %}
{# this is a workaround hack for the more straightforward-code of just passing required=required parameter. older versions of wtforms do not have
the necessary fix for required=False attributes, but will also not set the required flag in the first place. we skirt the issue using the code below #}
{% if field.flags.required and not required in kwargs %}
{% set kwargs = dict(required=True, **kwargs) %}
{% endif %}
{% if field.widget.input_type == 'checkbox' %}
{% call _hz_form_wrap(horizontal_columns, form_type, True, required=required) %}
<div class="checkbox">
<label>
{{field()|safe}} {{field.label.text|safe}}
</label>
</div>
{% endcall %}
{%- elif field.type == 'RadioField' -%}
{# note: A cleaner solution would be rendering depending on the widget,
this is just a hack for now, until I can think of something better #}
{% call _hz_form_wrap(horizontal_columns, form_type, True, required=required) %}
{% for item in field -%}
<div class="radio">
<label>
{{item|safe}} {{item.label.text|safe}}
</label>
</div>
{% endfor %}
{% endcall %}
{%- elif field.type == 'SubmitField' -%}
{# deal with jinja scoping issues? #}
{% set field_kwargs = kwargs %}
{# note: same issue as above - should check widget, not field type #}
{% call _hz_form_wrap(horizontal_columns, form_type, True, required=required) %}
{{field(class='btn btn-%s' % button_map.get(field.name, 'default'),
**field_kwargs)}}
{% endcall %}
{%- elif field.type == 'FormField' -%}
{# note: FormFields are tricky to get right and complex setups requiring
these are probably beyond the scope of what this macro tries to do.
the code below ensures that things don't break horribly if we run into
one, but does not try too hard to get things pretty. #}
<fieldset>
<legend>{{field.label}}</legend>
{%- for subfield in field %}
{% if not bootstrap_is_hidden_field(subfield) -%}
{{ form_field(subfield,
form_type=form_type,
horizontal_columns=horizontal_columns,
button_map=button_map) }}
{%- endif %}
{%- endfor %}
</fieldset>
{% else -%}
<div class="form-group {% if field.errors %} has-error{% endif -%}
{%- if field.flags.required %} required{% endif -%}
">
{%- if form_type == "inline" %}
{{field.label(class="sr-only")|safe}}
{% if field.type == 'FileField' %}
{{field(**kwargs)|safe}}
{% else %}
{{field(class="form-control", **kwargs)|safe}}
{% endif %}
{% elif form_type == "horizontal" %}
{{field.label(class="control-label " + (
" col-%s-%s" % horizontal_columns[0:2]
))|safe}}
<div class=" col-{{horizontal_columns[0]}}-{{horizontal_columns[2]}}">
{% if field.type == 'FileField' %}
{{field(**kwargs)|safe}}
{% else %}
{{field(class="form-control", **kwargs)|safe}}
{% endif %}
</div>
{%- if field.errors %}
{%- for error in field.errors %}
{% call _hz_form_wrap(horizontal_columns, form_type, required=required) %}
<p class="help-block">{{error}}</p>
{% endcall %}
{%- endfor %}
{%- elif field.description -%}
{% call _hz_form_wrap(horizontal_columns, form_type, required=required) %}
<p class="help-block">{{field.description|safe}}</p>
{% endcall %}
{%- endif %}
{%- else -%}
{{field.label(class="control-label")|safe}}
{% if field.type == 'FileField' %}
{{field(**kwargs)|safe}}
{% else %}
{{field(class="form-control", **kwargs)|safe}}
{% endif %}
{%- if field.errors %}
{%- for error in field.errors %}
<p class="help-block">{{error}}</p>
{%- endfor %}
{%- elif field.description -%}
<p class="help-block">{{field.description|safe}}</p>
{%- endif %}
{%- endif %}
</div>
{% endif %}
{% endmacro %}
{# valid form types are "basic", "inline" and "horizontal" #}
{% macro quick_form(form,
action="",
method="post",
extra_classes=None,
role="form",
form_type="basic",
horizontal_columns=('lg', 2, 10),
enctype=None,
button_map={},
id="",
novalidate=False) %}
{#-
action="" is what we want, from http://www.ietf.org/rfc/rfc2396.txt:
4.2. Same-document References
A URI reference that does not contain a URI is a reference to the
current document. In other words, an empty URI reference within a
document is interpreted as a reference to the start of that document,
and a reference containing only a fragment identifier is a reference
to the identified fragment of that document. Traversal of such a
reference should not result in an additional retrieval action.
However, if the URI reference occurs in a context that is always
intended to result in a new request, as in the case of HTML's FORM
element, then an empty URI reference represents the base URI of the
current document and should be replaced by that URI when transformed
into a request.
-#}
{#- if any file fields are inside the form and enctype is automatic, adjust
if file fields are found. could really use the equalto test of jinja2
here, but latter is not available until 2.8
warning: the code below is guaranteed to make you cry =(
#}
{%- set _enctype = [] %}
{%- if enctype is none -%}
{%- for field in form %}
{%- if field.type == 'FileField' %}
{#- for loops come with a fairly watertight scope, so this list-hack is
used to be able to set values outside of it #}
{%- set _ = _enctype.append('multipart/form-data') -%}
{%- endif %}
{%- endfor %}
{%- else %}
{% set _ = _enctype.append(enctype) %}
{%- endif %}
<form
{%- if action != None %} action="{{action}}"{% endif -%}
{%- if id %} id="{{id}}"{% endif -%}
{%- if method %} method="{{method}}"{% endif %}
class="form
{%- if extra_classes %} {{extra_classes}}{% endif -%}
{%- if form_type == "horizontal" %} form-horizontal
{%- elif form_type == "inline" %} form-inline
{%- endif -%}
"
{%- if _enctype[0] %} enctype="{{_enctype[0]}}"{% endif -%}
{%- if role %} role="{{role}}"{% endif -%}
{%- if novalidate %} novalidate{% endif -%}
>
{{ form.hidden_tag() }}
{{ form_errors(form, hiddens='only') }}
{%- for field in form %}
{% if not bootstrap_is_hidden_field(field) -%}
{{ form_field(field,
form_type=form_type,
horizontal_columns=horizontal_columns,
button_map=button_map) }}
{%- endif %}
{%- endfor %}
</form>
{%- endmacro %}

View File

@ -18,22 +18,51 @@
<p>请输入您的账号密码</p>
</div>
</div>
<div class="row d-flex justify-content-center" style="background: url({{ url_for('static', filename='/images/DSC00993.jpg') }}), #ffffff;background-size: cover, auto;padding-top: 45px;">
<div class="row d-flex justify-content-center"
style="background: url({{ url_for('static', filename='/images/DSC00993.jpg') }}), #ffffff;background-size: cover, auto;padding-top: 45px;">
<div class="col-md-6 col-xl-4">
<div class="card mb-5" id="cardbody" style="background: rgba(255,255,255,0.6);">
<div class="card-body d-flex flex-column align-items-center">
<div class="bs-icon-xl bs-icon-circle bs-icon-primary bs-icon my-4" style="background: rgba(26,26,26,0.7);"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-person">
<div class="bs-icon-xl bs-icon-circle bs-icon-primary bs-icon my-4"
style="background: rgba(26,26,26,0.7);">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor"
viewBox="0 0 16 16" class="bi bi-person">
<path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10z"></path>
</svg></div>
<form class="text-center" method="post"><input class="form-control" type="text" id="account" placeholder="账号" name="account" required="">
</svg>
</div>
{# <form method="POST">#}
{# {{ form.hidden_tag() }}#}
{# {{ form.name.label }} {{ form.name() }}#}
{# {{ form.submit() }}#}
{# </form>#}
<form class="text-center" method="POST">
{{ form.hidden_tag() }}
{{ form.account }}
<div class="mb-3"></div>
<div class="mb-3"><input class="form-control" type="password" id="password" name="password" placeholder="密码" required=""></div>
<div class="mb-3"><button class="btn btn-primary d-block w-100" type="submit">Login</button></div>
<div class="mb-3">{{ form.password }}</div>
<div class="mb-3">{{ form.submit }}</div>
<div class="row">
<div class="col d-lg-flex justify-content-lg-center align-items-lg-center"><a id="register" href="#">注册账号</a></div>
<div class="col d-lg-flex justify-content-lg-center align-items-lg-center"><a
id="register" href="#">注册账号</a></div>
<div class="col"><a id="forgetpassword" href="#">找回密码</a></div>
</div>
</form>
{# <input class="form-control" type="text"#}
{# id="account" placeholder="账号"#}
{# name="account" required="">#}
{# <div class="mb-3"></div>#}
{# <div class="mb-3"><input class="form-control" type="password" id="password"#}
{# name="password" placeholder="密码" required=""></div>#}
{# <div class="mb-3">#}
{# <button class="btn btn-primary d-block w-100" type="submit">Login</button>#}
{# </div>#}
{# <div class="row">#}
{# <div class="col d-lg-flex justify-content-lg-center align-items-lg-center"><a#}
{# id="register" href="#">注册账号</a></div>#}
{# <div class="col"><a id="forgetpassword" href="#">找回密码</a></div>#}
{# </div>#}
</div>
</div>
</div>