405 Error: The method is not allowed for the requested URL
405 Error: The method is not allowed for the requested URL
我一直在尝试为我的网站编写重设密码。但是,我继续运行进入405错误。 Google 说很可能是客户端错误,但我认为我的 html 没问题。我不确定还有什么可能导致错误。
我试过在没有内容的情况下测试 url,但这也没有用。
routes.py
def send_reset_email(user):
token = user.get_reset_token()
msg = Message('Password Reset Request', sender='noreply@clubsapp.com', recipients=[user.email])
msg.body = f'''To reset your password, visit the following link:
{url_for('reset_token', token=token, _external=True)}
If you did not make this request then simply ignore this email and no change will be made.
'''
mail.send(msg)
@users.route('/reset_request', methods=['GET, POST'])
def reset_request():
if current_user.is_authenticated:
return redirect(url_for('main.home'))
form = RequestResetForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
send_reset_email(user)
flash('An email has been sent with instructions to reset your password', 'info')
return redirect(url_for('users.login'))
return render_template('reset_request.html', title='Reset Password', form=form)
@users.route('/reset_password/<token>', methods=['GET, POST'])
def reset_token(token):
if current_user.is_authenticated:
return redirect(url_for('main.home'))
user = User.verify_reset_token(token)
if user is None:
flash('That is an invalid or expired token', 'warning')
return redirect(url_for('reset_request'))
form = ResetPasswordForm()
if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
user.password = hashed_password
db.session.commit()
flash(f'Your password has been updated, you are now able to log in!', 'success')
return redirect(url_for('users.login'))
return render_template('reset_token.html', title='Reset Password', form=form)
forms.py
class RequestResetForm(FlaskForm):
email = StringField('Email',
validators=[DataRequired(), Email()],
render_kw={"placeholder":"Enter Email"})
submit = SubmitField('Request Password Reset')
def validate_email(self, email):
user = User.query.filter_by(email=email.data).first()
if user is None:
raise ValidationError('There is no account with that email. You must register first.')
class ResetPasswordForm(FlaskForm):
password = PasswordField('Password',
validators=[DataRequired(), EqualTo('confirm_password', message='Passwords Must Match')],
render_kw={"placeholder":"Create Password"})
confirm_password = PasswordField('Confirm Password',
validators=[DataRequired(), EqualTo('password', message='Passwords Must Match')],
render_kw={"placeholder":"Confirm Password"})
submit = SubmitField('Reset Password')
models.py
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
firstname = db.Column(db.String(15), nullable=False)
lastname = db.Column(db.String(15), nullable=False)
email = db.Column(db.String(60), unique=True, nullable=False)
password = db.Column(db.String(60), nullable=False)
role = db.Column(db.Integer(), nullable=False, default=ROLES['student'])
clubs = db.relationship('Club', secondary=user_club_assoc_table)
def get_reset_token(self, expires_sec=1800):
s = Serializer(app.config['SECRET_KEY'], expires_sec)
return s.dumps({'user_id': self.id})
@staticmethod
def verify_reset_token(token):
s = Serializer(app.config['SECRET_KEY'])
try:
user_id = s.loads(token)['user_id']
except:
return None
return User.query.get(user_id)
def __repr__(self):
return f'{self.firstname} {self.lastname}'
login.html
{% extends "layout.html" %}
{% block content %}
<h1>Login Page</h1>
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Login</legend>
...(irrelevant content)
<div class="border-top pt-3">
<small class="text-muted">
<a class="ml-2" href="{{ url_for('users.register') }}">Don't Have An Account?</a>
</small>
<small class="text-muted ml-2">
<a class="ml-2" href="{{ url_for('users.reset_request') }}">Forgot Password?</a>
</small>
</div>
{% endblock content %}
这是一个简单的错误。不是 methods=['GET, POST']
.
改为
methods=['GET', 'POST']
HTTP Methods
Web applications use different HTTP methods when accessing URLs. You
should familiarize yourself with the HTTP methods as you work with
Flask. By default, a route only answers to GET requests. You can use
the methods argument of the route() decorator to handle different HTTP
methods.
from flask import request
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return do_the_login()
else:
return show_the_login_form()
我一直在尝试为我的网站编写重设密码。但是,我继续运行进入405错误。 Google 说很可能是客户端错误,但我认为我的 html 没问题。我不确定还有什么可能导致错误。
我试过在没有内容的情况下测试 url,但这也没有用。
routes.py
def send_reset_email(user):
token = user.get_reset_token()
msg = Message('Password Reset Request', sender='noreply@clubsapp.com', recipients=[user.email])
msg.body = f'''To reset your password, visit the following link:
{url_for('reset_token', token=token, _external=True)}
If you did not make this request then simply ignore this email and no change will be made.
'''
mail.send(msg)
@users.route('/reset_request', methods=['GET, POST'])
def reset_request():
if current_user.is_authenticated:
return redirect(url_for('main.home'))
form = RequestResetForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
send_reset_email(user)
flash('An email has been sent with instructions to reset your password', 'info')
return redirect(url_for('users.login'))
return render_template('reset_request.html', title='Reset Password', form=form)
@users.route('/reset_password/<token>', methods=['GET, POST'])
def reset_token(token):
if current_user.is_authenticated:
return redirect(url_for('main.home'))
user = User.verify_reset_token(token)
if user is None:
flash('That is an invalid or expired token', 'warning')
return redirect(url_for('reset_request'))
form = ResetPasswordForm()
if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
user.password = hashed_password
db.session.commit()
flash(f'Your password has been updated, you are now able to log in!', 'success')
return redirect(url_for('users.login'))
return render_template('reset_token.html', title='Reset Password', form=form)
forms.py
class RequestResetForm(FlaskForm):
email = StringField('Email',
validators=[DataRequired(), Email()],
render_kw={"placeholder":"Enter Email"})
submit = SubmitField('Request Password Reset')
def validate_email(self, email):
user = User.query.filter_by(email=email.data).first()
if user is None:
raise ValidationError('There is no account with that email. You must register first.')
class ResetPasswordForm(FlaskForm):
password = PasswordField('Password',
validators=[DataRequired(), EqualTo('confirm_password', message='Passwords Must Match')],
render_kw={"placeholder":"Create Password"})
confirm_password = PasswordField('Confirm Password',
validators=[DataRequired(), EqualTo('password', message='Passwords Must Match')],
render_kw={"placeholder":"Confirm Password"})
submit = SubmitField('Reset Password')
models.py
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
firstname = db.Column(db.String(15), nullable=False)
lastname = db.Column(db.String(15), nullable=False)
email = db.Column(db.String(60), unique=True, nullable=False)
password = db.Column(db.String(60), nullable=False)
role = db.Column(db.Integer(), nullable=False, default=ROLES['student'])
clubs = db.relationship('Club', secondary=user_club_assoc_table)
def get_reset_token(self, expires_sec=1800):
s = Serializer(app.config['SECRET_KEY'], expires_sec)
return s.dumps({'user_id': self.id})
@staticmethod
def verify_reset_token(token):
s = Serializer(app.config['SECRET_KEY'])
try:
user_id = s.loads(token)['user_id']
except:
return None
return User.query.get(user_id)
def __repr__(self):
return f'{self.firstname} {self.lastname}'
login.html
{% extends "layout.html" %}
{% block content %}
<h1>Login Page</h1>
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Login</legend>
...(irrelevant content)
<div class="border-top pt-3">
<small class="text-muted">
<a class="ml-2" href="{{ url_for('users.register') }}">Don't Have An Account?</a>
</small>
<small class="text-muted ml-2">
<a class="ml-2" href="{{ url_for('users.reset_request') }}">Forgot Password?</a>
</small>
</div>
{% endblock content %}
这是一个简单的错误。不是 methods=['GET, POST']
.
改为
methods=['GET', 'POST']
HTTP Methods
Web applications use different HTTP methods when accessing URLs. You should familiarize yourself with the HTTP methods as you work with Flask. By default, a route only answers to GET requests. You can use the methods argument of the route() decorator to handle different HTTP methods.
from flask import request @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': return do_the_login() else: return show_the_login_form()