RESTful風格下或油,比較充分的利用了HTTP1.1標準中規(guī)定的集中請求方式
l GET:用于提交向服務器獲取數(shù)據(jù)的請求
l POST:用于提交數(shù)據(jù)給服務器進行數(shù)據(jù)更新的請求
l PUT:用于提交數(shù)據(jù)給服務器進行數(shù)據(jù)添加的請求
l DELETE:用于提交給服務器刪除條件數(shù)據(jù)的請求
在這樣的處理風格下,目前更加適合項目開發(fā)并且成本較低的一種比較流行的開發(fā)模式:項目的前后端分離結(jié)構(gòu)模型的優(yōu)勢更加突出,通過RESTful風格指定的格式定義不同的數(shù)據(jù)處理的請求方式,后端只需要提供對應的接口,前端視圖部分負責調(diào)用進行數(shù)據(jù)展示洲劣;數(shù)據(jù)的交互全部交給異步調(diào)用進行實現(xiàn),能最大程度的發(fā)揮項目開發(fā)過程中開發(fā)人員的能力课蔬!
下面是一個基本案例[參考官方文檔整理]囱稽,了解一下RESTful在Django項目中的主要工作流程和操作方式
1. 創(chuàng)建案例項目
執(zhí)行命令創(chuàng)建項目
django-admin startproject myrest_ex02
進入項目根目錄中,執(zhí)行命令創(chuàng)建一個應用:用于進行代碼文件描述的應用
django-admin startapp snippet
2. 配置開發(fā)環(huán)境
確保在django的基礎上二跋,安裝restful需要的各種依賴包
pip install django
pip install djangorestframework # restful框架
pip install pygments # 代碼文件描述模塊
打開項目配置文件settings.py战惊,添加rest框架模塊和我們的應用程序模塊
INSTALLED_APPS = [
…… **'rest_framework'**, **'snippet.apps.SnippetConfig'**,
]
3. 數(shù)據(jù)模型定義
打開snippet應用的數(shù)據(jù)模型定義模塊models.py,添加一個定義代碼描述的類型
from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles
LEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([item[1][0], item[0]] for item in LEXERS)
STYLE_CHOICES = sorted((item, item) for item in get_all_styles())
class Snippet(models.Model):
# 創(chuàng)建時間:默認添加時間
created = models.DateTimeField(auto_now_add=True)
# 主題
title = models.CharField(max_length=100, blank=True, default='')
# 代碼片段
code = models.TextField()
linenos = models.BooleanField(default=False)
# 語法
language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
# 高亮
style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)
class Meta:
ordering = ('created',)
執(zhí)行命令將數(shù)據(jù)模型和數(shù)據(jù)庫進行數(shù)據(jù)同步
python manage.py makemigrations snippet
python manage.py migrate
4. 數(shù)據(jù)模型序列化處理
在snippet應用中扎即,添加一個序列化模塊吞获,用于進行數(shù)據(jù)模型對象的序列化操作
在myrest_ex02/snippet/目錄下創(chuàng)建文件:serializers.py
# coding:utf-8
from rest_framework import serializers
from .models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
class SnippetSerializer(serializers.ModelSerializer):
class Meta:
model = Snippet
fields = ['id', 'title', 'code', 'linenos', 'language', 'style']
PS:序列化操作本身提供了一個基本接口serializers.Serializer類型况凉,但是這個類型本身提供的實現(xiàn)機制不利于代碼的復用性,封裝的ModelSerializer更加友好的提供了序列化的實現(xiàn)方式更加友好各拷!
5. 交互測試
已經(jīng)開發(fā)好了一部分序列交互的部分刁绒,我們接下來就可以通過django shell交互方式進行數(shù)據(jù)對象的序列化操作測試了,測試通過之后繼續(xù)開發(fā)視圖部分代碼烤黍。
執(zhí)行命令進入shell交互窗口
python manage.py shell
(1) 在交互窗口中導入我們需要的模塊
from snippet.models import Snippet
from snippet.serializers import SnippetSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONPerser
(2) 添加數(shù)據(jù)到數(shù)據(jù)庫
>>> snippet = Snippet(code='name = "jerry"')
>>> snippet.save()
>>>
>>> snippet2 = Snippet(code='print("hello python")')
>>> snippet.save()
(3) 序列化對象數(shù)據(jù)
>>> serializer = SnippetSerializer(snippet2)
>>> serializer.data
{'id': None, 'title': '', 'code': 'print("hello python")', 'linenos': False, 'language': 'python', 'sty
le': 'friendly'}
>>> **serializer2 = SnippetSerializer(snippet)**
>>> **serializer2.data**
{'id': 3, 'title': '', 'code': 'name = "jerry"', 'linenos': False, 'language': 'python', 'style': 'frie
ndly'}
(4) JSON格式化序列數(shù)據(jù)
通過JSON格式化渲染的數(shù)據(jù)知市,就是最終可以交互的JSON字符串數(shù)據(jù)
>>> content = JSONRenderer().render(serializer.data)
>>>
>>> content
b'{"id":null,"title":"","code":"print(\\"hello python\\")","linenos":false,"language":"python","style":
"friendly"}'
(5) 反序列化JSON數(shù)據(jù)
反序列化在WEB應用中,主要用于解析視圖客戶端提交的JSON數(shù)據(jù)速蕊,轉(zhuǎn)化成數(shù)據(jù)對象之后進行CRUD的操作
>>> from django.utils.six import BytesIO
>>>
>>> stream = BytesIO(content)
>>> data = JSONParser().parse(stream)
>>>
>>> serializer = SnippetSerializer(data=data)
>>> serializer.is_valid()
True
>>>
>>> serializer.save()
<Snippet: Snippet object (4)>
(6) 序列化查詢結(jié)果集
在實際項目操作過程中嫂丙,我們在Django項目里面操作的往往都是QuerySet查詢結(jié)果集
對于查詢結(jié)果集的序列化處理方式如下
>>> res = SnippetSerializer(Snippet.objects.all(), many=True)
>>> res.data
[OrderedDict([('id', 1), ('title', ''), ('code', 'foo="bar"\n'), ('linenos', False), ('language', 'pyth
on'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', ''), ('code', 'print("hello world")\n'
), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title
', ''), ('code', 'name = "jerry"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])
, OrderedDict([('id', 4), ('title', ''), ('code', 'print("hello python")'), ('linenos', False), ('langu
age', 'python'), ('style', 'friendly')])]
6. 視圖函數(shù):API數(shù)據(jù)接口
經(jīng)過第5步的交互測試,已經(jīng)完成了對數(shù)據(jù)的處理方式的基本操作測試
接下來開始開發(fā)視圖交互函數(shù)规哲,也就是給其他調(diào)用的客戶端提供數(shù)據(jù)的API接口函數(shù)跟啤!
(1) 數(shù)據(jù)列表接口函數(shù)——snippet_list
打開項目應用的視圖處理模塊:snippet.views
開發(fā)數(shù)據(jù)列表接口函數(shù)
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from .models import Snippet
from .serializers import SnippetSerializer
@csrf_exempt
def snippet_list(reuqest):
if request.method == “GET”:
# 查詢所有數(shù)據(jù)
snippets = Snippet.objects.all()
# 序列化數(shù)據(jù)
serializers = SnippetSerializer(snippets, many=True)
# 返回數(shù)據(jù)
return JsonResponse(serializers.data, safe=False)
elif request.method == “POST”:
# 解析提交的數(shù)據(jù)
data = JSONParser().parse(request)
# 反解析序列數(shù)據(jù)
serializers = SnippetSerializer(data=data)
# 驗證并保存數(shù)據(jù)
if serializers.is_valid():
serializers.save()
# 返回視圖頁面
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
(2) 對象數(shù)據(jù)增刪改API接口函數(shù)開發(fā)
定義一個接口函數(shù),通過request.method直接判斷進行不同請求方式的處理
@csrf_exempt
def snippet_detail(request, pk):
# 首先查詢得到數(shù)據(jù)對象
try:
snippet = Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
return HttpResponse(status=404)
# 獲取單個數(shù)據(jù)的操作
if request.method == “GET”:
# 序列化數(shù)據(jù)
serializers = SnippetSerializer(snippet)
return JsonResponse(serializers.data)
# 提交數(shù)據(jù)的操作
elif request.method == “PUT”:
# 反解析數(shù)據(jù)
data = JSONParser().parse(request)
# 序列化操作
serializers = SnippetSerializer(data=data)
# 驗證有效性并存儲
if serializers.is_valid():
serializers.save()
# 返回視圖處理界面
return JsonResponse(serializers.data)
return JsonResponse(serializers.errors, status=400)
# 刪除數(shù)據(jù)的操作
elif request.method ==”DELETE”:
snippet.delete()
return HttpResponse(status=204)
7. 運行測試
(1) 瀏覽器測試
執(zhí)行命令運行項目
python manage.py shell
瀏覽器訪問http://localhost:8000/snippet/ 查看所有數(shù)據(jù)列表
瀏覽器訪問http://localhost:8000/snippet/1/查看指定的對象數(shù)據(jù)
|
|
其他請求方式通過工具進行測試驗證
(2) Postman測試工具
l get測試
|
|
l delete測試
|
|
再次查詢
|
|