美文网首页
Vue+Django REST framework 打造生鲜电商

Vue+Django REST framework 打造生鲜电商

作者: 吕阳 | 来源:发表于2018-01-11 17:18 被阅读813次

    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。


      微信截图_20180111112739.png
    • 点击goods点击过滤器filter

    微信截图_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/ 提交商品
      微信截图_20180111131009.png
    2. 打开nvicat查看user
    微信截图_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:


    微信截图_20180111131514.png 微信截图_20180111132007.png
    • 数据库:


      微信截图_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
    
    

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


    微信截图_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")
    
    
    • 效果


      微信截图_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 打造生鲜电商

          本文链接:https://www.haomeiwen.com/subject/varonxtx.html