🌀 Demystifying POST–REDIRECT–GET in Flask
Ever submitted a form in your Flask app and then hit refresh—only to get a browser warning about resending data? Welcome to the world of POST resubmission, a sneaky little side effect that’s solved beautifully by the Post–Redirect–Get (PRG) pattern.
Let’s break it down 👇
📬 The Problem with POST: Form Resubmission
Imagine this flow:
- User fills out a form (e.g., update profile).
- You handle the form with
POST
. - You use
render_template()
to show the dashboard directly. - Then... the user refreshes the page.
🔁 Result: The browser resubmits the form, triggering a second POST!
This can:
- Cause duplicate database writes
- Repeat email or username changes
- Show misleading flash messages again
- Annoy users with “Confirm form resubmission” alerts
✅ Enter the Hero: Post–Redirect–Get (PRG)
Instead of rendering the updated page right after the POST
, PRG introduces a redirect step so the browser only refreshes with a safe GET
.
PRG flow:
POST → Redirect → GET
✨ Example: Updating Profile
@app.route('/account', methods=['GET', 'POST'])
@login_required
def account():
form = UpdateProfileForm()
if form.validate_on_submit():
current_user.username = form.username.data
current_user.email = form.email.data
db.session.commit()
flash('Your account has been updated!', 'success')
return redirect(url_for('account')) # 🔄 Redirect fixes refresh bug
return render_template('dashboard.html', form=form, user=current_user)
📌 Why This Works
- User submits form →
POST
runs and updates DB - Server sends a redirect to
/account
- Browser follows redirect → does a GET
- Refreshing now re-runs the GET, not the form submission
🧪 Bonus Tip: Use DevTools to Watch the Flow
In your browser's developer tools:
- Check the Network tab
- Watch for the
POST
request, followed by a302 Found
redirect - The next request will be
GET
—clean and safe for refreshes
Top comments (0)