
本文介绍在 flask 应用中处理“检查仓库是否存在 → 显示中间提示页 → 创建新仓库”这一典型三步流程的正确实现方式,重点解决重定向与模板渲染的协同问题,并提供可立即使用的 html + python 完整方案。
本文介绍在 flask 应用中处理“检查仓库是否存在 → 显示中间提示页 → 创建新仓库”这一典型三步流程的正确实现方式,重点解决重定向与模板渲染的协同问题,并提供可立即使用的 html + python 完整方案。
在构建 GitHub 仓库自动化工具时,常见的交互逻辑是:用户提交表单 → 后端检查仓库是否已存在 → 若不存在,则先展示一个友好提示页(如“GitHub Repo does not exist, Creating new repo”),再自动触发仓库创建操作。但许多开发者误以为可在 return 之后继续执行代码,或试图在重定向后直接渲染模板,导致流程中断或页面跳转异常。
正确的做法是将中间提示页作为独立路由,并通过前端 JavaScript 实现“延时自动跳转”,从而清晰分离关注点:后端只负责响应请求、渲染页面;前端负责用户体验与流程衔接。
✅ 推荐实现方案
1. 更新 Flask 路由逻辑
将 /check_repo 的“不存在分支”改为重定向至新路由 /repo_does_not_exist,该路由专用于渲染静态提示页:
@app.route('/check_repo', methods=['POST'])
def repo_exists():
repo_name = request.form.get('Application_Name')
owner_email = request.form.get('Owner_Email') # 注意:需同步传递邮箱参数
# 示例:构造 GitHub API 请求(请补全实际 params)
params = {
'url': f'https://api.github.com/repos/{{owner}}/{{repo_name}}',
'auth': HTTPBasicAuth('username', 'token'),
'headers': {'Accept': 'application/vnd.github.v3+json'}
}
try:
response = requests.get(params['url'], auth=params['auth'], headers=params['headers'])
if response.status_code == 200:
return render_template('repo_exists.html', repo_name=repo_name)
else:
# 重定向到中间提示页,并携带必要参数(如 repo_name)
return redirect(url_for('repo_does_not_exist', repo_name=repo_name))
except Exception as e:
return render_template('error.html', message=f"API check failed: {str(e)}")
@app.route('/repo_does_not_exist', methods=['GET'])
def repo_does_not_exist():
repo_name = request.args.get('repo_name', 'unknown')
return render_template('repo_does_not_exist.html', repo_name=repo_name)
@app.route('/create_repo', methods=['POST'])
def create_repo():
repo_name = request.form.get('Application_Name')
owner_email = request.form.get('Owner_Email')
# ✅ 此处执行真正的仓库创建逻辑(如调用 GitHub API 创建 repo)
# 示例伪代码:
# create_response = requests.post(
# 'https://api.github.com/user/repos',
# json={'name': repo_name, 'private': True},
# auth=HTTPBasicAuth('username', 'token')
# )
# 创建成功后,跳转至结果页
return redirect(url_for('repo_created', repo_name=repo_name))
@app.route('/repo_created')
def repo_created():
repo_name = request.args.get('repo_name', 'unknown')
return render_template('repo_created.html', repo_name=repo_name)
⚠️ 注意事项:
Ralph Loop (Agent Mode)下载引导 OpenClaw 代理使用 exec 和 process 工具执行 Ralph Wiggum 循环。通过 pty:true 提供正确的 TTY 支持,编排编码代理(Codex, Claude Code, OpenCode, Goose)。利用 PROMPT.md、AGENTS.md、SPECS 和 IMPLEMENTATION_PLAN.md 规划和构建代码。包含规划与构建模式、背压机制、沙箱及完成条件。用户请求循环,代理使用工具执行。
- /repo_does_not_exist 必须使用 methods=['GET'],因为它是通过 redirect() 触发的 GET 请求;
- 使用 url_for() 传参(如 repo_name)确保上下文信息不丢失;
- 避免在 create_repo 中 return render_template(...) 后再调用 redirect() —— Python 函数遇到第一个 return 即终止,后续代码永不执行。
2. 创建中间提示页 repo_does_not_exist.html
此页面显示提示消息,并在 2 秒后自动提交表单(隐式触发 /create_repo POST 请求):
<!-- templates/repo_does_not_exist.html -->
{% extends 'base.html' %}
{% block content %}
<h2 style="color: #28a745; text-align: center;">⏳ Repository Not Found</h2>
<p style="text-align: center; font-size: 1.2em;">
GitHub repository <strong>"{{ repo_name }}"</strong> does not exist.<br>
Creating a new private repository...
</p>
<!-- 自动提交表单 -->
<script>
// 页面加载后 2 秒自动提交
setTimeout(() => {
document.getElementById('autoSubmitForm').submit();
}, 2000);
</script>
{% endblock %}3. 补充结果页 repo_created.html
提升完成感,支持用户返回首页:
<!-- templates/repo_created.html -->
{% extends 'base.html' %}
{% block content %}
<div style="text-align: center; padding: 60px 20px;">
<h2 style="color: #28a745;">✅ Repository Created!</h2>
<p><strong>{{ repo_name }}</strong> has been successfully created on GitHub.</p>
<a href="%7B%7B%20url_for('index')%20%7D%7D" class="btn btn-primary" style="margin-top: 20px;">
Create Another Repository
</a>
</div>
{% endblock %}
✅ 总结关键原则
- 路由职责单一化:每个路由只做一件事(检查、提示、创建、展示结果);
- 状态靠参数传递:使用 url_for(..., param=value) 在重定向中携带必要上下文;
- 前端接管延时跳转:避免后端阻塞等待,用 JS 控制 UX 流程;
- POST/GET 严格区分:表单提交用 POST,提示页展示用 GET,防止刷新重复提交;
- 错误防御:对网络请求添加 try/except,并提供降级反馈。
按此结构组织代码,即可实现流畅、健壮、符合 Web 最佳实践的多步操作流程。











