drf(3)
1 不使用drf编写5个接口
1.1 路由
urlpatterns = [
path('books/', views.BookView.as_view()),
path('books/<int:pk>', views.BookDetailView.as_view()),
]
1.2 视图类
# 图书新增:psot 图书查询所有:get
class BookView(View):
def get(self, request):
books = []
book_list = Book.objects.all()
# book_list=[book1,book2]
# 组装成 [{name:银瓶梅,pirce:18},{name:银瓶梅,pirce:18}]
for book in book_list:
books.append({'id':book.id,'name': book.name, 'price': book.price})
return JsonResponse(books, safe=False,json_dumps_params={'ensure_ascii':False})
def post(self,request):
# 前端传入的
name=request.POST.get('name')
price=request.POST.get('price')
# 存到表中
book=Book.objects.create(name=name,price=price)
# return JsonResponse({'id':book.id,'name':book.name,'price':book.price})
return JsonResponse({'msg':'新增成功','code':100})
# 图书查询一个:get ,图书修改一个:put ,图书删除一个:delete
class BookDetailView(View):
def get(self,request,pk):
book = Book.objects.all().filter(pk=pk).first()
return JsonResponse({'id':book.id,'name':book.name,'pirce':book.price})
def delete(self,request,pk):
Book.objects.all().filter(pk=pk).delete()
return JsonResponse({'code':100,'msg':"删除成功"})
def put(self,request,pk):
# 前端传入的,put请求从django 的POST取不出来
import json
try:
data=json.loads(request.body)
except Exception as e:
data=request.POST
request.data=data
book=Book.objects.all().filter(pk=pk).first()
book.price=request.data.get('price')
book.name=request.data.get('name')
book.save()
return JsonResponse({'code':100,'msg':"修改成功"})
3 序列化类Serializer的反序列化
3.1 使用drf的APIView写5个接口
from rest_framework.views import APIView
# 图书新增:psot 图书查询所有:get
class BookView(APIView):
def get(self, request):
books = []
book_list = Book.objects.all()
for book in book_list:
books.append({'id':book.id,'name': book.name, 'price': book.price})
return JsonResponse(books, safe=False,json_dumps_params={'ensure_ascii':False})
def post(self,request):
# 前端传入的,继承了APIView
name=request.data.get('name')
price=request.data.get('price')
# 存到表中
book=Book.objects.create(name=name,price=price)
# return JsonResponse({'id':book.id,'name':book.name,'price':book.price})
return JsonResponse({'msg':'新增成功','code':100})
# 图书查询一个:get ,图书修改一个:put ,图书删除一个:delete
class BookDetailView(APIView):
def get(self,request,pk):
book = Book.objects.all().filter(pk=pk).first()
return JsonResponse({'id':book.id,'name':book.name,'pirce':book.price})
def delete(self,request,pk):
Book.objects.all().filter(pk=pk).delete()
return JsonResponse({'code':100,'msg':"删除成功"})
def put(self,request,pk):
book=Book.objects.all().filter(pk=pk).first()
book.price=request.data.get('price')
book.name=request.data.get('name')
book.save()
return JsonResponse({'code':100,'msg':"修改成功"})
3.2 使用APIView+序列化类(序列化:查单个,查所有)+Response来写5个接口
序列化类
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.Serializer):
# read_only=True 意思是只读,只用来做序列化,不用来做反序列化
# 如果不写read_only=True,这个字段必传,如果不传,数据校验不过
# 如果写了read_only=True,这个字段不传
id=serializers.IntegerField(read_only=True) # model中Auto,本质就是数字,IntegerField
name=serializers.CharField(max_length=8,min_length=3,error_messages={'max_length':'太长了'})
# price=serializers.IntegerField()
price=serializers.CharField(max_length=1000) # 写成CharField也能映射成功
视图类
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializer import BookSerializer
# 图书新增:psot 图书查询所有:get
class BookView(APIView):
def get(self, request):
book_list = Book.objects.all()
ser=BookSerializer(instance=book_list,many=True)
return Response(ser.data)
def post(self,request):
# 前端传入的,继承了APIView
name=request.data.get('name')
price=request.data.get('price')
# 存到表中
book=Book.objects.create(name=name,price=price)
# return JsonResponse({'id':book.id,'name':book.name,'price':book.price})
return Response({'msg':'新增成功','code':100})
# 图书查询一个:get ,图书修改一个:put ,图书删除一个:delete
class BookDetailView(APIView):
def get(self,request,pk):
book = Book.objects.all().filter(pk=pk).first()
ser = BookSerializer(instance=book)
return Response(ser.data)
def delete(self,request,pk):
Book.objects.all().filter(pk=pk).delete()
return Response({'code':100,'msg':"删除成功"})
def put(self,request,pk):
book=Book.objects.all().filter(pk=pk).first()
book.price=request.data.get('price')
book.name=request.data.get('name')
book.save()
return Response({'code':100,'msg':"修改成功"})
3.3 使用APIView+序列化类(序列化:查单个,查所有 反序列化:新增一个,修改一个)+Response来写5个接口
序列化类
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.Serializer):
# read_only=True 意思是只读,只用来做序列化,不用来做反序列化
# 如果不写read_only=True,这个字段必传,如果不传,数据校验不过
# 如果写了read_only=True,这个字段不传
id=serializers.IntegerField(read_only=True) # model中Auto,本质就是数字,IntegerField
name=serializers.CharField(max_length=8,min_length=3,error_messages={'max_length':'太长了'})
# price=serializers.IntegerField()
price=serializers.CharField(max_length=1000) # 写成CharField也能映射成功
def create(self, validated_data): # 代码一点没少写,甚至多了,好处解耦了,view代码少了
# validated_data就是校验过后的数据
# 高级
book=Book.objects.create(**validated_data)
# 菜鸡
# name=validated_data.get('name')
# price=validated_data.get('price')
# book = Book.objects.create(name=name,price=price)
return book # 一定要return新增的对象
def update(self, instance, validated_data):
# instance 是要修改的对象
# validated_data是校验过后数据
instance.name=validated_data.get('name')
instance.price=validated_data.get('price')
instance.save() # 一定不要忘了保存,才存到数据库
return instance # 一定要return新增的对象
视图类
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializer import BookSerializer
# 图书新增:psot 图书查询所有:get
class BookView(APIView):
def get(self, request):
book_list = Book.objects.all()
ser=BookSerializer(instance=book_list,many=True)
return Response(ser.data)
def post(self,request):
# 反序列化---》传得是data=前端传入的数据request.data
ser=BookSerializer(data=request.data)
# 数据校验
if ser.is_valid(): # forms组件就这么做的
# 保存-->会报错----》需要在序列化类中重写create方法
ser.save()
return Response({'msg':'新增成功','code':100})
else:
print(ser.errors)
return Response({'msg': '数据没有校验通过', 'code': 101})
# 图书查询一个:get ,图书修改一个:put ,图书删除一个:delete
class BookDetailView(APIView):
def get(self,request,pk):
book = Book.objects.all().filter(pk=pk).first()
ser = BookSerializer(instance=book)
return Response(ser.data)
def delete(self,request,pk):
Book.objects.all().filter(pk=pk).delete()
return Response({'code':100,'msg':"删除成功"})
def put(self,request,pk):
# 修改,就有book对象,拿到要修改的对象
book=Book.objects.filter(pk=pk).first()
# 使用data的数据,修改book这个对象
ser = BookSerializer(instance=book,data=request.data)
if ser.is_valid():
# 会报错,需要重写序列化类的updata方法
ser.save()
return Response({'code':100,'msg':"修改成功"})
else:
return Response({'code': 101, 'msg': "修改失败"})
3.4 重点总结
# 改了put方法和post方法
# 1 在视图类中使用
# 新增
ser=BookSerializer(data=request.data)
if ser.is_valid():
ser.save()
# 修改
ser=BookSerializer(instance=book,data=request.data)
if ser.is_valid():
ser.save()
# 2 在序列化类中,重写create和updata
def create(self, validated_data):
book=Book.objects.create(**validated_data)
return book
def update(self, instance, validated_data):
instance.name=validated_data.get('name')
instance.price=validated_data.get('price')
instance.save() # 一定不要忘了保存,才存到数据库
return instance # 一定要return新增的对象
#### 每个字段有自己的校验规则#####
# 数据校验---》序列化类的字段,有字段属性
# 在字段上加属性---》就会按这个属性校验
name=serializers.CharField(max_length=8,min_length=3)
price=serializers.CharField(min_length=1000) # 写成CharField也能映射成功
# 拿到数据校验失败的原因
ser.errors
#### 校验是否是以sb开头---》参照forms组件的---》局部钩子,全局钩子
4 局部和全局钩子
# 无论新增还是修改,只要执行ser.is_valid()就会触发校验
# 牢牢记住:先走字段自己的校验规则---》再走局部钩子---》再走全局钩子
# 写在序列化类中的局部钩子函数,校验单个字段
# 写在序列化类中的全局钩子函数,校验所有字段
# 局部钩子,校验书名不能以sb开头 forms组件没有,validate有
def validate_name(self,name):
# name就是 要校验的字段对应的前端传入的值
if name.startswith('sb'):
# 校验失败,抛异常
raise ValidationError('不能以sb开头')
else:
return name
# 全局钩子
def validate(self, attrs):
# attrs 校验过后的数据---》字段自己校验完后,局部钩子走完过的数据
name=attrs.get('name')
price=attrs.get('price')
# 加判断,如果通过,就返回attrs
# 如果不通过就抛异常
if name == price:
raise ValidationError('名字和价格不能一样')
else:
return attrs
5 序列化类ModelSerializer的使用
# Serializer基类,序列化类都要继承它,写字段,重写create和updata方法
# 有没有一种简单方案,不写字段了(因为字段跟表有对应关系),不写update和create了
# 原来必须要重写update和create了的原因是---》新增不知道要增加到哪个表中去
# ModelSerializer就可以完成---》跟表有对应关系---》字段不用写了,存到哪也知道,不写update和create了
# 重点:
1 class Meta: 中model和fields意思
2 给字段类加属性 extra_kwargs
3 局部全局钩跟之前没有任何区别
4 create和update不需要写了
5 可以重写某个字段,但注意缩进
class BookSerializer(serializers.ModelSerializer):
# 要序列化的字段,没有写,但是写了model=Book,它自动把Book表中的字段映射出来,相当于
# name = serializers.CharField(max_length=32)
# price = serializers.IntegerField()
# 缩进关系搞懂
class Meta:
model = Book # 跟Book做对应
# fields='__all__' # 序列化和反序列化Book中的所有字段
fields = ['name', 'price'] # 只序列化和反序列化某几个字段
# 重点: 如果不重写字段,但是我想给字段类加属性---》使用下面的方式
# 如果不这样写,name会默认使用model的规则max_length=32
# 如果这样写了,最大长度是8 ,最小长度是3
extra_kwargs = {
'name': {'max_length': 8, 'min_length': 3},
'price': {'max_value': 88}
}
# 表示重写name这个字段,会走它的规则
# name=serializers.CharField(max_length=8,min_length=3)
# 之前教的局部钩子和全局钩子完全一样,一毛一样
# 不需要重写create和update方法了,因为ModelSerializer已经写了
drf(3)的更多相关文章
- DRF如何序列化外键的字段
我觉得在有些应用场景下,这个操作是有用的,因为可以减少一个AJAX的请求,以增加性能. 当然,是二次请求,还是一次传输.这即要考虑用户体验,还要兼顾服务器性能. 一切是有条件的平衡吧.就算是一次传输, ...
- DRF限制访问频次
官方文档:https://www.django-rest-framework.org/api-guide/throttling/ 1.什么场景下需要限制访问频次呢? 1)防爬虫:爬虫可能会在短时间内大 ...
- DRF缓存
对于现在的动态网站来讲,所有的界面展示都是通过客户端请求服务端,服务端再去请求数据库,然后将请求到的数据渲染后返回给客户端.用户每次访问页面都需要去请求数据库,如果同时有多个人访问的话,对于我们的数据 ...
- drf相关问题
drf自定义用户认证: 登录默认 使用django的ModelBackend,对用户名和密码进行验证.但我们平时登录网站时除了用户名也可以用邮箱或手机进行登录,这就需要我们自己扩展backend 一. ...
- DRF 缓存解决方案 drf-extensions / redis
drf-extensions 概述 drf-extensions组件内部提供了 DRF 的本地内存方式的缓存方式 本地内存方式缓存在项目重启后则会消失 官方点击 这里 安装 pip3 install ...
- DRF 商城项目 - 用户( 登录, 注册,登出,个人中心 ) 逻辑梳理
用户登录 自定义用户登录字段处理 用户的登录时通过 手机号也可以进行登录 需要重写登录验证逻辑 from django.contrib.auth.backends import ModelBacken ...
- luffy项目后台drf搭建(1)
一 进入虚拟环境 打开crm,输入命令 workon luffy 虚拟环境使用文档 二 安装基本类库 pip install django pip install PymySQL pip instal ...
- DRF项目创建流程(1)
一 web应用模式 前后端不分离 前后端分离 二 RESTFUL API规范 REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态 ...
- DRF初识与序列化
一.Django的序列化方法 1.为什么要用序列化组件 做前后端分离的项目,我们前后端数据交互一般都选择JSON,JSON是一个轻量级的数据交互格式.那么我们给前端数据的时候都要转成json格式,那就 ...
- restfull规范、DRF视图和路由
一.restfull规范的简单介绍 1.介绍 REST:表述性状态转移,是一种web交互方案 资源:在web中只要有被引用的必要都是资源 URI: URI 统一资源标识符 URL 统一资源定位符 统一 ...
随机推荐
- 大道至简读后感以及JAVA伪代码
<大道至简>这本书引用<愚公移山>一文,生动完美的诠释了编程的整个过程.在两千年前的寓言中,愚公集项目组织者.团队经理.编程人员.技术分析师等众多角色于一身.首先是原始需求的产 ...
- 修复右键批量打印PDF文件的功能
bat文件内容如下, 直接右键管理员运行即可. @echo off rem "功能描述:修复右键批量打印PDF文件的功能" rem "制作人:赵龙" rem & ...
- 几十行代码实现简易版koa~
application.js const http = require("http")// 洋葱模型 function compose(middleware){ return fu ...
- Vulnhub 靶场 BEELZEBUB: 1
Vulnhub 靶场 BEELZEBUB: 1 前期准备 靶机地址:https://www.vulnhub.com/entry/beelzebub-1,742/ kali攻击机ip:192.168.1 ...
- Flink写入Redis集群 重写flink-connector-redis包,解决Cluster无法输入密码问题
起因:使用flink的时候难免和redis打交道,相信大家都使用过flink-connector-redis来处理,但是当我想要使用RedisSink写入集群时,发现居然不支持使用密码,于是有了这篇笔 ...
- 吴恩达老师机器学习课程chapter04——神经网络
吴恩达老师机器学习课程chapter04--神经网络 本文是非计算机专业新手的自学笔记,高手勿喷,欢迎指正与其他任何合理交流. 本文仅作速查备忘之用,对应吴恩达(AndrewNg)老师的机器学期课程第 ...
- java的集合以及数据结构
一.集合 1.介绍 红色为接口 蓝色为实现类 2.三种遍历方式 迭代器 增强for lambda表达式 Integer[] arr = col.toArray(new Integer[col.size ...
- 【转载】win10怎么设置窗口护眼?
转载地址:http://www.downza.cn/xy/122656.html win10设置窗口护眼模式的方法 2021-04-13 13:30:54来源:下载之家作者:down 小伙伴们你们知道 ...
- SpringCloud-Hoxton.SR1-config整合
1.前一篇讲到了整合eureka和gateway,实现了服务的发现与注册以及网关的统一入口,这一篇在此基础上整合分布式配置中心config,首先新建一个子项目config-services作为服务端, ...
- 项目中pom.xml的某些坐标无法加载
项目中pom.xml的某些坐标无法加载 maven官方查找对应的坐标文件下载 https://mvnrepository.com/artifact/com.fasterxml.jackson.core ...