Django中REST風格資料傳輸
在《Python Web開發:測試驅動方法》一書中的第七章,主要講解了如何利用url的方式進行資料的傳遞和儲存。
本書主要採用了先測試、後建立功能的方式進行書寫,基本上所有的內容都是通過功能測試、單元測試和實現功能三個步驟的迴圈工作。這種方法讓我們能夠深刻地理解TDD這一基本思想,但並不利於Django框架的基本學習,所以我將前端html頁面、檢視層views.py和模型層models.py單獨摘出來,幫自己梳理一下思路。
模板層
到本書的第七章,建立了兩個html檔案,分別是主頁的home.html和用於不同使用者記錄和傳輸資料的list.html。
看過這本書的讀者可以知道,在這一章,list.html是copy自home.html,之後刪除了home中的table部分。home.html的主要功能是在form元素中新增method="POST"
action="/lists/new"
這兩個屬性,當用戶在輸入框中輸入資料後,以POST的方式,傳輸到新的url/lists/new
。
同理,list.html的form 的action屬性被設定為/lists/{{ list.id }}/add_item
, 跳轉到了新的頁面。
home.html
<!DOCTYPE html>
<html>
<head>
<title>To-Do lists</title>
</head>
<body>
<h1>Start a new To-Do list</h1 >
<form method="POST" action="/lists/new">
<input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>
{% csrf_token %}
</form>
</body>
</html>
list.html
<!DOCTYPE html>
<html>
<head>
<title >To-Do lists</title>
</head>
<body>
<h1>Your To-Do list</h1>
<form method="POST" action="/lists/{{ list.id }}/add_item">
<input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>
{% csrf_token %}
</form>
<table id="id_list_table">
{% for item in list.item_set.all%}
<tr><td>{{forloop.counter}}: {{ item.text }}</td></tr>
{% endfor %}
</table>
</body>
</html>
urls.py
個人理解,Django的urls.py檔案就是一個對映表,可以將url與檢視層的功能方法對應起來,換句話說,它就是一個url請求對映表。
Django建議開發者將專案的總urls檔案與各個應用的檔案分開儲存,所以本文建立了superlists/urls.py
和lists/url.py
兩個urls.py。
superlists/urls.py
from django.conf.urls import url, include
from lists import views as list_views
from lists import urls as list_urls
urlpatterns = [
url(r'^$', list_views.home_page, name='home'),
url(r'^lists/', include(list_urls)),
]
lists/url.py
from django.conf.urls import url
from lists import views
urlpatterns = [
url(r'^new$', views.new_list, name='new_list'),
url(r'^(\d+)/$', views.view_list, name='view_list'),
url(r'^(\d+)/add_item$', views.add_item, name='add_item'),
]
模型層和檢視層
Django並不是嚴格意義上的MVC模式,即MODEL, VIEW, CONTROLLER。因為它的View層承擔了傳統的控制層的一部分功能,可以進行資料的操作。
在本文中,通過url的對映,views.py
中存在著一一對應的方法。使用者從home.html進入網站後,輸入資料跳轉到list.html
中,並執行new_list(request):
跳轉到持有相關id號的url中,並通過view_list(request, list_id):
顯示資料。而在list頁面中,每次提交則再次觸發action="/lists/{{ list.id }}/add_item"
,將資料新增到資料庫中後在此跳轉回/lists/{list_.id}/
。
models.py
from django.db import models
class List(models.Model):
pass
class Item(models.Model):
text = models.TextField(default='')
list = models.ForeignKey(List, default=None)
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from lists.models import Item, List
# Create your views here.
def home_page(request):
return render(request, 'home.html')
def view_list(request, list_id):
list_ = List.objects.get(id=list_id)
return render(request, 'list.html', {'list': list_})
def new_list(request):
list_ = List.objects.create()
Item.objects.create(text=request.POST['item_text'], list=list_)
return redirect(f'/lists/{list_.id}/')
def add_item(request, list_id):
list_ = List.objects.get(id=list_id)
Item.objects.create(text=request.POST['item_text'], list=list_)
return redirect(f'/lists/{list_.id}/')