第四章 DRF之Router 和 Serializer

Router簡單配置和映射

router = routers.DefaultRouter()

router.register("grades",GradeViewSet,"grades")

router.register("study/grades0",GradViewSetTemp,"grades0")

router.register("study/grades8",GradeGenericViewSet,"grades8")

router = SimpleRouter(trailing_slash=False)

#去除URL 尾部斜杠/

router = DefaultRouter(trailing_slash=False) #去除URL 尾部斜杠/

DefaultRouter路由器類似于上面的SimpleRouter,但是還包括一個默認返回所有列表視圖的超鏈接的API根視圖。它還生成可選的.json樣式格式后綴的路由

urlpatterns += router.urls

path('', include(router.urls)),

path('api/', include(router.urls)),

url(r'^api/', include((router.urls,'app_name'))),

url(r'^api/', include((router.urls,'app_name'), namespace='instance_name')),

Router其他Action

@action #根據(jù)Detail屬性來區(qū)分是 detail_route 還是 list_route 因此可直接用下面?zhèn)z

@detail_route? #對應的URL 一般是 grades/{pk}/方法名路徑

@list_route? ? #對應的URL 一般就是 grades/方法名路徑

http://127.0.0.1:8000/api/study/grades8/1/info/

如果不設置url_path 屬性則默認的用函數(shù)名 api/study/grades8/1/get_grade_info /

http://127.0.0.1:8000/api/study/grades8/clist/?name=高三

http://127.0.0.1:8000/api/study/grades8/clist/

自定義Router

可自定義路由,繼承SimpleRouter,比如只提供get/retrieve的映射從而達到只讀路由的目的,本例直接取自官網(wǎng),不再實驗

Serializer

修改過程,以點擊PUT為例,注意本次PUT的參數(shù)包含了id和日期

UpdateModelMixin 提供了update方法,點擊put后進入update方法。根據(jù)URL里面的pk可通過instance= self.get_object() 從數(shù)據(jù)庫查到該對象

然后獲取serializer 調用其 is_valid方法該方法會生成校驗后的validated_data

可以看到已經(jīng)沒有id和時間了,因為serializer里面定義了id和時間都是read_only=True

然后會調用serializer.save() 跳轉到 serializer 的 update方法該方法給instance的屬性賦值,然后調用 instance.save()保存入庫,然后返回改對象。

# .save() will create a new instance.

serializer = GradeSerializer(data=data)

# .save() will update the existing `grade`instance.

serializer = GradeSerializer(grade,data=data)

ModelSerializer

ModelSerializer繼承了Serializer,提供了數(shù)據(jù)庫實體類和序列化屬性的映射,并且提供了數(shù)據(jù)庫操作,增刪改。如下面的代碼就實現(xiàn)了上一節(jié)的功能

Serializer驗證

全局validate

通用方法驗證


Serializer實現(xiàn)

Serializer一對一關系

準備工作

1,修改settings文件增加媒體相關配置

MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

2,配置URL

# 配置上傳文件的訪問處理函數(shù)re_path(r'^media/(?P<path>.*)$', serve, {"document_root": MEDIA_ROOT}),

3,安裝 Pillow 用戶圖片類型的支持:

增加Model和Serializer

用 migrate 生成數(shù)據(jù)庫表后,通過配置admin后臺手動增加了一條記錄

用VUE作為前端進行增加/修改的測試

調整serializer

注意紅色圈起來的地方。開始做案例的時候,create 和 update 總是其中一個拋異常。

CREATE:? grade是外鍵,是不允許為空的,但是,ModelViewSet在接受創(chuàng)建的時候grade是沒值的,就導致直接驗證失敗,因此修改Model類,設置該值可為空。前端在創(chuàng)建的時候傳值的時候不應該給grade賦值,實際也沒法賦值。

UPDATE:? 假如不加上exclude(‘grade’)在前端接收到了grade的值,如果前端不做處理,直接返回修改,ModelViewSet在update函數(shù)里進行serializer驗證的時候會直接報錯”grade值必須唯一”,因為最終保存的方法里可以手動指定grade(并且部分方法需要grade對象而不是grade_id)因此前端并不需要返回grade值。

這里有兩種修改方式:

第一種方式是前端的修改方式就是要將grade值清空,然后再傳給后臺。

第二種方式是后臺不序列化grade,不傳給前端,也就是加上exclude(‘grade’)。

注意以下代碼的紅框部分

1, 給添加grade屬性指向Grade對象

2,? Profile的id可以直接從Grade對象的profile讀取

3,? 將Grade對象的profile重新賦值成修改保存后的profile,然后返還用于前端更新

前端頁面展示,這里先忽略圖片格式及Text格式,后面再處理:

圖片上傳

1, 安裝six

Pip install six

新建Base64ImageField

classBase64ImageField(serializers.ImageField):

完整代碼見github https://github.com/zhaorch/DRFtutorial

調整GrageSerializer

前端VUE 使用的是vue-image-crop-upload 控件

新增的時候如果不提供圖片,則需要設置圖片的logo為null 或者空,本次樣例是前端做的修改,判斷未選擇圖片時logo一定要賦值 null 或者‘’ 不能賦值成 undefined。DRF也需要做一定的修改

修改的時候由于前端使用的patch修改,也就是部分修改,所以在圖片未改變的情況下,將logo設置成 undefined 即可

富文本編輯

使用tinymce 富文本

https://github.com/aljosa/django-tinymce

pip installdjango-tinymce

INSTALLED_APPS= (

? ? ...

? ? 'tinymce',

)

urlpatterns= [

? ? ...

? ? url(r'^tinymce/', include('tinymce.urls')),

]

from tinymce.models import HTMLField

前端:

本次使用的是別人封裝好的

https://github.com/PanJiaChen/tinymce-all-in-one

需要注意一點的是,在編輯器切換綁定Model的時候需要手動指定一下該編輯器的hasChange屬性,

Serializer一對多關系

本案例做了2個多對一,區(qū)別在于:Student可以逐個添加。而StudentsGoods屬于Student的私人物品,嚴重依賴于Student因此在Student保存的時候批量增加和刪除,不單獨添加。


實體類

Serializer序列化類

StudentGoods 的 id 設置

Read_only = True :只讀,返回給客戶端,但是返回來的時候validate_data中會舍棄id屬性。Id的默認屬性就是read_only=True

Read_only=False:返回給客戶端,也會返回來,且會出現(xiàn)在validate_data中

Write_only = True:不會返回給客戶端,因此也無法修改

Write_only= Flase: 返回給客戶端,也會返回來,且會出現(xiàn)在validate_data中

Require=False:新建goods的時候驗證的時候如果不加上這個參數(shù)則會拋異常:id必須出現(xiàn)

ViewSet

Serializer多對多關系

關于Course的單表增刪改查,不再贅述,效果圖

Model

以Student 為主進行選課

Serializer

http://127.0.0.1:8000/api/students/list_student_course/

http://127.0.0.1:8000/api/students/1/set_course/

這兩個方法主體結構都是從update 方法以及 list方法復制的,但是舍棄了update方法的validate。直接使用的 request.data。

第一章 DRF概述

第二章 DRF安裝與項目創(chuàng)建

第三章 DRF之View進化論

第四章 DRF之Router 和 Serializer

第五章 DRF權限分頁查詢排序訪問限制

第六章 DRF Linux部署

第七章 DRF其他知識

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容