rest_framework_mongoengine实现后端的增删改查

rest_framework_mongoengine实现后端增删改查

一、增删改查

1. 继承ModelViewSet实现增删改查
  • 父urls.py
path("api/testapp/", include("apps.testapp.urls")), # 测试
  • 子urls.py
# -*- coding: utf-8 -*-
from django.urls import path
from rest_framework_mongoengine.routers import SimpleRouterfrom apps.testapp.views import TestView, ProductViewSeturlpatterns = [# 测试接口...
]model_mango_url = SimpleRouter()
model_mango_url.register(r'product', ProductViewSet)
urlpatterns += model_mango_url.urls
print("urlpatterns============", urlpatterns)
  • models.py
from django.db import models# Create your models here.
from mongoengine import Document, fieldsclass Product(Document):name = fields.StringField(required=True)description = fields.StringField()price = fields.StringField()
  • serializer.py
from rest_framework import serializers
from rest_framework_mongoengine.serializers import DocumentSerializerfrom apps.testapp.models import Productclass ProductSerializer(DocumentSerializer):# 序列化的是后更改了name字段 required=Falsename = serializers.CharField(required=False)class Meta:model = Productfields = '__all__'
  • views.py
from django.http import JsonResponse
from django.shortcuts import render# Create your views here.
from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework.views import APIView
from rest_framework_mongoengine.viewsets import ModelViewSetfrom apps.testapp.models import Product
from apps.testapp.serializers import ProductSerializerclass ProductViewSet(ModelViewSet):queryset = Product.objects.all()serializer_class = ProductSerializer
1.1 创建(create)
1.新增单个
POST {{ipaddr}}api/testapp/product/{"name":"iphone14","description":"十分骄傲了就是佛爱事件的发生","price":"12"
}
2.批量插入
  • urls.py
urlpatterns = [# 批量插入path(r'product/create', ProductViewSet.as_view({'post': 'create_many'})),
]
  • views.py
class ProductViewSet(ModelViewSet):queryset = Product.objects.all()serializer_class = ProductSerializer# 如果重写的是create方法,那么之前的创建单个资源,也会走这个方法,所以为了区分,保留之前的单个字典插入,这里命名craete_manydef create_many(self, request, *args, **kwargs):serializer = self.serializer_class(data=request.data, many=True)if serializer.is_valid():products = [Product(**item) for item in serializer.validated_data]Product.objects.insert(products)return Response(serializer.validated_data, status=201)return Response(serializer.errors, status=400)
  • 测试
POST   {{ipaddr}}api/testapp/product/create[{"name": "iphone16","description": "十分骄傲了就是佛爱事件的发生","price": "12"},{"name": "iphone17","description": "十分骄傲了就是佛爱事件的发生","price": "12"},{"name": "iphone18","description": "十分骄傲了就是佛爱事件的发生","price": "12"}
]
1.2 读取(read)
1.获取所有列表 list
GET {{ipaddr}}api/testapp/product/

说明:底层使用的list方法

2.获取单个详情 retrieve
GET {{ipaddr}}api/testapp/product/660cbeb432362db8ac968ee9/

说明:底层使用的是retrieve

3.分页查询
GET {{ipaddr}}api/testapp/product?page=2&limit=2
  • settings.py
REST_FRAMEWORK = {..."DEFAULT_PAGINATION_CLASS": "dvadmin.utils.pagination.CustomPagination",  # 自定义分页...
}
  • pagination.py
