本文作者:Eric
作者 Github : https://github.com/Ratherman
自由團隊將從0到1 手把手教各位讀者學會(1)Python基礎語法、(2)Python Web 網頁開發框架 – Django 、(3)Python網頁爬蟲 – 周易解夢網、(4)Tensorflow AI語言模型基礎與訓練 – LSTM、(5)實際部屬AI解夢模型到Web框架上。
AI . FREE Team 讀者專屬福利 → Python Basics 免費學習資源
探討 Django Chatterbot 是如何運作的。
我們在昨天的內容將 Django Chatterbot 的專案 clone 到自己的本地端,並且做了一些調整,最後將專案 Run 了起來。隨著文章一天一天走來,我們都已經具備基本的 Django 開發能力,今天我們就會在了解 Chatterbot 是如何在 Django 運作的。
首先,從專案的結構開始看,假設大家也是使用 VScode 開啟昨天的 Django Chatterbot 專案,可以發現在左側的 panel 看到像是下方的架構:
example_app/
init.py
settings.py
urls.py
views.py
wsgi.py
static/
css/ ...
img/ ...
js/ ...
templates/
app.html
nav.html
同樣都是 Django Project,不過我們還是可以拿現在的 Django Chatterbot 和之前我們一連開發一周以上的 DI_project (Hashtag 古人 和 學派)比對一番。
首先大家可以發現本專案是一個 APP,而他具備所有 Django Project 所需要的元素,所以也可以視為一個完整的 Django Project;和 DI_project 不同,我們是在 DI_project 當中又建立的一個附屬於 DI_project 的 APP,DI_project/demo_app/urls.py 設定需要 DI_project/urls.py 寫一個 path object include 進來。
一樣有 templates/
目錄,在裡面就會放 views.py 將會 render 出來的模板。
一樣有 static/
目錄,只是在其中還有在細分成 css/
目錄、img/
目錄、js/
目錄,我們當初 css 的部分是直接 introduce 一個 remote 的 bootstrap css,所以沒有看到實體的檔案,這邊 css/
裡面裝的 css file 其中一個就是 bootstrap.css。
大家可以看到 settings.py 內部有註冊的 app 有兩行不是原本預設的 app。
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'chatterbot.ext.django_chatterbot', 'example_app', )
其中的chatterbot.ext.django_chatterbot
,是因為有利用到 chatterbot 的套件;另一個 example_app
則為 APP 的命名,回顧在 DI_project 當中的 settings.py 是還有透過 demo_app/apps.py 才將 app 註冊進 INSATLLED_APPS 裡面。
這邊大家會看到,其寫法好像跟之前用到的不太一樣。
... urlpatterns = [ url(r'^$', ChatterBotAppView.as_view(), name='main'), url(r'^admin/', admin.site.urls, name='admin'), url(r'^api/chatterbot/', ChatterBotApiView.as_view(), name='chatterbot'), ]
可以改寫成下面這個樣子,一樣在 run server 時一切順利
... from django.urls import path urlpatterns = [ #url(r'^$', .as_view(), name='main'), #url(r'^admin/', admin.site.urls, name='admin'), #url(r'^api/chatterbot/', ChatterBotApiView.as_view(), name='chatterbot'), path('', ChatterBotAppView.as_view(), name='main'), path('admin/', admin.site.urls, name='admin'), path('api/chatterbot/', ChatterBotApiView.as_view(), name='chatterbot'), ]
不過,原本寫法的 url()
內是什麼意思呢?首先 r 表示的就是 正則表示法(Regular Expression),通常會利用這樣的技巧來索引出符合句法規則的內容,像是 ^
表示字串最前面應該要是什麼內容;而 $
表示字串最後面應該是什麼,所以 r'^$'
表示的就是 空字串。
而第三個的 r'api/chatterbot/'
因為沒有 $
的限制,所以其實在 server run 起來之後,瀏覽器中使用以下3種url都會得到相同的結果(參考下圖)。
可以在 url object (或是 path object,兩者做的事情很類似),看到以下結論:
http://127.0.0.1:8000/ 這個 url 會對應到 views.py 的 ChatterBotAppView
class
http://127.0.0.1:8000/api/chatterbot/ 這個 url 會對應到 views.py 的 ChatterBotApiView
class
http://127.0.0.1:8000/admin 這個則是會連動到之前也有提到 Django Admin 介面
剛好在上面提到 Django Admin,相信大家在昨天的操作內容中有稍微和 chatbot 聊過天了,我們聊天的內容其實會被存在資料庫當中,而最快速可以看到資料庫內容的方式就是透握 Django Admin 的 GUI 介面看了。所以有興趣看看自己昨天和 chatbot 聊什麼的人可以跟著一起這樣做。
python manage.py createsuperuser
設定帳號、信箱、密碼
python manage.py runserver
開啟瀏覽器至 http://127.0.0.1:8000/admin
輸入 superuser 的帳號密碼
點選介面的 statements(參考下圖) 這樣就可以看到過去的聊天訊息了喔!
之前在 DI_project 中我們在兩個自己開發的 app (i.e. demo_app 和 front_end)當中的 views.py 都只有用到 def
based 的方式構成 view;而在現在 example/ views.py 中,則還有拉高一個層級,使用到了不同的 class
去構成 view,所以是屬於 class
based 的 view。
class ChatterBotAppView
在這裡簡單的就使用了一行帶過,原因是因為,它把大部分的邏輯處理寫進了 templates, static/js/ 內。
ChatterBotApiView
這邊的內容相較之下多了很多,不過主要就包含 def post
和 def get
兩個 HttpRequest 的邏輯處理。在這裡的內容大家應該不陌生,因為我們有一起使用過 Django Rest Framework 開發學派增刪改查的 API,所以對於收到 HttpRequest
以及利用 serialize
回傳 JSON
形式的資料也就都不陌生了。
剛剛在第四部份提到 app.html 會處理相對多的邏輯,所以我們就先來看看 example_app/templates/app.html,我們看的到 html 文件的基本架構(最開始引入 css、中間是靜態的 html 內容、下方引入js的部分)。在這邊,除了 introduce 工具層級的 js 檔之外(見下方),
... <script src="{% static 'js/jquery.js' %}"></script> <script src="{% static 'js/js.cookie.js' %}"></script> <script src="{% static 'js/bootstrap.js' %}"></script> ...
另外,還有將 JavaScript 處理邏輯的部分放進 <script></script>
內部,我們在 DI_project/front_end 開發時,是將 JavaScript 處理邏輯的部分獨立出一個檔案,然後再 introduce 進 html 檔案裡面,和這邊不太一樣,不過兩種方式都可以行的通。
其中關於 credential 的 csfr token,在這邊提供了第二種方式可以去避免在請求 server 時回傳 403 Forbidden 的訊息。
var csrftoken = Cookies.get('csrftoken'); function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } });
在 templates/app.html 當中有引用 JQuery 的 Library,所以在 <script></script>
當中可以看到不少 $(".class_name")
的結構,在這邊如果是用.
那後面就要接 class 的名字;之前是使用#
,是因為後面接的是 id。
... var $chatlog = $('.js-chat-log'); var $input = $('.js-text'); var $sayButton = $('.js-say'); ...
最後我們也看到了 AJAX 的 POST Request,其中 AJAX 內部的結構相信大家也不陌生了。一個完整的 AJAX 需要包含 Request type、 Request url、POST 給 API 的 data 是什麼,而最後一個之前沒有提到的是 contentType,這個是用來告訴 API,我們傳給它的資料格式為何,在這邊就是 JSON 形式。
... var $submit = $.ajax({ type: 'POST', url: chatterbotUrl, data: JSON.stringify(inputData), contentType: 'application/json' }); ...
具備 python basic 的基礎、Django 開發的經驗後,相信各位隨著這篇文章的導讀,也能夠知道這整個 Django 專案是如何運作的了,大家可以再好好看看 app.html 其他 call function 的部分,這邊就不細講了。
我們今天一起看了 Django Chatterbot 專案內部結構以及所包含的程式碼內容,發現這個 Project 和之前我們開發的 DI_project 在概念上有些相似。當今天有一個在本地端網頁可以順利地的 run 起來服務之後,下一步會想要做的事情就是將服務分享給網路上的其他人使用。在明天,我們會和大家一起研究,要如何才能將服務放在網路上讓大家一起用了!
自由團隊 官方網站:https://aifreeblog.herokuapp.com/
自由團隊 Github:https://github.com/AI-FREE-Team/
自由團隊 粉絲專頁:https://www.facebook.com/AI.Free.Team/
自由團隊 IG:https://www.instagram.com/aifreeteam/
自由團隊 Youtube:https://www.youtube.com/channel/UCjw6Kuw3kwM_il39NTBJVTg/
文章同步發布於:第十二屆 IT 挑戰賽部落格