Djangoで単語帳開発Part6

こんにちは、にわこまです。

今回は単語帳のメイン機能である、表示された英語に対して日本語で答える機能を作成します。

 

「Djangoで単語帳開発」シリーズはDjangoのチュートリアルとして利用されることを目的としています。

誤字脱字や分かりにくい点がありましたら、ご連絡お願い致します。

 

 

スポンサードサーチ


Djangoで単語帳開発Part6

Part5まで、モデル作成、単語一覧、削除、編集の機能やページを作成してきました。単語帳として完成していないのは、英単語に対して日本語で答えるという機能がないからです。

 

単語帳には、選択しから選んで答えるタイプと表示された英単語に対して日本語を入力して答えるタイプなどがあると思います。

今回は、後者のタイプで作成していきます。

 

 

単語帳メインページの作成

flashcard/templates/flashcardの下に、answer.htmlファイルを作成し、編集します。

{% extends 'flashcard/base.html' %}

{% block title %}Answer{% endblock %}

{% block content %}
<article class="answer">
  <div class="page-name">
    <h1>単語帳</h1>
  </div>
  {% if answer_message == '' %}
    <div class="answer-form">
      <form action="{% url 'answer' %}" method="post">
        {% csrf_token %}
        <div class="field">
          <p style="margin: 5px 0">問題: {{ en_word }}</p>
          <input hidden type="text" name="en_problem" value="{{ en_word }}">
        </div>
        <div class="field">
          <label>解答</label><input type="text" name="jp_answer">
        </div>
        <input type="submit" value="解答" style="margin: 5px 0">
      </form>
    </div>
  {% else %}
    <div class="answer-and-review">
      <p>{{ answer_message }}</p>
      <a href="{% url 'answer' %}">次の問題へ</a>
    </div>
  {% endif %}
</article>
{% endblock %}

 

コードの解説

1行目の「{% extends ‘flashcard/base.html’ %}」は、「base.htmlを拡張してanswer.htmlを作成します」という宣言を行っています。

 

3行目の「{% block title %}Answer{% endblock %}」は、タイトルにAnswerを代入しています。

 

10~29行目は、if-else文によって処理や表示を条件分岐させています。

10~23行目のif文では、問題や解答するフォームを表示します。 24~29行目のelse文では、問題に解答した後に、正解か不正解かをmessagesによって表示します。

 

現在のフォルダ状況(templatesのみ)↓↓↓

templates
   |-flashcard
      |-base.html
      |-index.html
      |-wordlist.html
      |-registration.html
      |-worddelete.html
      |-wordedit.html
      |-answer.html  # 追加部

 

 

スポンサードサーチ


views.pyの編集

問題選択や、正解・不正解の判定を行う機能を作成します。flashcard/views.pyに以下のプログラムを追記します。

import numpy.random as random
     .
   省略
     .
def answer(request):
    answer_message = ''
    if(request.method == 'POST'):
        problem_word = request.POST['en_problem']
        answer_word = request.POST['jp_answer']
        mw_obj = MyWord.objects.filter(en_word=problem_word).first()
        jp_list = mw_obj.jp_word.split('\u3000')
        if(answer_word in jp_list):
            answer_message = '正解です。'
        else:
            answer_message = '不正解です。'
    count_mw = MyWord.objects.count()
    en_word = MyWord.objects.all()[random.randint(0, count_mw-1)]

    params = {
        'en_word':en_word,
        'answer_message':answer_message,
    }
    return render(request, 'flashcard/answer.html', params)

 

コードの解説

1行目の「import numpy.random as random」は、モデルから単語を1つ選択するするために使います。

5行目の「def answer(request):」は、関数の宣言と定義を行っています。

6行目は、変数の初期化を行っています。

7行目では、解答ボタンをクリックしたかを判定しています。つまり、表示された英語に対して解答フォームに入力を行ったかを確認しています。

8,9行目では、送信されてきた英単語と回答を変数に代入しています。

10行目では、mw_objに送信されてきた英語が格納されている1行を代入しています。

11行目では、mw_objに格納されている日本語の部分を取り出しています。日本語の部分は単語と単語の間が全角のスペースで区切られているはずであるため、「split(‘\u3000’)」によって文字列を分割しています。

12~15行目は、11行目で分割した文字列に送信されてきた日本語が含まれているかを判定しています。

16,17行目では、モデルの中から英単語を1つだけを取り出しています。

 

urls.pyの編集

views.pyで関数を定義したため、その関数とURLを対応付けさせます。flashcard/urls.pyに以下のプログラムを追記します。

path('answer', views.answer, name='answer'),

 

ちゃんと対応付けさせることができているか確認を行います。サーバを起動します。

