下面是一个与前面不同的综合示例,展示如何使用 Python + Flask + HTML + CSS + JavaScript + jQuery + Bootstrap + SQLAlchemy 开发一个简单的 在线问答系统。用户可以提出问题、回答问题、查看问题列表以及查看问题详情。


1. 项目结构

qa_system/
│
├── app.py                  # Flask 应用主文件
├── models.py               # SQLAlchemy 模型定义
├── requirements.txt        # 依赖文件
├── static/                 # 静态文件(CSS, JS, 图片等)
│   ├── css/
│   │   └── styles.css      # 自定义 CSS
│   └── js/
│       └── scripts.js      # 自定义 JavaScript
│
├── templates/              # HTML 模板文件
│   ├── base.html           # 基础模板
│   ├── index.html          # 主页模板
│   ├── ask_question.html   # 提问模板
│   ├── questions.html      # 问题列表模板
│   ├── question_detail.html # 问题详情模板
│   └── answer_question.html # 回答问题模板
│
└── database.db             # SQLite 数据库文件

2. 安装依赖

在项目根目录下创建 requirements.txt 文件,内容如下:

Flask==2.3.2
Flask-SQLAlchemy==3.0.5
Bootstrap==5.3.0
jQuery==3.6.0

安装依赖:

pip install -r requirements.txt

3. Flask 应用 (app.py)

from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'  # SQLite 数据库
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'your_secret_key'  # 用于消息闪现的密钥
db = SQLAlchemy(app)

# 问题模型
class Question(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.Text, nullable=False)
    answers = db.relationship('Answer', backref='question', lazy=True)

# 回答模型
class Answer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text, nullable=False)
    question_id = db.Column(db.Integer, db.ForeignKey('question.id'), nullable=False)

# 主页路由
@app.route('/')
def index():
    return render_template('index.html')

# 提问路由
@app.route('/ask', methods=['GET', 'POST'])
def ask_question():
    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']
        new_question = Question(title=title, content=content)
        db.session.add(new_question)
        db.session.commit()
        flash('问题提交成功!', 'success')
        return redirect(url_for('questions'))
    return render_template('ask_question.html')

# 问题列表路由
@app.route('/questions')
def questions():
    questions = Question.query.all()
    return render_template('questions.html', questions=questions)

# 问题详情路由
@app.route('/question/<int:id>')
def question_detail(id):
    question = Question.query.get_or_404(id)
    return render_template('question_detail.html', question=question)

# 回答问题路由
@app.route('/answer/<int:id>', methods=['GET', 'POST'])
def answer_question(id):
    question = Question.query.get_or_404(id)
    if request.method == 'POST':
        content = request.form['content']
        new_answer = Answer(content=content, question=question)
        db.session.add(new_answer)
        db.session.commit()
        flash('回答提交成功!', 'success')
        return redirect(url_for('question_detail', id=question.id))
    return render_template('answer_question.html', question=question)

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(debug=True)

4. HTML 模板

基础模板 (templates/base.html)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>在线问答系统</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <div class="container">
            <a class="navbar-brand" href="{{ url_for('index') }}">在线问答系统</a>
            <div class="navbar-nav">
                <a class="nav-link" href="{{ url_for('ask_question') }}">提问</a>
                <a class="nav-link" href="{{ url_for('questions') }}">问题列表</a>
            </div>
        </div>
    </nav>
    <div class="container mt-4">
        {% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
                {% for category, message in messages %}
                    <div class="alert alert-{{ category }}">{{ message }}</div>
                {% endfor %}
            {% endif %}
        {% endwith %}
        {% block content %}{% endblock %}
    </div>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script src="{{ url_for('static', filename='js/scripts.js') }}"></script>
</body>
</html>
主页模板 (templates/index.html)
{% extends 'base.html' %}

{% block content %}
<h1>欢迎来到在线问答系统!</h1>
<p>提出问题或回答问题。</p>
<a href="{{ url_for('ask_question') }}" class="btn btn-primary">提问</a>
<a href="{{ url_for('questions') }}" class="btn btn-secondary">查看问题列表</a>
{% endblock %}
提问模板 (templates/ask_question.html)
{% extends 'base.html' %}

{% block content %}
<h1>提问</h1>
<form method="POST">
    <div class="mb-3">
        <label for="title" class="form-label">标题</label>
        <input type="text" class="form-control" id="title" name="title" required>
    </div>
    <div class="mb-3">
        <label for="content" class="form-label">内容</label>
        <textarea class="form-control" id="content" name="content" rows="5" required></textarea>
    </div>
    <button type="submit" class="btn btn-primary">提交</button>
</form>
{% endblock %}
问题列表模板 (templates/questions.html)
{% extends 'base.html' %}

{% block content %}
<h1>问题列表</h1>
<ul class="list-group">
    {% for question in questions %}
    <li class="list-group-item">
        <h5>{{ question.title }}</h5>
        <p>{{ question.content }}</p>
        <a href="{{ url_for('question_detail', id=question.id) }}" class="btn btn-primary btn-sm">查看详情</a>
    </li>
    {% endfor %}
</ul>
{% endblock %}
问题详情模板 (templates/question_detail.html)
{% extends 'base.html' %}

{% block content %}
<h1>{{ question.title }}</h1>
<p>{{ question.content }}</p>
<h3>回答</h3>
<ul class="list-group">
    {% for answer in question.answers %}
    <li class="list-group-item">
        <p>{{ answer.content }}</p>
    </li>
    {% endfor %}
</ul>
<a href="{{ url_for('answer_question', id=question.id) }}" class="btn btn-primary mt-3">回答问题</a>
<a href="{{ url_for('questions') }}" class="btn btn-secondary mt-3">返回问题列表</a>
{% endblock %}
回答问题模板 (templates/answer_question.html)
{% extends 'base.html' %}

{% block content %}
<h1>回答问题</h1>
<h3>{{ question.title }}</h3>
<p>{{ question.content }}</p>
<form method="POST">
    <div class="mb-3">
        <label for="content" class="form-label">回答内容</label>
        <textarea class="form-control" id="content" name="content" rows="5" required></textarea>
    </div>
    <button type="submit" class="btn btn-primary">提交</button>
</form>
<a href="{{ url_for('question_detail', id=question.id) }}" class="btn btn-secondary mt-3">返回问题详情</a>
{% endblock %}

5. 静态文件

CSS (static/css/styles.css)
body {
    padding: 20px;
}

h1 {
    color: #333;
}
JavaScript (static/js/scripts.js)
$(document).ready(function() {
    console.log("QA System is ready!");
});

6. 运行应用

在项目根目录下运行:

python app.py

访问 http://127.0.0.1:5000/ 即可看到在线问答系统。


7. 功能说明

  1. 提问:用户可以提出问题。
  2. 问题列表:用户可以查看所有问题。
  3. 问题详情:用户可以查看问题详情和回答。
  4. 回答问题:用户可以为问题提交回答。

8. 扩展功能

  • 添加用户认证系统,记录用户的提问和回答。
  • 增加问题分类和搜索功能。
  • 使用 AJAX 实现无刷新回答提交和问题列表更新。

希望这个示例对你有帮助!如果有任何问题,欢迎随时提问!

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