八、商品詳情頁功能
8.1.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__'
8.2.熱賣商品接口實作
隻需要在過濾器中增加“is_hot”就可以了
goods/filters.py裡的GoodsFilter添加“is_hot”
class Meta:
model = Goods
fields = ['pricemin', 'pricemax','is_hot']
在背景設定商品的“is_hot”為True,然後前端就可以顯示出來了

8.3.使用者收藏接口實作
(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實作唯一聯合,一個商品隻能收藏一次
validators = [
UniqueTogetherValidator(
queryset=UserFav.objects.all(),
fields=('user', 'goods'),
#message的資訊可以自定義
message="已經收藏"
)
]
model = UserFav
#收藏的時候需要傳回商品的id,因為取消收藏的時候必須知道商品的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")
測試代碼:
通路位址:http://127.0.0.1:8000/userfavs/,收藏三個商品,檢視已收藏清單
重複收藏某個商品會提示“已經收藏”
8.4.drf的權限認證
(1)自定義權限
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使用來做使用者認證的
authentication_classes = (JSONWebTokenAuthentication,SessionAuthentication)
#搜尋的字段
lookup_field = 'goods_id'
def get_queryset(self):
#隻能檢視目前登入使用者的收藏,不會擷取所有使用者的收藏
return UserFav.objects.filter(user=self.request.user)
說明:
- 隻有登入使用者才可以收藏
- 使用者隻能擷取自己的收藏,不能擷取所有使用者的收藏
- JSONWebTokenAuthentication認證不應該全局配置,因為使用者擷取商品資訊或者其它頁面的時候并不需要此認證,是以這個認證隻要局部中添加就可以
- 删除settings中的'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
8.5.使用者收藏功能和vue聯調
修改為local_host
//收藏
export const addFav = params => { return axios.post(`${local_host}/userfavs/`, params) }
//取消收藏
export const delFav = goodsId => { return axios.delete(`${local_host}/userfavs/`+goodsId+'/') }
export const getAllFavs = () => { return axios.get(`${local_host}/userfavs/`) }
//判斷是否收藏
export const getFav = goodsId => { return axios.get(`${local_host}/userfavs/`+goodsId+'/') }
- 删除收藏:根據商品'goods_id'
- 已收藏的商品顯示“已收藏”,沒有收藏就顯示“收藏”
轉載于:https://my.oschina.net/u/3961402/blog/2222291