08-个人中心功能开发
一、个人中心功能开发
1、DRF的API文档自动生成和功能详解
在路由中配置DRF的API文档(http://127.0.0.1:8000/docs/),一访问出现报错:说AutoSchema对象没有get_link属性,一查资料,DRF没有设置默认的DEFAULT_SCHEMA_CLASS,因此添加到REST_FRAMEWORK设置
REST_FRAMEWORK = { 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema' }
这里面我们需要维护这个文档,让前端人员更能够利用接口文档来和前端联调。文档中的说明由help_text来说明。
2、动态设置serializer和permission获取用户信息
users/views.py:
from django.contrib.auth.backends import ModelBackend from django.contrib.auth import get_user_model from django.db.models import Q from rest_framework import mixins from rest_framework.mixins import CreateModelMixin from rest_framework import viewsets from rest_framework.response import Response from rest_framework import status from rest_framework import permissions from rest_framework import authentication from random import choice from rest_framework_jwt.serializers import jwt_encode_handler,jwt_payload_handler#这两步是生成token关键源码 from rest_framework_jwt.authentication import JSONWebTokenAuthentication from utils.yunpian import YunPian from MxShop.settings import APIKEY from .serializers import SmsSerializer,UserRegisterSerializer,UserDetailSerializer from .models import VerifyCode User = get_user_model() class UserViewset(CreateModelMixin,mixins.RetrieveModelMixin,viewsets.GenericViewSet): """ 用户 """ serializer_class = UserRegisterSerializer queryset = User.objects.all() authentication_classes = (authentication.SessionAuthentication,JSONWebTokenAuthentication) # permission_classes = (permissions.IsAuthenticated,) def get_serializer_class(self): #动态的加载序列化器 if self.action == "retrive": return UserDetailSerializer elif self.action == "create": return UserRegisterSerializer return UserDetailSerializer def get_permissions(self): #动态加载权限验证(看源码然后重载这个方法) if self.action == "retrive": return [permissions.IsAuthenticated()] elif self.action == "create": return [] return [] def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = self.perform_create(serializer) # token返回的时候,是返回serializer.data,因此要放在data里边 re_dict = serializer.data payload = jwt_payload_handler(user) #要和前端保持一致,前端也叫token re_dict["token"] = jwt_encode_handler(payload) re_dict["name"] = user.name if user.name else user.username headers = self.get_success_headers(serializer.data) return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers) def get_object(self): return self.request.user #重载上面create中的perform_create方法 def perform_create(self, serializer): return serializer.save()
序列化器(users.serializers.py)中的UserDetailSeralizer的代码:
class UserDetailSerializer(serializers.ModelSerializer): """ 用户详情化序列化类 """ class Meta: model = User fields = ("name","birthday","gender","email","mobile")
经DRF文档调试,能提供前端接口,因此我们需要与vue联调。
3、vue和用户接口信息联调
前端vue信息调试好,一刷新,就可以看到刚才后端返回的json数据映射到前端来了。
4、用户个人信息修改
用户个人修改,mixins提供了一个接口UpdateModelMixin类用于更新(put,patch)数据。当用户视图类继承了UpdateModelMixin就可以进行更新操作,我们来到DRF文档操作。
class UserViewset(CreateModelMixin,mixins.UpdateModelMixin,mixins.RetrieveModelMixin,viewsets.GenericViewSet): """ 用户 """ ...
然后来到vue中联调。
5、用户收藏功能
用户收藏功能,返回的是goods的id与收藏的id,我们需要的是返回goods的详情页,因此我们到收藏视图类中新添加序列化器:
from goods.serializers import GoodsSerializer class UserFavDetailSerializer(serializers.ModelSerializer): goods = GoodsSerializer() class Meta: model = UserFav fields = ("goods","id")
序列化器编写完成之后,我们需要到视图类中动态调用序列化器,因此需要重写GenericAPIView中的get_serializer_class方法。
class UserFavViewset(mixins.CreateModelMixin,mixins.ListModelMixin,mixins.DestroyModelMixin,viewsets.GenericViewSet): """ list: 获取用户收藏列表 retrieve: 判断某个商品是否收藏 create: 收藏商品 """ # queryset = UserFav.objects.all() #配置之后,必须登录才能获取相关操作 permission_classes = (IsAuthenticated,IsOwnerOrReadOnly) 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) def get_serializer_class(self): if self.action == "list": return UserFavDetailSerializer elif self.action == "create": return UserFavSerializer return UserFavSerializer
然后到浏览器中,查看是否返回
查看成功,然后删除收藏调试功能是否健全:
数据就变成了三条啦,收藏功能完成。
6、用户留言功能
user_operation/views.py:
class LeavingMessageViewset(mixins.ListModelMixin,mixins.DestroyModelMixin,mixins.CreateModelMixin, viewsets.GenericViewSet): """ list: 获取用户留言 create: 添加留言 delete: 删除留言 """ permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication) serializer_class = LeavingMessageSerializer def get_queryset(self): return UserLeavingMessage.objects.filter(user=self.request.user)
user_operation/serializers.py:
from rest_framework import serializers from rest_framework.validators import UniqueTogetherValidator from .models import UserFav,UserLeavingMessage from goods.serializers import GoodsSerializer class LeavingMessageSerializer(serializers.ModelSerializer): user = serializers.HiddenField( default=serializers.CurrentUserDefault() ) add_time = serializers.DateTimeField(read_only=True,format="%Y-%m-%d %H:%M:%S")#只可以看见不能修改 class Meta: model = UserLeavingMessage fields = ("user", "message_type", "subject","message","file","id","add_time")
路由配置:
#留言 router.register(r"messages",LeavingMessageViewset,base_name="messages")
经测试,添加删除都没有问题,前端都将路由配置好了的。
7、用户收货地址列表页接口开发
viewsets.ModelViewSet将所有的mixins以及GenericViewset继承,为了方便直接继承它。user_operation/views.py:
class AddressViewset(viewsets.ModelViewSet): """ 收货地址管理 list: 获取收货地址 create: 添加收货地址 update: 更新收货地址 delete: 删除收货地址 """ permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication) serializer_class = AddressSerializer def get_queryset(self): return UserAddress.objects.filter(user=self.request.user)
user_operation/serializers.py:
class AddressSerializer(serializers.ModelSerializer): user = serializers.HiddenField( default=serializers.CurrentUserDefault() ) add_time = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M:%S") class Meta: model = UserAddress fields = ("user", "province", "city", "district", "address", "id", "add_time","signer_name","signer_mobile")
配置路由:
from user_operation.views import AddressViewset router = DefaultRouter() #收货地址 router.register(r"address",AddressViewset,base_name="address")
DRF文档测试:
测试成功后,vue和收货地址接口联调结果:
这样地址的信息就没有啦,测试添加也是成功的,因此个人中心开发完毕。