python manage.py runserver

 

サーバを起動させたら「http://localhost:8000/flashcard/answer」にアクセスします。以下のようなページが表示されます。私の場合は「english」が問題として表示されました。

 

「numpyがありません」というエラーが出た人は、「Ctrl + Break」でサーバを終了させ以下のコマンドを実行してください。

「python -m pip install numpy」

 

 

正しく解答すると以下のように表示されます。

 

正しくない解答をすると以下のように表示されます。

 

以上でURLの対応付けと動作確認は終了です。

 

 

その他(ナビゲーション)

注意
ここからは、djangoとは関係ありません。興味が無かったら読み飛ばしてください。

 

単語帳メインページを完成させたら単語帳としては完成ですが、「単語一覧から単語帳」や「単語登録から一覧」へのページ移動がかなりめんどうくさいため、ナビゲーションを作成します。

 

ナビゲーションとは、私のブログで言うと「ホームやプログラミング、技術メモ、本、ブログ、プロフィール、サイトについて、お問い合わせ」と書いてあるところのことを言います。

 

ナビゲーションがあれば、かなり楽にページを移動することができます。flashcard/templates/flashcardの下にmenu.htmlファイルを作成し編集します。

<div class="menu">
  <div class="menu-inner">
    <ul>
      <li><a href="{% url 'index' %}">Top</a></li>
      <li><a href="{% url 'wordlist' %}">英単語一覧</a></li>
      <li><a href="{% url 'wordregistration' %}">英単語登録</a></li>
      <li><a href="{% url 'answer' %}">単語帳</a></li>
    </ul>
  </div>
</div>

 

コードの解説

4行目の「{% url ‘index’ %}」は、views.pyで定義したindex関数のことを指します。indexの部分は、urls.pyで設定したpathの第3引数です。

 

base.htmlに追加

menu.htmlを作っただけでは、ページに表示されません。また、menu.htmlは全ページで表示されてほしいため、base.htmlにmenu.htmlをインクルードします。

flashcard/templates/flashcard/base.htmlに以下のプログラムを追記します。

<body>
    <header>
      <div class="app-name">
        <h1>Flashcard on Django</h1>
      </div>
    </header>
    {% include "flashcard/menue.html" %}  # 追加部
    <div class="content">
      {% block content %}{% endblock %}
    </div>
    <footer>
      <div class="text-right">
        <p>CopyRight 2019:Niwakoma</p>
      </div>
    </footer>
  </body>

headerとcontentの間に追記しました。

「include」は他のhtmlファイルを呼び出すことができます。ナビゲーションのような全ページに必要な機能を別のファイルで書いて呼び出すことができます。

今回は、別ファイルでナビゲーションを作成しましたが、base.htmlファイルに直接書いても問題ありません。

 

動作確認

ナビゲーションがちゃんと機能しているか確認するため、サーバを起動させます。

python manage.py runserver

 

サーバを起動させたら「http://localhost:8000/flashcard/」にアクセスします。以下のようなページが表示されます。

 

念のためナビゲーションから他のページにアクセスできるか確認します。

 

以上でナビゲーションの確認は終了です。

 

現在のフォルダ状況(templatesのみ)

templates
   |-flashcard
      |-base.html
      |-index.html
      |-wordlist.html
      |-registration.html
      |-worddelete.html
      |-wordedit.html
      |-answer.html
      |-menu.html  #追加部

 

 

スポンサードサーチ


その他(装飾)

注意
ここからは、djangoとは関係ありません。興味が無かったら読み飛ばしてください。

 

単語帳を完成させて、ナビゲーションを作成、追加しましたが、見栄えが良くありません。ゆえに、装飾を行いたいと思います。

flashcard/static/flashcard/style.cssを編集します。 cssファイルのコードは長くなるため、別ページに置いておきます。また、ダウンロードできるようにしておきます。

style.cssファイルのコードはこちら

 

ダウンロードはこちら

 

 

 

まとめ

今回は、単語帳のメイン機能を完成させるため一番簡単な方法を実装しました。普通の単語帳と比べると使いにくいですが、djangoの勉強にはなったのではないかなと思います。

また、これから発展させることができるのではないかと思います。

 

例えば、
・10単語ずつ出題する
・解答を記入式から選択式にする
・単語を特定のグループに分けられるようにする
など...

 

djangoは「Instagram」の開発に使われていたり、pythonの重要が高まってきていたりしているため、これからdjangoの重要も高まるはずです。勉強していて損はありません。

みなさんも、自分自身のアプリケーションを作ってみてください。

 

最後までお読みいただきありがとうございます。


スポンサードサーチ