Django REST Framework Quickstart 專案
初衷
在2018年5月份接觸並搭建過基於Django的後端平臺,由於當時時間緊任務單一,很多細節也沒去深究。但是我清除地記著我是有去找過Django REST相關的解讀的,但是無果。最近有些時間,開始搭建一個較完整的基於Django的平臺,結果發現“毒”還在,看來只能自制“解藥”了。因為離上一次寫類似部落格的東西已經很久了,所以語言組織已經退化,不求寫清楚了,但求和我一樣的入門者有一個可聊的話題。
建立工程,新增一個應用
基於virtualenv建立工作環境,遠離python版本管理的煩惱
virtualenv -p /usr/local/bin/python3 py3envsource py3env/bin/activate pip install django pip install djangorestframework
建立工程和應用
django-admin.py startproject tutorial .cd tutorial django-admin.py startapp quickstart
預設使用sql資料庫初始化資料庫設定
python manage.py migrate
建立管理員賬號
python manage.py createsuperuser
關於Quickstart
這是一個官方的demo:, 目的是為了向開發者展示該元件的易用性,但是立足點似乎有點高,作為剛剛開始接觸Django並想要了解REST元件的同學來說,這個例子的文件比較晦澀,而且絕大部分資料也只是對官方文件的翻譯。該demo的功能,是實現一套簡單的api(含檢視),用於管理員檢視和編輯Django的使用者和組資訊。
瞭解流程
由於Django本身是MVC(MVT)結構,便於開發,但不便於入門理解,簡單地說,就是不便於在入門時理解Demo程式碼中的關聯性。
-
Django的MTV模組
M:負責業務和資料庫的關係對映
T:負責如何把html頁面展示給使用者
V:負責業務邏輯,呼叫M和T(MVC中C的角色)
-
Django對請求的處理流程並不是僅僅MTV三個模組
Django處理流程
其實從WSGI以後,都算作Django的工作範圍,WSGI透過呼叫Django中的Django.core.wsgi的入口方法(wgsi.py檔案)以後,就將請求的資料結構傳遞給Django的各種中介軟體,具體會流經哪些中介軟體?可見setting.py中的MIDDLEWARE配置(跨域過濾之類的一般會設定在中介軟體中) -
Django app內部的流程會相對清晰一些:
透過model與資料庫對話
使用模板渲染HTML或者任何格式化過的響應
返回一個純文字響應(不被顯示的)(API)
URLconf是指urls.py選擇一個檢視來處理請求
被選擇的那個檢視通常要做下面所列出的一件或者更多件事情:
返回response
額外的重點:序列化
序列化和反序列化的目的就是物件和傳輸資料(或是儲存資料)之間的轉換。Django本身和Django REST 元件都提供了序列化的輔助類,目的是為了簡化程式碼(可以想象一下JAVA裡的序列化操作,雖然有工具可以生成程式碼),特別是ModelForm、ModelSerializer這些類,可以透過直接連線model模組,完成序列化和反序列化的工作。序列化功能的實現,往往是實現功能的第一步。我們可以理解成資料流驅動了編碼順序。
序列化:物件 -> 位元組序列(資料庫或者response)
反序列化:位元組序列 -> 物件
從上面的描述上看,序列化功能類一般會用在連線model、return response,以及資料庫操作上。
再看Demo程式碼
1、真正的第一步應該是設計並建立資料庫,而demo是要實現專案使用者的操作,使用了自帶的使用者資訊所在資料庫。
2、實現序列化功能
在知道後端有什麼(資料庫),前端要什麼之後,我們就可以設計序列化功能。因為資料庫有什麼我們就可以知道應該反序列出來什麼,前端要什麼,我們就知道需要序列化到response什麼內容了。
Django提供了通用的serializers、ModelSerializer、HyperlinkedModelSerializer等封裝等級不同和型別不同的序列化器輔助類,唯一的區別就是簡化程式碼的程度不同,如果對序列化的具體操作不熟悉
from django.contrib.auth.models import User, Groupfrom rest_framework import serializersclass UserSerializer(serializers.HyperlinkedModelSerializer): """ 使用者資訊的序列化器(根據前端需要的資料資訊來組織結構) """ class Meta: model = User fields = ('url', 'username', 'email', 'groups')class GroupSerializer(serializers.HyperlinkedModelSerializer): """ 組資訊的序列化器 """ class Meta: model = Group fields = ('url', 'name')
3、實現View
這個Demo變得晦澀難懂的一大原因就是直接用了最簡潔的程式碼方式,這裡的viewsets就是其中之一,包括上面HyperlinkedModelSerializer。差別之處可以參考:
""" View中,必然會看到model(運算元據庫)和序列化器(組織response內容) """from django.contrib.auth.models import User, Groupfrom rest_framework import viewsetsfrom quickstart.serializers import UserSerializer, GroupSerializerclass UserViewSet(viewsets.ModelViewSet): """ 處理檢視、編輯使用者的介面 """ queryset = User.objects.all().order_by('-date_joined') serializer_class = UserSerializerclass GroupViewSet(viewsets.ModelViewSet): """ 處理檢視、編輯使用者組的介面 """ queryset = Group.objects.all() serializer_class = GroupSerializer
為了理解這些晦澀的用法,還是總結下,Django Rest對檢視寫法的精簡可以一步步歸納為:
1、使用常規方式實現,最顯式的實現方式,也是最好理解的方式:(讀取資料庫位元組序列->反序列化->序列化後response)
@csrf_exemptdef snippet_list(request): """ 展示所以snippets,或建立新的snippet. """ if request.method == 'GET': snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) return JSONResponse(serializer.data) elif request.method == 'POST': data = JSONParser().parse(request) serializer = SnippetSerializer(data=data) if serializer.is_valid(): serializer.save() return JSONResponse(serializer.data, status=201) return JSONResponse(serializer.errors, status=400)
2、使用基於函式檢視的@api_view裝飾器,加快實現
@api_view(['GET', 'POST'])def snippet_list(request): """ 展示或建立snippets. """ if request.method == 'GET': snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) return Response(serializer.data) elif request.method == 'POST': serializer = SnippetSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
3、使用基於類檢視的APIView
class SnippetList(APIView): """ List all snippets, or create a new snippet. """ def get(self, request, format=None): snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) return Response(serializer.data) def post(self, request, format=None): serializer = SnippetSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
4、基於ViewSets的抽象行為(配合Routers實現),該方法也可以簡化urlconf,所以這可能就是Django生態的好處,讓我們更加關注api的互動,但是這之前還是需要清楚這些方法的演變過程。從這個角度上看,讀了N遍官方文件之後,能發現官方真正想要傳達的意思。
class SnippetViewSet(viewsets.ModelViewSet): """ This viewset automatically provides `list`, `create`, `retrieve`, `update` and `destroy` actions. Additionally we also provide an extra `highlight` action. """ queryset = Snippet.objects.all() serializer_class = SnippetSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,) @detail_route(renderer_classes=[renderers.StaticHTMLRenderer]) def highlight(self, request, *args, **kwargs): snippet = self.get_object() return Response(snippet.highlighted) def perform_create(self, serializer): serializer.save(owner=self.request.user)
4、實現urlpatterns
使用viewsets和router後,由於封裝處理了“get”、“post” 等預設動作,所以在url.py指出特定的uri便可,這就是所謂的RESTFul,因為所有的“動作”都沒有暴露到api的命名中。
from django.contrib import adminfrom django.urls import pathfrom django.conf.urls import url, includefrom rest_framework import routersfrom quickstart import views router = routers.DefaultRouter() router.register(r'users', views.UserViewSet) router.register(r'groups', views.GroupViewSet)# 使用URL路由來管理我們的API# 另外新增登入相關的URLurlpatterns = [ url(r'^', include(router.urls)), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), path('admin/', admin.site.urls), ]
5、執行測試。
python manage.py runserver
便可看到一套自帶介面的api,一開始可能會有疑問,說好是寫一套apis的,怎麼成了一個介面了,其實就是Django MTV的福利(自帶doc有沒有),大家試著去訪問: ,就能看到一個正常的介面返回了。
執行結果
作者:蘿蔔日誌
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/132/viewspace-2818823/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- django rest framework(4)DjangoRESTFramework
- Django REST framework 分頁DjangoRESTFramework
- django rest framework serializers小結DjangoRESTFramework
- Django rest framework之ModelSerializDjangoRESTFramework
- Django REST framework完全入門DjangoRESTFramework
- django rest_framework面經DjangoRESTFramework
- Django REST framework API 指南(21):SchemasDjangoRESTFrameworkAPI
- 深度解析Django REST Framework 批量操作DjangoRESTFramework
- django rest framework mixins小結DjangoRESTFramework
- Django REST framework API 指南(8):渲染DjangoRESTFrameworkAPI
- Django REST framework API 指南(6):路由DjangoRESTFrameworkAPI路由
- Django REST framework API 指南(7):解析DjangoRESTFrameworkAPI
- Token認證——Django Rest framework(1)DjangoRESTFramework
- Django REST framework API 指南(15):限流DjangoRESTFrameworkAPI
- Django REST Framework中的Serializer relationsDjangoRESTFramework
- 管理平臺模板 Django REST Framework +ElementUIDjangoRESTFrameworkUI
- Django REST framework API 指南(18):版本控制DjangoRESTFrameworkAPI
- Django REST framework API 指南(17):分頁DjangoRESTFrameworkAPI
- View + django-rest-framework序列化ViewDjangoRESTFramework
- django rest framework 檢視原始碼解析DjangoRESTFramework原始碼
- Django REST framework API 指南(1):請求DjangoRESTFrameworkAPI
- Django REST framework API 指南(2):響應DjangoRESTFrameworkAPI
- django rest framework apiview、viewset總結分析DjangoRESTFrameworkAPIView
- Django REST framework API 指南(3):檢視DjangoRESTFrameworkAPI
- Django REST framework API 指南(23):返回 URLDjangoRESTFrameworkAPI
- Django REST framework API 指南(24):異常DjangoRESTFrameworkAPI
- Django REST framework API 指南(26):測試DjangoRESTFrameworkAPI
- Django REST framework API 指南(27):SettingsDjangoRESTFrameworkAPI
- Django REST framework API 指南(16):過濾DjangoRESTFrameworkAPI
- Django REST framework API 指南(13):認證DjangoRESTFrameworkAPI
- Django-rest-framework 是個什麼鬼?DjangoRESTFramework
- Django REST framework API 指南(5):檢視集DjangoRESTFrameworkAPI
- 快用Django REST framework寫寫API吧DjangoRESTFrameworkAPI
- Django REST framework的請求與響應DjangoRESTFramework
- Django REST framework API 指南(4):通用檢視DjangoRESTFrameworkAPI
- Django REST framework API 指南(22):Format 字尾DjangoRESTFrameworkAPIORM
- Django REST framework API 指南(25):狀態碼DjangoRESTFrameworkAPI
- Django REST framework API 指南(9):序列化DjangoRESTFrameworkAPI