SHOEISHA iD

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

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

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

【トップページを実装しよう!】PythonとSQLで実装する「ホームページ」の仕組み

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

記事一覧を表示する

 投稿された一筆書きの絵の記事タイトルを、1ページあたり最大5件まで表示します。5件以上ある場合のページ遷移(ページネーション)については、後のセクション(「5件ずつ記事のページを遷移する」)で解説します。まずは、最新の記事タイトル5件を表示する処理を実装します。

記事一覧を表示したホームページ
記事一覧を表示したホームページ

etc.pyファイルをコーディングする

 記事タイトルを表示する前に、タグなどが投稿された場合にタグの機能を無効化する「エスケープ」の処理が必要です。その処理を「get_html」関数で行います。

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

def get_html(text):
  text = re.sub(re.compile('<.*?>'), ' ', text)
  text = text.replace('<','<')
  text = text.replace('>','>')
  text = text.replace('&','&')
  text = text.replace('\"','"')
  text = text.replace('\'','’')
  text = text.replace('\n','<br />')
  return html.unescape(text)

def random_load(cur):
  xy = ''
  sql = 'SELECT xy FROM article WHERE id = (SELECT ABS(RANDOM()) % (SELECT MAX(id) FROM article) + 1) LIMIT 1;'
  for row in cur.execute(sql):
    if row[0] != None:
      xy = row[0]
      if (xy != ''):
        print('<script>loadPos("{}");</script>'.format(xy))

サンプルコードの解説

 モジュールを読み込みます。

 get_html関数で、HTMLタグをエスケープします。

 「text」引数の'<'、'>'、'&'、'\"'、'\''、'\n'のHTMLとして意味を持つ記号を単なる文字列に変換します。

 「unescape」関数は一見「アンエスケープ(エスケープしない)」ように見えますが、正しくは「Unicode Escape」です。ユニコードになった文字列を人間が読める文字列にエスケープします。

home.pyファイルをコーディングする

 第4回で作ったデータベース「bezierbbs.db」ファイルからデータを取得します。記事を降順(idが大きいものから小さいものへの順番で)に取得します。

 記事のオフセット(OFFSET、偏り)として「select」変数を、記事の表示最大数(ARTICLE_NUM = 5)ずつをページの先頭にしてセットします。GETのselectパラメータがない場合は'1'番目です。ちなみに、このselect変数はSQL文のSELECT文とは別物です。

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

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

  print('''
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>一筆書きBBS</title>
  <link href="css/pc.css" rel="stylesheet" type="text/css" />
  <link href="css/mobile.css" rel="stylesheet" type="text/css" media="only screen and (max-width:1023px)" />
  <script type="text/javascript" src="js/main.js"></script>
</head>
<body>

<div id="left">
  <header>
    <h1>一筆書きBBS</h1>
    <nav>
      <a href="?page=home">HOME</a>
      <a href="?page=draw">DRAW</a>
      <a href="?page=about">ABOUT</a>
    </nav>
  </header>
  <h2>記事</h2>
  <ul>
  ''')

  title = ''
  speaker = ''
  date = ''
  ARTICLE_NUM = 5
  data = (ARTICLE_NUM,(select-1)*ARTICLE_NUM)
  sql = '''SELECT id,title,speaker,date FROM article ORDER BY id DESC LIMIT ? OFFSET ?''' #
  for row in cur.execute(sql,data):
    if row[0] != None:
      id = row[0]
    if row[1] != None:
      title = etc.get_html(row[1])
    if row[2] != None:
      speaker = etc.get_html(row[2])
    if row[3] != None:
      date = row[3]
    print('''
    <li><a href="?page=comment&article_id={}">{}</a><br />{}<br />{}</li>
    '''.format(id,title,date,speaker))
  print('</ul>')

  etc.random_load(cur)

サンプルコードの解説

 select変数はGETしたselectパラメータから取得します。

 「title」変数に記事タイトルを、「speaker」変数に発言者名を、「date」変数に日時を、「ARTICLE_NUM」変数(定数として使うので全て大文字に)は一度に表示する最大件数を5件にします。

 SQL文は、「article」テーブルの「id」カラムを降順に(ORDER BY id DESC)、LIMITで最大5件、OFFSETでオフセットを(select-1)*ARTICLE_NUM件目からの、レコードを取得します。

 row[0]にarticleテーブルのidカラムが、row[1]にtitleカラムが、row[2]にspeakerカラムが、row[3]にdateカラムが取得できます。

 コメントページへのリンクをタイトルにHTML5文書を出力します。

次のページ
5件ずつ記事のページを遷移する

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

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

もっと読む

この記事の著者

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

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

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

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

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

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/22089 2025/10/29 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング