mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-30 21:44:04 +03:00
contextvars for request context
This commit is contained in:
parent
c9e7b68a4c
commit
06d21eb246
|
@ -8,6 +8,7 @@ The wrapped request then offers a richer API, in particular :
|
|||
- full support of PUT method, including support for file uploads
|
||||
- form overloading of HTTP method, content type and content
|
||||
"""
|
||||
import contextvars
|
||||
import io
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
|
@ -149,6 +150,8 @@ class Request:
|
|||
authenticating the request's user.
|
||||
"""
|
||||
|
||||
_context_instance = contextvars.ContextVar('request')
|
||||
|
||||
def __init__(self, request, parsers=None, authenticators=None,
|
||||
negotiator=None, parser_context=None):
|
||||
assert isinstance(request, HttpRequest), (
|
||||
|
@ -458,3 +461,11 @@ class Request:
|
|||
# Hack to allow our exception handler to force choice of
|
||||
# plaintext or html error responses.
|
||||
self._request.is_ajax = lambda: value
|
||||
|
||||
@classmethod
|
||||
def get_current(cls, default=None):
|
||||
return cls._context_instance.get(default)
|
||||
|
||||
@classmethod
|
||||
def set_current(cls, value):
|
||||
return cls._context_instance.set(value)
|
||||
|
|
|
@ -29,6 +29,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
from rest_framework.compat import postgres_fields
|
||||
from rest_framework.exceptions import ErrorDetail, ValidationError
|
||||
from rest_framework.fields import get_error_detail, set_value
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.settings import api_settings
|
||||
from rest_framework.utils import html, model_meta, representation
|
||||
from rest_framework.utils.field_mapping import (
|
||||
|
@ -115,6 +116,12 @@ class BaseSerializer(Field):
|
|||
self.partial = kwargs.pop('partial', False)
|
||||
self._context = kwargs.pop('context', {})
|
||||
kwargs.pop('many', None)
|
||||
|
||||
if isinstance(self._context, dict) and ('request' not in self._context):
|
||||
request = Request.get_current()
|
||||
if request:
|
||||
self._context['request'] = request
|
||||
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
|
|
|
@ -489,9 +489,11 @@ class APIView(View):
|
|||
"""
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.headers = self.default_response_headers # deprecate?
|
||||
|
||||
request = self.initialize_request(request, *args, **kwargs)
|
||||
self.request = request
|
||||
self.headers = self.default_response_headers # deprecate?
|
||||
Request.set_current(request)
|
||||
|
||||
try:
|
||||
self.initial(request, *args, **kwargs)
|
||||
|
|
Loading…
Reference in New Issue
Block a user