Djangoで単語帳開発Part4

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

今回は、ブラウザから英単語と日本語訳を登録できるようにします。

 

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

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

 

 

スポンサードサーチ


Djangoで単語帳開発Part4

Part3までは、モデルとトップページや単語リストページの作成を行いました。

Django Adminで登録した単語に関しては、ブラウザで表示させて確認することができました。しかし、登録に関しては手間がかかります。

 

現在の手順のイメージ

 

本記事では、Django Adminにログインしなくてもブラウザから単語を登録できるようにします。

 

これから作成する手順のイメージ

 

 

フォームの作成

フォームとは、ユーザから入力を受ける部分のことを指します。

まず、そのフォームに必要なデータをひとまとめにするフォームクラスを作成します。

 

新たにflashcardの下にforms.pyというファイルを作成し、編集します。

from django import forms

# Create your forms hear.
class RegistrationForm(forms.Form):
    en_word = forms.CharField(label='English', max_length=200)
    jp_word = forms.CharField(label='日本語', max_length=200)

 

コードの解説

1行目は、フォームを作るときに必ず必要なものです。

 

4行目では、「forms.Form」を継承してクラスの宣言を行っています。

en_wordは英単語を代入する変数です。
jp_wordは日本語を代入する変数です。

「forms.CharField」は文字列を変数に代入させるためのものです。「label」はフォームをブラウザに表示するときに使います。変数がどのようなどのようなものであるかを表すものです。

 

 

スポンサードサーチ


単語登録ページの作成

単語登録ページのhtmlファイルを作成します。flashcard/templates/flashcard/の中にregistration.htmlを作成し、編集します。

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

{% block title %}Registration{% endblock %}

{% block content %}
<article class="registration">
  <div class="page-name">
    <h1>英単語登録フォーム</h1>
  </div>
  <p style="margin: 0;padding:0;">※複数の日本語訳を入力する際は、全角スペースで区切ってください。</p>
  {% if messages %}
    <ul class="messages">
      {% for message in messages %}
        <li {% if message.tags %} class="{{ message.tags }}" {% endif %}>{{ message }}</li>
      {% endfor %}
    </ul>
  {% endif %}
  <div class="registration-form">
    <form action="{% url 'wordregistration' %}" method="post">
      {% csrf_token %}
      {% for field in form %}
        <div class="field">
          {{ field.label_tag }}{{ field }}
        </div>
        {{ field.errors }}
      {% endfor %}
      <input type="submit" value="registration" style="margin: 5px 0">
    </form>
  </div>
</article>
{% endblock %}

※修正しました。(修正日:2019年12月26日)

上記のコード19行目
修正前:「{% url ‘word_registration’ %}」
修正後:「{% url ‘wordregistration’ %}」

修正前のコードでエラーが出てうまく実行できなかった方、大変申し訳ありませんでした。

 

コードの解説

1行目は、「flashcard/base.htmlを拡張してregistration.htmlを作成します」という宣言です。

 

3行目は、base.htmlのタイトルにRegistrationを代入しています。

 

11行目~16行目は、後述するmessagesがあれば表示するようにしてあります。messagesは、特定の動作が完了した場合やしなかった場合に、任意の言葉を表示させることができます。

 

18行目~29行目は、単語を登録するためのフォームです。

「{% csrf_token %}」は、クロスサイトリクエストフォージェリというwebアプリケーションの脆弱性を突く攻撃を防ぐためのものです。

「{% for field in form %}{% endfor %}」で囲まれている部分は、RegistraionFormに宣言されている変数を1つずつ取り出しています。

「{{ field.label_tag }}」は、変数1つひとつに設定したlabelを表示します。「{[ field ]}」は、ユーザが入力する部分を表示します。

 

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

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

 

 

views.pyの編集

単語を登録する機能を作成します。flashcard/views.pyに以下のプログラムを追記します。

from django.contrib import messages
from .forms import RegistrationForm
     .
     .
     .
    省略
     .
     .
     .
