組建一個關(guān)于書籍、作者、出版社的例子:
from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField() class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField()
我們現(xiàn)在來創(chuàng)建一個簡單的view函數(shù)以便讓用戶可以通過書名從數(shù)據(jù)庫中查找書籍。
通常,表單開發(fā)分為兩個部分: 前端HTML頁面用戶接口和后臺view函數(shù)對所提交數(shù)據(jù)的處理過程。 第一部分很簡單;現(xiàn)在我們來建立個view來顯示一個搜索表單:
from django.shortcuts import render_to_response def search_form(request): return render_to_response('search_form.html')
這個view函數(shù)可以放到Python的搜索路徑的任何位置。 為了便于討論,咱們將它放在 books/views.py 里。
這個 search_form.html 模板,可能看起來是這樣的:
Search
而 urls.py 中的 URLpattern 可能是這樣的:
from mysite.books import views urlpatterns = patterns('', # ... (r'^search-form/$', views.search_form), # ... )
(注意,我們直接將views模塊import進(jìn)來了,而不是用類似 from mysite.views import search_form 這樣的語句,因?yàn)榍罢呖雌饋砀啙崱#?
現(xiàn)在,如果你運(yùn)行 runserver 命令,然后訪問http://127.0.0.1:8000/search-form/,你會看到搜索界面。 非常簡單。
不過,當(dāng)你通過這個form提交數(shù)據(jù)時,你會得到一個Django 404錯誤。 這個Form指向的URL /search/ 還沒有被實(shí)現(xiàn)。 讓我們添加第二個視圖函數(shù)并設(shè)置URL:
# urls.py urlpatterns = patterns('', # ... (r'^search-form/$', views.search_form), (r'^search/$', views.search), # ... ) # views.py def search(request): if 'q' in request.GET: message = 'You searched for: %r' % request.GET['q'] else: message = 'You submitted an empty form.' return HttpResponse(message)
暫時先只顯示用戶搜索的字詞,以確定搜索數(shù)據(jù)被正確地提交給了Django,這樣你就會知道搜索數(shù)據(jù)是如何在這個系統(tǒng)中傳遞的。 簡而言之:
??? 在HTML里我們定義了一個變量q。當(dāng)提交表單時,變量q的值通過GET(method=”get”)附加在URL /search/上。
??? 處理/search/(search())的視圖通過request.GET來獲取q的值。
需要注意的是在這里明確地判斷q是否包含在request.GET中。就像上面request.META小節(jié)里面提到,對于用戶提交過來的數(shù)據(jù),甚至是正確的數(shù)據(jù),都需要進(jìn)行過濾。 在這里若沒有進(jìn)行檢測,那么用戶提交一個空的表單將引發(fā)KeyError異常:
# BAD! def bad_search(request): # The following line will raise KeyError if 'q' hasn't # been submitted! message = 'You searched for: %r' % request.GET['q'] return HttpResponse(message)
查詢字符串參數(shù)
因?yàn)槭褂肎ET方法的數(shù)據(jù)是通過查詢字符串的方式傳遞的(例如/search/?q=django),所以我們可以使用requet.GET來獲取這些數(shù)據(jù)。我們知道在視圖里可以使用request.GET來獲取傳統(tǒng)URL里的查詢字符串(例如hours=3)。
獲取使用POST方法的數(shù)據(jù)與GET的相似,只是使用request.POST代替了request.GET。那么,POST與GET之間有什么不同?當(dāng)我們提交表單僅僅需要獲取數(shù)據(jù)時就可以用GET; 而當(dāng)我們提交表單時需要更改服務(wù)器數(shù)據(jù)的狀態(tài),或者說發(fā)送e-mail,或者其他不僅僅是獲取并顯示數(shù)據(jù)的時候就使用POST。 在這個搜索書籍的例子里,我們使用GET,因?yàn)檫@個查詢不會更改服務(wù)器數(shù)據(jù)的狀態(tài)。 (如果你有興趣了解更多關(guān)于GET和POST的知識,可以參見http://www.w3.org/2001/tag/doc/whenToUseGet.html。)
既然已經(jīng)確認(rèn)用戶所提交的數(shù)據(jù)是有效的,那么接下來就可以從數(shù)據(jù)庫中查詢這個有效的數(shù)據(jù)(同樣,在views.py里操作):
from django.http import HttpResponse from django.shortcuts import render_to_response from mysite.books.models import Book def search(request): if 'q' in request.GET and request.GET['q']: q = request.GET['q'] books = Book.objects.filter(title__icontains=q) return render_to_response('search_results.html', {'books': books, 'query': q}) else: return HttpResponse('Please submit a search term.')
讓我們來分析一下上面的代碼:
- ??? 除了檢查q是否存在于request.GET之外,我們還檢查來reuqest.GET[‘q']的值是否為空。
- ??? 我們使用Book.objects.filter(title__icontains=q)獲取數(shù)據(jù)庫中標(biāo)題包含q的書籍。 icontains是一個查詢關(guān)鍵字。這個語句可以理解為獲取標(biāo)題里包含q的書籍,不區(qū)分大小寫。
- ??? 這是實(shí)現(xiàn)書籍查詢的一個很簡單的方法。 我們不推薦在一個包含大量產(chǎn)品的數(shù)據(jù)庫中使用icontains查詢,因?yàn)槟菚苈?(在真實(shí)的案例中,我們可以使用以某種分類的自定義查詢系統(tǒng)。 在網(wǎng)上搜索“開源 全文搜索”看看是否有好的方法)
??? 最后,我們給模板傳遞來books,一個包含Book對象的列表。 查詢結(jié)果的顯示模板search_results.html如下所示:
You searched for: {{ query }}
{% if books %}Found {{ books|length }} book{{ books|pluralize }}.
-
{% for book in books %}
- {{ book.title }} {% endfor %}
No books matched your search criteria.
{% endif %}??? 注意這里pluralize的使用,這個過濾器在適當(dāng)?shù)臅r候會輸出s(例如找到多本書籍)。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
