首先回顧一下圖書薦購模塊要實現(xiàn)的內(nèi)容。
圖書薦購模塊包括薦購圖書、已薦購圖書的展示、取消薦購、薦購反饋。
- 薦購圖書,讀者在概要信息頁面和詳情頁面都要能薦購圖書,薦購圖書可選薦購理由,有薦購理由的圖書館可以優(yōu)先處理。
- 已薦購圖書的展示,在圖書的詳細(xì)頁面展示該書已被薦購的次數(shù),在讀者個人信息頁面展示該讀者已薦購的圖書列表。
- 讀者能夠取消已薦購的圖書,取消薦購后該書的薦購次數(shù)相應(yīng)減少。
- 薦購反饋,圖書館可以對被薦購圖書進(jìn)行處理,包括已接受薦購、正在購買中、圖書已到館、圖書已上架和未采納薦購,并給出未采納的理由。
首先實現(xiàn)用戶薦購圖書的功能,由于考慮到移動端用戶,讀者薦購圖書的地方改為只在詳情頁面薦購。在詳情頁面的前臺要做一個用戶的權(quán)限判斷,如果是新注冊用戶,提醒用戶完善個人信息后再薦購。用戶完善個人信息后,等待圖書管理員審核通過后即可薦購圖書。在用戶點擊薦購按鈕后,系統(tǒng)首先查重館藏是否存在該圖書,如果已經(jīng)存在圖書,則提醒讀者查詢館藏,如果館藏沒有圖書,則提醒用戶薦購成功,并將該圖書的id和讀者的id保存到圖書薦購表recommend中。
還存在一種表單薦購的情況,即讀者查詢不到想要薦購的圖書,可以通過填寫表單的方式薦購圖書。如下圖

表單薦購除了要保存讀者的薦購信息,還要保存薦購的圖書信息,例如讀者填寫了書名、作者、出版社等信息,需要將這些信息保存到圖書信息表book_info中。
下面開始實現(xiàn)圖書薦購的功能,首先定義模型文件models.py。
from django.db import models
from user.models import MyUser
from book.models import Book_info
class Recommend(models.Model):
rec_id = models.AutoField('序號', primary_key=True)
rec_reason = models.CharField('薦購理由', null=True, blank=True, max_length=150)
rec_feedback = models.CharField('薦購反饋', default='處理中', max_length=150)
user_id = models.ForeignKey(MyUser,on_delete=models.CASCADE, blank=True, null=True, verbose_name='薦購用戶')
book_id = models.ForeignKey(Book_info ,on_delete=models.CASCADE, blank=True, null=True, verbose_name='圖書')
class Meta:
verbose_name = '圖書薦購'
verbose_name_plural = '圖書薦購'
這里將薦購反饋設(shè)為默認(rèn)“處理中”,然后外鍵user_id和book_id分別關(guān)聯(lián)用戶信息表MyUser和圖書信息表Book_info。
然后到圖書詳情頁的模板book_detail.html中做如下修改:
book 下的 book_detail.html
{% if perms.recommend.add_recommend %}
<a href="{% url 'recommend' %}?book_id={{ book_details.book_id }}">
<button type="submit" class="btn btn-primary btn-block">薦購</button>
</a>
{% else %}
<div class="alert alert-warning">請到個人中心完善資料后再薦購圖書</div>
{% endif %}
上面的模板中,首先通過perms.recommend.add_recommend對用戶的權(quán)限做了一個判斷,如果有權(quán)限才顯示薦購按鈕,如果沒有則顯示對應(yīng)的提示信息。
薦購按鈕的url地址我們通過GET方法將圖書的book_id傳給后面。
接著,需要到recommend下的urls.py定義上面的url地址信息。
urlpatterns = [
path('recommend.html', views.recommendView, name='recommend'),
]
然后就是編寫對應(yīng)的視圖函數(shù)recommendView了。
#recommend 的 views.py
from django.shortcuts import render,redirect
from .models import Recommend
from book.models import Book_info
from user.models import MyUser
from book.forms import commendbookForm
from django.contrib.auth.decorators import login_required, permission_required
import re, requests
#館藏查重,如果館藏存在圖書則返回True,否則返回False
def checkBook(isbn):
try:
lib_url = 'http://192.168.1.9:8080/opac/openlink.php?strSearchType=isbn&strText={}'.format(isbn)
r = requests.get(lib_url, timeout=5)
try:
result = re.findall('<p style="font-size:14px;">檢索到 <strong class="red">(.*?)</strong> 條',r.text)[0]
if result:
return True
except:
return False
except:
return False
#處理薦購
@login_required(login_url='/user/login.html')
def recommendView(request):
username = request.user.username
userinstance = MyUser.objects.get(username=username)
#如果是POST請求,說明是用戶在填寫薦購表單
if request.method == 'POST':
#如果用戶提交了圖書的isbn則查重圖書
try:
#調(diào)用checkBook函數(shù)檢查館藏,如果館藏已有則提示,否則返回False,執(zhí)行except部分
if checkBook(request.POST.get('book_isbn')):
message="館藏已有該書,請查看館藏書目"
return render(request, 'recommend.html', {'message':message})
else:
return Flase
except:
#實例化薦購表單模型,傳入POST請求的值
commendbook = commendbookForm(request.POST)
#如果通過表單驗證,將薦購的圖書信息保存到數(shù)據(jù)表book_info中
if commendbook.is_valid():
commendbook.save()
message = '薦購成功!'
#這里因為有外鍵約束,直接向Recommend模型中插入數(shù)據(jù)不行的,而要插入外鍵關(guān)聯(lián)的模型對象
user_id = MyUser.objects.get(id=userinstance.id)
book_id = Book_info.objects.get(book_id=Book_info.objects.last().book_id)
#將用戶的user_id和圖書的book_id插入到薦購信息表Recommend中
#如果有薦購理由rec_reason,則一并插入
if request.POST.get('rec_reason'):
rec_reason = request.POST.get('rec_reason')
r = Recommend(user_id=user_id, book_id=book_id, rec_reason=rec_reason)
r.save()
else:
r = Recommend(user_id=user_id, book_id=book_id)
r.save()
return render(request, 'recommend.html', {'message':message})
#否則是GET請求,GET請求有兩種情況,一種是瀏覽,一種是用戶在圖書詳情頁點擊薦購
else:
#通過獲取GET請求中是否有book_id參數(shù)來判斷是不是薦購
if request.GET.get('book_id'):
user_id = MyUser.objects.get(id=userinstance.id)
book_id = Book_info.objects.get(book_id=request.GET.get('book_id'))
book_isbn = Book_info.objects.get(book_id=request.GET.get('book_id')).book_isbn
if checkBook(book_isbn):
message ="館藏已有該書,請查看館藏書目"
return render(request, 'recommend.html', locals())
else:
Recommend.objects.create(user_id=user_id, book_id=book_id)
message = '薦購成功!'
return render(request, 'recommend.html', locals())
else:
return redirect('/user/login.html')#跳轉(zhuǎn)到登錄頁面
上面的代碼中首先定義了一個簡單的查重函數(shù)checkBook,通過傳入的參數(shù)isbn進(jìn)行查重。處理薦購的視圖函數(shù),首先做一個登陸驗證,然后判斷是GET請求還是POST請求,如果是POST請求則說明是用戶的表單薦購,需要額外保存圖書信息,如果是GET請求,則獲取GET請求的參數(shù)book_id,查重后做相關(guān)處理。
涉及到圖書薦購還有圖書館管理員對圖書薦購的處理,我們到下一章繼續(xù)。