Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into grigi/master
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalik committed Dec 6, 2024
2 parents af389ce + 5a4cbe7 commit ab94a26
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 4 deletions.
2 changes: 1 addition & 1 deletion ninja/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Settings(BaseModel):
"ninja.pagination.LimitOffsetPagination", alias="NINJA_PAGINATION_CLASS"
)
PAGINATION_PER_PAGE: int = Field(100, alias="NINJA_PAGINATION_PER_PAGE")
PAGINATION_MAX_LIMIT: int = Field(inf, alias="NINJA_PAGINATION_MAX_LIMIT")
PAGINATION_MAX_LIMIT: int = Field(inf, alias="NINJA_PAGINATION_MAX_LIMIT") # type: ignore

# Throttling
NUM_PROXIES: Optional[int] = Field(None, alias="NINJA_NUM_PROXIES")
Expand Down
3 changes: 2 additions & 1 deletion ninja/orm/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from ninja.orm.factory import create_schema
from ninja.orm.fields import register_field
from ninja.orm.metaclass import ModelSchema

__all__ = ["create_schema", "ModelSchema"]
__all__ = ["create_schema", "register_field", "ModelSchema"]
15 changes: 14 additions & 1 deletion ninja/orm/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from pydantic.fields import FieldInfo
from pydantic_core import PydanticUndefined, core_schema

from ninja.errors import ConfigError
from ninja.openapi.schema import OpenAPISchema
from ninja.types import DictStrAny

Expand Down Expand Up @@ -81,6 +82,10 @@ def validate(cls, value: Any, _: Any) -> Any:
TModel = TypeVar("TModel")


def register_field(django_field: str, python_type: Any) -> None:
TYPES[django_field] = python_type


@no_type_check
def create_m2m_link_type(type_: Type[TModel]) -> Type[TModel]:
class M2MLink(type_): # type: ignore
Expand Down Expand Up @@ -148,7 +153,15 @@ def get_schema_field(
max_length = field_options.get("max_length")

internal_type = field.get_internal_type()
python_type = TYPES[internal_type]
try:
python_type = TYPES[internal_type]
except KeyError as e:
msg = [
f"Do not know how to convert django field '{internal_type}'.",
"Try from ninja.orm import register_field",
f"register_field('{internal_type}', <your-python-type>)",
]
raise ConfigError("\n".join(msg)) from e

if field.primary_key or blank or null or optional:
default = None
Expand Down
21 changes: 20 additions & 1 deletion tests/test_orm_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from util import pydantic_ref_fix

from ninja.errors import ConfigError
from ninja.orm import create_schema
from ninja.orm import create_schema, register_field
from ninja.orm.shortcuts import L, S


Expand Down Expand Up @@ -581,3 +581,22 @@ class Meta:
SomeReqFieldModel, optional_fields=["some_field", "other_field", "optional"]
)
assert Schema.json_schema().get("required") is None


def test_register_custom_field():
class MyCustomField(models.Field):
description = "MyCustomField"

class ModelWithCustomField(models.Model):
some_field = MyCustomField()

class Meta:
app_label = "tests"

with pytest.raises(ConfigError):
create_schema(ModelWithCustomField)

register_field("MyCustomField", int)
Schema = create_schema(ModelWithCustomField)
print(Schema.json_schema())
assert Schema.json_schema()["properties"]["some_field"]["type"] == "integer"

0 comments on commit ab94a26

Please sign in to comment.