Django專案——編輯主題的條目
阿新 • • 發佈:2018-12-03
一 程式碼
1 learning_logs/urls.py
# -*- coding: utf-8 -*- from django.conf.urls import url from . import views urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^topics/$', views.topics, name='topics'), url(r'^topics/(?P<topic_id>\d+)/$', views.topic, name='topic'), # 用於新增新主題的網頁 # 該URL 模式將請求交給檢視函式 new_topic() url(r'^new_topic/$', views.new_topic, name='new_topic'), # 用於新增新條目的頁面 # 這個 URL 模式與形式為 http://localhost:8000/new_entry/ id / 的 URL 匹配,其中 id 是一個與主題 ID 匹配的數字。 # 程式碼 (?P<topic_id>\d+) 捕獲一個數字值,並將其儲存在變數 topic_id 中。 # 請求的 URL 與這個模式匹配時, Django 將請求和主題 ID 傳送給函式 new_entry() 。 url(r'^new_entry/(?P<topic_id>\d+)/$', views.new_entry, name='new_entry'), # 用於編輯條目的頁面 # 在 URL (如 http://localhost:8000/edit_entry/1/ )中傳遞的 ID 儲存在形參 entry_id 中。 # 這個 URL 模式將預期匹配的請求傳送給檢視函式 edit_entry() url(r'^edit_entry/(?P<entry_id>\d+)/$', views.edit_entry, name='edit_entry'), ]
2 learning_logs/views.py
# -*- coding: utf-8 -*- from django.shortcuts import render from django.http import HttpResponseRedirect, Http404 from django.core.urlresolvers import reverse from django.contrib.auth.decorators import login_required from .models import Topic, Entry from .forms import TopicForm, EntryForm def index(request): return render(request, 'learning_logs/index.html') @login_required def topics(request): topics = Topic.objects.filter(owner=request.user).order_by('date_added') context = {'topics': topics} return render(request, 'learning_logs/topics.html', context) @login_required def topic(request, topic_id): topic = Topic.objects.get(id=topic_id) # Make sure the topic belongs to the current user. if topic.owner != request.user: raise Http404 entries = topic.entry_set.order_by('-date_added') context = {'topic': topic, 'entries': entries} return render(request, 'learning_logs/topic.html', context) @login_required def new_topic(request): """ 新增新主題 """ if request.method != 'POST': # 未提交資料:建立一個新表單 form = TopicForm() else: # POST 提交的資料 , 對資料進行處理 # HttpResponseRedirect 類,使用者提交主題後我們將使用這個類將使用者重定向到網頁 topics 。 # 函式 reverse() 根據指定的 URL 模型確定 URL ,這意味著 Django將在頁面被請求時生成 URL 。 # 我們還匯入了剛才建立的表單 TopicForm 。 # 我們使用使用者輸入的資料(它們儲存在 request.POST 中)建立一個 TopicForm 例項 # 這樣物件 form 將包含使用者提交的資訊。 form = TopicForm(request.POST) # 函式 is_valid() 核實使用者填寫了所有必不可少的欄位(表單欄位預設都是必不可少的), # 且輸入的資料與要求的欄位型別一致(例如,欄位 text 少於 200 個字元)。 # 這種自動驗證避免了我們去做大量的工作。 if form.is_valid(): new_topic = form.save(commit=False) new_topic.owner = request.user # 將表單中的資料寫入資料庫 new_topic.save() # 使用 reverse() 獲取頁面 topics 的 URL ,並將其傳遞給 HttpResponseRedirect() # 後者將使用者的瀏覽器重定向到頁面 topics 。 # 在頁面 topics 中,使用者將在主題列表中看到他剛輸入的主題。 return HttpResponseRedirect(reverse('learning_logs:topics')) context = {'form': form} return render(request, 'learning_logs/new_topic.html', context) @login_required def new_entry(request, topic_id): """ 在特定的主題中新增新條目 """ # 形參 topic_id ,用於儲存從 URL 中獲得的值。渲染頁面以及處理表單資料時,都 # 需要知道針對的是哪個主題,因此我們使用 topic_id 來獲得正確的主題。 topic = Topic.objects.get(id=topic_id) if topic.owner != request.user: raise Http404 if request.method != 'POST': # 未提交資料 , 建立一個空表單 form = EntryForm() else: # POST 提交的資料 , 對資料進行處理 form = EntryForm(data=request.POST) if form.is_valid(): # 讓 Django 建立一個新的條目物件,並將其儲存到 new_entry 中,但不將它儲存到資料庫中。 new_entry = form.save(commit=False) # 設定條目物件的屬性 topic ,再將條目物件儲存到資料庫。 new_entry.topic = topic new_entry.save() # 呼叫 reverse() 時,需要提供兩個實參:要根據它來生成 URL 的 URL 模式的名稱; # 列表 args ,其中包含要包含在 URL 中的所有實參。在這裡,列表 args 只有一個元素 —— topic_id 。 # 接下來,呼叫 HttpResponseRedirect() 將使用者重定向到顯示新增條目所屬主題的頁面,使用者將在該頁面的 # 條目列表中看到新新增的條目。 return HttpResponseRedirect(reverse('learning_logs:topic', args=[topic_id])) context = {'topic': topic, 'form': form} return render(request, 'learning_logs/new_entry.html', context) ''' 頁面 edit_entry 收到 GET 請求時, edit_entry() 將返回一個表單,讓使用者能夠對條目進行編輯。 頁面收到 POST 請求(條目文字經過修訂)時,它將修改後的文字儲存到資料庫中 ''' @login_required def edit_entry(request, entry_id): """ 我們獲取使用者要修改的條目物件,以及與該條目相關聯的主題。在請求方法為 GET 時將執行的 if 程式碼塊中,我們使用實 參 instance=entry 建立一個 EntryForm 例項。 這個實參讓 Django 建立一個表單,並使用既有條目物件中的資訊填充它。使用者將看到既有的資料,並能夠編輯它們。 處理 POST 請求時,我們傳遞實參 instance=entry 和 data=request.POST ,讓 Django 根據既有條目物件建立一個表單例項, 並根據 request.POST 中的相關資料對其進行修改。然後,我們檢查表單是否有效,如果有效,就呼叫 save() ,且不指定任何實參。 接下來,我們重定向到顯示條目所屬主題的頁面,使用者將在其中看到其編輯的條目的新版本。""" entry = Entry.objects.get(id=entry_id) topic = entry.topic if topic.owner != request.user: raise Http404 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('learning_logs:topic', args=[topic.id])) context = {'entry': entry, 'topic': topic, 'form': form} return render(request, 'learning_logs/edit_entry.html', context)
3 learning_logs/templates/learning_logs/edit_entry.html
{% extends "learning_logs/base.html" %} {% block content %} <p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p> <p>Edit entry:</p> <!--實參 action 將表單發回給函式 edit_entry() 進行處理。在標籤 url 中,我們將條目 ID 作為一個實參, 讓檢視物件能夠修改正確的條目物件。我們將提交按鈕命名為 儲存修改 ,以提醒使用者:單擊該按鈕將儲存所做的編輯, 而不是建立一個新條目--> <form action="{% url 'learning_logs:edit_entry' entry.id %}" method='post'> {% csrf_token %} {{ form.as_p }} <button name="submit">儲存修改</button> </form> {% endblock content %}
4 learning_logs/templates/learning_logs/topic.html
{% extends 'learning_logs/base.html' %}
{% block content %}
<p>主題: {{ topic }}</p>
<p>條目:</p>
<p>
<!---顯示條目前新增連結,因為在這種頁面中,執行的最常見的操作是新增新條目。-->
<a href="{% url 'learning_logs:new_entry' topic.id %}">新增新條目</a>
</p>
<ul>
{% for entry in entries %}
<li>
<p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
<p>{{ entry.text|linebreaks }}</p>
<p>
<!--我們將編輯連結放在每個條目的日期和文字後面。在迴圈中,我們使用模板標籤 url .
根據 URL 模式 edit_entry 和當前條目的 ID 屬性( entry.id )來確定 URL 。連結
文字為 "編輯條目" ,它出現在頁面中每個條目的後面。-->
<a href="{% url 'learning_logs:edit_entry' entry.id %}">編輯條目</a>
</p>
</li>
{% empty %}
<li>
沒有針對該主題的條目.
</li>
{% endfor %}
</ul>
{% endblock content %}
二 測試結果