【 一 】request对象
request
是被drf
封装了一层新的request
对象,django
原生的request
封装在新对象的_request
属性里,可以使用request._request
访问原生request
但django
为了方便 封装时通过__getattribute__
和__getattr__
做了处理 直接使用request.method
也能访问到request._request.method
1.解析器
不用的话 默认支持JSONParser,FormParser,MultiPartParser三种解析器
需要改默认 需要改全局配置 setting里新增
例:DEFAULT_PARSER_CLASSES":[“rest_framework.parsers.JSONParser”]
单个配置解析器JSONParser,FormParser
from rest_framework.parsers import JSONParser, FormParser
from rest_framework.negotiation import DefaultContentNegotiationclass UserInFo(APIView):def get(self,request, *args,**kwargs):# 所有解析器parser_classes = [JSONParser,FormParser] #JSON格式和formdata# 根据请求,匹配对应的解析器 寻找content_negotiation_class = DefaultContentNegotiation#获取参数方法request.query_params.get("id") #获取get url参数 id#post请求#request.data
文件解析器
from rest_framework.parsers import MultiPartParser
class UserInFo(APIView):def post(self,request,params):parser_classes = [ MultiPartParser] #文件解析器包括 文件和其他表单#获取文件对象file=request.data.get("img")
2.获取参数
1.读取请求头的content-type类型读取
2.根据不同类型获取解析器
#http://127.0.0.1:8000/getUserInfo/?id=1&&name=xxxx
request.query_params.get("id") #获取get url参数 idrequest.data #获取请求体 post 参数
【 二 】DRF 中的模型序列化(重要)
【0】为什么要使用序列化
'''1 基于APIView写5个接口-做序列化的时候,方法很笨,手动做的-后期如果想多序列化某个或少序列化某个字段,比较麻烦'''#2 借助于 drf 提供的序列化类1 帮助我们快速序列化2 帮助我们做反序列化之前的数据校验3 帮助我们做反序列化# 3 序列化类使用之序列化3.1 写一个类,继承Serialier3.2 在类中写字段,字段就是要序列化的字段3.3 在视图函数中,序列化类,实例化得到对象,传入该传的参数- 多条- 单条3.4 调用序列化类对象的 serializer.data 方法完成序列化
【1】序列化组件使用原理
- 序列化: 序列化器会把模型对象转换成字典,经过response以后变成json字符串
- 反序列化: 把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型
- 反序列化: 完成数据校验功能
【2】序列化组件serializer的简单使用
写一个序列化类
在类中写要序列化的字段,想序列化哪个字段,就在类中写哪个字段
在视图类中导入该序列化类,实例化序列化类得到序列化类的对象,将需要序列化的对象传入
序列化类的对象.data 是一个字典
把字典返回,如果不使用rest_framework提供的Response,就得使用JsonResponse
【3】序列化之查询、删除指定id的接口
# 1 基于View+JsonResponse编写5个接口-1 序列化需要自己做-2 post提交数据,如果是json格式,在request.POST取不到数据--》request.bodydic=json.loads(request.body) # request.body bytes格式Book.objects.create(**dic)
- 创建任意名称的py文件,在该文件中创建序列化类,该序列化类需要继承APIView from。
问:
这个序列化创建的表跟我models.py文件中的Book的表并是不是同一张表
答:
在 Django 中,
models.py中定义的模型类和
rest_framework 中的序列化器不是同一个概念。
在使用 Django REST Framework 进行 API 开发时,通常需要同时使用模型类和序列化器
- 模型类(Model):模型类定义了数据的结构,它们对应于数据库中的表。通过定义模型类,您可以轻松地与数据库进行交互,包括检索、创建、更新和删除数据。
- 序列化器(Serializer):序列化器用于定义 API 的输入和输出格式。它们负责将模型类实例转换为 JSON 或其他格式,以便通过 API 进行传输,并且还能够将传入的数据反序列化为模型实例。序列化器还可以用于验证传入的数据是否符合预期的格式和规则。
通过使用序列化器,您可以轻松地在 Django 中创建强大的 RESTful API,而无需手动编写数据转换和验证逻辑。序列化器可以帮助您更高效地处理数据,并提供了一种清晰的方式来定义 API 的输入和输出格式。
【3.0】JsonResponse跟Response的区别
JsonResponse
和 Response
是用于在 Django 中返回 HTTP 响应的两种不同方式。
-
JsonResponse
:
JsonResponse
是 Django 中的一个类,用于返回 JSON 数据格式的 HTTP 响应。- 它是从
django.http
模块中导入的,通常用于 Django 视图函数中。 - 使用
JsonResponse
可以方便地将 Python 数据结构(如字典或列表)转换为 JSON 格式,并将其作为响应的主体返回给客户端。
示例:
from django.http import JsonResponsedef my_view(request):data = {'key': 'value'}return JsonResponse(data)
-
Response
:
Response
是 Django REST Framework(DRF)中的一个类,用于返回 HTTP 响应。- 它是从
rest_framework.response
模块中导入的,用于 DRF 的视图函数或视图类中。 Response
不仅可以返回 JSON 格式的数据,还可以返回其他格式的数据(如 XML、HTML 等)。- 它提供了更多的灵活性和功能,如内容协商(Content Negotiation)、状态码的自定义、序列化器的使用等。
示例:
from rest_framework.response import Response
from rest_framework.views import APIViewclass MyAPIView(APIView):def get(self, request):data = {'key': 'value'}return Response(data)
总的来说,JsonResponse
适用于基于 Django 的项目,特别是在处理简单的 JSON 数据时;而 Response
适用于使用 Django REST Framework 构建的 API,提供了更多的功能和灵活性。
【3.1】定义一个Serializer序列化器
from django.db import modelsclass Book(models.Model):name = models.CharField(max_length=88)price = models.IntegerField()publish = models.CharField(max_length=66)
问:
是不是在views.py中使用-序列化后就不需要用from django.http import JsonResponse这个的方法来而是用from rest_framework.response import Response这个方法对吧
答:
在 Django REST Framework 中,通常使用 Response
类来返回 API 的响应,而不是直接使用 Django 中的 JsonResponse
。Response
类提供了更多的功能,可以自动将数据序列化为 JSON(或其他格式),并设置正确的 HTTP 头部。这使得处理 API 响应更加简单和灵活。
【3.2】在views.py
- 在序列化数据的时候,需要指定many=True,因为查到的数据是多条
- 不需要定义serializer.py文件
def get(self, request):books = Book.objects.all()book_ser = BookSerializer(books, many=True)return Response(book_ser.data)
from .models import Book
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializer import BookSerializer# 查询多条数据
# http://127.0.0.1:8000/Api01/books/
class BookView(APIView):def get(self, request):res_list = Book.objects.all()# 要序列化的qs对象,但是如果是多条数据,必须加 many=Trueserializer = BookSerializer(instance=res_list, many=True) # instance=None, data=emptyreturn Response({'code': 100, 'msg': '查询成功', 'results': serializer.data})# 查询单条数据
# http://127.0.0.1:8000/Api01/books/1/
class BookDetailView(APIView):def get(self, request,pk):res_list = Book.objects.filter(pk=pk).first()# 要序列化的qs对象,但是如果是多条数据,必须加 many=True 则单条不用serializer = BookSerializer(res_list)return Response({'code': 100, 'msg': '查询成功', 'results': serializer.data})
- 删除跟查询一样
from .models import Book
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializer import BookSerializer
from rest_framework import status
from django.shortcuts import get_object_or_404
class BookView(APIView):def delete(self,request,pk):# try:# # 尝试获取要删除的书籍对象# book = Book.objects.get(pk=pk)# except Book.DoesNotExist:# # 如果找不到对应的书籍,则返回 404 错误# raise NotFound("Book not found")instace = get_object_or_404(Book,pk=pk)instace.delete()return Response({'code': 100, 'msg': '查询成功'}, status=status.HTTP_204_NO_CONTENT)
注意:
我在上述的代码中,BookView
类继承自 Django Rest Framework 的 APIView
类,用于处理书籍的查询请求。在 get
方法中,您使用 Book.objects.all()
查询了所有的书籍记录,并将其序列化为 JSON 格式的数据,然后将其作为响应返回给客户端。
对于添加、更新和删除操作,您需要更复杂的逻辑来确保数据的合法性和完整性。一般来说,这些操作需要在视图中进行验证,并根据验证结果执行相应的操作。在 Django Rest Framework 中,您可以通过重写视图的 post
、put
、patch
和 delete
方法来实现这些操作。
【4】反序列化之更改、增加数据
-
增、改
-
这个就用到了
from rest_framework.exceptions import ValidationError
跟函数的validated_data
的方法了。 -
在我们定义的
Serializers.py文件中
-
需要在序列化类中定义校验规则,如果客户端返回给后端的数据符合校验规则,就需要将数据保存到数据库,当数据通过校验的时候,如果不在序列化类中重写update方法就会抛出异常。
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from Api01.models import Bookclass BookSerializer(serializers.Serializer):name = serializers.CharField()price = serializers.IntegerField()publish = serializers.CharField()def create(self,validated_data):# 简单的来说就是验证book里面的数据是否合法book = Book.objects.create(**validated_data)return bookdef update(self, instance, validated_data):# instance:对象# validated_data 数据# 笨办法-y优化--》使用反射instance.name = validated_data.get('name')instance.price = validated_data.get('price')instance.publish = validated_data.get('publish')instance.save() # 更改保存到数据中return instance
- urls.py
from django.urls import path,include
# BookView、BookDetailView 这个就是我在views.py 定义的类
from Api01.views import BookView,BookDetailView
urlpatterns = [path('books/', BookView.as_view()),path('books/<int:pk>/', BookView.as_view()),]
class BookView(APIView):def post(self, request):# 前端无论以什么编码格式--》提交到后端你的数据,都会被解析到 request.data 中,是个字典# 如果是urlencoded或form-data编码--》不能直接这样写,要写成如下# 提取请求数据data = request.dataprint(data)# <QueryDict: {'name': ['啊啥的'], 'price': ['222'], 'publish': ['啊啥的']}># 使用序列化器验证数据obj = BookSerializer(data=data)print(obj)if obj.is_valid():# 如果数据有效,创建新的书籍对象obj.save()return Response({'code': 200,'mes':'添加成功'})else:return Response({'code': 200,'mes':'添加失败!!!','errors':obj.errors})
class BookDetailView(APIView):def post(self, request):# 前端无论以什么编码格式--》提交到后端你的数据,都会被解析到 request.data 中,是个字典# 如果是urlencoded或form-data编码--》不能直接这样写,要写成如下# 提取请求数据data = request.dataprint(data)# 使用序列化器验证数据obj = BookSerializer(data=data)print(obj)if obj.is_valid():# 如果数据有效,创建新的书籍对象obj.save()return Response({'code': 200,'mes':'添加成功'})else:return Response({'code': 200,'mes':'添加失败!!!','errors':obj.errors})
class BookDetailView(APIView):def put(self,request,pk):# 提取请求数据data = request.dataprint(data)book = Book.objects.filter(pk=pk).first()res_data = BookSerializer(instance=book, data=data)# 如果数据有效,保存更新后的书籍对象# serializer.is_valid()print(res_data)if res_data.is_valid():res_data.save()return Response({'code': 100, 'msg': '更改成功!!!'})else:return Response({'code': 200, 'mes': '找不到表中的数据', 'errors': res_data.errors})