前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python测试开发django-rest-framework-93.联合唯一校验

python测试开发django-rest-framework-93.联合唯一校验

作者头像
上海-悠悠
发布2021-02-03 09:59:04
9270
发布2021-02-03 09:59:04
举报
文章被收录于专栏:从零开始学自动化测试

前言

前面添加商品,商品code只能添加一次可以用唯一字段校验UniqueValidator,如果用户收藏商品,一个用户可以收藏多个商品,一个商品也可以被多个人收藏。 但是同一个人针对同一个商品,只能收藏一次,于是可以用UniqueTogetherValidator联合唯一校验

收藏商品

添加商品和收藏商品 models.py 模型设计

代码语言:javascript
复制
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

class Goods(models.Model):
    """商品表"""
    goods_name = models.CharField(max_length=30,
                                  default="",
                                  verbose_name="商品名称")
    goods_code = models.CharField(max_length=30,
                                  unique=True,
                                  verbose_name="商品代号")
    merchant_id = models.CharField(max_length=30,
                                   default="",
                                   blank=True, null=True,
                                   verbose_name="商户ID")
    merchant_name = models.CharField(max_length=30,
                                     default="",
                                     blank=True, null=True,
                                     verbose_name="商户名称")
    # goods_price = models.FloatField(blank=True, null=True,
    #                                 default=0,
    #                                 verbose_name="商品价格")
    goods_price = models.DecimalField(max_digits=10, decimal_places=2,
                                      blank=True, null=True,
                                      default=0, verbose_name="商品价格")
    goods_stock = models.IntegerField(blank=True, null=True,
                                      default=0,
                                      verbose_name="商品库存")
    goods_groupid = models.IntegerField(blank=True, null=True,
                                        default=0,
                                        verbose_name="商品分组")
    goods_status = models.IntegerField(choices=(
                                                (0, '下架'),
                                                (1, '出售中')
                                               ),
                                       default=1,
                                       verbose_name="0下架 1出售中")

    price = models.FloatField(blank=True, null=True,
                              default=0,
                              verbose_name="成本价")

    create_time = models.DateTimeField(auto_now_add=True, verbose_name="添加时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="修改时间")

    class Meta:
        verbose_name_plural = '商品'
        verbose_name = "商品信息"

    def __str__(self):
        return self.goods_code

class UserCollect(models.Model):
    """用户收藏商品"""
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户id")
    goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name="商品", help_text="商品id")
    status = models.CharField(choices=(
                                        (0, '取消收藏'),
                                        (1, '已收藏')
                                       ),
                              default=1,
                              verbose_name="0取消收藏 1已收藏")
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="添加时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="修改时间")

    class Meta:
        verbose_name = '用户收藏'
        verbose_name_plural = verbose_name
        # 唯一联合,一个商品只能收藏一次
        unique_together = ("user", "goods")

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

序列化收藏商品

序列化的时候user字段是隐藏字段,不需要用户传过来,用户只要登录了可以通过request.user获取当前登录的账号 status有2个状态,不需要用户传入,设置read_only=True validators.UniqueTogetherValidator联合校验’user’, ‘goods’字段的唯一性 该验证器可用于unique_together对模型实例施加约束。它具有两个必需参数和一个可选messages参数:

  • queryset 必需-这是应针对其强制执行唯一性的查询集。
  • fields 必填-字段名称的列表或元组,应组成唯一的集合。 这些必须作为字段存在于序列化程序类中。
  • message -验证失败时应使用的错误消息。
代码语言:javascript
复制
from .models import Goods, UserCollect
from rest_framework import validators
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

class UserCollectSerializer(serializers.ModelSerializer):
    # 获取当前登录的用户
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    status = serializers.ChoiceField(choices=(
                                                (0, '取消收藏'),
                                                (1, '已收藏')
                                               ),
                                           read_only=True)

    def to_representation(self, instance):
        """to_representation自定义序列化数据的返回"""
        data = super().to_representation(instance)
        data.update(status=instance.get_status_display())
        return data

    class Meta:
        # validate实现唯一联合,一个商品只能收藏一次
        validators = [
            validators.UniqueTogetherValidator(
                queryset=UserCollect.objects.all(),
                fields=('user', 'goods'),
                # message的信息可以自定义
                message="已收藏"
            )
        ]
        model = UserCollect
        # 收藏的时候需要返回商品的id,因为取消收藏的时候必须知道商品的id是多少
        fields = '__all__'  # 返回全部的字段

添加收藏和查询的视图

代码语言:javascript
复制
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

class UserCollectAPIView(APIView):
    """我的收藏"""

    def get(self, request, *args, **kwargs):
        """查询我的收藏"""
        collect = UserCollect.objects.all().filter(status=1, user=request.user)   # 查询自己的收藏
        serializer = UserCollectSerializer(instance=collect, many=True, context={"request": request})

        return Response({
            "code": 0,
            "msg": "success!",
            "data": serializer.data
        })

    def post(self, request, *args, **kwargs):
        """添加收藏"""
        verify_data = UserCollectSerializer(data=request.data, context={"request": request})
        if verify_data.is_valid():
            save = verify_data.save()
            return Response({
                "code": 0,
                "msg": "success!",
                "data": UserCollectSerializer(instance=save, context={"request": request}).data
            })
        else:
            return Response({
                "code": 10086,
                "msg": "参数不合法",
                "data": verify_data.errors
            })

测试我的收藏功能

收藏商品的时候,传商品id即可

如果已经收藏,会提示已收藏

查询的时候,每个用户只查询自己的,并且状态为1 的数据

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 从零开始学自动化测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 收藏商品
  • 序列化收藏商品
  • 测试我的收藏功能
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档