def wordregistration(request):
    if(request.method == 'POST'):
        regi_en_word = request.POST['en_word']
        regi_jp_word = request.POST['jp_word']
        exist = MyWord.objects.filter(en_word=regi_en_word)
        if(len(exist) == 0):
            mw = MyWord()
            mw.en_word = regi_en_word
            mw.jp_word = regi_jp_word
            mw.save()
            messages.success(request, '登録しました。')
    else:
            messages.error(request, ‘登録できませんでした。すでに登録されています。’)

    form = RegistrationForm()

    params = {
        'form':form,
    }

    return render(request, 'flashcard/registration.html', params)

 

コードの解説

1行目の「from django.contrib import messages」は、単語の登録に成功した時や失敗したときに表示する文字列を設定するためのものです。

 

2行目の「from .forms import RegistrasionForm」は、単語登録ページのviewに必要なためインポートしています。

「from .forms import RegistrasionForm」はインポート文であるため、ファイルの上の方に追記します。私の場合、「from .models import MyWord」の下に追記しました。

 

10行目の「def wordregistration(request):」は、単語登録ページのviewです。wordlistの関数よりも下の行に追記しました。

 

11行目の「if(request.method == ‘POST’):」は、単語を登録するボタンを押されたことを判定しています。

 

12,13行目の「regi_en_word = request.POST[‘en_word’]」と「regi_jp_word = request.POST[‘jp_word’]」は、送信されてきた英単語と日本語訳を変数に代入しています。

 

14行目の「exist = mw.objects.filter(en_word=regi_en_word)」は、モデルから同じ英単語が登録されているか、検索をかけています。

次のif文でexistの大きさが0であれば同じ英単語が登録されていないことになります。逆に0以上であれば同じ単語がすでに登録されていることになります。

 

15~20行目のif文の中では、モデルに単語を代入して保存しています。

20行目の「messages.success(request, ‘登録しました。’)」は、先ほど紹介したmessagesに第2引数の文字列が表示されます。

 

21,22行目のelse文の中の「messages.error(request, ‘登録できませんでした。すでに登録されています。’)」は、単語の保存に失敗したときに表示されます。

 

24行目の変数formには、RegistrationFrom()が代入されています。

 

urls.pyの編集

viewを作成したためurlを設定します。flashcard/urls.pyに以下のプログラムを追記します。

path('wordregistration', views.wordregistration, name="wordregistration"),

 

urlpatternsの3行目に追記しました。

 

確認

単語登録ページの動作確認を行うため、サーバを起動させます。

python manage.py runserver

 

サーバを起動させたら「http://localhost:8000/flashcard/wordregistration」にアクセスをします。

以下のようなページが表示されます。

 

次に、登録の処理が機能しているか確認を行います。現在何が登録されているか確かめるため「http://localhost:8000/flashcard/wordlist」にアクセスをします。 私の場合は、以下のような単語が登録されていました。

 

次に、単語登録ページに移動します。Englishと日本語にそれぞれ英語と日本語を入力して、registrationボタンをクリックします。

私は、Englishにbook、日本語に本と入力しました。

 

単語の登録に成功すると「・登録しました。」というメッセージが表示されます。

 

すでに登録されている単語を入力すると「・登録できませんでした。すでに登録されています。」というメッセージが表示されます。

 

単語の登録に成功したら、単語リストページに移動してキーボードのF5を押して、ページを更新します。入力した単語が表示されていたら確認は終了です。

 

 

スポンサードサーチ


まとめ

今回は、ブラウザから単語を登録する機能を作成しました。これにより単語を登録するために、いちいちDjango Adminにログインしなくて済みます。

 

ユーザからの入力を受けるためには、フォームを作る必要があります。

 

モデルにデータを保存するときは、

モデル名.データ名 = データ
モデル名.save()

というようにして保存します。

 

htmlファイルでformを使う際は、「{% csrf_token %}」を書く必要があります。これは、webページの脆弱性を突く攻撃を防ぐためのものです。

 

Djangoで単語帳開発Part5では、単語の登録と編集について書きたいと思います。

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


スポンサードサーチ