1. 程式人生 > >Django Serializer HiddenField隱藏欄位

Django Serializer HiddenField隱藏欄位

Django rest_framework serializer.HiddenField(default=serializer.CurrentUser())

在用Dajngo RestFramework時, 有時候需要這麼一個場景,前端不需要傳一個或多個欄位,這些字是直接根據使用者登入資訊判斷自動賦值的,如果用mixin和viewset進行搭配寫介面,要麼重寫create, update等方法,要麼就是在serializer_class時就定義預設值,而第二種方法明顯簡單一些。具體看程式碼

# 假如我定義了一個serliazer,shop和status都是自動判斷後賦值的
# 用HiddenField定義欄位,default方法來寫具體賦值函式
# default方法是一個類,需要重寫set_context的方法 from rest_framework.compat import ( InvalidTimeError, MaxLengthValidator, MaxValueValidator, MinLengthValidator, MinValueValidator, unicode_repr, unicode_to_repr ) class CurrentShopDefault(object): def set_context(self, serializer_field): self.shop = serializer_field.context['request'
].user.shop def __call__(self): return self.shop def __repr__(self): return unicode_to_repr('%s()' % self.__class__.__name__) class CurrentStatus(object): def set_context(self, serializer_field): user_info = serializer_field.context['request'].user if user_info.shop.shop_type == 'SHOP_TYPE_COMCIRCLE'
: self.status = 1 else: self.status = 2 def __call__(self): return self.status def __repr__(self): return unicode_to_repr('%s()' % self.__class__.__name__) # 定義serializer class GameSerializer(serializers.ModelSerializer): class Meta: model = Game exclude = ['created_time'] shop = serializers.HiddenField( default=CurrentShopDefault() ) status = serializers.HiddenField( default=CurrentStatus() )

最後在view檔案的class裡直接指定serializer_class就好了

class GameOpView(mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.RetrieveModelMixin,  mixins.DestroyModelMixin, viewsets.GenericViewSet):
    """
       retrieve:
           獲取-遊戲詳情
       create:
           建立-遊戲
       update:
           更新-遊戲
       delete:
           刪除-遊戲
       partial_update:
           更新遊戲狀態
       total_info:
           遊戲資料總覽
   """
    permission_classes = [IsShop, ]
    pagination_class = StandardResultsSetPagination

    def get_queryset(self):
        return Game.objects.filter(
            Q(shop=self.request.user.shop) | Q(shop__com_circle=self.request.user.shop))

    def get_serializer_class(self):
        if self.action == 'partial_update':
            return GameStatusSerializer
        elif self.action == 'retrieve':
            return GameReadSerializer
        else:
            return GameSerializer