Pydantic model support for Django & Django-Rest-Framework ✨
Pyngo :snake:
Utils to help integrate pydantic into Django projects
Installation
You can add pyngo in a few easy steps. First of all, install the dependency:
$ pip install pyngo
---> 100%
Successfully installed pyngo
Features 🎉
- Using Pydantic to Build your Models in Django Project.
- Using
OpenAPIutilities to build params from a basic model. - using
QueryDictModelto buildPydanticmodels from aQueryDictobject. - propagate any errors from Pydantic in Django Rest Framework.
- Tested in Python 3.10 and up.
Examples 📚
OpenAPI
pyngo.openapi_params()can build params from a basic model
from pydantic import BaseModel
from pyngo import openapi_params
class Model(BaseModel): bingo: int
print(openapi_params(Model))
pyngo.ParameterDict.requiredis set according to the type of the variable
from typing import Optional
from pydantic import BaseModel
from pyngo import openapi_params
class Model(BaseModel): required_param: int optional_param: Optional[int]
print(openapi_params(Model))
Other fields can be set through the field’s info:
from pydantic import BaseModel, Field
from pyngo import openapi_params
class WithDescription(BaseModel): described_param: str = Field( description="Hello World Use Me!" )
class InPath(BaseModel): path_param: str = Field(location="path")
class WithDeprecated(BaseModel): deprecated_field: bool = Field(deprecated=True)
class WithNoAllowEmpty(BaseModel): canbeempty: bool = Field(allowEmptyValue=False)
print(openapi_params(WithDescription)[0]["description"]) print(openapi_params(InPath)[0]["in"]) print(openapi_params(WithDeprecated)[0]["deprecated"]) print(openapi_params(WithNoAllowEmpty)[0]["allowEmptyValue"])
Django
pyngo.querydicttodict()andpyngo.QueryDictModelare conveniences for building apydantic.BaseModelfrom adjango.QueryDict.
from typing import List
from django.http import QueryDict
from pydantic import BaseModel
from pyngo import QueryDictModel, querydicttodict
class Model(BaseModel): single_param: int list_param: List[str]
class QueryModel(QueryDictModel): single_param: int list_param: List[str]
querydict = QueryDict("singleparam=20&list_param=Life")
print(Model.modelvalidate(querydicttodict(querydict, Model))) print(QueryModel.modelvalidate(querydict))
Note: Don't forget to Setup the Django Project.
Django Rest Framework
pyngo.drferrordetails()will propagate any errors from Pydantic.
from pydantic import BaseModel, ValidationError
from pyngo import drferrordetails
class Model(BaseModel): foo: int bar: str
data = {"foo": "Cat"}
try: Model.model_validate(data) except ValidationError as e: print(drferrordetails(e))
Errors descend into nested fields:
from typing import List
from pydantic import BaseModel, ValidationError
from pyngo import drferrordetails
class Framework(BaseModel): frm_id: int
class Language(BaseModel): framework: List[Framework]
data = {"framework": [{"frmid": "nota_number"}, {}]} expected_details = { "framework": { "0": {"frm_id": ["value is not a valid integer"]}, "1": {"frm_id": ["field required"]}, } }
try: Language.model_validate(data) except ValidationError as e: print(drferrordetails(e))
Development 🚧
Setup environment 📦
Install uv from https://docs.astral.sh/uv/ and just from your OS package manager or https://just.systems.
And then install the development dependencies:
# Install dependencies for development
uv sync --all-groups
Run tests 🌝
You can run all the tests with:
just test
Note: You can also generate a coverage report with:
just test-html
Format the code 🍂
Execute the following command to apply pre-commit formatting:
just format
Execute the following command to apply mypy type checking:
just lint
License 🍻
This project is licensed under the terms of the MIT license.