DRF实战---个人中心开发

个人中心开发

使用DRF生成开发文档

https://www.django-rest-framework.org/topics/documenting-your-api/

提供接口获取单个用户的个人信息

复用ConsumerViewset 继承RetrieveModelMixin

class ConsumerViewset(CreateModelMixin, mixins.UpdateModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
动态获取permission
  • 当用户获取数据时需要验证是否登录

这时的url 应当为 user/id,一般的做法是

    # permission_classes = (permissions.IsAuthenticated, )

但是我们已经复用了ConsumerViewset类,因为该类还实现了用户注册的功能,而注册时是不需要验证是否已经登录的

所有我们需要设置动态的permission

    def get_permissions(self):
        if self.action == "retrieve":
            return [permissions.IsAuthenticated()]
        elif self.action == "create":
            return []
        return []

补充:或者我们将user_id返回给前端,让前端带着id来请求url user/id

  • 最后加入用户认证的功能,上面的方法只是判断用户是否登录,并不会进行认证,只有认证过的用户才算登录

JSONWebTokenAuthentication 是使用JWT模式进行认证
SessionAuthentication 是使用Session模式进行认证,方便浏览器端的调试

    authentication_classes = (JSONWebTokenAuthentication, authentication.SessionAuthentication )
动态获取serializer
  • 当返回数据给前端时,我们不能在使用注册时的Serializer,重写一个DetailSerializer专门用来返回用户信息
class ConsumerDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ("name", "birthday", "mobile", "gender", "email")
  • 因为是复用的同一个View,所有判断是注册还是retrieve操作来获取不同的serializer,重写get_serializer_class方法动态指定serializer
 def get_serializer_class(self):
        if self.action == "retrieve":
            return ConsumerDetailSerializer
        elif self.action == "create":
            return ConsumerRegSerializer

        return ConsumerDetailSerializer

修改用户个人资料

  • 继承UpdateModelMixin,它支持put 和 patch 请求

补充,小tips,get_object方法

   # 当Retrieve和Update,Destroy的时候都会用到该方法
    def get_object(self):
        return self.request.user

完善个人收藏

因为个人收藏中要包含收藏的商品,而原来的serializer只会返回goods_id 和 id ,所有需要重写序列号类,用于返回收藏详情页的信息

  • 新建serializer
class UserFavDetailSerializer(serializers.ModelSerializer):
    goods = GoodsSerializer()
    class Meta:
        model = UserFav
        field = ('goods','id')

因为goods本身就是外键,只会调用出一个对象出来,所有就会不用再设置many=True了,所有many=True,就相当于xxx_set的set,只有没有设置外键要反向引用的时候才会设置

  • 这里也涉及到了动态调用Serializer class的问题,所以也需要重写get_serializer_class方法
    # serializer_class = UserFavSerializer
    def get_serializer_class(self):
        if self.action == "list":
            return UserFavDetailSerializer
        elif self.action == "create":
            return UserFavSerializer

        return UserFavSerializer

小tips,serializers.HiddenField,隐藏了该字段,会做后端的操作,但不会序列号返回给前端

    # 获取当前用户,并且隐藏了该字段,不会序列号返回给前端
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )

用户留言功能

  • views
class UserRemarkViewset(mixins.CreateModelMixin,mixins.RetrieveModelMixin,
                        mixins.DestroyModelMixin,mixins.ListModelMixin,viewsets.GenericViewSet):
    """
    list:
        获取用户留言
    create:
        添加留言
    delete:
        删除留言功能
    """
    queryset = UserRemark.objects.all()
    serializer_class = UserRemarkSerializer

    permission_classes = (IsAuthenticated,IsOwnerOrReadOnly)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)

    def get_queryset(self):
        return UserRemark.objects.filter(user=self.request.user)
  • serializers
class UserRemarkSerializer(serializers.ModelSerializer):
    # 获取当前用户,并且隐藏了该字段,不会序列号返回给前端
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    # read_only=True 这个值只返回给前端不让前端提交
    # write_only=True 这个值只会提交,不会返回给前端
    # format 设置日期格式
    add_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M')
    class Meta:
        model = UserRemark
        fields = ("user", "message_type", "subject", "message", "file", "id" ,"add_time")

注意:

read_only=True 这个值只返回给前端,不让前端提交
write_only=True 这个值只会让前端提交,不会再返回给前端

用戶收穫地址

  • views
class UserAddressViewset(viewsets.ModelViewSet):
    """
    收货地址管理
    list:
        获取收货地址
    create:
        添加收货地址
    update:
        更新收货地址
    delete:
        删除收货地址
    """
    queryset = UserAddress.objects.all()
    serializer_class = UserAdressSerializer

    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)

    def get_queryset(self):
        return UserAddress.objects.filter(user=self.request.user)

因为这里用到了 增删改查 四个接口,所有可以直接继承Modelviewset

  • serialiers
class UserAdressSerializer(serializers.ModelSerializer):
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    add_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M')

    class Meta:
        model = UserAddress
        fields = ("id", "user", "province", "city", "district", "address", "signer_name", "add_time", "signer_mobile")

你可能感兴趣的:(Django,Rest,Framework)