SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Pythonで学ぶバックエンド開発

【PythonとSQLiteで学ぶ「データの書き込み方法」】Web掲示板にコメント機能を実装しよう!

Pythonで学ぶバックエンド開発 第7回

コメントページでコメントを表示する

 記事の絵に対する感想などのコメントを書き込んだり表示したりできるようにします。やっとコネクトの「commit」メソッドでデータベースにコメントを挿入してデータベースを書き換えるSQL文をコーディングします。

コメントを表示したコメントページ
コメントを表示したコメントページ

「pages」→「comment.py」ファイルをコーディングする

 まずコメント一覧を表示します。今回は1つのページに最大5件まで表示することにします。「SELECT」文のSQL文でデータベースの「comment」テーブルからコメントレコードを取り出します。

サンプルコード「pages」→「comment.py」ファイル
import pages.etc as etc

def html(form,con,cur):
  article_id = int(form.getfirst('article_id', '0'))
  select = int(form.getfirst('select', '1'))
(中略)
  print('''
(中略)
  <h2>コメント</h2>
  <ul>
'''.format(title,xy,title,speaker,date,sentence))

  speaker = ''
  date = ''
  sentence = ''
  COMMENT_NUM = 5
  data = (article_id,COMMENT_NUM,(select-1)*COMMENT_NUM)
  sql = '''SELECT speaker,date,sentence FROM comment WHERE article_id = ? ORDER BY id DESC LIMIT ? OFFSET ?'''
  for row in cur.execute(sql,data):
    if row[0] != None:
      speaker = etc.get_html(row[0])
    if row[1] != None:
      date = row[1]
    if row[2] != None:
      sentence = etc.get_html(row[2])
    print('''
    <li>{}<br />{}<br />{}</li>
    '''.format(speaker,date,sentence))
  print('</ul>')

サンプルコードの解説

 「html」関数でURLの「select」パラメータのページの5件のコメントを表示します。

 「<h2>コメント</h2>」の次の行に「<ul>」タグを書き足すのを忘れないように。

 SQL文で「comment」テーブルのarticle_idカラムがarticle_id変数の、idが降順(DESC)で、制限(LIMIT)が5レコードで、オフセット5レコードで、「speaker」カラムをrow[0]から、「date」カラムをrow[1]から、「sentence」カラムをrow[2]から取得してHTMLのリストタグに出力します。

コメントページ遷移を表示する

 コメントのページを5件ずつ遷移できる機能を実装します。(1ページあたり)最大5件ずつとし、レコードをWebページ1、2、3... に分けます。 SQL文で記事に対するコメントの数(COUNT)を取得し、cur.fetchone()で取得した結果、0番目のインデックス(count[0])にコメント数が格納されます。

コメントページ遷移を表示したコメントページ
コメントページ遷移を表示したコメントページ
「pages」→「comment.py」ファイル
import pages.etc as etc

def html(form,con,cur):
(中略)
  print('<div id="select"><a href="index.py">戻る</a> ')
  data = (article_id,)
  sql = 'SELECT COUNT(id) FROM comment WHERE article_id = ?'
  cur.execute(sql,data)
  count = cur.fetchone()
  for i in range(1,2+int((count[0]-1)/COMMENT_NUM)):
    if i == select:
      print('<a href="?page=comment&article_id={}&select={}" id="select_num">{}</a> '.format(article_id,i,i))
    else:
      print('<a href="?page=comment&article_id={}&select={}">{}</a> '.format(article_id,i,i))

  print('''
  </div>
''')

サンプルコードの解説

 SQL文でcommentテーブルからarticle_idがarticle_id変数の、idレコードの数を取得します。

 HTMLのリンクタグにコメントのページ番号を出力します。その際現在のページ番号は「#select_num」セレクタで背景色を黒色にします。

コメント入力欄を表示する

 「form」 タグを使い、入力したコメントを「送信」ボタンで同じコメントページにPOST送信します。 送信されたデータは、html関数の冒頭部分(form.getfirst)で受け取ります。 POSTされたspeakerパラメータとsentenceパラメータを受け取り、SQL文のINSERT INTOを使ってcommentテーブルに挿入します。

 テストが終わった場合は、「XAMPP」を「Stop」ボタンで停止しておくとよいでしょう。

コメント入力欄を表示したコメントページ
コメント入力欄を表示したコメントページ
「pages」→「comment.py」ファイル
import datetime
import pages.etc as etc

def html(form,con,cur):
  article_id = int(form.getfirst('article_id', '0'))
  select = int(form.getfirst('select', '1'))

  speaker = form.getfirst('speaker', '')
  speaker.strip()
  sentence = form.getfirst('sentence', '')
  sentence.strip()
  if article_id > 0 and speaker != '' and sentence != '':
    date = datetime.datetime.now()
    sql = 'INSERT INTO comment(article_id,speaker,date,sentence) VALUES (?,?,?,?)'
    data = (article_id,speaker,date,sentence)
    cur.execute(sql,data)
    con.commit()

  title = ''
  xy = ''
  data = (article_id,)
  sql = 'SELECT title,speaker,date,sentence,xy FROM article WHERE id = ?'
  for row in cur.execute(sql,data):
    if row[0] != None:
      title = etc.get_html(row[0])
    if row[1] != None:
      speaker = etc.get_html(row[1])
    if row[2] != None:
      date = row[2]
    if row[3] != None:
      sentence = etc.get_html(row[3])
    if row[4] != None:
      xy = row[4]

  print('''
(中略)
  <h2>コメント</h2>
  <ul>
'''.format(title,xy,title,speaker,date,sentence))
(中略)
  print('''
  </div>
  <h2>コメント投稿</h2>
  <form method="post" action="?page=comment&article_id={}">
    <input placeholder="お名前" name="speaker" />
    <textarea placeholder="ここにコメントを書く。" name="sentence"></textarea>
    <input type="submit" />
  </form>
'''.format(article_id))

サンプルコードの解説

 html関数でGETされたarticle_idパラメータとPOSTされたspeakerパラメータとdate変数とPOSTされたsentenceパラメータをdataタプルに入れて、SQL文のcommentテーブルの同名のカラムに左から順に「VALUES (?,?,?,?)」から渡して実行します。

 コメント投稿は「index.py?page=comment&article_id=記事番号」にspeakerとsentenceとともにPOSTします。

おわりに

 今回は「一筆書きBBS」のコメントページを作成しました。「submit」ボタンでPOSTされたパラメータを、SQL文(INSERT INTO)でデータベースに挿入しました。

 次回はついに最終回です。この一筆書きBBSのテーマである「お絵描き記事」をデータベースに保存します。

この記事は参考になりましたか?

Pythonで学ぶバックエンド開発連載記事一覧

もっと読む

この記事の著者

大西 武(オオニシ タケシ)

 1975年香川県生まれ。大阪大学経済学部経営学科中退。プログラミング入門書などを30冊以上商業出版する作家。ドコモでグランプリなどコンテストに20回以上入賞するアーティスト。オリジナルの間違い探し「3Dクイズ」がTVで約10回出題。プロフィールサイト:https://profile.vixar.jp

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

CodeZine編集部(コードジンヘンシュウブ)

CodeZineは、株式会社翔泳社が運営するソフトウェア開発者向けのWebメディアです。「デベロッパーの成長と課題解決に貢献するメディア」をコンセプトに、現場で役立つ最新情報を日々お届けします。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/22090 2025/11/20 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング