1. 程式人生 > >Django REST framework+Vue 打造生鮮電商專案(筆記五)

Django REST framework+Vue 打造生鮮電商專案(筆記五)

一、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.py
from 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',