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

前言

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

收藏商品

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

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 -验证失败时应使用的错误消息。

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__' # 返回全部的字段

添加收藏和查询的视图

# 作者-上海悠悠 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年第六期《python接口自动化+测试开发》课程,1月9号开学(火热报名中!)

本期上课时间:1月9号-4月18号,每周六、周日晚上20:30-22:30

(0)

相关推荐

  • Python中django.db.models.Model方法

    Python中django.db.models.Model方法的用法:示例1: model_format_dict123456789101112131415161718# 需要导入模块: from d ...

  • Django的开发流程与数据库设计

    引言:项目开发流程: 需求分析(成员:架构师 .产品经理 .开发者组长) 在跟客户谈需求之前,会大致先了解客户的需求,然后自己先设计一套比较好写的方案.跟客户沟通交流中引导客户往我们之前想好的方案上面 ...

  • Django学习笔记

    初始Django Django 最初被设计用于具有快速开发需求的新闻类站点,目的是要实现简单快捷的网站开发.Django是一个开放源代码的 Web 应用框架,由Python写成.采用了 MVT 的软件 ...

  • python测试开发django -140.Bootstrap 缩略图

    前言 网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 class .thumbnail 的& ...

  • python测试开发django -143.Bootstrap 表单控件校验状态

    前言 Bootstrap 对表单控件的校验状态,如 error.warning 和 success 状态,都定义了样式.使用时,添加 .has-warning..has-error 或 .has-su ...

  • python测试开发django -142.Bootstrap 表单(form)

    前言 HTML 表单用于收集不同类型的用户输入.boostrap中表单有几种样式 基本垂直表单 内联表单 form-inline 水平排列表单 form-horizontal 基本表单实例 单独的表单 ...

  • python测试开发django -141.Bootstrap 面板(Panels)

    # 前言 面板组件用于把 DOM 组件插入到一个盒子中.创建一个基本的面板,只需要向 元素添加 class .panel 和 class .panel-default 即可 基础面板 不带标题的基本面 ...

  • python测试开发django -144.Ace Editor 在线编辑python代码

    前言 网页上想在线编辑代码,可以使用Ace Editor 在线编辑实现.比如我们想实现一个功能,在网页版上写python代码,能有python的语法自动补齐功能. Ace Editor 在线编辑 AC ...

  • python测试开发django-10.django连接mysql

    前言 Django 对各种数据库提供了很好的支持,包括:PostgreSQL.MySQL.SQLite.Oracle.本篇以mysql为例简单介绍django连接mysql进行数据操作 Django连 ...

  • python测试开发django-73.django视图 CBV 和 FBV

    前言 FBV(function base views) 就是在视图里使用函数处理请求,这一般是学django入门的时候开始使用的方式. CBV(class base views) 就是在视图里使用类处 ...

  • python测试开发django-83.Dockerfile部署django项目

    前言 现在流行用 docker 部署环境,python 开发的 django 项目也可以写个 Dockefile 文件,方便docker部署. django 是依赖于python环境的,所有镜像制作是 ...

  • python测试开发django-1.开始hello world!

    前言 当你想走上测试开发之路,用python开发出一个web页面的时候,需要找一个支持python语言的web框架.django框架有丰富的文档和学习资料,也是非常成熟的web开发框架,想学pytho ...