# -*- coding: utf-8 -*-from collections import OrderedDictfrom django.core import paginator
from django.core.paginator import Paginator as DjangoPaginator, InvalidPage
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Responseclass CustomPagination(PageNumberPagination):page_size = 10page_size_query_param = "limit"max_page_size = 999django_paginator_class = DjangoPaginatordef paginate_queryset(self, queryset, request, view=None):"""Paginate a queryset if required, either returning apage object, or `None` if pagination is not configured for this view."""empty = Truepage_size = self.get_page_size(request)if not page_size:return Nonepaginator = self.django_paginator_class(queryset, page_size)page_number = request.query_params.get(self.page_query_param, 1)if page_number in self.last_page_strings:page_number = paginator.num_pagestry:self.page = paginator.page(page_number)except InvalidPage as exc:# msg = self.invalid_page_message.format(#     page_number=page_number, message=str(exc)# )# raise NotFound(msg)empty = Falseif paginator.num_pages > 1 and self.template is not None:# The browsable API should display pagination controls.self.display_page_controls = Trueself.request = requestif not empty:self.page = []return list(self.page)def get_paginated_response(self, data):code = 2000msg = 'success'page = int(self.get_page_number(self.request, paginator)) or 1total = self.page.paginator.count if self.page else 0limit = int(self.get_page_size(self.request)) or 10is_next = self.page.has_next() if self.page else Falseis_previous = self.page.has_previous() if self.page else Falseif not data:code = 2000msg = "暂无数据"data = []return Response(OrderedDict([('code', code),('msg', msg),('page', page),('limit', limit),('total', total),('is_next', is_next),('is_previous', is_previous),('data', data)]))
4.根据name模糊查询 list

重写list方法,最好不要重写retrieve方法,二者区别如下:

获取所有列表 底层使用list方法:api/product/
获取单个资源 底层使用retrieve:api/product/123456789/ # 数字是id

因此,如果重写retrieve方法,那么传递参数的时候如果再拼接api/product/name/ 底层识别路径参数的时候不容易区分是name还是id;

  • views.py
class ProductViewSet(ModelViewSet):queryset = Product.objects.all()serializer_class = ProductSerializerdef list(self, request, *args, **kwargs):"""重写list方法,根据name字段模糊查询,获取所有列表也是走这个方法"""# request.query_params.get('name') 这种方式接受参数 url格式为:/product/?name=apple;# kwargs.get("name")  # 这种方式接受参数 url格式:/product/<str:name>/name = request.query_params.get('name')if name:product = Product.objects.filter(name__icontains=name)serializer = self.get_serializer(product, many=True)return Response(serializer.data)else:print("list方法 获取所有列表============")return super().list(request, *args, **kwargs)
  • 测试
# 根据name模糊查询
GET  {{ipaddr}}api/testapp/product/?name=iphone18
# 查询所有
GET  {{ipaddr}}api/testapp/product/
5.多条件查询 list

重写list方法

  • views.py
from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework.views import APIView
from rest_framework_mongoengine.viewsets import ModelViewSetfrom apps.testapp.models import Product
from apps.testapp.serializers import ProductSerializerclass ProductViewSet(ModelViewSet):queryset = Product.objects.all()serializer_class = ProductSerializerdef list(self, request, *args, **kwargs):"""重写list方法,根据name字段模糊查询,获取所有列表也是走这个方法"""# request.query_params.get('name') 这种方式接受参数 url格式为:/product/?name=apple;# kwargs.get("name")  # 这种方式接受参数 url格式:/product/<str:name>/params = request.query_paramsname = params.get('name')price = params.get('price')# 根据查询参数过滤 querysetqueryset = Product.objects.all()if name:queryset = queryset.filter(name__icontains=name)if price:queryset = queryset.filter(price=price)# 序列化查询结果,并返回响应serializer = self.get_serializer(queryset, many=True)return Response(serializer.data)
  • 测试
GET   {{ipaddr}}api/testapp/product/?name=iphone18&price=136
6.返回部分字段
  • views.py
from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework.views import APIView
from rest_framework_mongoengine.viewsets import ModelViewSetfrom apps.testapp.models import Product
from apps.testapp.serializers import ProductSerializerclass TestView(APIView):class ProductViewSet(ModelViewSet):queryset = Product.objects.all()serializer_class = ProductSerializerdef list(self, request, *args, **kwargs):"""重写list方法,根据name字段模糊查询,获取所有列表也是走这个方法"""# request.query_params.get('name') 这种方式接受参数 url格式为:/product/?name=apple;# kwargs.get("name")  # 这种方式接受参数 url格式:/product/<str:name>/params = request.query_paramsname = params.get('name')price = params.get('price')queryset = Product.objects.all()if name:queryset = queryset.filter(name__icontains=name)if price:queryset = queryset.filter(price=price)# 定义一个包含部分字段的新序列化器class PartialProductSerializer(ProductSerializer):class Meta(ProductSerializer.Meta):fields = ('name', 'price')# 序列化查询结果,并返回响应serializer = PartialProductSerializer(queryset, many=True)return Response(serializer.data)
  • 测试
