Vue+Django REST framework 打造生鲜电商项目8-1~

8-1 viewset实现详情页接口

8-2 热卖商品接口实现

  • models中is_hot字段,使用过滤查询goods中is_hot为True的字段

  • goods/filter mate中加入 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(name='shop_price', help_text="最低价格",lookup_expr='gte')
    pricemax = django_filters.NumberFilter(name='shop_price', lookup_expr='lte')
    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', 'is_hot', 'is_new']
  • 进入网址会有所有的api。


    Vue+Django REST framework 打造生鲜电商项目8-1~_第1张图片
    微信截图_20180111112739.png
  • 点击goods点击过滤器filter

Vue+Django REST framework 打造生鲜电商项目8-1~_第2张图片
微信截图_20180111112759.png

8-3 用户收藏接口和实现

  1. 用户行为,写在user_operation/views.py下面
from rest_framework import mixins, viewsets

from user_operation.models import UserFav
from user_operation.serializers import UserFavSerializer


class UserFavViewset(mixins.CreateModelMixin,mixins.DestroyModelMixin, viewsets.GenericViewSet):
    queryset = UserFav.objects.all()
    serializer_class = UserFavSerializer
  1. user-operation/ser
from rest_framework import serializers

from user_operation.models import UserFav

__author__ = 'lv'
__date__ = '2018/1/11 12:44'



class UserFavSerializer(serializers.ModelSerializer):
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    class Meta:
        model = UserFav
        fields = ("user","goods")
  1. urls
router.register(r'userfavs', UserFavViewset, base_name="userfavs")
  • 2个字段 user,和goodsid,其中user是要服务器自己获取当前用户的。

  • 说实话我有点小震惊,这么点代码就完成了post请求,我的天啊.
    RUN:

  1. 打开http://localhost:8000/userfavs/ 提交商品
    Vue+Django REST framework 打造生鲜电商项目8-1~_第3张图片
    微信截图_20180111131009.png
  2. 打开nvicat查看user
Vue+Django REST framework 打造生鲜电商项目8-1~_第4张图片
微信截图_20180111131114.png
  • 我是登录的,居然保存成功了.木哈哈哈

  • 如果要做删除的功能,最好返回id字段.
    user_operation/serializer.py

class UserFavSerializer(serializers.ModelSerializer):
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    class Meta:
        model = UserFav
        fields = ("user","goods","id")

RUN:


Vue+Django REST framework 打造生鲜电商项目8-1~_第5张图片
微信截图_20180111131514.png
  • 删除
    直接网址http://localhost:8000/userfavs/2/点击delete红钮也能删除
Vue+Django REST framework 打造生鲜电商项目8-1~_第6张图片
微信截图_20180111132007.png
  • 数据库:


    Vue+Django REST framework 打造生鲜电商项目8-1~_第7张图片
    微信截图_20180111132119.png
  • 细节优化,如果用户点击收藏过的商品,不应该重复收藏,这需要在models中类UserFavs,mate中配置unique_together = ("user", "goods")

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

    class Meta:
        verbose_name = '用户收藏'
        verbose_name_plural = verbose_name
        unique_together = ("user", "goods")

    def __str__(self):
        return self.user.username

这样重复点击收藏效果如下:


Vue+Django REST framework 打造生鲜电商项目8-1~_第8张图片
微信截图_20180111132746.png
  • 在serializers里面设置重复收藏,可以自定义错误信息
class UserFavSerializer(serializers.ModelSerializer):
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )

    class Meta:
        model = UserFav
        validators = [
            UniqueTogetherValidator(
                queryset=UserFav.objects.all(),
                fields=('user', 'goods'),
                message="已经收藏"
            )
        ]

        fields = ("user", "goods", "id")

  • 效果


    Vue+Django REST framework 打造生鲜电商项目8-1~_第9张图片
    微信截图_20180111154510.png

8-4drf的权限验证

  • 没有权限验证,会有这样一个问题,如果一个用户传送不属于他收藏的ID,就会删除其他人的收藏数据,这样就要验证他提交的ID,中的user是不是当前用户的user

  • token认证最好放到具体的view里面,不要放到全局之中.如果在前端请求中每一个都加入了token的认证.那么连最基础的goods页面都请求不了.

  • IsAuthenticated如果用户没有登录的话会抛出401

  • IsOwnerOrReadOnly这个权限就是验证是否是当前用户

  • authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    这个一个是token认证,一个是session认证.

  1. user_operation/views.py

class UserFavViewset(mixins.CreateModelMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin,
                     mixins.DestroyModelMixin, viewsets.GenericViewSet):
    """
    list:
        获取用户收藏列表
    retrieve:
        判断某个商品是否已经收藏
    create:
        收藏商品
    """
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    serializer_class = UserFavSerializer
    lookup_field = "goods_id"

    def get_queryset(self):
        return UserFav.objects.filter(user=self.request.user)
  1. setting 去掉
    # 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',

  2. utils/permission

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

**最好补一个postman测试.

8-5 vue联调

登录情况下,都可以,
未登录有bug

你可能感兴趣的:(Vue+Django REST framework 打造生鲜电商项目8-1~)