DRF实操学习——收货地址的设计

DRF实操学习——收货地址的设计

  • 1.行政区划表的设计
  • 2. 行政区划表接口演示
    • 1.返回所有的省份
    • 2. 查询指定上级行政区划的所有子区划,以及展示自身区划
  • 3.行政区划表接口重写
  • 补充:前端请求逻辑
  • 4. 优化
  • 5.收货地址的设计
  • 6. 收货地址表接口重写
  • 7.优化
    • 1. 优化返回的数据
    • 2.增加额外的校验,重写 validate_<field_name> 方法

分析:

  1. 提供收货地址的选择:提供行政区划的三级联动查询,省——市——区
  2. 完成用户保存添加的收货地址

1.行政区划表的设计

在这里插入图片描述

  1. 在users的models中增加模型类Area,然后迁移映射
# 行政区划表
class Area(models.Model):name = models.CharField(max_length=20,verbose_name='名称')# 'self'建立外键关联自身主键。添加的上级行政区划必须是行政区划表中已有的数据# 省份没有上级行政区划 on_delete=models.SET_NULL删除时设置为空,null=True允许为空# blank=True,parent = models.ForeignKey('self',on_delete=models.SET_NULL,null=True,blank=True,verbose_name='上级行政区划')class Meta:db_table = 'area'verbose_name = '行政区划'verbose_name_plural = verbose_name
  1. 将省份等行政区划的基础数据配置进去
    在这里插入图片描述
  2. 编写序列化器
class AreaSerializer(ModelSerializer):class Meta:model = Areafields = ['id','name']
  1. 编写视图
class AreaViewSet(ModelViewSet):queryset = Area.objects.all()serializer_class = AreaSerializer
  1. 增加路由
from django.urls import path
from rest_framework.routers import DefaultRouter
from rest_framework_jwt.views import obtain_jwt_token
from .views import *urlpatterns = [path('login/', obtain_jwt_token),path('image/verification/<uuid:uuid>/', ImageVerifyView.as_view())
]
router = DefaultRouter()
router.register('users', UserViewSet)
router.register('area', AreaViewSet)
urlpatterns += router.urls

2. 行政区划表接口演示

分析:
把查询划分为两个接口

  1. 得到所有的省份:修改list视图函数,返回所有省份
  2. 把省份的id传入,修改详情路由,查询指定上级行政区划的所有子区划,以及展示自身区划

1.返回所有的省份

重写get_queryset方法,当操作为list操作时,查询所有parent=None的数据,即省份

class AreaViewSet(ModelViewSet):queryset = Area.objects.all()serializer_class = AreaSerializerdef get_queryset(self):if self.action == 'list':#查询所有parent=None的数据,即省份return Area.objects.filter(parent=None)else:return self.queryset

2. 查询指定上级行政区划的所有子区划,以及展示自身区划

  1. 优化返回结果,修改序列化器
# 行政区划序列化器
class AreaSerializer(ModelSerializer):"""行政区划自身序列化器"""class Meta:model = Areafields = ['id','name']# 增加一个新的行政区划的序列化器
class ParentSerializer(ModelSerializer):"""行政区划自身序列化器及子级区划"""# parent时外键关联自身,Area表时一对多查询# 生成管理器:源模型类名小写_set。通过管理器获取源模型类的所有数据area_set = AreaSerializer(many=True,read_only=True)class Meta:model = Areafields = ['id','name','area_set']
  1. 重写get_serializer_class
class AreaViewSet(ModelViewSet):queryset = Area.objects.all()serializer_class = AreaSerializerdef get_queryset(self):if self.action == 'list':# 查询所有parent=None的数据,即省份return Area.objects.filter(parent=None)else:return self.queryset# get_serializer返回的是对象,get_serializer_class返回的是类# 重写get_serializer或get_serializer_class都可以def get_serializer_class(self):if self.action == 'retrive':#省份return ParentSerializer else:return AreaSerializer

接口验证如下:
在这里插入图片描述

3.行政区划表接口重写

重写create、update、destroy方法

    @wrap_permisssion(RootPermission)#修改权限为root用户def create(self, request, *args, **kwargs):return ModelViewSet.create(self, request, *args, **kwargs)@wrap_permisssion(RootPermission)#修改权限为root用户def update(self, request, *args, **kwargs):return ModelViewSet.create(self, request, *args, **kwargs)@wrap_permisssion(RootPermission)#修改权限为root用户def destroy(self, request, *args, **kwargs):return ModelViewSet.create(self, request, *args, **kwargs)

补充:前端请求逻辑

