プログラミング塾の質問・回答コーナーを作りたい。個人ユーザーの質問は無料で受け付け、公開とする。企業ユーザーの質問は別のストアサイトで番号付きのチケットを発行し、それを使用し、非公開とする。
【Copilotの答えの始め】
Flask、MySQL Connector、Bootstrapを使用してプログラミング塾の質問・回答コーナーを作成するための基本的な手順を示します。以下のような機能を実装する必要があります。
1. 環境設定
最初に、必要なパッケージをインストールします。
1
|
pip install Flask mysql-connector-python Flask-Bootstrap |
2. データベースの設計
まず、データベースのテーブルを設計します。例えば、users、questions、answers、ticketsテーブルを作成します。
users テーブル
1 2 3 4 5 |
CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(100) NOT NULL, user_type ENUM('individual', 'corporate') NOT NULL ); |
questions テーブル
1 2 3 4 5 6 7 |
CREATE TABLE questions ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT, question_text TEXT, is_public BOOLEAN, FOREIGN KEY (user_id) REFERENCES users(id) ); |
tickets テーブル(企業ユーザーの質問を管理)
1 2 3 4 5 6 7 8 |
CREATE TABLE tickets ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT, question_id INT, ticket_number VARCHAR(50), FOREIGN KEY (user_id) REFERENCES users(id), FOREIGN KEY (question_id) REFERENCES questions(id) ); |
3. Flaskアプリの構築
次に、Flaskアプリを作成し、MySQLデータベースに接続します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
from flask import Flask, render_template, request, redirect, url_for from flask_bootstrap import Bootstrap import mysql.connector app = Flask(__name__) Bootstrap(app) # MySQLデータベースに接続 db = mysql.connector.connect( host="localhost", user="root", password="password", database="your_database_name" ) @app.route('/') def index(): return render_template('index.html') # 質問の表示と投稿用ルート @app.route('/questions') def questions(): cursor = db.cursor(dictionary=True) cursor.execute("SELECT * FROM questions WHERE is_public = TRUE") questions = cursor.fetchall() return render_template('questions.html', questions=questions) @app.route('/ask', methods=['GET', 'POST']) def ask(): if request.method == 'POST': user_id = request.form['user_id'] question_text = request.form['question_text'] is_public = True if request.form['user_type'] == 'individual' else False cursor = db.cursor() cursor.execute("INSERT INTO questions (user_id, question_text, is_public) VALUES (%s, %s, %s)", (user_id, question_text, is_public)) db.commit() if not is_public: question_id = cursor.lastrowid ticket_number = generate_ticket_number() cursor.execute("INSERT INTO tickets (user_id, question_id, ticket_number) VALUES (%s, %s, %s)", (user_id, question_id, ticket_number)) db.commit() return redirect(url_for('questions')) return render_template('ask.html') def generate_ticket_number(): import random return 'TICKET-' + str(random.randint(1000, 9999)) if __name__ == '__main__': app.run(debug=True) |
4. Bootstrapによるフロントエンドの構築
テンプレートファイルを作成し、Bootstrapを使用してユーザーインターフェースを設計します。
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>プログラミング塾 - 質問・回答コーナー</title> <link href="{{ url_for('static', filename='bootstrap.min.css') }}" rel="stylesheet"> </head> <body> <div class="container"> <h1>プログラミング塾 - 質問・回答コーナー</h1> <a href="{{ url_for('questions') }}" class="btn btn-primary">質問を見る</a> <a href="{{ url_for('ask') }}" class="btn btn-secondary">質問を投稿する</a> </div> </body> </html> |
questions.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>公開質問一覧</title> <link href="{{ url_for('static', filename='bootstrap.min.css') }}" rel="stylesheet"> </head> <body> <div class="container"> <h1>公開質問一覧</h1> <ul> {% for question in questions %} <li>{{ question.question_text }}</li> {% endfor %} </ul> <a href="{{ url_for('index') }}" class="btn btn-secondary">戻る</a> </div> </body> </html> |
ask.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>質問を投稿</title> <link href="{{ url_for('static', filename='bootstrap.min.css') }}" rel="stylesheet"> </head> <body> <div class="container"> <h1>質問を投稿</h1> <form method="post"> <div class="form-group"> <label for="user_id">ユーザーID</label> <input type="text" class="form-control" id="user_id" name="user_id" required> </div> <div class="form-group"> <label for="question_text">質問内容</label> <textarea class="form-control" id="question_text" name="question_text" required></textarea> </div> <div class="form-group"> <label for="user_type">ユーザータイプ</label> <select class="form-control" id="user_type" name="user_type" required> <option value="individual">個人</option> <option value="corporate">企業</option> </select> </div> <button type="submit" class="btn btn-primary">送信</button> </form> <a href="{{ url_for('index') }}" class="btn btn-secondary">戻る</a> </div> </body> </html> |
これで、Flask、MySQL Connector、Bootstrapを使用して基本的な質問・回答コーナーを作成する手順が理解できたと思います。これらの基本を基にして、さらに機能を追加したり、デザインを改善したりすることができます。
【Copilotの答えの終わり】
回答関連の画面とコントローラーも
【Copilotの答えの始め】
了解しました!次に、回答関連の画面とコントローラーを追加しましょう。
Flaskアプリの更新
1. 回答の表示と投稿のルート
Flaskアプリに回答を表示し、投稿するための新しいルートを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@app.route('/question/<int:question_id>', methods=['GET', 'POST']) def question(question_id): if request.method == 'POST': answer_text = request.form['answer_text'] cursor = db.cursor() cursor.execute("INSERT INTO answers (question_id, answer_text) VALUES (%s, %s)", (question_id, answer_text)) db.commit() return redirect(url_for('question', question_id=question_id)) cursor = db.cursor(dictionary=True) cursor.execute("SELECT * FROM questions WHERE id = %s", (question_id,)) question = cursor.fetchone() cursor.execute("SELECT * FROM answers WHERE question_id = %s", (question_id,)) answers = cursor.fetchall() return render_template('question.html', question=question, answers=answers) |
2. 回答画面のテンプレート
question.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>質問と回答</title> <link href="{{ url_for('static', filename='bootstrap.min.css') }}" rel="stylesheet"> </head> <body> <div class="container"> <h1>質問と回答</h1> <h2>質問: {{ question.question_text }}</h2> <h3>回答一覧</h3> <ul> {% for answer in answers %} <li>{{ answer.answer_text }}</li> {% endfor %} </ul> <h3>新しい回答を投稿</h3> <form method="post"> <div class="form-group"> <label for="answer_text">回答内容</label> <textarea class="form-control" id="answer_text" name="answer_text" required></textarea> </div> <button type="submit" class="btn btn-primary">送信</button> </form> <a href="{{ url_for('questions') }}" class="btn btn-secondary">戻る</a> </div> </body> </html> |
これにより、質問に対して回答を投稿し、表示する機能が追加されます。
3. データベースの更新
回答関連のテーブルをすでに作成しているため、特に変更は必要ありません。ただし、必要に応じてフィールドやインデックスを追加することもできます。
これで、質問・回答コーナーに必要な基本機能が揃いました。
【Copilotの答えの終わり】
熱帯夜絵画の融ける茶褐色
