django-rest-framework学习之路-8-Request请求与Response返回

django-rest-framework学习之路-8-Request请求与Response返回

django-rest-framework学习之路-8-Request请求与Response返回

request请求对象

我们先把权限校验等给取消,方便调试

snippets/views.py内容变成了

from django.contrib.auth.models import Userfrom rest_framework import renderers, viewsets, permissionsfrom rest_framework.decorators import actionfrom rest_framework.request import Requestfrom rest_framework.response import Responsefrom snippets.models import Snippetfrom snippets.permissions import IsOwnerOrReadOnlyfrom snippets.serializers import SnippetSerializer, UserSerializerclass UserViewSet(viewsets.ModelViewSet):    """    此视图自动提供`list`和`detail`操作。    """    queryset = User.objects.all()    serializer_class = UserSerializerclass 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 Userfrom rest_framework import serializersfrom snippets.models import Snippetclass 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的标准响应周期来处理的。

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部