django-rest-framework学习之路-8-Request请求与Response返回
django-rest-framework学习之路-8-Request请求与Response返回
request请求对象
我们先把权限校验等给取消,方便调试
snippets/views.py内容变成了
from django.contrib.auth.models import User
from rest_framework import renderers, viewsets, permissions
from rest_framework.decorators import action
from rest_framework.request import Request
from rest_framework.response import Response
from snippets.models import Snippet
from snippets.permissions import IsOwnerOrReadOnly
from snippets.serializers import SnippetSerializer, UserSerializer
class UserViewSet(viewsets.ModelViewSet):
"""
此视图自动提供`list`和`detail`操作。
"""
queryset = User.objects.all()
serializer_class = UserSerializer
class SnippetViewSet(viewsets.ModelViewSet):
"""
此视图自动提供`list`,`create`,`retrieve`,`update`和`destroy`操作。
另外我们还提供了一个额外的`highlight`操作。
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,)
@action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
def highlight(self, request, *args, **kwargs):
snippet = self.get_object()
return Response(snippet.highlighted)
def perform_create(self, serializer):
serializer.save()
def create(self, request: Request, *args, **kwargs):
print("POST方法进入create函数")
print(f"request dict:{request.__dict__}")
print(f"data:{request.data}")
print(f"query_params:{request.query_params}")
print(f"parsers:{request.parsers}")
print(f"user:{request.user}")
print(f"auth:{request.auth}")
print(f"method:{request.method}")
print(f"content_type:{request.content_type}")
print(f"stream:{request.stream}")
return super().create(request, *args, **kwargs)
snippets/serializers.py内容变成了
from django.contrib.auth.models import User
from rest_framework import serializers
from snippets.models import Snippet
class SnippetSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html')
class Meta:
model = Snippet
fields = ('url', 'id', 'highlight', 'owner',
'title', 'code', 'linenos', 'language', 'style')
class UserSerializer(serializers.ModelSerializer):
snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail', read_only=True)
class Meta:
model = User
fields = ('url', 'id', 'username', 'snippets')
常用的属性
.data属性
request.data 返回请求正文的解析内容
- 它包括所有解析的内容, 包括 文件或非文件 输入。
- 它支持解析除POST之外的HTTP方法的内容,这意味着你可以访问PUT和PATCH请求的内容。
- 它支持REST framework灵活的请求解析,而不仅仅支持表单数据。 例如,你可以以与处理传入表单数据相同的方式处理传入的JSON数据
例如请求:
curl --location --request POST 'http://127.0.0.1:8000/snippets/snippets/' \
--header 'Host: 127.0.0.1' \
--header 'Content-Type: application/json' \
--data-raw '{
"title": "标题~~~",
"code": "代码~~~",
"linenos": false,
"language": "c",
"style": "friendly",
"A":1,
"B":"2"
}'
这样可以获取完整的body数据
.query_params属性
获取查询路径的请求参数,包括GET请求,POST请求
print(f"query_params:{request.query_params}")
例如
curl --location --request POST --X POST 'http://127.0.0.1:8000/snippets/snippets/?query1=1&query2=哈哈&query2=嘿嘿'
--header 'User-Agent: Apipost client Runtime/+https://www.apipost.cn/'
--header 'Host: 127.0.0.1'
--header 'Content-Type: application/json'
--data '{
"title": "标题~",~",
"code": "代码
"linenos": false,
"language": "c",
"style": "friendly",
"A": 1,
"B": "2"
}'
.method
request.method 返回请求的HTTP方法的 大写 字符串表示形式。
透明地支持基于浏览器的 PUT, PATCH 和 DELETE 表单。
.user
request.user 通常返回一个 django.contrib.auth.models.User 实例, 尽管该行为取决于所使用的的认证策略。
如果请求未认证则 request.user 的默认值为 django.contrib.auth.models.AnonymousUser的一个实例。
如果添加了认证,使用则显示登录者
.auth
request.auth 返回任何其他身份验证上下文。 request.auth 的确切行为取决于所使用的的认证策略,但它通常可以是请求被认证的token的实例。
如果请求未认证或者没有其他上下文,则 request.auth 的默认值为 None.
以下是你通常并不需要访问的属性
.parsers属性
APIView类或@api_view装饰器将根据view中设置的parser_classes集合或基于DEFAULT_PARSER_CLASSES设置,确保此属性自动设置为Parser实例列表。
你通常并不需要访问这个属性。
Note: 如果客户端发送格式错误的内容,则访问request.data可能会引发ParseError。默认情况下REST framework的 APIView类或@api_view装饰器将捕获错误并返回400 Bad Request响应。
如果客户端发送具有无法解析的内容类型的请求,则会引发 UnsupportedMediaType 异常, 默认情况下会捕获该异常并返回 415 Unsupported Media Type 响应。
.authenticators
APIView 类或 @api_view 装饰器将根据在view中设置的 authentication_classes 或基于DEFAULT_AUTHENTICATORS 设置,确保此属性自动设置为 Authentication 实例的列表。
你通常并不需要访问此属性。
.content_type
request.content_type 返回表示HTTP请求正文的媒体类型的字符串对象,如果未提供媒体类型,则返回空字符串。
你通常不需要直接访问请求的内容类型,因为你通常将依赖于REST framework的默认请求解析行为。
如果你确实需要访问请求的内容类型,你应该使用 .content_type 属性,而不是使用 request.META.get('HTTP_CONTENT_TYPE'), 因为它为基于浏览器的非表单内容提供了透明的支持。
.stream
request.stream 返回一个表示请求主体内容的流。
你通常不需要直接访问请求的内容类型,因为你通常将依赖于REST framework的默认请求解析行为。
Response返回对象
PS:(通常来说使用APIView类和@api_view函数即可,无需自己处理返回,除非自定义)
EST framework 通过提供一个 Response 类来支持 HTTP content negotiation,该类允许你返回可以呈现为多种内容类型的内容,具体取决于客户端的请求。
Response 类是 Django中 SimpleTemplateResponse 类的一个子类。Response 对象用Python基本数据类型初始化。 然后REST framework 使用标准的HTTP content negotiation 来确定如何呈现最终的响应内容。
你并不需要一定是用 Response 类,你可以从你的视图返回常规的 HttpResponse 或者 StreamingHttpResponse 对象。使用Response类只提供了一个可以呈现多种格式的更好的界面来返回 content-negotiated 的 Web API 响应。
除非由于某种原因你要对 REST framework 做大量的自定义,否则你应该始终对返回对象的views使用 APIView 类或者 @api_view 函数。这样做可以确保视图在返回之前能够执行 content negotiation 并且为响应选择适当的渲染器。
属性
.data
Request 对象的未渲染内容。
.status_code
HTTP 响应的数字状态吗。
.content
response的呈现内容。 .render() 方法必须先调用才能访问 .content 。
.template_name
template_name 只有在使用 HTMLRenderer 或者其他自定义模板作为response的渲染器时才需要提供该属性。
.accepted_renderer
将用于呈现response的render实例。
自动通过 APIView 或者 @api_view 在view返回response之前设置。
.accepted_media_type
由 content negotiation 阶段选择的媒体类型。
自动通过 APIView 或者 @api_view 在view返回response之前设置。
.renderer_context
一个将传递给渲染器的.render()方法的附加上下文信息字典。
自动通过 APIView 或者 @api_view 在view返回response之前设置。
标准的HttpResponse 属性
Response 类扩展了 SimpleTemplateResponse,并且所有常用的属性和方法都是提供的。比如你可以使用标准的方法设置response的header信息:
response = Response()
response['Cache-Control'] = 'no-cache'
.render()
Signature: .render()
和其他的 TemplateResponse 一样,调用该方法将response的序列化数据呈现为最终的response内容。 当 .render() 被调用时, response的内容将被设置成在 accepted_renderer实例上调用 .render(data, accepted_media_type, renderer_context) 方法返回的结果。
你通常并不需要自己调用 .render() ,因为它是由Django的标准响应周期来处理的。