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__" #將所有字段顯示出來

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

 

 二、熱賣商品接口實現spa

數據的模型類中有is_hot這個字段,所以過濾商品的時候咱們應該加上is_hot字段。前端的邏輯中,有這個is_hot的條件,所以在過濾器中加上過濾字段爲:3d

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"]

 

 會發現數據沒有熱銷的,所以咱們須要去後臺管理系統去修改幾條數據展現。修改好以後,驗證數據。結果出現熱搜啦。rest

 

 三、用戶收藏接口實現code

用戶收藏,是用戶操做的,所以須要到user_operation中的視圖中操做:jwt

user_operation/views.py:blog

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") #數據庫聯合索引的認證

 

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

四、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',
    ]
}

 

 

 

 

 

 

 

 

 

 

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

相關文章
相關標籤/搜索