Django----rest framework mixins小結


引言

  mixins在drf中主要配合viewset共同使用,實現http方法與mixins的相關類與方法進行關聯。

from rest_framework import viewsets
  • 1

  在這個viewset中,只要有5類Minxin,他們與http方法對應如下: 
Mixins
下面,我們將逐個Mixins介紹!

### 1. CreateModelMixin

# 源碼 class CreateModelMixin(object): """ Create a model instance ==>創建一個實例 """ def create(self, request, *args, **kwargs): # 獲取相關serializer serializer = self.get_serializer(data=request.data) # 進行serializer的驗證 # raise_exception=True,一旦驗證不通過,不再往下執行,直接引發異常 serializer.is_valid(raise_exception=True) # 調用perform_create()方法,保存實例 self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) def perform_create(self, serializer): # 保存實例 serializer.save() def get_success_headers(self, data): try: return {'Location': str(data[api_settings.URL_FIELD_NAME])} except (TypeError, KeyError): return {}

  由上圖可以看出這個類的一個邏輯,其中,perform_create( )對serializer直接進行save保存,當在一些情境下,我們需要對perform_create( )進行重寫。 
那么我們現在可能有一個下面的需要: 
  假設現在有一個course課程model,里面維持了一個數,記錄課程收藏數,還存在一個用戶收藏userfav的model(應當有一個外鍵指向course),當一個用戶對課程進行收藏,理論上現在post進來的應該是userfav的instance,顯然,我們還需要對相應course的收藏數進行+1。 
  這個時候,我們就需要重寫perform_create( )方法!

def perform_create(self, serializer): # 重寫save的邏輯 instance = serializer.save() course = instance.course course.fav_num += 1 course.save()

  顯然,這不是唯一的解決方法,我們還可以在seriliazer進行設置,我們還可以使用drf的信號量進行解決!

2. ListModelMixin

# 源碼 class ListModelMixin(object): """ List a queryset.==> 列表頁獲取 """ def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) # 這是一個分頁功能,如果在viewset中設置了pagination_class,那么這里就會起作用 # 獲取當前頁的queryset,如果不存在分頁,返回None page = self.paginate_queryset(queryset) if page is not None: # 分頁不為空,那么不能簡單的執行Response(serializer.data) # 還需要將相關的page信息序列化在進行響應 serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data)

  ListModelMixin一般用來獲取列表頁,大多數情況下比較簡單,不需要重寫相關的方法。

3. RetrieveModelMixin

# 源碼 class RetrieveModelMixin(object): """ Retrieve a model instance.==> 獲取某一個對象的具體信息 """ def retrieve(self, request, *args, **kwargs): # 一般訪問的url都為/obj/id/這種新式 # get_object()可以獲取到這個id的對象 # 注意在viewset中設置lookup_field獲取重寫get_object()方法可以指定id具體對象是什么~! instance = self.get_object() serializer = self.get_serializer(instance) return Response(serializer.data)

  對retrieve這個方法的重寫幾率比較高,例如我們在增加點擊數的時候,經常要對其進行一個重寫。

4. RetrieveModelMixin

# 源碼 class UpdateModelMixin(object): """ Update a model instance.==> 更新某個具體對象的內容 """ def update(self, request, *args, **kwargs): partial = kwargs.pop('partial', False) instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) self.perform_update(serializer) if getattr(instance, '_prefetched_objects_cache', None): # If 'prefetch_related' has been applied to a queryset, we need to # forcibly invalidate the prefetch cache on the instance. instance._prefetched_objects_cache = {} return Response(serializer.data) def perform_update(self, serializer): serializer.save() def partial_update(self, request, *args, **kwargs): kwargs['partial'] = True return self.update(request, *args, **kwargs)

  RetrieveModelMixin的實現邏輯基本整合了Create以及Retrieve,先得到具體的實例,再對其進行驗證以及保存,如果需要對更新這個邏輯進行自定義,那么需要重寫perform_update( )方法,而盡量少去重寫update( )

5. DestroyModelMixin

# 源碼 class DestroyModelMixin(object): """ Destroy a model instance. """ def destroy(self, request, *args, **kwargs): instance = self.get_object() self.perform_destroy(instance) return Response(status=status.HTTP_204_NO_CONTENT) def perform_destroy(self, instance): instance.delete()

  DestroyModelMixin的邏輯也相對比較簡單,我們取CreateModelMixin下面的例子,當我們取消收藏,那么我們的DestroyModelMixin就發揮作用了。同理

def perform_create(self, serializer): instance = serializer.save() course = instance.course if course.fav_num > 0: course.fav_num -= 1 else: course.fav_num = 0 course.save()

小結

  mixins相對比較好理解,本篇只是簡要的分析了源碼的內容以及各個mixins的邏輯,最重要的還是學會去重寫它們相關的方法。 
  一般情況下,當我們在操作某一個model的時候,涉及到另外一個model中數據的修改,那么就需要對這個mixins下執行save的邏輯的方法進行重寫。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM