07-商品詳情頁功能


一、商品詳情頁功能

1、viewsets實現商品詳情頁接口

  商品詳情頁,需要加上mixins.RetrieveModelMixin,因為路由為/goods/id/,因此在之前商品列表頁視圖中繼承詳情頁類。代碼邏輯為:

class GoodsListViewSet(mixins.ListModelMixin,mixins.RetrieveModelMixin,viewsets.GenericViewSet):
    """
    商品列表頁 分頁 搜索 過濾 排序
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsSetPagination
    filter_backends = [DjangoFilterBackend,filters.SearchFilter,filters.OrderingFilter]
    #這是精確搜索過濾,我們需要的是模糊搜索
    # filterset_fields = ['name', 'shop_price']
    filter_class = GoodsFilter
    search_fields = ("name","goods_brief","goods_desc")
    ordering_fields = ("shop_price","sold_num","add_time")
goods/serializers.py中的邏輯為:
from rest_framework import serializers

from .models import Goods,GoodsCategory,GoodsImage


class GoodsImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = GoodsImage
        fields = ("image",)


class GoodsSerializer(serializers.ModelSerializer):
    """
    在這里可以利用新寫的字段來覆蓋已有字段
    """
    category = GoodsCategorySerializer() #在這里實例化外鍵的序列化器,就可以完成
    images = GoodsImageSerializer(many=True) #名字一定要和related_name="images"中的名字一樣
    class Meta:
        model = Goods #指明model
        #fields = ['category', 'goods_sn', 'name', 'click_num','sold_num','fav_num','add_time'] #指明字段
        fields = "__all__" #將全部字段顯示出來

這樣商品的詳情頁就完成啦。

 

 2、熱賣商品接口實現

數據的模型類中有is_hot這個字段,因此過濾商品的時候我們應該加上is_hot字段。前端的邏輯中,有這個is_hot的條件,因此在過濾器中加上過濾字段為:

import django_filters
from django.db.models import Q

from .models import Goods


class GoodsFilter(django_filters.rest_framework.FilterSet):
    """
    商品過濾器
    """
    pricemin = django_filters.NumberFilter(field_name="shop_price",lookup_expr="gte")
    pricemax = django_filters.NumberFilter(field_name="shop_price", lookup_expr="lte")
    name = django_filters.CharFilter(field_name="name", lookup_expr="icontains")
    #這里過濾的字段要和前端傳過來的字段一樣
    top_category = django_filters.NumberFilter(method="top_category_filter")

    def top_category_filter(self,queryset,name,value):
        return queryset.filter(Q(category_id=value)|Q(category__parent_category_id=value)|Q(category__parent_category__parent_category_id=value))

    class Meta:
        model = Goods
        fields = ["pricemin","pricemax","name","top_category","is_hot"]

 

 會發現數據沒有熱銷的,因此我們需要去后台管理系統去修改幾條數據展示。修改好之后,驗證數據。結果出現熱搜啦。

 

 3、用戶收藏接口實現

用戶收藏,是用戶操作的,因此需要到user_operation中的視圖中操作:

user_operation/views.py:

from django.shortcuts import render
from rest_framework import viewsets
from rest_framework import mixins

from .models import UserFav
from .serializers import UserFavSerializer

# Create your views here.
#添加一條記錄, 獲取收藏商品列表的功能  刪除一條記錄  因此繼承
class UserFavViewset(mixins.CreateModelMixin,mixins.ListModelMixin,mixins.DestroyModelMixin,viewsets.GenericViewSet):
    """
    用戶收藏功能
    """
    queryset = UserFav.objects.all()
    serializer_class = UserFavSerializer

user_operaton/serializers.py:

from rest_framework import serializers
from rest_framework.validators import UniqueTogetherValidator

from .models import UserFav


class UserFavSerializer(serializers.ModelSerializer):
    """
    用戶會收藏同一商品多次,因此這是不合理的  所以利用Django的model來實現這一合理操作(也可以下面自己配置)
    """
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    class Meta:
        model = UserFav
        validators = [
            UniqueTogetherValidator(
                queryset=UserFav.objects.all(),
                fields=['user', 'goods'],
                message="已經收藏"
            )
        ]
        fields = ("user","goods","id")

user_operation/models.pymodel---UserFav中的元類中定義聯合索引去重:

class UserFav(models.Model):
    """
    用戶收藏
    """
    user = models.ForeignKey(User, verbose_name="用戶",on_delete=models.CASCADE)
    goods = models.ForeignKey(Goods, verbose_name="商品", help_text="商品id",on_delete=models.CASCADE)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加時間")

    class Meta:
        verbose_name = '用戶收藏'
        verbose_name_plural = verbose_name
        unique_together = ("user", "goods") #數據庫聯合索引的認證

 

 完成了收藏功能,以及刪除功能。

4、DRF的權限驗證

因為上面的操作有一定的問題,任何一個人都可以刪除數據庫中的收藏,因此DRF官方文檔中提供了權限認證

 

 user_operation/views.py

from django.shortcuts import render
from rest_framework import viewsets
from rest_framework import mixins
from rest_framework.permissions import IsAuthenticated
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.authentication import SessionAuthentication

from utils.permissions import IsOwnerOrReadOnly
from .models import UserFav
from .serializers import UserFavSerializer

# Create your views here.
#添加一條記錄, 獲取收藏商品列表的功能  刪除一條記錄  因此繼承
class UserFavViewset(mixins.CreateModelMixin,mixins.ListModelMixin,mixins.DestroyModelMixin,viewsets.GenericViewSet):
    """
    用戶收藏功能
    """
    # queryset = UserFav.objects.all()
    #配置之后,必須登錄才能獲取相關操作
    permission_classes = (IsAuthenticated,IsOwnerOrReadOnly)
#因為項目是JWT認證,因此將認證放到具體的認證中,而不是全局設置中 authentication_classes
= (JSONWebTokenAuthentication,SessionAuthentication) serializer_class = UserFavSerializer
lookup_field = "goods_id" #直接可以看商品id查詢收藏的,就不用來找收藏的id啦
  #我們只能獲取當前用戶的UserFav,因此我們要重載get_queryset方法 
def get_queryset(self):
return UserFav.objects.filter(user=self.request.user)

utils/permissions.py:DRF官網permissions提供的權限驗證)

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`.
        return obj.user == request.user

MxShop/settings.py:

#配置用戶認證,將JSONWebTokenAuthentication拿到具體用戶操作認證,不然常規的商品列表頁都不能訪問
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        # 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ]
}

 

 

 

 

 

 

 

 

 

 

 整個用戶的收藏以及取消收藏功能開發完成。

打賞

免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2022 CODEPRJ.COM