在这里插入图片描述
选择省份的输入框,会向后端发送请求,获取所有省份,渲染到前端。比如选择湖北省,然后前端获取到湖北省的id,再次向后端发起请求,获取到湖北省下的所有区划。同理,在根据孝感市的id获取到孝感市下的所有区划。

4. 优化

分析:
特点:增加、删除、修改、更新操作少。查询操作多。
所以可以增加缓存功能,因为msyql性能相对来收比较慢,主要是做持久化数据。redis相当于是内存,高速读取数据库。可以将查询操作多的数据放在redis中,即将高频数据或临时数据缓存。

  1. 下载第三方库drf-extensions
    在这里插入图片描述

  2. 在settings中新增一个缓存配置
    在这里插入图片描述
    在这里插入图片描述

  3. 优化视图

from rest_framework_extensions.cache.mixins import CacheResponseMixin#继承CacheResponseMixin,那么该视图下的所有操作都会缓存到area库中
class AreaViewSet(CacheResponseMixin, ModelViewSet):queryset = Area.objects.all()serializer_class = AreaSerializer
  1. 发送查询请求后,查看redis的4号库,可以查看到数据,后续查询该数据时,会现在redis中查询数据是否存在,存在则直接返回,不存在,则去数据库中查询,然后再缓存在redis中
    在这里插入图片描述
    在这里插入图片描述

5.收货地址的设计

分析:
一个用户可以有多个收货地址:一对多关系。
定义收货地址模型类 ,新建一个收货地址表,外键关联用户表,保存是哪个用户创建的。

  1. 在users的models中增加模型类Address,然后迁移映射
# 行政区划表
class Address(ModelSetMixin):name = models.CharField(max_length=40,verbose_name='地址名')receiver = models.CharField(max_length=40,verbose_name='收货人')# on_delete=models.PROTECT受保护的,防止删除与该外键相关联的对象# 这里都关联了Area表,管理器都是area_set,管理器冲突,因此要重命名管理器名province = models.ForeignKey(Area,on_delete=models.PROTECT,verbose_name='省',related_name='province_address')city = models.ForeignKey(Area,on_delete=models.PROTECT,verbose_name='市',related_name='city_address')district = models.ForeignKey(Area,on_delete=models.PROTECT,verbose_name='区',related_name='district_address')place = models.CharField(max_length=40,verbose_name='详情地址')mobile = models.CharField(max_length=11,verbose_name='手机')user = models.ForeignKey(User,on_delete=models.CASCADE,verbose_name='用户')class Meta:ordering = ['-update_time']db_table = 'adress'verbose_name = '收货地址'verbose_name_plural = verbose_name
  1. 创建序列化器
class AddressSerializer(ModelSerializer):class Meta:model = Addressexclude = ['is_delete']
  1. 编写视图
    分析:
    创建:当前登录用户
    修改:当前登录用户
    删除:当前登录用户
    查询:当前登录用户
    查询详情:当前登录用户
    所以我们可以对查询集进行处理
class AddressViewSet(ModelViewSet):queryset = Address.objects.all()serializer_class = AddressSerializerpermission_classes = [IsAuthenticated]def get_queryset(self):# 之前是判断有没有权限,可以返回数据# 这里直接只能返回该用户的数据,爬虫无法找到return self.request.user.address_set.filter(is_delete=False)

补充另一种写法:
不在视图中写queryset
在这里插入图片描述

则需要在路由中补充basename
在这里插入图片描述

  1. 增加路由
from django.urls import path
from rest_framework.routers import DefaultRouter
from rest_framework_jwt.views import obtain_jwt_token
from .views import *urlpatterns = [path('login/', obtain_jwt_token),path('image/verification/<uuid:uuid>/', ImageVerifyView.as_view())
]
router = DefaultRouter()
router.register('users', UserViewSet)
router.register('area', AreaViewSet)
# 如果在AddressViewSet不写queryset,则需要在路由中
# 增加basename,指定模型类
router.register('address', AddressViewSet, basename='address')
urlpatterns += router.urls

6. 收货地址表接口重写

	@auto_userdef create(self, request, *args, **kwargs):max_count = 3if self.get_queryset().count() >= max_count:return Response({'detail':f'收货地址数量超过{max_count}条上限'},status=HTTP_400_BAD_REQUEST)return ModelViewSet.create(self, request, *args, **kwargs)@update_auto_userdef update(self, request, *args, **kwargs):return ModelViewSet.create(self, request, *args, **kwargs)@destory_auto_userdef destroy(self, request, *args, **kwargs):return ModelViewSet.create(self, request, *args, **kwargs)

7.优化

1. 优化返回的数据

在这里插入图片描述
修改序列化器