GET  {{ipaddr}}api/testapp/product/?name=iphone18&price=136[{"name": "iphone18","price": "136"}
]
7.排序查询
  • views.py
from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework.views import APIView
from rest_framework_mongoengine.viewsets import ModelViewSetfrom apps.testapp.models import Product
from apps.testapp.serializers import ProductSerializerclass TestView(APIView):class ProductViewSet(ModelViewSet):queryset = Product.objects.all()serializer_class = ProductSerializerdef list(self, request, *args, **kwargs):"""重写list方法,根据name字段模糊查询,获取所有列表也是走这个方法"""# request.query_params.get('name') 这种方式接受参数 url格式为:/product/?name=apple;# kwargs.get("name")  # 这种方式接受参数 url格式:/product/<str:name>/params = request.query_paramsname = params.get('name')price = params.get('price')queryset = Product.objects.all()if name:queryset = queryset.filter(name__icontains=name)if price:queryset = queryset.filter(price=price)# 定义一个包含部分字段的新序列化器class PartialProductSerializer(ProductSerializer):class Meta(ProductSerializer.Meta):fields = ('name', 'price')# queryset = queryset.order_by('price')  # 按照price字段升序排序queryset = queryset.order_by('-price')  # 按照price字段降序排序# 序列化查询结果,并返回响应serializer = PartialProductSerializer(queryset, many=True)return Response(serializer.data)
  • 测试
GET   {{ipaddr}}api/testapp/product/?name=iphone18[{"name": "iphone18","price": "436"},{"name": "iphone18","price": "166"},{"name": "iphone18","price": "136"},{"name": "iphone18","price": "12"}
]
1.3 更新(update)
1.修改单个
PUT {{ipaddr}}api/testapp/product/660cc1ce799f2e1df6778875/
{"price":"15999"
}
2.批量修改

举例:批量修改name="iphone14"的数据,price更新为1300

  • views.py
# Create your views here.
from rest_framework.response import Response
from rest_framework.decorators import api_view, action
from rest_framework.views import APIView
from rest_framework_mongoengine.viewsets import ModelViewSetfrom apps.testapp.models import Product
from apps.testapp.serializers import ProductSerializerclass ProductViewSet(ModelViewSet):queryset = Product.objects.all()serializer_class = ProductSerializer"""@action说明:methods:一个列表,包含允许的 HTTP 方法。例如,['get', 'post'] 表示这个动作既允许 GET 请求也允许 POST 请求。detail:一个布尔值,指示这个动作是否适用于单个实例。如果设置为 True,则动作的 URL 将包含一个实例的主键,例如 /products/1/batch_update/。如果设置为 False,则动作的 URL 不包含实例的主键,例如 /products/batch_update/。"""@action(methods=['post'], detail=False)def batch_update(self, request):# 获取请求的数据data = request.data# 确保请求的数据中包含了需要更新的名称和价格if 'name' in data and 'price' in data:# 获取要更新的名称和价格name_to_update = data['name']new_price = data['price']# 执行批量更新操作updated_count = Product.objects.filter(name=name_to_update).update(price=new_price)# 返回更新结果return Response({'message': f'Updated {updated_count} products.', 'name': name_to_update, 'new_price': new_price})else:# 如果请求的数据不完整,返回错误信息return Response({'error': 'Name and price fields are required.'}, status=400)
  • 测试
POST  {{ipaddr}}api/testapp/product/batch_update/{"name":"iphone14","price":"1300"
}
1.4 删除(Delete)
1.删除单个资源
DELETE  {{ipaddr}}api/testapp/product/660cbeb432362db8ac968ee9/
2.批量删除
  • views.py
