(项目)生鲜超市(八)
九、个人中心
1、drf的api文档生成
之前配置过文档的url:
1 path('docs',include_docs_urls(title='倍思乐接口文档')),
然后访问该接口就会自动生成接口文档:
可以在该文档中做交互和测试,文档可以生成js,shell和python代码段,可以拿来直接使用。
添加注释,在每个接口的注释中按照ViewSet的格式进行添加注释,比如GoodsListViewSet:
1 class GoodsListViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet): 2 """ 3 list: 4 商品列表,分页,搜索,过滤,排序 5 retrieve: 6 获取商品详情 7 """
字段的注释有三种添加方式,model的字段中加,serializer的字段加,filter的字段加。
2、个人信息修改
首先在users/serialziers.py中添加用户详细信息的序列化字段:
1 class UserDetailSerializer(serializers.ModelSerializer): 2 class Meta: 3 model = User 4 fields = ("name", "gender", "birthday", "email", "mobile")
在个人中心中,想要获取个人信息,只需要在UserViewSet中继承RetrieveModelMixin类:
1 class UserViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet): 2 """用户""" 3 5 queryset = User.objects.all() 6 7 def create(self, request, *args, **kwargs): 8 serializer = self.get_serializer(data=request.data) 9 serializer.is_valid(raise_exception=True) 10 11 user = self.perform_create(serializer) 12 re_dict = serializer.data 13 payload = jwt_payload_handler(user) 14 re_dict["token"] = jwt_encode_handler(payload) 15 re_dict["name"] = user.name if user.name else user.username 16 17 headers = self.get_success_headers(serializer.data) 18 return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers) 19 20 def perform_create(self, serializer): 21 return serializer.save()
现在就可以从数据库中获取用户的数据了:
想要修改个人资料,只需要在UserViewSet接口继承UpdateModelMixin即可:
1 class UserViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet): 2 """用户""" 3 4 # serializer_class = UserRegSerializer 5 queryset = User.objects.all() 6 authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication) 7 8 def create(self, request, *args, **kwargs): 9 serializer = self.get_serializer(data=request.data) 10 serializer.is_valid(raise_exception=True) 11 12 user = self.perform_create(serializer) 13 re_dict = serializer.data 14 payload = jwt_payload_handler(user) 15 re_dict["token"] = jwt_encode_handler(payload) 16 re_dict["name"] = user.name if user.name else user.username 17 18 headers = self.get_success_headers(serializer.data) 19 return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers) 20 21 # 动态获取权限,注册的时候不应该有权限限制,在获取用户详情的时候,需要有权限登录 22 def get_permissions(self): 23 if self.action == 'retrieve': 24 return [permissions.IsAuthenticated()] 25 elif self.action == 'create': 26 return [] 27 return [] 28 29 # 动态选择序列化 30 def get_serializer_class(self): 31 if self.action == "retrieve": 32 return UserDetailSerializer 33 elif self.action == "create": 34 return UserRegSerializer 35 return UserDetailSerializer 36 37 # 虽然继承了Retrieve可以获取用户详情,但是并不知道用户的id,所有要重写get_object方法 38 def get_object(self): 39 return self.request.user 40 41 def perform_create(self, serializer): 42 return serializer.save()
现在修改个人资料,修改成功:
3、用户收藏商品详情
在user_operation/serializers.py中添加用户收藏详情的序列化:
1 class UserFavDetailSerializer(serializers.ModelSerializer): 2 # 通过商品id获取收藏的商品,需要嵌套商品的序列化 3 goods = GoodsSerializer() 4 5 class Meta: 6 model = UserFav 7 fields = ("goods", "id")
在UserFavViewSet接口中动态获取收藏序列化:
1 class UserFavViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin, 2 mixins.RetrieveModelMixin, viewsets.GenericViewSet): 3 """用户收藏""" 4 5 # permission是权限验证 IsAuthenticated必须登录用户 IsOwnerOrReadOnly必须是当前登录的用户 6 permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) 7 8 # authentication是用户认证 9 authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication) 10 11 # 搜索的字段 12 lookup_field = 'goods_id' 13 14 # 动态选择serializer 15 def get_serializer_class(self): 16 if self.action == "list": 17 return UserFavDetailSerializer 18 elif self.action == "create": 19 return UserFavSerializer 20 return UserFavSerializer 21 22 # 只能查看当前登录用户的收藏,不会获取所有用户的收藏 23 def get_queryset(self): 24 return UserFav.objects.filter(user=self.request.user)
可以在个人中心我的收藏看到收藏的商品及商品详情,还可以删除收藏。
4、用户留言功能
在serializers.py中添加用户留言的序列化字段:
1 class LeavingMessageSerializer(serializers.ModelSerializer): 2 user = serializers.HiddenField( 3 default=serializers.CurrentUserDefault() 4 ) 5 # read_only:只返回,post时候可以不用提交 6 add_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M') 7 8 class Meta: 9 model = UserLeavingMessage 10 fields = ("user", "message_type", "subject", "message", "file", "id", "add_time")
然后在views.py中编写用户留言的接口:
1 class LeavingMessageViewSet(mixins.ListModelMixin, mixins.DestroyModelMixin, mixins.CreateModelMixin, 2 viewsets.GenericViewSet): 3 """ 4 list: 5 获取用户留言 6 create: 7 添加留言 8 delete: 9 删除留言功能 10 """ 11 12 permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) 13 authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication) 14 serializer_class = LeavingMessageSerializer 15 16 # 获取自己的留言 17 def get_queryset(self): 18 return UserLeavingMessage.objects.filter(user=self.request.user)
注册url:
1 router.register(r'messages', LeavingMessageViewSet, base_name='messages') # 用户留言
5、用户收货地址
在serializers.py中对收货地址所需的字段进行序列化:
1 class AddressSerializer(serializers.ModelSerializer): 2 user = serializers.HiddenField( 3 default=serializers.CurrentUserDefault() 4 ) 5 add_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M') 6 7 class Meta: 8 model = UserAddress 9 fields = ("id", "user", "province", "city", "district", "address", "signer_name", "add_time", "signer_mobile")
然后在views.py中编写收货地址的接口,这里直接继承ModelViewSet即可,它将增删改查全部集中在了一起:
1 class AddressViewSet(viewsets.ModelViewSet): 2 """ 3 收货地址管理 4 list: 5 获取收货地址 6 create: 7 添加收货地址 8 update: 9 更新收货地址 10 delete: 11 删除收货地址 12 """ 13 14 permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) 15 authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication) 16 serializer_class = AddressSerializer 17 18 def get_queryset(self): 19 return UserAddress.objects.filter(user=self.request.user)
注册url:
1 router.register(r'address',AddressViewSet , base_name="address") # 收货地址