Handle lazy() proxies in user-supplied objects

master
Cristi Vîjdea 2018-12-21 00:44:05 +02:00 committed by Cristi Vijdea
parent 0c38c30020
commit bbed2acf06
2 changed files with 17 additions and 7 deletions

View File

@ -1,12 +1,16 @@
import six
import collections
import logging
import re
from collections import OrderedDict
from coreapi.compat import urlparse
from django.urls import get_script_prefix
from django.utils.functional import Promise
from inflection import camelize
from .utils import filter_none
from .utils import filter_none, force_real_str
logger = logging.getLogger(__name__)
@ -128,13 +132,19 @@ class SwaggerDict(OrderedDict):
if id(obj) in memo:
return memo[id(obj)]
if isinstance(obj, dict):
if isinstance(obj, Promise) and hasattr(obj, '_proxy____cast'):
# handle __proxy__ objects from django.utils.functional.lazy
obj = obj._proxy____cast()
if isinstance(obj, collections.Mapping):
result = OrderedDict()
memo[id(obj)] = result
for attr, val in obj.items():
result[attr] = SwaggerDict._as_odict(val, memo)
return result
elif isinstance(obj, (list, tuple)):
elif isinstance(obj, six.string_types):
return force_real_str(obj)
elif isinstance(obj, collections.Iterable) and not isinstance(obj, collections.Iterator):
return type(obj)(SwaggerDict._as_odict(elem, memo) for elem in obj)
return obj

View File

@ -4,7 +4,7 @@ from django.shortcuts import resolve_url
from django.template.loader import render_to_string
from django.utils.functional import Promise
from rest_framework.renderers import BaseRenderer, JSONRenderer, TemplateHTMLRenderer
from rest_framework.utils import json
from rest_framework.utils import encoders, json
from .app_settings import redoc_settings, swagger_settings
from .codecs import VALIDATORS, OpenAPICodecJson, OpenAPICodecYaml
@ -76,7 +76,7 @@ class _UIRenderer(BaseRenderer):
def set_context(self, renderer_context, swagger=None):
renderer_context['title'] = swagger.info.title or '' if swagger else ''
renderer_context['version'] = swagger.info.version or '' if swagger else ''
renderer_context['oauth2_config'] = json.dumps(self.get_oauth2_config())
renderer_context['oauth2_config'] = json.dumps(self.get_oauth2_config(), cls=encoders.JSONEncoder)
renderer_context['USE_SESSION_AUTH'] = swagger_settings.USE_SESSION_AUTH
renderer_context.update(self.get_auth_urls())
@ -120,7 +120,7 @@ class SwaggerUIRenderer(_UIRenderer):
def set_context(self, renderer_context, swagger=None):
super(SwaggerUIRenderer, self).set_context(renderer_context, swagger)
renderer_context['swagger_settings'] = json.dumps(self.get_swagger_ui_settings())
renderer_context['swagger_settings'] = json.dumps(self.get_swagger_ui_settings(), cls=encoders.JSONEncoder)
def get_swagger_ui_settings(self):
data = {
@ -157,7 +157,7 @@ class ReDocRenderer(_UIRenderer):
def set_context(self, renderer_context, swagger=None):
super(ReDocRenderer, self).set_context(renderer_context, swagger)
renderer_context['redoc_settings'] = json.dumps(self.get_redoc_settings())
renderer_context['redoc_settings'] = json.dumps(self.get_redoc_settings(), cls=encoders.JSONEncoder)
def get_redoc_settings(self):
data = {