Flask/Werkzeug ، كيفية إرجاع الصفحة السابقة بعد تسجيل الدخول
سؤال
أنا أستخدم Flask Micro-Framework الذي يعتمد على Werkzeug ، والذي يستخدم Python.
قبل كل صفحة مقيدة ، يوجد ديكور لضمان تسجيل الدخول ، وإعادتها حاليًا إلى صفحة تسجيل الدخول إذا لم يتم تسجيل الدخول ، مثل ذلك:
# Decorator
def logged_in(f):
@wraps(f)
def decorated_function(*args, **kwargs):
try:
if not session['logged_in']:
flash('Please log in first...', 'error')
return redirect(url_for('login'))
else:
return f(*args, **kwargs)
except KeyError:
flash('Please log in first...', 'error')
return redirect(url_for('login'))
return decorated_function
# Login function
@app.route('/', methods=['GET', 'POST'])
def login():
"""Login page."""
if request.method=='POST':
### Checks database, etc. ###
return render_template('login.jinja2')
# Example 'restricted' page
@app.route('/download_file')
@logged_in
def download_file():
"""Function used to send files for download to user."""
fileid = request.args.get('id', 0)
### ... ###
بعد تسجيل الدخول ، يحتاج إلى إرجاع المستخدمين إلى الصفحة التي نقلتهم إلى صفحة تسجيل الدخول. يحتاج أيضًا إلى الاحتفاظ بأشياء مثل المتغيرات التي تم تمريرها (أي الرابط بالكامل بشكل أساسي www.example.com/download_file؟id=3)
لا أحد يعرف كيفية القيام بذلك؟
شكرا لك على مساعدتك :-)
المحلول
أعتقد أن الممارسة القياسية هي إلحاق عنوان URL الذي يحتاج المستخدم إلى إعادة توجيهه بعد تسجيل دخول ناجح إلى نهاية QueryString لعنوان URL.
يمكنك تغيير ديكورك إلى شيء كهذا (مع إزالة التكرار في وظيفة الديكور الخاصة بك أيضًا):
def logged_in(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if session.get('logged_in') is not None:
return f(*args, **kwargs)
else:
flash('Please log in first...', 'error')
next_url = get_current_url() # However you do this in Flask
login_url = '%s?next=%s' % (url_for('login'), next_url)
return redirect(login_url)
return decorated_function
سيكون عليك استبدال شيء ما get_current_url()
, ، لأنني لا أعرف كيف يتم ذلك في قارورة.
ثم ، في معالج تسجيل الدخول الخاص بك ، عندما يقوم المستخدم بتسجيل الدخول بنجاح ، يمكنك التحقق لمعرفة ما إذا كان هناك أ next
المعلمة في الطلب ، وإذا كان الأمر كذلك ، فأنت إعادة توجيهها إلى عنوان URL هذا. خلاف ذلك ، يمكنك إعادة توجيهها إلى عنوان URL الافتراضي (عادة /
, ، اعتقد).
نصائح أخرى
يمكنك استخدام سلسلة استعلام للحفاظ على معلومات الملف سليمة فوق نقرة أو اثنين. واحدة من الأشياء الجميلة حول url_for
هو كيف يمرر معلمات غير معروفة كقواس الاستعلام. لذلك دون تغيير صفحة التسجيل الخاصة بك كثيرًا ، يمكنك أن تفعل شيئًا كهذا:
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if g.user is None:
return redirect(url_for('register', wantsurl = request.path))
return f(*args, **kwargs)
return decorated_function
هنا wantsurl
سوف يتتبع عنوان URL الذي هبطه المستخدم. إذا ذهب مستخدم غير مسجل إلى /download/some/file.txt
, login_required
سوف نرسل لك إلى /register?wantsurl=%2Fdownload%2Fsome%2Ffile.txt
ثم تضيف بضعة أسطر إلى وظيفة التسجيل الخاصة بك:
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'GET':
if 'wantsurl' in request.args:
qs = request.args['wantsurl']
return render_template('register.html', wantsurl=qs)
if request.method == 'POST':
if 'wantsurl' in request.form and everything_else_ok:
return redirect(request.form['wantsurl'])
من شأن ذلك إعادة توجيه تلقائي إلى التنزيل على التسجيل الناجح ، شريطة أن يكون لديك شيء في النموذج يسمى "wanturl" مع قيمة qs
, ، أو يمكنك إرسال النموذج الخاص بك مع سلسلة استعلام ؛ يمكن أن يكون ذلك قليلاً إذا كان الإخلاء في القالب.