vitalik / django-ninja

💨 Fast, Async-ready, Openapi, type hints based framework for building APIs
https://django-ninja.dev
MIT License
7.28k stars 432 forks source link

[BUG] model_dump defaults to `mode=python` #1273

Open orf opened 2 months ago

orf commented 2 months ago

Describe the bug All calls to BaseModel.model_dump use the default mode argument, which is python and not json. For example:

This means models that use custom types (such as any of these built-in Pydantic types) do not work:

import pydantic, ninja

api = NinjaAPI()

class SomeModel(pydantic.BaseModel):
    url: pydantic.AnyUrl

@api.get("/test")
def example(request) -> SomeModel:
    return SomeModel.model_validate({
        "url": "custom-protocol://foo/bar"
    })

Fails with:

TypeError: Type is not JSON serializable: pydantic_core._pydantic_core.Url

It seems like we should default to using .model_dump(mode='json')?

You could change example to this:

@api.get("/test", response=SomeModel)
def example(request):
    return SomeModel.model_validate({
        "url": "custom-protocol://foo/bar"
    }).model_dump(mode='json')

But this is a shame: we end up calling model_dump and model_validate multiple times (which can be expensive with a lot of data), and we loose type hints on the function.

Versions (please complete the following information):