from django.http import JsonResponse
from django.shortcuts import render# Create your views here.
from rest_framework.response import Response
from rest_framework.decorators import api_view, action
from rest_framework.views import APIView
from rest_framework_mongoengine.viewsets import ModelViewSetfrom apps.testapp.models import Product
from apps.testapp.serializers import ProductSerializerclass ProductViewSet(ModelViewSet):queryset = Product.objects.all()serializer_class = ProductSerializer@action(methods=['post'], detail=False)def batch_delete(self, request):# 获取请求的数据data = request.data# 确保请求的数据中包含了需要删除的名称if 'name' in data:# 获取要删除的名称name_to_delete = data['name']# 执行批量删除操作deleted_count = Product.objects.filter(name=name_to_delete).delete()# 返回删除结果return Response({'message': f'Deleted {deleted_count} products.', 'name': name_to_delete})else:# 如果请求的数据不完整,返回错误信息return Response({'error': 'Name field is required.'}, status=400)
  • 测试
POST   {{ipaddr}}api/testapp/product/batch_delete/{"name":"iphone19"
}

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

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

相关文章

如何在苹果手机上安装iOS应用的.ipa文件?

哈喽&#xff0c;大家好呀&#xff0c;淼淼又来和大家见面啦&#xff0c;如今移动应用市场不断的发展&#xff0c;许多开发者小伙伴们都选择将他们的应用发布到苹果App Store上&#xff0c;但是&#xff0c;有时候他们可能希望通过直接分享IPA文件来分发他们的App&#xff0c;那…

自定义javax.validation 校验能用 spring

自定义注解 import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*;Target(ElementType.FIELD) Documented Retention(value RetentionPolicy.RUNTIME) Constraint(validatedBy {IdExistMyTestValidator.class }) public in…

STM32标准库+HAL库 | CPU片内FLASH存储器数据掉电读写

一、片内FLASH 在STM32芯片内部有一个FLASH存储器&#xff0c;它主要用于存储代码&#xff0c;我们在电脑上编写好应用程序后&#xff0c;使用下载器把编译后的代码文件烧录到该内部FLASH中&#xff0c; 由于FLASH存储器的内容在掉电后不会丢失&#xff0c;芯片重新上电复位后&…

ArduPilot开源飞控之ROS系统简介

ArduPilot开源飞控之ROS系统简介 1. 源由2. ROS系统3. 安装2.1 安装Docker2.2 安装ROS2 4. 总结5. 补充资料 1. 源由 之前在ArduPilot开源飞控之硬件SBC分析中讨论过&#xff0c;个人角度最推荐其中两个系统是&#xff1a; Rpanion-server【推荐&#xff0c;简单】BlueOS【推…

SAP Fiori开发中的JavaScript基础知识14 - promise, async, await异步编程

1. 前言 本文将介绍JavaScript中异步编程技术&#xff0c;包括promise, sync, await的使用。 2. Promise 2.1 简介 Promise 是 JavaScript 中用于处理异步操作的一种对象。它代表了一个异步操作的最终完成&#xff08;或失败&#xff09;及其结果值。 Promise 对象有三种状…

Unity之Unity面试题(四)

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之Unity面试题&#xff08;四&#xff09; TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取…

什么是并行通信、串行通信?什么是全双工、半双工、单工? 什么是异步通信、同步通信? 什么是RS232、RS485?什么是pwm?

什么是并行通信、串行通信&#xff1f; 嵌入式系统中的通信是指两个或两个以上的主机之间的数据互交&#xff0c;这里的主机可以是计算机也可以是嵌入式主机&#xff0c;甚至可以是芯片。主机间通信的方式一般可以分为两类&#xff1a;并行通信和串行通信。并行通信是指多个比特…

华为配置静态ARP示例

华为配置静态ARP示例 组网图形 图1 配置静态ARP组网图 静态ARP简介配置注意事项组网需求配置思路操作步骤配置文件相关信息 静态ARP简介 静态ARP表项是指网络管理员手工建立IP地址和MAC地址之间固定的映射关系。 正常情况下网络中设备可以通过ARP协议进行ARP表项的动态学习&…

Android10以上MediaProject截屏

起因 在系统升级到Android10以上之后&#xff0c;之前的截屏方式不能用了&#xff0c;而且必须将MediaProject放在forground service里面跑才行。网上搜了一圈&#xff0c;都是语焉不详或者没有完整的一个代码应用。只能自己写一个&#xff0c;记录下 代码实现 新建一个Scre…

