全網第一篇系列講述Django線上項目實戰的文章。前端
上一篇咱們主要完成了Gua的API很簡單的GET操做,那麼這一節,咱們要說這麼幾個東西:正則表達式
若是你關注了『皮爺擼碼』公衆號,而且從公衆號裏面得知了代碼的下載地址,下載代碼以後,會看到一個config/config.json
文件,別慌,這個是皮爺故意這麼寫的。目的就是:數據庫
不過,爲了讓你們讀懂代碼,我會在config/config.json
文件裏面對應的key添加一些解釋說明的。django
咱們在上一篇文章討論了RESTful API的設計規範,可是在前一篇文章,咱們的接口只是很簡單的:json
http://127.0.0.1:8000/gua?checkNum=111111複製代碼
這個不符合咱們的規範啊,咱們的規範,至少應該是長這個樣子的:後端
http://127.0.0.1:8000/v1/api/gua?checkNum=111111複製代碼
那麼,咱們今天就來實現這樣的接口。api
首先,仍是須要來修改咱們的urls.py
文件,將以前的:bash
from apps.Gua.views import GuaViewurlpatterns = [ path('admin/', admin.site.urls), path('gua', GuaView.as_view()),]複製代碼
改爲服務器
from django.urls import path,includeimport apps.Guaurlpatterns = [ path('admin/', admin.site.urls), path('v1/api/gua', include('apps.Gua.urls')),]複製代碼
這裏看到,有一個include()
的東西,顯然,這裏的代碼的意思就是,咱們須要在apps/Gua/
目錄下面,也建立一個urls.py
文件,咱們建立好,須要在這裏面添加如下代碼:微信
from django.urls import pathfrom .views import GuaViewurlpatterns = [ path('', GuaView.as_view()) ]複製代碼
你看,這裏咱們是否是把上一節課的URL給拆成了兩個部分來解析?放到兩個文件裏面作處理。
可是,這裏寫的這個:
path('', GuaView.as_view())複製代碼
實際對應的URL是:
http://127.0.0.1:8000/v1/api/gua複製代碼
咱們其實仍是須要後面的checkNum
的,可是,爲了符合RESTful API的規範:若是要訪問單個資源,請將資源ID也放入到URL中,那麼,這個正確的URL就應該是:
http://127.0.0.1:8000/v1/api/gua/111111複製代碼
想要實現這樣,不難啊,只須要將以前的那個path
改爲:
path('/<str:check_num>', GuaView.as_view())複製代碼
同時,咱們的GuaView
裏面的get()
方法,也得作一些修改,將check_num
做爲參數傳進去:
def get(self, request, check_num): #下面的邏輯代碼省略,只須要注意第三個參數check_num就能夠複製代碼
好了,這個部分就匹配成功了。其實合起來,咱們是經過:
path('v1/api/gua/<str:check_num>', GuaView.as_view())複製代碼
來匹配URL:
http://127.0.0.1:8000/v1/api/gua/111111複製代碼
只不過爲了靈活性和擴展性,咱們拆開來了。
接着,確定會有小夥伴問<str:check_num>
這是個啥?
其實,這個是Django的路由機制。格式就是:
<類型:變量名>複製代碼
轉換格式類型 | 說明 |
---|---|
str | 匹配除分隔符(/)外的非空字符,默認類型等價於 |
int | 匹配0和正整數 |
slug | 匹配字母、數字、橫槓、下劃線組成的字符串,str的子集 |
uuid | 匹配格式化的UUID,如075194d3-6885-417e-a8a8-6c931e272f00 |
path | 匹配任何非空字符串,包括路徑分隔符,是全集 |
一樣,URL的匹配還支持正則表達式。
之後若是想要擴展本身的API的話,別忘了使用RESTful 規範。
上一篇咱們的數據返回,是在數據庫裏面拿到數據,通過了一層序列化,把數據轉換成Json格式,而後直接返回的,其實,在RESTful規範裏面,這樣作有些不妥,全部的數據,都應該放到data
裏面,這裏咱們就來簡單實現一下這個。
來到Gua/views.py
文件裏面,把咱們的GuaView
的get()
方法作一些調整就好。皮爺這裏僅僅只是作了簡單的修改,其實應該考慮到各類狀況,各類錯誤的處理,不一樣錯誤還應該有不一樣的錯誤代碼等等。咱們目前就先簡單來作一下:
def get(self, request, check_num): response = {'code': 200} result = Gua.objects.filter(gua_serial=check_num).first() if result is None: response['code'] = '100090' response['msg'] = 'search_failed' return Response(data=response, status=200) response['msg'] = 'success' serializer = GuaSerializer(result) response['data'] = serializer.data return Response(data=response, status=200)複製代碼
能夠看到,在最後的Response()
裏面的data
, 咱們傳入了一個dict()
類型的數據,這個數據是咱們本身封裝好的。最後的返回結果以下圖:
能夠看到,搜搜結果數據是在data
裏面放着。
其實,對於一個後端程序來講,POST的方法和GET方法都是很常見的,咱們以前,在GuaView
裏面編寫的get()
方法,其實就是對應的GET method。對於一些操做,咱們須要將數據存儲到服務器上,這個時候,咱們就要使用POST方法了。那麼,實現POST方法其實也很簡單,只須要編寫對應的post()
方法就能夠了。
常規來講,POST的請求,若是請求成功,服務器須要將存儲的數據返回到前端,以表示請求成功。這裏,我就來列舉代碼中的一個post()
方法,來給你們說一下寫post有哪些注意的地方:
# 這裏的model之類的就都先省略了,直接來講方法 def post(self, request): app_version = request.data.get('appVersion') checkNum = request.data.get('checkNum') gender = request.data.get('gender', "") fromPage = request.data.get('fromPage') gua_r = GuaRModel() gua_r.appVersion = app_version gua_r.checkNum = checkNum gua_r.gender = gender gua_r.fromPage = fromPage year = str(datetime.datetime.now().year) month = str(datetime.datetime.now().month).zfill(2) day = str(datetime.datetime.now().day).zfill(2) gua_r.dayTime = "{}{}{}".format(year, month, day) gua_r.guaName = Gua.objects.filter(gua_serial=checkNum).first().gua_title result = gua_r.save() response = {} if result is None: response['code'] = '100093' response['msg'] = 'Report failed' return Response(datetime=response) response['code'] = '200' response['msg'] = 'success' serializer = GuaReportSerializer(gua_r) response['data'] = serializer.data return Response(data=response)複製代碼
能夠看到,這個方法首先是來處理POST請求傳過來的那些參數的值。而後,建立一個咱們須要存儲的類,再將這些數值賦給它,最後調用一個model.save()
方法就好,最後在把剛纔的數據序列化,返回到前端就好。是否是很簡單啊?固然,這裏只是最簡單的POST操做,POST還有不少複雜的操做,之後慢慢給你們道來。
Restframework的分頁有好幾種實現方式:
settings.py
中直接設置;PageNumberPagination
實現分頁;LimitOffsetPagination
實現分頁;CursorPagination
實現分頁。這裏,皮爺使用的是自定義PageNumberPagination
來實現的分頁。
首先,咱們先來收一下如何在settings.py
裏面,只須要直接加入如下配置就能夠:
# rest framework系統自帶的分頁REST_FRAMEWORK = { # 分頁 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', # LimitOffsetPagination 分頁風格 'PAGE_SIZE': 30, # 每頁多少條記錄}複製代碼
接下來,咱們說一下如何自定義PageNumberPagination
來實現的分頁。
咱們在Gua/views.py
裏面,首先寫一個class,繼承PageNumberPagination
:
from rest_framework.pagination import PageNumberPaginationclass GuaRPagination(PageNumberPagination): page_size = 30 # 表示每頁的默認顯示數量 page_size_query_param = 'page_size' # 表示url中每頁數量參數 page_query_param = 'page' # 表示url中的頁碼參數 max_page_size = 100 # 表示每頁最大顯示數量,作限制使用,避免忽然大量的查詢數據,數據庫崩潰複製代碼
而後,咱們只須要在須要分頁的地方,這麼寫就能夠:
def get(self, request,*args,**kwargs): response = {'code': 200} result = GuaRModel.objects.all() response['msg'] = 'success' response['size'] = len(result) # 如下幾行代碼是關鍵 pg = GuaRPagination() page_role = pg.paginate_queryset(queryset=result, request=request, view=self) serializer = GuaReportSerializer(page_role, many=True) response['data'] = serializer.data return Response(data=response, status=200)複製代碼
由於咱們在GuaRPagination
裏面定義了請求URL裏面能夠攜帶分頁的參數:page
和page_size
,分別表示請求第幾頁內容
和當前頁面最大顯示條數
。因此,咱們的請求URL就能夠變成這個樣子:
# 表示請求第三頁,每頁最大顯示10條數據http://127.0.0.1:8000/v1/api/gua/list?page=3&page_size=10複製代碼
好比測試,咱們若是請求如下接口:
http://127.0.0.1:8000/v1/api/gua/list?page=3&page_size=6複製代碼
那麼應該表示的是第三頁,而且顯示的是六條數據:
看到,是否是這樣?哈哈哈哈啊。
好了,今天說的內容不少,接口還有不少內容,好比權限管理啊等等,這些我往後都會說道。皮爺只有一個宗旨:就是要讓你經過個人這個系列的文章,可以開發出來一套完整的系統。
這些全部代碼,我都會上傳到GitHub上,獲取方式就是請關注微信公衆號『皮爺擼碼』,而後回覆『網站代碼』便可得到連接地址。
好了,系列文章今天這一章節就先說到這裏,正好立刻就要雙11了,又到了一年一度買服務器的時候了。照目前的趨勢,皮爺今年確定又會購買服務器了,服務器是真的不嫌多啊,一臺服務器能夠寫網站,兩臺服務器就能夠玩 RPC,三臺能夠搞集羣。。。
下面這個連接你們能夠在雙十一的時候在阿里雲享受優惠,注意,每一年就此一次,錯過了可就要等一年的哦:
https://www.aliyun.com/1111/2019/group-buying-share?ptCode=59102A206508DC8B402167FFD766D480647C88CF896EF535&userCode=nrkmbo9q&share_source=copy_link
喜歡的同窗,能夠把皮爺的文章分享出來,讓跟多的人一塊兒來學習。這個系列教程的文章,皮爺都會講源代碼放到 GitHub 上,想要獲取代碼的同窗,請關注微信公衆號『皮爺擼碼』,而後回覆『網站代碼』便可得到連接地址。這裏有更多更好玩的東西,等你一塊兒來學習提升。