class AddressSerializer(ModelSerializer):province_name = serializers.CharField(source='province.name',read_only=True)city_name = serializers.CharField(source='city.name',read_only=True)district_name = serializers.CharField(source='district.name',read_only=True)class Meta:model = Addressexclude = ['is_delete']

查询结果如下:
在这里插入图片描述

2.增加额外的校验,重写 validate_<field_name> 方法

字段级别的校验

from rest_framework.serializers import ModelSerializer
from rest_framework import serializers
from .models import *
import reclass AddressSerializer(ModelSerializer):province_name = serializers.CharField(source='province.name',read_only=True)city_name = serializers.CharField(source='city.name',read_only=True)district_name = serializers.CharField(source='district.name',read_only=True)class Meta:model = Addressexclude = ['is_delete']#自定义校验器,增加额外的校验功能:重写 validate_<field_name> 方法,字段级别的校验# 对手机号码进行校验def validate_mobile(self,value):if not re.match(r'1[3-9]\d{9}$',value):raise serializers.ValidationError('手机号码格式错误')return value

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/433488.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

示例说明:elasticsearch实战应用

Elasticsearch 是一个基于 Lucene 的分布式搜索和分析引擎&#xff0c;广泛应用于日志分析、全文搜索、数据可视化等领域。以下是 Elasticsearch 实战应用的一些关键点和步骤&#xff1a; 1. 环境搭建 首先&#xff0c;你需要在你的环境中安装和配置 Elasticsearch。 安装 E…

一个 Java 语言简化处理 PDF 的框架,提供了一套简单易用的 API 接口,满足多样化需求又能简化开发流程的处理方案(附教程)

前言 当前市面上处理 PDF 文件的工具众多&#xff0c;但它们往往存在一定的局限性&#xff0c;比如复杂交互、功能单一等问题。尤其对于那些需要频繁生成或编辑 PDF 文档的应用场景来说&#xff0c;找到一个既能满足多样化需求又能简化开发流程的处理方案显得尤为重要。那么&a…

中国的互联网电商,终于还是“连上了”

什么才是更好的互联网&#xff1f; 答案很简单&#xff1a;真正的互联。 9月26日&#xff0c;据市场消息&#xff0c;京东物流和菜鸟速递将分别接入淘天、京东平台。同时&#xff0c;京东也将在“双11”前开通支付宝支付&#xff0c;时隔13年再度携手阿里支付体系。 消息一出…

【x**3专享#2】编译 uboot 和 kernel 的文件结构

虚拟机交叉编译环境配置及内核编译步骤说明书 请先查看前篇文章内容 1. 获取虚拟机 IP 地址 打开虚拟机终端&#xff0c;执行以下命令查看虚拟机 IP 地址&#xff1a;ifconfig或者ip addr记录 eth0 或 ens33 等网络接口的 inet 后面的 IP 地址 2. 使用 Xftp 连接虚拟机 打开…

Springboot中yml文件不生效原因分析及解决

在Spring Boot项目中&#xff0c;YML文件是常用的配置文件格式。然而&#xff0c;有时你可能会遇到YML文件中的配置不生效的问题。本文将分析可能的原因并提供解决方案。 1. 格式错误 YML文件非常敏感&#xff0c;任何缩进或语法错误都可能导致配置不被解析。确保使用两个空格…

基于YOLOv5s的无人机航拍输电线瓷瓶检测(附数据集与操作步骤)

本文主要内容:详细介绍了无人机航拍输电线瓷瓶检测的整个过程&#xff0c;从创建数据集到训练模型再到预测结果全部可视化操作与分析。 文末有数据集获取方式&#xff0c;请先看检测效果 现状 输电线路绝缘瓷瓶的检测主要依赖人工巡检。巡检人员需携带专业设备&#xff0c;攀…

Python:百度贴吧实现自动化签到

早知道&#xff0c;还是python。 Github项目仓库在这。 相关API 签到贴吧列表 签到分为两个接口&#xff0c;PC端签到一次经验2&#xff0c;而移动端签到则是一次经验6。该用哪个接口已经很明显了。不过这里还是列出PC端的签到API。 # PC端签到接口 # sign_url "https:…

ROS理论与实践学习笔记——2 ROS通信机制之通信机制实践

5.1 话题发布 需求描述&#xff1a;编码实现乌龟运动控制&#xff0c;让小乌龟做圆周运动。 实现分析&#xff1a; ①乌龟运动控制实现&#xff0c;关键节点有两个&#xff0c;一个是乌龟运动显示节点 turtlesim_node&#xff0c;另一个是控制节点&#xff0c;二者是订阅发布模…

用Swift实现验证回文字符串

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&#xff0c;如果它是 回文串 &#xff0c;返回 true &#xff1b;否则&#…