IO多路转接之poll

目录 1. poll 的基本认识 2. poll 基于 select 的突破 3. poll() 系统调用 3.1. struct pollfd 结构 4. poll() 的 demo 5. poll 的总结 1. poll 的基本认识 poll 是一种多路转接的方案&#xff0c; 它的核心功能和 select 一模一样&#xff0c;我们知道 IO 等待事件就绪…

WebLogic 数据源连接泄露

编码时,有时会忘记释放使用的数据源连接,造成连接泄露,没有连接资源可用。 现象 java.sql.SQLException: Cannot obtain XAConnectionat weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1691)at weblogic.jdbc.jta.DataSource.getConnectionIntern…

论文略读:Window Attention is Bugged: How not to Interpolate Position Embeddings

iclr 2024 reviewer 打分 6666 窗口注意力、位置嵌入以及高分辨率微调是现代Transformer X CV 时代的核心概念。论文发现&#xff0c;将这些几乎无处不在的组件简单地结合在一起&#xff0c;可能会对性能产生不利影响问题很简单&#xff1a;在使用窗口注意力时对位置嵌入进行插…

华为再次布局新行业:合作伙伴已超前谋划,该领域将大有可为

华为布局新行业 华为向外界公布了一个重要信息&#xff1a;在过去的三年里&#xff0c;尽管受到美国的制裁&#xff0c;华为仍然成功地完成了超过13000个元器件的国产替代研发&#xff0c;以及4000多块电路板的迭代开发。 不仅在硬件领域取得了显著成就&#xff0c;在软件和生…

oracle 19c数据库W00n进程使用很多PGA内存资源的分析

今天&#xff0c;客户反馈测试环境的数据库PGA资源不足&#xff0c;报错ORA-04036: 实例使用的 PGA 内存超出 PGA_AGGREGATE_LIMIT&#xff1b;分析是多个W00n进程使用大量PGA-触发了BUG&#xff0c;对应解决办法就是打补丁。&#xff08;民间办法就是KILL进程、重启数据库&…

大数据面试高频问题:大数据相关基础组件的维护及调优案例大全

目录 1、 Hadoop HDFS 磁盘空间不足问题 2、 Apache Spark Executor 内存溢出问题

基于云开发和微信小程序的爱宠家系统

基于云开发和微信小程序的爱宠家系统 “Development of PetCare Home System based on Cloud Computing and WeChat Mini Program” 完整下载链接:基于云开发和微信小程序的爱宠家系统 文章目录 基于云开发和微信小程序的爱宠家系统摘要第一章 系统概述1.1 研究背景1.2 研究目…

3d视图模型乱了怎么调?---模大狮模型网

在进行3D建模时&#xff0c;有时候您可能会遇到视图模型混乱的情况。这可能是由于模型结构问题、导入导出错误或编辑操作不当等原因造成的。混乱的模型不仅影响工作效率&#xff0c;还可能导致渲染结果不理想。本文将介绍六种有效的方法来调整混乱的3D视图模型&#xff0c;帮助…

css样式问题 --持续更新

css 去除 el-input 和 el-textarea 边框样式 <style> .el-input__wrapper,.el-textarea__inner {border: none !important;box-shadow: none !important;padding: 0px;} </style>

【数据可视化包Matplotlib】Matplotlib基本绘图方法

目录 一、Matplotlib绘图的基本流程&#xff08;一&#xff09;最简单的绘图&#xff08;仅指定y的值&#xff09;&#xff08;二&#xff09;更一般的绘图&#xff08;同时指定x和y的值&#xff09;&#xff08;三&#xff09;增加更多的绘图元素 二、布局相关的对象——Figur…

Linux系统问题汇总

1. MAC版本VMawre打开一个已有的镜像文件&#xff1a;File——Open——CentOS 7-MySQL.vmx&#xff1b; 2. ifconfig 或者 ifconfig -a查看虚拟机接口及其网络&#xff1b; 问题&#xff1a; 2.1 ens33端口不存在&#xff1a;用ifconfig -a查看即可&#xff1b; 2.2 ens33端…