Django REST framework+Vue 打造生鮮電商專案(筆記五)
阿新 • • 發佈:2018-11-11
一、viewsets實現商品詳情頁介面
(1)商品詳情頁只需要多繼承一個類(mixins.RetrieveModelMixin)就可以了,(它的功能就是展示商品詳情)
class GoodsListViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin,viewsets.GenericViewSet):
(2)商品輪播圖實現
商品輪播圖是一個外來鍵(因為輪播圖的畫素比普通的商品圖片高,所以單獨做成外來鍵),序列化外來鍵用巢狀的方法來實現
#輪播圖 class GoodsImageSerializer(serializers.ModelSerializer):class Meta: model = GoodsImage fields = ("image",) #商品列表頁 class GoodsSerializer(serializers.ModelSerializer): #覆蓋外來鍵欄位 category = CategorySerializer() #images是資料庫中設定的related_name="images",把輪播圖巢狀進來 images = GoodsImageSerializer(many=True) class Meta: model= Goods fields = '__all__'
(3)熱賣商品介面實現
只需要在過濾器中增加“is_hot”就可以了
goods/filters.py裡的GoodsFilter新增“is_hot”
class Meta: model = Goods fields = ['pricemin', 'pricemax','is_hot']
在後臺設定商品的“is_hot”為True,然後前端就可以顯示出來了
二、使用者收藏介面實現
(1)序列化
user_operation/serializers.py
# user_operation/serializers.pyfrom rest_framework import serializers from user_operation.models import UserFav from rest_framework.validators import UniqueTogetherValidator class UserFavSerializer(serializers.ModelSerializer): #獲取當前登入的使用者 (因為如果不加這段,在收藏的時候無法自動獲取當前使用者,只能我們自己手動進行選擇某個使用者,這不符合邏輯) user = serializers.HiddenField( default=serializers.CurrentUserDefault() ) class Meta: #validate實現唯一聯合,一個商品只能收藏一次。(也可以在user_operation的model裡面的UserFav的Meta裡寫上“unique_together = ("user", "goods")”,作用一樣) validators = [ UniqueTogetherValidator( queryset=UserFav.objects.all(), fields=('user', 'goods'), #message的資訊可以自定義 message="已經收藏" ) ] model = UserFav # 新增"id"是為了後續的刪除功能可以使用,這個id表示的是一條收藏記錄,不是goods的id fields = ("user", "goods",'id')
(2)user_operation/views.py
# user_operaton/views.py from rest_framework import viewsets from rest_framework import mixins from .models import UserFav from .serializers import UserFavSerializer class UserFavViewset(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin): ''' 使用者收藏 ''' queryset = UserFav.objects.all() serializer_class = UserFavSerializer
繼承的類的作用:
mixins.CreateModelMixin 新增收藏(相當於建立資料庫)
mixins.DestroyModelMixin 取消刪除(相當於資料庫刪除)
mixins.ListModelMixin 獲取已收藏的商品列表
(3)配置url
# 配置使用者收藏的url router.register(r'userfavs', UserFavViewset, base_name="userfavs")
(Tips:重複收藏出錯時,返回的是“non_field_errors:["已經收藏"]”,這裡的“non_field_errors"表示的是”整體錯誤“,不是某個欄位出錯)
三、drf的許可權認證
utils資料夾下新建permissions.py,程式碼如下:
這個官網有例項,直接複製過來就可以了,把其中的owner改為user即可
# utils/permissions.py from rest_framework import permissions class IsOwnerOrReadOnly(permissions.BasePermission): """ Object-level permission to only allow owners of an object to edit it. Assumes the model instance has an `owner` attribute. """ def has_object_permission(self, request, view, obj): # Read permissions are allowed to any request, # so we'll always allow GET, HEAD or OPTIONS requests. if request.method in permissions.SAFE_METHODS: return True # Instance must have an attribute named `owner`. #obj相當於資料庫中的model,這裡要把owner改為我們資料庫中的user return obj.user == request.user
(2)user_operation/views
# user_operaton/views.py from rest_framework import viewsets from rest_framework import mixins from .models import UserFav from .serializers import UserFavSerializer from rest_framework.permissions import IsAuthenticated from utils.permissions import IsOwnerOrReadOnly from rest_framework_jwt.authentication import JSONWebTokenAuthentication from rest_framework.authentication import SessionAuthentication class UserFavViewset(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin): ''' 使用者收藏 ''' serializer_class = UserFavSerializer # permission是用來做許可權判斷的 # IsAuthenticated:必須登入使用者;IsOwnerOrReadOnly:必須是當前登入的使用者 permission_classes = (IsAuthenticated,IsOwnerOrReadOnly) #auth使用來做使用者認證的。“JSONWebTokenAuthentication”是允許用”Token“登陸;“SessionAuthentication”是允許用”使用者名稱密碼“登陸。雖然在setting.py裡面有配置
#“SessionAuthentication”,但在這裡我們相當於重寫了認證方法,所以“SessionAuthentication”要重新寫上去 authentication_classes = (JSONWebTokenAuthentication,SessionAuthentication) #搜尋的欄位。預設是收藏記錄的id,改成按照商品的id進行搜尋、刪除 lookup_field = 'goods_id' # 有些人會有疑問就是當用戶刪除的時候,會把其他收藏此商品的使用者的收藏記錄刪掉嗎?其實不會的,因為這個lookup_field是基於下面的
# “UserFav.objects.filter(user=self.request.user)”來進行刪除的 def get_queryset(self): #只能檢視當前登入使用者的收藏,不會獲取所有使用者的收藏 return UserFav.objects.filter(user=self.request.user)
說明:
- 只有登入使用者才可以收藏
- 使用者只能獲取自己的收藏,不能獲取所有使用者的收藏
- 登陸使用者只可以刪除自己的收藏,不可以刪除別人的
- JSONWebTokenAuthentication認證不應該全域性配置,因為使用者獲取商品資訊或者其它頁面的時候並不需要此認證,所以這個認證只要區域性中新增就可以
- 刪除settings中的'rest_framework_jwt.authentication.JSONWebTokenAuthentication',