day13-drf的请求和响应
请求对象
REST框架引入了一个扩展了常规HttpRequest的请求对象,并提供更灵活的请求解析。请求对象的核心功能是属性,request.data,这与request.POST类似,单对于WebAPIS更有用
响应对象
REST framework还引入了一个响应对象,这是一种TemplateResponse类型,它接受未渲染的内容,并使用内容协商来确定返回给客户端的正确内容类型
from rest_framework.response import Response from rest_framework import status return Response(data,status)
状态码
在视图中使用熟悉HTTP状态码并不总是容易读懂,而且当使用了错误的状态码还不容易发现,REST框架为每个状态码提供了更显式的表示符,比如status模块中的HTTP_400_BAD_REQUEST
from rest_framework import status ...... # 返回成功 return Response(serializer.data, status=status.HTTP_201_CREATED) # 返回失败 return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
视图包装器
- @api_view 用来装饰函数视图
装饰了视图之后,请求对象、响应对象才能够从django请求对象,响应对象包装成DRF中的请求对象,请求里面才会有request.data
from rest_framework.decorators import api_view
@api_view(["get", "put", "delete"]) def student_detail_update_delete(request, pk, format=None): ......
- APIview 用来装饰类视图
序列化可浏览API
修改视图:
在视图函数里面加关键字参数format,默认format=None
@api_view(["get","post"]) def student_list_or_create(request, format=None): """ 学生列表,学生创建视图 :param request: :return: """ if request.method == "GET": # 1、拿到所有对象 obj = Student.objects.all() # 2、序列化 serializer = StudentSerializer(obj, many=True) # 3、返回drf的响应 return Response(serializer.data) elif request.method == "POST": # 1、创建序列化器 serializer = StudentSerializer(data=request.data) # 2、校验 if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
修改路由
在路由中添加格式,使用format_suffix_patterns
from django.urls import path from rest_framework.urlpatterns import format_suffix_patterns from . import views urlpatterns = [ path("students/", views.student_list_or_create, name="list_create"), path("students/<int:pk>/", views.student_detail_update_delete, name="detail_update_delete") ] # 处理一下路由,选择不同的渲染格式 urlpatterns = format_suffix_patterns(urlpatterns)
通过不同的url后缀来获取不同的内容:
/students.json #返回json数据
/students.api # 可浏览API,html
还可以通过accept来控制响应格式
accpet:application/json
accpet:text/html
常用序列化器字段
read_only
字段只读,默认为False。只读字段只会包含在序列化输出中,创建修改对象(反序列化)时不会包含该字段,即使输入了也会被忽略
序列化器中,id、创建时间就是read_only=True
1 from crm.serializers import StudentSerializer 2 3 print(StudentSerializer()) 4 5 6 # 输出: 7 StudentSerializer(instance=<QuerySet [<Student: 中欧>, <Student: 子是>, <Student: 李大毛>, <Student: 李小毛>, <Student: 小大>, <Student: 王玉>, <Student: 赵六>]>, many=True): 8 id = IntegerField(label='ID', read_only=True) 9 ... 10 c_time = DateTimeField(label='创建时间', read_only=True) 11 ...
write_only
字段只写,默认值为False。和read_only相反,序列化时不包含,创建修改对象时必须包含该字段,在可视化API中不展示该字段
class StudentSerializer(serializers.ModelSerializer): """ 模型序列化器 """ # 加了之后,页面api序列化展示页面,不展示phone字段 phone = serializers.CharField(write_only=True) # 元信息 class Meta: # 指定根据那个模型生成序列化器 model = Student # 指定序列化那些字段 # fields = ['id', 'name', 'sex'] # 序列化所有字段 fields = '__all__' # 排除某个字段 # exclude = ['id']
required
字段必须,默认值为True。必须字段在创建修改对象时必须包含,否则抛出异常。当设置为False时,在创建修改对象时可以不用包含该字段
当模型中字段有默认值,或者blank=True时,required就是False
class Student(models.Model): # 必须继承 """ 每个字段实例的名称,类属性名称,就是数据库字段的名称 """ age = models.SmallIntegerField("年龄", null=True, blank=True, help_text="年龄") sex = models.SmallIntegerField("性别", default=1, help_text="性别") qq = models.CharField("qq号码", max_length=20, null=True, blank=True, unique=True, help_text="qq号码") ...... # 输出的StudentSerializer(): age = IntegerField(allow_null=True, help_text='年龄', label='年龄', max_value=32767, min_value=-32768, required=False) sex = IntegerField(help_text='性别', label='性别', max_value=32767, min_value=-32768, required=False)
default
默认值。如果一个字段设置了默认值,那么在反序列化时,没有提供该字段,则使用默认值进行填充;
局部更新(更新单个字段,或多个字段),default不会应用,因为局部更新时,只有更新字段会被校验返回
class StudentSerializer(serializers.ModelSerializer): """ 模型序列化器 """ # 定制模型,替换存在的字段模型, # sex字段原本默认值是1,更改后默认为0 sex = serializers.IntegerField(default=0) ......
还可以设置一个函数或者一个可调用对象
可以设置为一个函数或其他可条用对象,在这种情况下,会使用调用后的结果进行填充。调用时它将不接受任何参数。如果可调用对象有一个requires_context=True的属性,那么序列化字段会被当做参数传 入例如:
class CurrentUserDefault:
"""
May be applied as a `default=...` value on a serializer field.
Returns the current user.
"""
requires_context = True
def __call__(self, serializer_field):
return serializer_field.context['request'].user
在序列化时,如果实例中不存在对象属性或字典键,将使用default的值填充
注意:设置默认值,代表字该字段不是必需的,同时包含默认和必需的关键字参数是无效的,将引发错误
allow_null
模型里面字段设置null=True,对应allow_null=True
source
将用于填充字段的属性的名称。可以是一个只接受self参数的方法, 比如URLField(source='get_absolute_url')
,或者是一个句点法的属性,比如CharField(source='channel.name')
。
:用于给模型额外添加字段
class StudentSerializer(serializers.ModelSerializer): """ 模型序列化器 """ channel_name = serializers.CharField(source='channel.name') # 元信息 class Meta: # 指定根据那个模型生成序列化器 model = Student # 指定序列化那些字段,当使用source后,如果用fields指定字段需要将字段添加到fields的列表里 # fields = ['id', 'name', 'sex', 'channel_name'] # 序列化所有字段 fields = '__all__'
validators
应该应用到输入字段的验证器函数的列表,它要么引发验证错误,要么简单地返回。验证器函数通常应该引发serializers.ValidationError
,但Django内置的ValidationError
也被支持,以便与Django或第三方Django包中定义的验证器兼容。
error_messages
错误消息字典
label
一个短文本字符串,可以用作HTML表单字段或其他描述性元素中的字段名。
help_text
可以在HTML表单字段或其他描述性元素中用作字段描述的文本字符串。
CharField
文本字段,可以验证文本小于max_length
大于min_length
RegexField
文本字段,可以验证文本是否匹配给定正则表达式。
class StudentSerializer(serializers.ModelSerializer): """ 模型序列化器 """ phone = serializers.RegexField(r'^1[3-9]\d{9}$', allow_blank=True, allow_null=True, help_text='手机号码', label='手机号码', max_length=20, required=False, validators=[ UniqueValidator(queryset=Student.objects.all())]) # 元信息 class Meta: # 序列化所有字段 fields = '__all__'
IntergerField
整数字段,可以验证整数小于max_value
,大于min_value
FloatField
实数字段,可以验证整数小于max_value
,大于max_value
DecimalField
以十进制表示Python中由decimal的实例。
更多详解官方文档:https://www.django-rest-framework.org/api-guide/fields/#serializer-fields