Pydbull is a library for building Pydantic models from other data models (such as Django models). It is designed to inherit the original model's validation rules.
The name pydbull is a portmanteau of pydantic and builder, and a play on the word pitbull as a guard-dog for your data.
pip install pydbullThe @model_validator decorator is used to inherit validation rules from any supported data model (e.g., Django model).
For example:
import pydbull
import pydantic
from django.db import models
class User(models.Model):
name = models.CharField(max_length=5)
age = models.IntegerField()
@pydbull.model_validator(User)
class UserModel(pydantic.BaseModel):
name: str
# The following will raise a ValidationError
UserModel(name="ABCDEF")This will make the UserModel model inherit the validation rules from the User model, meaning that
the UserModel.name field will have a maximum length of 5 characters.
The pydantic model can be extended with additional fields, methods or validators just like any other pydantic model.
import pydbull
import pydantic
from django.db import models
class User(models.Model):
name = models.CharField(max_length=100)
@pydbull.model_validator(User)
class UserModel(pydantic.BaseModel):
name: str
age: int
@pydantic.field_validator("age")
def validate_age(cls, v: int) -> int:
if v < 18:
raise ValueError("Age must be over 18.")
return v
# The following will raise a ValidationError
UserModel(name="John", age=17)If the Django model has some additional constraints, the pydantic model will inherit and validate them as well.
import pydbull
import pydantic
from django.db import models
from django.core.validators import MinValueValidator
class User(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField(validators=[MinValueValidator(5)])
class Meta:
constraints = [
models.CheckConstraint(
check=models.Q(age__lte=10, name__iexact="john"),
name="age_must_be_less_than_10_for_users_with_name_john",
)
]
@pydbull.model_validator(User)
class UserModel(pydantic.BaseModel):
name: str
age: int
# The following will raise a ValidationError
UserModel(name="Pepa", age=4)
# The following will also raise a ValidationError
UserModel(name="John", age=11)The model_to_pydantic function is used to build a Pydantic model from a supported data model (e.g., Django model).
For example:
import pydbull
import pydantic
from django.db import models
from django.core.validators import MinValueValidator
class DjangoModel(models.Model):
field_1 = models.CharField(max_length=5, help_text="Some help text (will be inherited by Pydantic model)")
field_2 = models.IntegerField(validators=[MinValueValidator(5)])
PydanticModelCls = pydbull.model_to_pydantic(DjangoModel)
pyd_model = PydanticModelCls(field_1="test", field_2=5)
assert pyd_model.model_dump() == {
"field_1": "test",
"field_2": 5,
"id": None
}
# The following will raise a ValidationError
PydanticModelCls(field_1="test", field_2=4)
# You can use `fields` parameter to specify which fields to include in the Pydantic model.
pydbull.model_to_pydantic(DjangoModel, fields=["field_1"])
# You can also use `exclude` parameter to specify which fields to exclude from the Pydantic model.
pydbull.model_to_pydantic(DjangoModel, exclude=["id"])
# You can use `field_annotations` parameter to specify additional field annotations for the Pydantic model.
pydbull.model_to_pydantic(DjangoModel, field_annotations={"field_1": pydantic.Field(max_length=2, description="Some description")})Currently, Pydbull supports the following data models:
- Django models
To see how to extend Pydbull to support other data models, see the Extending Pydbull section.
Pydbull can be extended to support other data models by implementing Adapter class for the data model type.
The Adapter class should inherit from ABC class pydbull.BaseAdapter and implement it's abstract methods.
For example, see the implementation of DjangoAdapter class in pydbull.django module.
Pull requests for any improvements are welcome.
Poetry is used to manage dependencies. To get started follow these steps:
git clone https://github.com/coexcz/pydbull
cd pydbull
poetry install
poetry run pytestWe have a configuration for pre-commit, to add the hook run the following command:
pre-commit install