class GoodsListViewSet(mixins.ListModelMixin,mixins.RetrieveModelMixin,viewsets.GenericViewSet):
class GoodsImageSerializer(serializers.ModelSerializer):
class Meta:
model = GoodsImage
fields = ('image', ) # 包含所有字段
class GoodsSerializer(serializers.ModelSerializer):
category = GoodCategorySerializer()
# images为GoodImage中外键的relate_name,用于反向查询
images = GoodsImageSerializer(many=True) # 反向查询,一对多
class UserFavViewSet(mixins.CreateModelMixin,mixins.DestroyModelMixin,
mixins.ListModelMixin,mixins.RetrieveModelMixin,viewsets.GenericViewSet):
"""
list:
获取用户收藏列表
retrieve:
判断某个商品是否已经收藏
create:
收藏商品
"""
# ListModelMixin 展示所有查到的数据,以列表形式返回
# RetrieveModelMixin 用来 userfav/2/ 时,可以查询到单个详情,实现当个实例的GET方法
# queryset = UserFav.objects.all()
# serializer_class = UserFavSerializer
def get_serializer_class(self):
if self.action == "list":
return UserFavDetailSerializer
elif self.action == "create":
return UserFavSerializer
return UserFavSerializer
# def perform_create(self, serializer):
# instance = serializer.save()
# goods = instance.goods
# goods.fav_num += 1
# goods.save()
# 设置JSONWebTokenAuthentication为局部,让用户访问Goods列表时不做登录限制
# 设置SessionAuthentication,让已登录用户访问收藏列表时不会提示用户认证未提供,方便开发时的调试(因为调试时,往往不会讲token放到header中),
# 这个类的设置主要是为了使用token或者session验证方式获取用户信息,然后交给permission验证
authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
lookup_field = "goods_id" # 因为goods是外键,所有加下划线
# 重写get_queryset,只返回当前用户的收藏信息
def get_queryset(self):
return UserFav.objects.filter(user=self.request.user)
http://127.0.0.1:8000/userfavs/1/ Method:Delete
models中
unique_together={('user', 'goods')},
表中已经存在重复的记录了,删除重复记录,重新migrate
serializers中
class Meta:
model = UserFav
validators = [
UniqueTogetherValidator(
queryset=UserFav.objects.all(),
fields=('user', 'goods'),
message="已经收藏"
)
]
# 返回id,便于后续删除跟新操作
fields = ('user','goods','id')
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`.
# obj就是数据库中查出来的那个对象
return obj.user == request.user
设置JSONWebTokenAuthentication为局部,让用户访问Goods列表时不做登录限制
设置SessionAuthentication,让已登录用户访问收藏列表时不会提示用户认证未提供,方便开发时的调试(因为调试时,往往不会讲token放到header中),
这个类的设置主要是为了使用token或者session验证方式获取用户信息,然后交给permission验证
class UserFavViewSet(mixins.CreateModelMixin,mixins.DestroyModelMixin,
mixins.ListModelMixin,mixins.RetrieveModelMixin,viewsets.GenericViewSet):
"""
list:
获取用户收藏列表
retrieve:
判断某个商品是否已经收藏
create:
收藏商品
"""
# ListModelMixin 展示所有查到的数据,以列表形式返回
# RetrieveModelMixin 用来 userfav/2/ 时,可以查询到单个详情,实现当个实例的GET方法
queryset = UserFav.objects.all()
serializer_class = UserFavSerializer
# IsAuthenticated 判断是否登录 IsOwnerOrReadOnly 让用户只能对自己的收藏列表进行操作
permission_classes = (IsAuthenticated,IsOwnerOrReadOnly)
# 设置JSONWebTokenAuthentication为局部,让用户访问Goods列表时不做登录限制
# 设置SessionAuthentication,让已登录用户访问收藏列表时不会提示用户认证未提供,
# 猜测,是用来保存token的,表示这个类已经验证过token了
# 当请求的消息头没有带上token时就会返回"detail": "Authentication credentials were not provided."
# 如果带了,就会直接返回结果
authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
lookup_field = "goods_id" # 因为goods是外键,所有加下划线
# 重写get_queryset,只返回当前用户的收藏信息
def get_queryset(self):
return UserFav.objects.filter(user=self.request.user)
lookup_field = “goods_id” # 因为goods是外键,所有加下划线
查询或删除的url
http://127.0.0.1:8000/userfavs/16/ 16为goods_id