如下內容是我關於完成生鮮電商項目後的一點總結,可能只有作完這個項目的人可能勉強看得懂一點,固然更可能是可能就只有我知道本身寫的什麼鬼了....(笑)前端
這一點的感想主要是,在什麼狀況下重載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
對這段的分析,就是用戶在前端傳過來三個數據(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
綜上所述,能夠知道,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
②添加商品到購物車時,因爲繼承是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)
綜上所述,重載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)
綜上所述,若是要把信息添加到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
②用戶添加收藏,實例化收藏記錄"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()
綜上所述,重載perform_create()的狀況有,若是須要利用到保存後的數據,例如購物車的商品以及數量,來減去庫存裏的,這裏就能夠重寫perfrom_create方法來接收剛剛保存的記錄,提取裏面的值進行額外操做。