收藏功能_Vue+DRF实战11.详情页、收藏、drf的权限校验功能实现

内容提要:

  • 详情页、校验是否为当前用户、配置联合唯一索引、drf的权限校验。

《Python前后端分离开发Vue+Django REST framework实战》作者bobby

——学习来源

7f94b66694537466044634f293f2bee1.png

第八章

商品详情页

8.1详情页实现

使用mixins.RetrieveModelMixin,就能立即实现商品详情页的功能。

如果商品详情的某个字段是外键,具有一对多的关系,则在serializers.py中,替换外键的配置即可。

from rest_framework import serializers
from goods.models import Goods,GoodsImage

class GoodsImageSerializer(serializers.ModelSerializer):
class Meta:
model = GoodsImage
fields = ("image",)

class GoodsSerializer(serializers.ModelSerializer):
category = GoodsCategorySerializer()
images = GoodsImageSerializer(many=True) # GoodsImage的外键名称是images
class Meta:
model = Goods
# fields = ('name','click_num','id') # 取出部分字段
fields = "__all__"
8.2热销商品实现

在filtes.py中商品过滤类添加is_hot过滤条件即可。

import django_filters
from .models import Goods

class GoodsFilter(django_filters.rest_framework.FilterSet):
...省略...
class Meta:
model = Goods
fields = ['price_min','price_max','name','is_hot'] # 把过滤条件添加进来
8.3商品收藏实现

serializers获取当前用户

官方文档:https://www.django-rest-framework.org/api-guide/validators/#currentuserdefault

如果想获取当前用户,可以使用以下方式。

from rest_framework import serializers
from .models import UserFav

class UserFavSerializer(serializers.ModelSerializer):
user = serializers.HiddenField(
default=serializers.CurrentUserDefault()
) # 字段是当前用户
class Meta:
model = UserFav
fields = ("user", "goods","id")

删除收藏

rest_framework使用的rest方式进行增删改查,通过DELETE方法,即可完成删除。

配置联合唯一索引

在实际场景中,单个字段可以重复,但是某两个字段(例如收藏的user和goods)作为一个集合时不允许重复。可以使用以下两种方法解决该问题。

方法一:设置models联合唯一索引

该方法需要修改models并migrate,将数据库的两个字段作为联合唯一索引)。

from datetime import datetime
from django.db import models
from django.contrib.auth import get_user_model
from goods.models import Goods

User = get_user_model()
class UserFav(models.Model):
"""用户收藏"""
user = models.ForeignKey(User,on_delete=models.CASCADE,verbose_name="用户")
goods = models.ForeignKey(Goods,on_delete=models.CASCADE,verbose_name="商品")
add_time = models.DateTimeField(default=datetime.now, verbose_name="添加时间")

class Meta:
verbose_name = "用户收藏"
verbose_name_plural = verbose_name
unique_together = ("user", "goods") # 联合唯一索引

def __str__(self):
return self.user.name

方法二:serializers中配置Validators

官方文档:https://www.django-rest-framework.org/api-guide/validators/#uniquetogethervalidator

在serializers.py中添加联合唯一索引。

from rest_framework import serializers
from .models import UserFav
from rest_framework.validators import UniqueTogetherValidator

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")
8.4drf的权限验证

在访问接口时,需要对收藏列表、收藏和取消收藏做单独的权限控制。

官方文档:https://www.django-rest-framework.org/api-guide/permissions/#examples

编写自定义权限校验的工具类。

# utils/permissions.py
from rest_framework import permissions

class IsOwnerOrReadOnly(permissions.BasePermission):
"""方法的权限校验"""
def has_object_permission(self, request, view, obj):
# 如果是安全的方法则返回True
if request.method in permissions.SAFE_METHODS:
return True

# 如果不是安全的方法,则判断是否为当前用户
return obj.user == request.user

在views中引用权限校验。

from rest_framework import viewsets
from rest_framework import mixins
from .models import UserFav
from .serializers import UserFavSerializer
from rest_framework.permissions import IsAuthenticated
from utils.permissions import IsOwnerOrReadOnly

class UserFavViewset(mixins.CreateModelMixin, mixins.DestroyModelMixin,viewsets.GenericViewSet):
"""用户收藏功能"""
permission_classes = (IsAuthenticated,IsOwnerOrReadOnly) # IsAuthenticated做了登录校验,IsOwnerOrReadOnly是自定义的权限校验
serializer_class = UserFavSerializer
def get_queryset(self):
return UserFav.objects.filter(user=self.request.user)
8.5更改单个记录的查询字段

使用mixins.RetrieveModelMixin时,默认查询是根据数据表准的id进行查找。如果想更改查找的字段,可以通过设置lookup_field来实现。

# views.py
from rest_framework import viewsets
from rest_framework import mixins
from .models import UserFav
from .serializers import UserFavSerializer
from rest_framework.permissions import IsAuthenticated
from utils.permissions import IsOwnerOrReadOnly

class UserFavViewset(mixins.CreateModelMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.DestroyModelMixin,viewsets.GenericViewSet):
"""用户收藏功能"""
permission_classes = (IsAuthenticated,IsOwnerOrReadOnly)
serializer_class = UserFavSerializer
lookup_field = "goods_id"
def get_queryset(self):
return UserFav.objects.filter(user=self.request.user)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值