超初心者用: Djangoでウェブアプリを作る ⑥ユーザーによるentryの編集
前回に引き続き、今回もユーザーによるデータの変更に対応していきます。今回はユーザー自身が entry を編集できるようにします。
Entry の編集
edit_entry URL
entry を編集するURLには id が必要になります。practicing_logs/urls.py はこんな感じになります。
# practicing_logs/urls.py #--省略-- urlpatterns = [ #--省略-- # entry を編集するためのページ url(r'^edit_entry/(?P<entry_id>\d+)/$', views.edit_entry, name='edit_entry'), ]
もうこりごりするほどこの形式を見てきましたね。 http://localhost:8000/edit_entry/1/ のリンクで entry_id が1の entry を編集できるページに飛びます。URLがそれとマッチするときedit_entry() の view function が呼ばれます。
edit_entry() view function
GET リクエストを edit_entry ページが受け取ったとき、 edit_entry() が entry を変更するためのフォームを返します。POST リクエストを受け取ったときは、修正された文章をデータベースに保存します。
#views.py from django.shortcuts import render #--省略-- from .models import Topic, Entry #<----ここ from .forms import TopicForm, EntryForm #--省略-- def edit_entry(request, entry_id): """すでにある entry の編集""" entry = Entry.objects.get(id=entry_id) topic = entry.topic if request.method != 'POST': # 何も変更がない時 form = EntryForm(instance=entry) else: # POST データが送信されたとき form = EntryForm(instance=entry, data=request.POST) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('practicing_logs:topic', args=[topic.id])) context = {'entry': entry, 'topic': topic, 'form': form} return render(request, 'practicing_logs/edit_entry.html', context)
まずは Entry モデルをインポートしなければなりません。
entry = Entry.objects.get(id=entry_id)
ユーザーが編集する entry を entry_id を使って入手します。
if request.method != 'POST':
もしリクエストがPOST以外であるならば、現在の entry の内容を持った EntryForm を作成します。つまり同じ内容を上書きする感じです。
form = EntryForm(instance=entry, data=request.POST)
リクエストがPOSTだった場合は、instance=entry と data=request.POST を送ります。これはPOSTのリクエストからのユーザーが入力した文章で form instance を作ります。そのあと整合性をチェックし、合格すれば save() を行ってデータベースに保存します。最後にはトピックページにリダイレクトします。
edit_entry template
# edit_entry {% extends "practicing_logs/base.html" %} {% block content %} <p><a href="{% url 'practicing_logs:topic' topic.id %}">{{ topic }}</a></p> <p>Edit entry:</p> <form action="{% url 'practicing_logs:edit_entry' entry.id %}" method='post'> {% csrf_token %} {{ form.as_p }} <button name="submit">save changes</button> </form> {% endblock content %}
action argument はedit_entry() にフォームを送ります。そして view function が entry を編集します。
edit_entry ページをリンクする
edit_entry ページをそれぞれの entry から飛べるようにします。
#topic.html #--省略-- {% for entry in entries %} <li> <p>{{ entry.date_added | date: 'M d, Y H:i' }}</p> <p>{{ entry.text | linebreakes }}</p> <p> <a href="{% url 'practicing_logs:edit_entry' entry.id %}">edit entry</a> </p> </li> #--省略--
それぞれの entry の本文の下に edit ページへのリンクを設置しました。entry id でどの entry を編集するかを識別しています。見た目はこんな感じです。
次回
次はユーザーそれぞれにアカウントを与えて、トピックと entry を管理していきます。