AI创作类工具系列之:芝士AI(paperzz)详细测评介绍

学生们&#xff01;又到了写论文的时候~以前以为大家的论文都是一个字一个字敲出来&#xff0c;然后反复修改&#xff0c;熬着大夜改论文。 后来才知道原来大家都会利用工具辅助自己写论文啊&#xff01;今天我就告诉大家一款非常好用的AI写作网站&#xff0c;节省时间&#xf…

代码随想录冲冲冲 Day58 图论Part9

47. 参加科学大会&#xff08;第六期模拟笔试&#xff09; 根据昨天的dijkstra进行堆优化 使用的原因是点多但边少 所以直接对于边进行操作 1.对于priority_queue来说 这是最小堆, 小于的话就是最大堆 之后由于是根据边来说的 所以新建一个Edge并且初始化一下 之后由于使用…

The Open Group 2024生态系统架构·可持续发展年度大会全面解读

在全球数字化转型加速的时代背景下&#xff0c;人工智能技术正以前所未有的速度重塑各行各业的生态系统。尤其是随着ChatGPT、Sora等技术的爆发&#xff0c;AIGC&#xff08;人工智能生成内容&#xff09;技术在多个领域展现出超越人类的能力&#xff0c;AGI&#xff08;通用人…

C语言-线程

一,线程的概念 1,线程的定义 在 C 语言中&#xff0c;线程是程序执行的最小单位&#xff0c;它是进程中的一个实体&#xff0c;是被系统独立调度和分派的基本单位。 2、线程的特点 轻型实体&#xff1a;线程是一个轻型实体&#xff0c;它只拥有必不可少的资源&#xff0c;如程…

Spring Security 是一个强大的和高度可定制的身份验证和访问控制框架。它是 Spring 项目家族的一员,用于构建安全的 Java 应用程序。

Spring Security 是一个强大的和高度可定制的身份验证和访问控制框架。它是 Spring 项目家族的一员&#xff0c;用于构建安全的 Java 应用程序。Spring Security 提供了全面的安全服务&#xff0c;从基本的登录认证到复杂的访问控制&#xff0c;几乎涵盖了所有与安全相关的需求…

Paxos 协议详解:分布式系统一致性的基石

文章目录 1. 分布式系统与一致性问题1.1 分布式系统的定义1.2 一致性问题的起源1.3 CAP 定理及其影响1.4 分布式系统中的失败假设 2. Paxos 协议的背景与介绍2.1 Paxos 协议是什么2.3 Paxos 解决什么问题 3. Paxos 的基本原理3.1 Paxos 角色3.2 Paxos 的多数原则3.3 Paxos 协议…

音视频入门基础:FLV专题(1)——FLV官方文档下载

一、FLV简介 Flash Video&#xff08;简称FLV&#xff09;&#xff0c;是一种网络视频格式&#xff0c;用作流媒体格式&#xff0c;它的出现有效地解决了视频文件导入Flash后&#xff0c;使导出的SWF文件体积庞大&#xff0c;不能在网络上有效使用等缺点。 一般FLV文件包在SW…

js删除emoji表情问题

emoji标签占位两个 &#xff0c;直接删除后一位会出现乱码符&#xff1b; 判断是否是emoji function isEmoji(char) {let code char.charCodeAt(0);return code>55296&&code<57343 } // 使用方法&#xff0c;传入单字符 console.log(isEmoji(1)); // false con…

手把手教你找到海外网红合作:海外红人营销渠道

在全球范围内&#xff0c;许多企业寻求与知名网红建立合作关系&#xff0c;以推广产品、共同创作内容或探索其他合作形式。以下是一些有效的方法来实现这一目标&#xff1a; 利用社交媒体平台&#xff1a;社交媒体是寻找海外网红的首选途径。平台如Instagram、YouTube和TikTok拥…

2025届 深圳 嵌入式岗 秋招上岸记录

文章目录 1 背景2 准备阶段2.1 前期2.1.1 掌握的技术栈2.1.2 项目经历2.1.3 比赛&奖学金经历 2.2 中期2.2.1 简历准备2.2.2 个人信息准备2.2.3 企业以及岗位信息的收集2.2.4 个人资料的准备 2.3 简历投递2.3.1 网申2.3.2 招聘会现场投递 3. 简历投递后3.1 测评3.2 笔试3.3 …

基于quill2.0的富文本编辑器,Fluent Editor,支持表格,图片,表情等

官网&#xff1a;Fluent Editor | 基于 Quill 2.0 的富文本编辑器 安装 npm i opentiny/fluent-editor quill 使用案例 <template><div class"publish-form-container"><!-- TODO --><div ref"quillEditorRef" class"quill…