關於完成生鮮電商項目後的一點總結

如下內容是我關於完成生鮮電商項目後的一點總結,可能只有作完這個項目的人可能勉強看得懂一點,固然更可能是可能就只有我知道本身寫的什麼鬼了....(笑)前端

這一點的感想主要是,在什麼狀況下重載CreateModelMixin裏面的create()方法和perform_create()方法(這裏只以CreateModelMixin舉例,其餘例如RetrieveModelMixin等差很少),何時重載Serializer裏面的create()方法,還有validate()的用法。數據庫

經過對這個項目中用到這種方法的總結,大概裏面有8個地方用到了上面所說的方法。後端

 

1、首先是validate()的用法,出現的地方有:ide

①用戶註冊時,在經過前面各類驗證以後,使用「 attrs["mobile"] = attrs["username"] 」,建立一個鍵值對,把前端傳過來的手機號碼保存起來,這裏的"mobile"是與用戶表中的字段保持一致。而後用「 del attrs["code"] 」刪除驗證碼。加密

    def validate(self, attrs):
        # 前端沒有傳mobile值到後端,這裏添加進來
        attrs["mobile"] = attrs["username"]
        # code是本身添加得,數據庫中並無這個字段,驗證完就刪除掉
        del attrs["code"]
        return attrs
View Code

 

對這段的分析,就是用戶在前端傳過來三個數據(username,password,code),而後在CreateModelMixin裏面把這些數據交給咱們自定義的serializer進行驗證,驗證成功後,原本下一步就是調用perform_create()進行保存,但是由於咱們設計的表中有mobile字段,且沒有code字段,因此就在前一步,也就是驗證成功後到調用perform_create()以前,添加mobile字段,刪除多餘的code字段。spa

②在訂單管理接口時,在validate()中添加自動生成的訂單號。設計

 def validate(self, attrs):
        # validate中添加order_sn,而後在view中就能夠save
        attrs["order_sn"] = self.generate_order_sn()
        return attrs
View Code

 

綜上所述,能夠知道,validate()的一個做用,就是提交上來的數據驗證成功後,在保存到數據庫以前,根據設計的表的須要對要進行保存的數據進行其餘必要的操做。(增刪等)code

 

2、接下來介紹重載Serializer的create()方法的狀況。orm

①對密碼進行加密保存。Serialzier的create()原本就是數據驗證(is_valid)經過後,CreateModelMixin調用perform_create(),而後裏面的.save()方法調用Serializer的create()方法把數據自動保存到數據庫中(固然,這裏的前提是繼承ModelSerializer)。重載Serializer的create(),意味着要咱們本身去寫保存數據的邏輯,不過項目中用了另外一種作法避免了本身寫保存邏輯。jwt

# 密碼加密保存
def create(self, validated_data):
        user = super(UserRegSerializer, self).create(validated_data=validated_data)
        user.set_password(validated_data["password"])
        user.save()
        return user
View Code

 

②添加商品到購物車時,因爲繼承是Serializer而不是ModelSerializer,因此須要重載create()

    def create(self, validated_data):
        user = self.context["request"].user
        nums = validated_data["nums"]
        goods = validated_data["goods"]

        existed = ShoppingCart.objects.filter(user=user, goods=goods)
        if existed:
            existed = existed[0]
            existed.nums += nums
            existed.save()
        else:
            existed = ShoppingCart.objects.create(**validated_data)
View Code

 

綜上所述,重載Serializer的狀況有:①繼承Serializer的時候須要咱們重載;②繼承ModelSerializer的時候,若是對保存到數據庫的數據須要進行額外的操做,能夠重載Serializer的create()。

 

3、介紹重載CreateModelMixin的create()(或者說成ModelViewset's create())的狀況。

①把用戶生成的token加載到頭部header中時,重載CreateModelMixin的create()。這樣才能夠用到裏面的添加信息到header的操做。

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = self.perform_create(serializer)
        re_dict = serializer.data
        payload = jwt_payload_handler(user)
        re_dict["token"] = jwt_encode_handler(payload)
        re_dict["name"] = user.name if user.name else user.username

        headers = self.get_success_headers(serializer.data)

        return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers)
View Code

 

綜上所述,若是要把信息添加到header裏面,就重載CreateModelMixin的create()方法。

 

 4、重載perform_create()方法。

①建立訂單後,重載perform_create(),實例化"order = serializer.save()",把購物車的商品和訂單order一塊兒添加到訂單的商品詳情表中。

    def perform_create(self, serializer):
        order = serializer.save()
        shop_carts = ShoppingCart.objects.filter(user=self.request.user)
        for shop_cart in shop_carts:
            order_goods = OrderGoods()
            order_goods.goods = shop_cart.goods
            order_goods.goods_num = shop_cart.nums
            order_goods.order = order
            order_goods.save()
            # 清空購物車
            shop_cart.delete()
        return order
View Code

 

②用戶添加收藏,實例化收藏記錄"instance = serializer.save()",而後經過「goods = instance.goods」獲取到商品,對它的goods.fav_nums += 1。

    def perform_create(self, serializer):
        instance = serializer.save()
        goods = instance.goods
        goods.fav_num += 1
        goods.save()
View Code

 

綜上所述,重載perform_create()的狀況有,若是須要利用到保存後的數據,例如購物車的商品以及數量,來減去庫存裏的,這裏就能夠重寫perfrom_create方法來接收剛剛保存的記錄,提取裏面的值進行額外操做。

相關文章
相關標籤/搜索