Photo by Nick Adams on Unsplash
在學會Django Administration操作及客製化技巧後,各位可以透過管理介面,新增幾筆「景點位置」及「景點貼文」資料,本文將介紹透過Django所提供的資料庫抽像介面(Database Abstraction API),查詢資料庫中的景點貼文資料,並且利用Django Template(樣板)來進行顯示,主要的重點包含:
- Django資料庫抽象API-查詢
- Django Template(樣板)
- Django Template(樣板)語法
一、Django資料庫抽象API-查詢
在Django Migration(資料遷移)的重要觀念文章中,建立了Django專案的應用程式(APP)資料模型,如下:
from django.db import models
from django.utils import timezone
# 景點位置
class Location(models.Model):
name = models.CharField(max_length=255) #位置名稱
#景點貼文
class Post(models.Model):
subject = models.CharField(max_length=255) #標題
content = models.CharField(max_length=255) #內容
author = models.CharField(max_length=20) #貼文者
create_date = models.DateField(default=timezone.now) #貼文時間
location = models.ForeignKey(Location, on_delete=models.CASCADE) #景點位置
範例中的資料模型皆繼承自Model類別,這也意味著,可以透過其中所提供的資料庫抽象API,來進行資料的新增、修改、刪除及查詢,本文將介紹查詢API的基本用法,而其餘的操作待後續依網站的功能來進行介紹。
開啟應用程式(APP)下的views.py,引用models中的Post(景點貼文)類別,接下來,即可在檢視函式(View Function)中,使用Model類別的資料庫抽像API。
首先,要查詢景點貼文資料表中所有的資料,可以利用以下的Django資料庫抽象API:
開啟應用程式(APP)下的views.py,引用models中的Post(景點貼文)類別,接下來,即可在檢視函式(View Function)中,使用Model類別的資料庫抽像API。
首先,要查詢景點貼文資料表中所有的資料,可以利用以下的Django資料庫抽象API:
from django.shortcuts import render
from django.http import HttpResponse
from .models import Post
def index(request):
posts = Post.objects.all()
#SELECT * FROM posts_post
return HttpResponse("My First Django App.")
以上的語法,相當於Django的資料庫抽象API,產生了SELECT語法,查詢資料表中的所有資料。
如果想要依條件進行資料篩選,則可以利用以下的Django資料庫抽象API:
如果想要依條件進行資料篩選,則可以利用以下的Django資料庫抽象API:
from django.shortcuts import render
from django.http import HttpResponse
from .models import Post
def index(request):
posts = Post.objects.filter(location="台南")
# SELECT * FROM posts_post WHERE location="台南"
return HttpResponse("My First Django App.")
以上的語法,透過Python的關鍵字參數(Keyword Argument)來指定資料篩選的條件,相當於SQL語法中的WHERE語法,取得台南位置的所有景點貼文。
而要取得某篇景點貼文的資料,則可以使用以下語法:
而要取得某篇景點貼文的資料,則可以使用以下語法:
from django.shortcuts import render
from django.http import HttpResponse
from .models import Post
def index(request):
posts = Post.objects.get(id=1)
# SELECT * FROM posts_post WHERE id=1
return HttpResponse("My First Django App.")
同樣利用Python的關鍵字參數(Keyword Argument),來進行資料主鍵(Primary Key)的設定,來取得指定的資料。
二、Django Template(樣板)
以上的檢視函式(View Function)中,都是回傳字串的型態,而在實務上,多數會回傳一個網頁的型態給使用者,也就是Django中的Template(樣板),來客製化頁面顯示的顏色、動畫、字型、樣式及按鈕等。
而要回傳Django Template(樣板),就需要使用Django的render()函式,語法如下:
而要回傳Django Template(樣板),就需要使用Django的render()函式,語法如下:
render(request, template_name, context)
第一個參數為request,template_name為回傳的樣板名稱,如果在檢視函式(View Function)中,有資料想要帶到Django Template(樣板)中來顯示時,可以透過context參數來設定,為字典(Dictionary)的資料型態。
舉例來說,如果要回傳一個Django Template(樣板),顯示資料表中的所有景點貼文, 則可以套用以下的寫法:
舉例來說,如果要回傳一個Django Template(樣板),顯示資料表中的所有景點貼文, 則可以套用以下的寫法:
from django.shortcuts import render
from django.http import HttpResponse
from .models import Post
def index(request):
posts = Post.objects.all()
return render(request, "posts/index.html", {"posts": posts})
這邊特別說明一下樣板名稱為什麼還要再多一層資料夾呢?因為Django在尋找應用程式的Template(樣板)時,會依據專案主程式下的settings.py,其中的INSTALLED_APPS的順序來進行尋找,如下:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'posts.apps.PostsConfig'
]
如果檢視函式(View Function)中的回傳樣板名稱只設定為index.html,當Django在依序尋找應用程式的樣板時,有相同的樣板名稱則會回傳,並且停止往下尋找,這時候如果在搜尋到posts應用程式之前,其它的應用程式也有index.html樣板名稱,就會回傳非posts應用程式的Template(樣板)。
所以這邊建議在規劃應用程式(APP)的Template(樣板)時,另外建立一個templates資料夾,這是Django在搜尋應用程式的Template(樣板)時,所會查找的資料夾。接著,在templates資料夾中再建立一個名為應用程式(APP)的資料夾,放置該應用程式的Template(樣板),如下範例:
所以這邊建議在規劃應用程式(APP)的Template(樣板)時,另外建立一個templates資料夾,這是Django在搜尋應用程式的Template(樣板)時,所會查找的資料夾。接著,在templates資料夾中再建立一個名為應用程式(APP)的資料夾,放置該應用程式的Template(樣板),如下範例:
其實這樣的做法就像是在設定Django Template(樣板)的命名空間(namespace),避免與其它應用程式(APP)的樣板命名空間相同。
三、Django Template(樣板)語法
建立應用程式(APP)的Template(樣板)後,接下來就要使用Django Template(樣板)語法,來顯示檢視函式(View Function)所帶過來的posts(景點貼文)資料。
2020/07/22補充說明
使用Visual Studio Code開發的朋友,在左方Extensions(擴充套件)的地方,搜尋django關鍵字,可以看到如下圖的套件:
2020/07/22補充說明
使用Visual Studio Code開發的朋友,在左方Extensions(擴充套件)的地方,搜尋django關鍵字,可以看到如下圖的套件:
安裝了這個套件後,在開發Django Template(樣板)時,就可以使用Code Snippets自動產生程式碼片段,來提升開發的效率。就算沒有安裝這個套件,同樣可以進行開發,只是需要逐字輸入程式碼。安裝完成後,開啟index.html可以看到右下角的語言模式,如下圖:
如果不是Django HTML的話,點選紅框處,接著在如下圖的搜尋地方輸入django,選擇Django HTML即可。
Django Template(樣板)的For迴圈語法為:
{% for item in items %}
...
{% endfor %}
在Django HTML語言模式下,輸入for按下Tab鍵,就會自動產生語法結構,這就是所謂的Code Snippets,非常的方便。如下範例:
接下來,要顯示posts物件中的屬性資料,則可以透過{{ }}符號來進行存取,如下範例:
從執行結果可以看到,Django Template(樣板)成功的回傳給瀏覽器,並且顯示了資料庫中的景點貼文資料。
四、小結
透過本文的教學,瞭解了如何透過Django資料庫抽象API來查詢資料,並且利用Django Template(樣板)語法,來客製化顯示資料至瀏覽器。不過這樣的畫面看起來非常的陽春,在下一篇教學文章中,將說明如何整合Bootstrap4框架到Django專案中,讓畫面更加精緻美觀。
如果您喜歡我的文章,請幫我按五下Like(使用Google或Facebook帳號免費註冊),支持我創作教學文章,回饋由LikeCoin基金會出資,完全不會花到錢,感謝大家。
如果您喜歡我的文章,請幫我按五下Like(使用Google或Facebook帳號免費註冊),支持我創作教學文章,回饋由LikeCoin基金會出資,完全不會花到錢,感謝大家。
跟了整篇教學,到第五個完全卡住QQ
回覆刪除我用pycharm設定了template -> post -> index.html
然後完全沒有辦法顯示,請問可能是什麼原因呢
Otto您好:
刪除可以檢查一下views.py檔案,在檢視函式最後return的時候,是否有指定樣板的路徑,如下範例:
return render(request, "post/index.html", {"posts": posts})
在第二個參數樣板路徑的地方,要指定樣板檔案(index.html)所擺放的資料夾路徑。
希望以上的解答有幫助到您 :)
讚讚 成功了!
回覆刪除MIKE大你好,想要請問
回覆刪除我執行網頁後,景點名稱會變成 Location object (1)
是哪一邊沒有處理好呢?
在 posts/models.py 的 class Location 裡面
刪除補上 def __str__(self) 那塊碼 就可以顯示名稱了!
感謝回覆!
刪除感謝Jiang的回覆,沒錯,也就是您在Django教學4所提出的「 覆寫(Method Overriding) __str__特殊方法(Magic Method) 這一處的功用」 :)
刪除請問HTML的擴充套件推薦用哪個呢?
回覆刪除謝謝~
Jiang您好:
刪除以下是我目前在使用VSCode開發前端時,有安裝的擴充套件,給您參考囉 :)
1. Live Server:
在儲存HTML檔的同時,自動即時更新瀏覽器,顯示剛剛所修改的結果。
2.Auto Rename Tag:
修改HTML的標籤時,會自動化更新尾部的標籤名稱,使前後標籤一致。
3.CSS Peek: 方便查看HTML檔中的樣式類別(class)。
謝謝~ ^^
刪除請問一下,為何model底下建立的class不需要用到__init__的方式去建立?
回覆刪除謝謝