Djangoで単語帳開発Part5
こんにちは、にわこまです。
今回は、登録した単語を削除したり、編集したりできる機能を作成します。
「Djangoで単語帳開発」シリーズはDjangoのチュートリアルとして利用されることを目的としています。
誤字脱字や分かりにくい点がありましたらご連絡お願い致します。
スポンサードサーチ
Djangoで単語帳開発Part5
Part4では、単語を登録する機能を作成しました。しかし間違って登録したり、不必要な単語が邪魔であったり感じることがあると思います。
そこで、今回は登録してある単語を削除、編集する機能を作成していきたいと思います。
今回の機能は単語リストページに追加し、単語リストページから単語削除ページや単語編集ページに移動するようにします。
単語削除ページの作成
単語リストページから削除する単語を選び、単語削除ページに移動して、単語削除の確認を行います。
flashcard/templates/flashcard/の下にworddelete.htmlファイルを作成し編集します。
{% extends 'flashcard/base.html' %}
{% block title %}Word Delete{% endblock %}
{% block content %}
<article class="word-delete">
<div class="page-name">
<h1>単語の削除</h1>
</div>
{% if messages %}
<div class="message">
<ul>
{% for message in messages %}
<li {% if message.tags %} class="{{ message.tags }}" {% endif %}>{{ message }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if del_en_word != '' and del_jp_word != '' %}
<div class="word-delete-form">
<h3 style="margin: 0;">本当に削除しますか?</h3>
<form action="{% url 'worddelete' %}" method="post">
{% csrf_token %}
<p style="margin: 0;">English : {{ del_en_word }}</p>
<p style="margin: 0;">日本語 : {{ del_jp_word }}</p>
<input hidden type="text" name="en_word" value="{{ del_en_word }}">
<input type="submit" value="削除" style="margin: 5px 0;">
</form>
</div>
{% endif %}
</article>
{% endblock %}
コードの解説
1行目は、「base.htmlを拡張してworddelete.htmlを作成する」という宣言を行っています。
3行目は、タイトルの部分にWord Deleteと表示されるようにtitleブロックの中に代入しています。
10~18行目は、削除が成功したか、失敗したかを知らせるメッセージを表示させる部分です。
19~30行目は、実際に単語を削除するための機能が書かれています。
19行目は、削除する単語が存在することを確認しています。
22行目のフォームタグのactionには、後に作成するworddeleteのURLを代入しています。
23行目の「{% csrf_token %}」は、webページの脆弱性を突いた攻撃を防ぐためのものです。ユーザからの入力はありませんが、フォームタグを使ってデータを送信するため設定してあります。
24、25行目は、後に作成するworddeleteのparamsです。削除する単語を表示します。
現在のフォルダ状況(templatesのみ)↓↓↓
templates
|-flashcard
|-base.html
|-index.html
|-wordlist.html
|-registration.html
|-worddelete.html #追加部
スポンサードサーチ
views.pyの編集
実際に単語を削除する機能を作成します。flashcard/views.pyに以下のプログラムを追記します。
def worddelete(request):
del_en_word = ''
del_jp_word = ''
if('del_id' in request.GET):
del_id = request.GET['del_id']
mws_obj = MyWord.objects.filter(id=del_id).first()
del_en_word = mws_obj.en_word
del_jp_word = mws_obj.jp_word
if(request.method == 'POST'):
word_delete = request.POST['en_word']
MyWord.objects.filter(en_word=word_delete).delete()
messages.success(request, '{0}を削除しました。'.format(word_delete))
params = {
'del_en_word':del_en_word,
'del_jp_word':del_jp_word,
}
return render(request, 'flashcard/worddelete.html', params)
コードの解説
1行目は、関数の宣言を行っています。
2、3行目は、変数の初期化を行っています。
4行目は、送られてきたURLに後述する「del_id」パラメータが含まれているか確認しています。つまり、削除する単語が指定されているか確認しています。
5行目は、URLからdel_idパラメータのデータを取り出し、変数に代入しています。
6行目は、del_idに代入されているidから、MyWordに格納されている単語を取り出しています。
7、8行目は、6行目で取り出した単語をそれぞれ変数に代入しています。
ここまでが、単語リストページから削除ボタンをクリックして、単語削除ページに単語を表示する処理です。
10行目は、単語削除ページから送られてきたデータであることを確認しています。
11行目は、削除する単語を変数に代入しています。
12行目は、実際にMyWordモデルからデータ(単語)を削除しています。
13行目は、messagesを使ってデータが削除されたことを伝えるメッセージを表示する設定を行っています。
以上までが、単語削除ページから削除ボタンをクリックして、実際にデータ(単語)を削除するまでの処理です。
urls.pyの編集
views.pyで関数を定義したため、その関数とURLを対応付けさせます。flashcard/urls.pyに以下のプログラムを追記します。
path('worddelete', views.worddelete, name='worddelete'),
ちゃんと対応付けることができているか確認を行います。サーバを起動します。
python manage.py runserver
サーバを起動させたら「http://localhost:8000/flashcard/worddelete」にアクセスをします。 以下のようなページが表示されていたら、URLを対応付けさせることができています。
直接、単語削除ページにアクセスしたため削除する単語は表示されません。
次に、単語リストページのwordlist.htmlファイルに単語削除ページへ移動するためのタグを追記します。
<p style="width: 20%">{{ word.en_word }}</p>
<p style="width: 60%">{{ word.jp_word }}</p>
<p class="jump"><a href="{% url 'worddelete' %}?del_id={{ word.id }}">削除</a></p> #追加部
追記したら、「http://localhost:8000/flashcard/wordlist」にアクセスします。 私の場合は以下のようなページが表示されました。削除ボタンが存在することを確認できます。
いずれかの削除ボタンをクリックすると以下のようなページに移動します。
削除ボタンとクリックすると、単語を削除したメッセージが表示されます。
本当に削除されているか確認するために「http://localhost:8000/flashcard/wordlist」にアクセスします。
削除した単語が表示されていないため、単語が削除されていることを確認しました。 以上で単語削除ページの確認は終了です。
単語編集ページの作成
単語リストページから編集する単語を選び、単語編集ページに移動して、単語編集と保存の確認を行います。
flashcard/templates/flashcardの下にwordedit.htmlファイルを作成し、編集します。
{% extends 'flashcard/base.html' %}
{% block title %}Word Edit{% endblock %}
{% block content %}
<article class="word-edit">
<div class="page-name">
<h1>単語の編集</h1>
</div>
{% if messages %}
<div class="message">
<ul>
{% for message in messages %}
<li {% if message.tags %} class="{{ message.tags }}" {% endif %}>{{ message }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if ed_en_word != '' and ed_jp_word != '' %}
<div class="word-edit-form">
<form action="{% url 'wordedit' %}" method="post">
{% csrf_token %}
<p style="margin: 0;">English : {{ ed_en_word }}</p>
<label>日本語 : </label><input type="text" name="jp_word" value="{{ ed_jp_word }}">
<input hidden type="text" name="en_word" value="{{ ed_en_word }}"><br>
<input type="submit" value="編集" style="margin: 5px 0;">
</form>
</div>
{% endif %}
</article>
{% endblock %}
コードの解説
1行目の「{% extends ‘flashcard/base.html’}」は、「base.htmlを拡張してwordedit.htmlを作成します」ということを宣言しています。
3行目の「{% block title %}Word Edit{% endblock %}」は、タイトルに「Word Edit」を代入しています。
10~18行目は、編集が完了したことを伝えるための機能です。messagesを使用しています。
19行目の「{% if ed_en_word != ” and ed_jp_word != ” %}」は、編集する単語が空でないことを確認しています。
20~28行目は、実際に単語を編集する部分です。編集にはformタグを使っているため「{% csrf_token %}」によって、webアプリケーションの脆弱性を突いた攻撃を防いでいます。
単語の編集では、英単語の編集は出来ないようになっています。なぜなら、モデルで英単語にuniqueキーを設定したからです。わざと同じ単語を入力、保存して、エラーが発生しないようにしています。
現在のフォルダ状況(templatesのみ)↓↓↓
templates
|-flashcard
|-base.html
|-index.html
|-wordlist.html
|-registration.html
|-worddelete.html
|-wordedit.html # 追加部
スポンサードサーチ
views.pyの編集
実際に単語を編集する機能を作成します。flashcard/views.pyに以下のプログラムを追記します。
def wordedit(request):
ed_en_word = ''
ed_jp_word = ''
if('ed_id' in request.GET):
ed_id = request.GET['ed_id']
mws_obj = MyWord.objects.filter(id=ed_id).first()
ed_en_word = mws_obj.en_word
ed_jp_word = mws_obj.jp_word
if(request.method == 'POST'):
en_word = request.POST['en_word']
new_jp_word = request.POST['jp_word']
mws_obj = MyWord.objects.filter(en_word=en_word).first()
mws_obj.jp_word = new_jp_word
mws_obj.save()
messages.success(request, '{0}を編集しました。'.format(en_word))
params = {
'ed_en_word':ed_en_word,
'ed_jp_word':ed_jp_word,
}
return render(request, 'flashcard/wordedit.html', params)
コードの解説
1行目の「def wordedit(request):」は、関数の宣言と定義を行っています。
2、3行目は、変数の初期化を行っています。
4行目は、送られてきたURLに「ed_id」(後述)が含まれているか確認しています。つまり、編集する単語が指定されているか確認しています。
5行目は、URLからed_idパラメータのデータを取り出し、変数に代入しています。
6行目は、ed_idに代入されているidから、MyWordに格納されている単語を取り出しています。
7、8行目は、6行目で取り出した単語をそれぞれ変数に代入しています。
ここまでが、単語リストページから編集ボタンをクリックして、単語編集ページに単語を表示する処理です。
10行目は、単語編集ページから送られてきたデータであることを確認しています。
11、12行目は、送られてきた単語を変数に代入しています。
13行目は、送られてきた英単語に一致する1行を取り出しています。
14行目は、取り出された1行の日本語の部分だけ上書きしています。
15行目は、データを保存しています。
16行目は、messagesを使ってデータが編集されたことを伝えるメッセージを表示する設定を行っています。
以上までが、単語編集ページから編集ボタンをクリックして、実際にデータ(単語)を編集するまでの処理です。
urls.pyの編集
views.pyで関数を定義したため、その関数とURLを対応付けさせます。flashcard/urls.pyに以下のプログラムを追記します。
path('wordedit', views.wordedit, name='wordedit'),
ちゃんと対応付けることができているか確認を行います。サーバを起動します。
python manage.py runserver
サーバを起動させたら「http://localhost:8000/flashcard/wordedit」にアクセスをします。 以下のようなページが表示されていたら、URLを対応付けさせられています。
直接、単語編集ページにアクセスしたため編集する単語は表示されません。
次に、単語リストページのwordlist.htmlファイルに単語編集ページへ移動するためのタグを追記します。
<p style="width: 20%">{{ word.en_word }}</p>
<p style="width: 60%">{{ word.jp_word }}</p>
<p class="jump"><a href="{% url 'worddelete' %}?del_id={{ word.id }}">削除</a></p>
<p class="jump"><a href="{% url 'word_edit' %}?ed_id={{ word.id }}">編集</a></p> # 追加部
追記したら、「http://localhost:8000/flashcard/wordlist」にアクセスします。 私の場合は以下のようなページが表示されました。編集ボタンが存在することを確認できます。
いずれかの編集ボタンをクリックすると以下のようなページに移動します。
日本語を入力するフォームに、新たに日本を入力したり、追加したりした後、編集をクリックします。
正しく編集されると以下のように表示されます。
本当に編集されているか確認するために「http://localhost:8000/flashcard/wordlist」にアクセスします。
編集した日本語が確認できたら、単語編集ページの確認は以上で終了です。
まとめ
今回は、ブラウザから単語の削除と編集を行えるようにしました。
URLに削除または編集する単語をパラメータとして付け加えることで、単語を指定しました。
今回はdjangoよりもhtmlを理解していないと難し箇所があったと思います。djangoではviewの作成でhtmlを使用するため、htmlもあわせて学習した方が良いと思います。
Djangoで単語帳開発Part6では、単語帳のメイン機能を作成していきます。
最後までお読みいただきありがとうございます。
スポンサードサーチ