New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug] pydantic json_encoder is ignored (is it bug or feature?) #247
Comments
I'm trying to use |
well.. Django-ninja can return other content types (yaml, xml, etc) @shughes-uk @KimSoungRyoul you can extend default json renderer with extra encoders like this: from ninja.responses import NinjaJSONEncoder
from ninja.renderers import JSONRenderer
class SecretsJSONEncoder(NinjaJSONEncoder):
def default(self, o):
if isinstance(o, (SecretStr, SecretBytes)):
return o.get_secret_value()
return super().default(o)
class MyJsonRenderer(JSONRenderer):
encoder_class = SecretsJSONEncoder
api = NinjaAPI(renderer=MyJsonRenderer()) |
Have not tested this, but this is closer to my desired behavior I think. Given that response schema's are always pydantic models, having ninja be able to support all the inbuilt pydantic fields by default make sense (not sure how to replicate that for xml or yaml) from ninja.responses import NinjaJSONEncoder
from ninja.renderers import JSONRenderer
from pydantic.json import pydantic_encoder
class PydanticJSONEncoder(NinjaJSONEncoder):
def default(self, o):
return pydantic_encoder(o)
class MyJsonRenderer(JSONRenderer):
encoder_class = PydanticJSONEncoder
api = NinjaAPI(renderer=MyJsonRenderer()) |
The solution that @shughes-uk suggested seems to work fine for pydantic builtins. However, you can also specify import json
from pydantic import BaseModel
from ninja.responses import NinjaJSONEncoder
from ninja.renderers import JSONRenderer
class PydanticJSONEncoder(NinjaJSONEncoder):
def default(self, o):
if isinstance(o, BaseModel):
return json.loads(o.json())
return super().default(o)
class MyJsonRenderer(JSONRenderer):
encoder_class = PydanticJSONEncoder
api = NinjaAPI(renderer=MyJsonRenderer()) This would actually use all json-related features of pydantic, but it also includes repetitive json encoding, which I find problematic because for performance reasons. Maybe we could write entirely different |
I'm thinking something along the lines of: from pydantic import BaseModel
from ninja.renderers import JSONRenderer
class PydanticJsonRenderer(JSONRenderer):
def render(self, request: HttpRequest, data: Any, *, response_status: int) -> Any:
if isinstance(data, BaseModel):
return data.json()
return super().render(request, data, response_status=response_status) |
I tried to do something similar to what I suggested above, but I ran into another problem – See https://github.com/vitalik/django-ninja/blob/master/ninja/operation.py#L196 This is unfortunate, because it makes working with custom json encoders on pydantic models really hard. I can always return I'm interested in why is |
example
override json_encoders
api_aaa
API Response's datetime field should not be isoformat because NinjaJsonEncoder does not use pydantic.json()is it bug or feature?
The text was updated successfully, but these errors were encountered: