表单传回数据
This commit is contained in:
parent
c8d3325988
commit
28c6d27461
20
app.py
20
app.py
@ -1,8 +1,15 @@
|
|||||||
from flask import Flask, render_template
|
from flask import Flask, render_template
|
||||||
from blueprint.Login import bp_login
|
from blueprint.Login import bp_login
|
||||||
|
from blueprint.error import bp_error
|
||||||
|
|
||||||
|
# 创建Flask应用程序实例
|
||||||
app = Flask(__name__)
|
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('/')
|
@app.route('/')
|
||||||
@ -10,15 +17,6 @@ def index():
|
|||||||
return render_template('index.html')
|
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__':
|
if __name__ == '__main__':
|
||||||
|
DEBUG = True
|
||||||
app.run()
|
app.run()
|
||||||
|
@ -9,11 +9,15 @@
|
|||||||
@Comment : 登录功能的蓝图
|
@Comment : 登录功能的蓝图
|
||||||
"""
|
"""
|
||||||
from flask import Blueprint, render_template
|
from flask import Blueprint, render_template
|
||||||
|
from blueprint.model import LoginForm
|
||||||
# 创建蓝图对象
|
# 创建蓝图对象
|
||||||
bp_login = Blueprint('bp_login', __name__)
|
bp_login = Blueprint('bp_login', __name__)
|
||||||
|
|
||||||
|
|
||||||
@bp_login.route('/login')
|
@bp_login.route('/', methods=['GET', 'POST'])
|
||||||
def login():
|
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
24
blueprint/error.py
Normal 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
25
blueprint/model.py
Normal 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"})
|
@ -1 +1,2 @@
|
|||||||
Flask~=2.2.3
|
Flask~=2.2.3
|
||||||
|
WTForms~=3.0.1
|
34
templates/bootstrap/base.html
Normal file
34
templates/bootstrap/base.html
Normal 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 -%}
|
6
templates/bootstrap/fixes.html
Normal file
6
templates/bootstrap/fixes.html
Normal 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 %}
|
38
templates/bootstrap/google.html
Normal file
38
templates/bootstrap/google.html
Normal 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 %}
|
51
templates/bootstrap/pagination.html
Normal file
51
templates/bootstrap/pagination.html
Normal 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=('«')|safe,
|
||||||
|
next=('»')|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 %}
|
45
templates/bootstrap/utils.html
Normal file
45
templates/bootstrap/utils.html
Normal 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">×</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 %}
|
213
templates/bootstrap/wtf.html
Normal file
213
templates/bootstrap/wtf.html
Normal 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 %}
|
@ -18,22 +18,51 @@
|
|||||||
<p>请输入您的账号密码</p>
|
<p>请输入您的账号密码</p>
|
||||||
</div>
|
</div>
|
||||||
</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="col-md-6 col-xl-4">
|
||||||
<div class="card mb-5" id="cardbody" style="background: rgba(255,255,255,0.6);">
|
<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="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>
|
<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>
|
</svg>
|
||||||
<form class="text-center" method="post"><input class="form-control" type="text" id="account" placeholder="账号" name="account" required="">
|
</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"></div>
|
||||||
<div class="mb-3"><input class="form-control" type="password" id="password" name="password" placeholder="密码" required=""></div>
|
<div class="mb-3">{{ form.password }}</div>
|
||||||
<div class="mb-3"><button class="btn btn-primary d-block w-100" type="submit">Login</button></div>
|
<div class="mb-3">{{ form.submit }}</div>
|
||||||
<div class="row">
|
<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 class="col"><a id="forgetpassword" href="#">找回密码</a></div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user