{"id":22177145,"url":"https://github.com/nextgencontributions/django2pydantic","last_synced_at":"2025-07-26T16:31:21.367Z","repository":{"id":263497381,"uuid":"879316562","full_name":"NextGenContributions/django2pydantic","owner":"NextGenContributions","description":"Django2pydantic is the most complete library for converting Django ORM models to Pydantic models","archived":false,"fork":false,"pushed_at":"2024-11-29T15:10:31.000Z","size":452,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-29T16:23:11.146Z","etag":null,"topics":["api","api-rest","converter","django","django-orm","django-orm-crud","inference","models","pydantic","pydantic-v2","rest-api","restapi","restful-api","schema"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NextGenContributions.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"NextGenContributions"}},"created_at":"2024-10-27T15:36:09.000Z","updated_at":"2024-11-29T15:10:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"2497ba44-ca65-46a3-aefb-4a7c00de29f2","html_url":"https://github.com/NextGenContributions/django2pydantic","commit_stats":null,"previous_names":["nextgencontributions/django2pydantic"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NextGenContributions%2Fdjango2pydantic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NextGenContributions%2Fdjango2pydantic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NextGenContributions%2Fdjango2pydantic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NextGenContributions%2Fdjango2pydantic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NextGenContributions","download_url":"https://codeload.github.com/NextGenContributions/django2pydantic/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227694330,"owners_count":17805565,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","api-rest","converter","django","django-orm","django-orm-crud","inference","models","pydantic","pydantic-v2","rest-api","restapi","restful-api","schema"],"created_at":"2024-12-02T08:25:51.960Z","updated_at":"2025-07-26T16:31:21.356Z","avatar_url":"https://github.com/NextGenContributions.png","language":"Python","funding_links":["https://github.com/sponsors/NextGenContributions"],"categories":[],"sub_categories":[],"readme":"![PyPI - License](https://img.shields.io/pypi/l/django)\n![PyPI - Downloads](https://img.shields.io/pypi/dm/django2pydantic)\n\n# Why\n\ndjango2pydantic is the most complete Pydantic schemas based on Django models.\n\n# What\n\ndjango2pydantic is a library that allows to define Pydantic schemas based on Django database models.\n\nSimilar libraries:\n\n- [Djantic](https://jordaneremieff.github.io/djantic/)\n- [Django Ninja Schema](https://django-ninja.dev/guides/response/django-pydantic/)\n- [Ninja Schema](https://github.com/eadwinCode/ninja-schema)\n\n# Key features\n\n- Supports all Django model field types\n- Supports @property decorated Django model methods\n- Supports all Django model relation fields:\n  - ForeignKey, OneToOneField, ManyToManyField\n  - The reverse relations of the above (ManyToOneRel, OneToOneRel, ManyToManyRel)\n- Supports defining nested relations\n- Provides as complete OpenAPI schema details as possible\n- Support for [SchemaField](https://pypi.org/project/django-pydantic-field/)\n\n# How to use\n\nSee the following usage examples:\n\n- [Basic usage example](examples/example.ipynb)\n- [Overriding Django field properties by using `InferExcept`](examples/overriding-django-field-properties-with-InferExcept.ipynb)\n- [Making required Django fields optional in Pydantic schema](examples/making-fields-optional-with-InferExcept.ipynb)\n\n# Some details\n\n## Django fields blank and null\n\nThere are some nuances related to the use of `blank` and `null` in Django fields\nand how they impact the output pydantic types, but generally:\n- If `null=True` the output **type** will be `Optional` (i.e. `str | None`).\n- If `blank=True` the field will be **optional** (with **exceptions**).\nThis is to be more in line with the Django admin/form validation behavior.\n- Whether the field is **required** is determined by the **default** value (can be overridden).\n  - If the **default** is `PydanticUndefined`, the field is always **required**.\n  - If the **default** is `None` (or `\"\"` in case of string), the field is **optional**.\n- If `null=False` and `blank=True`, the field typically requires implementing `clean()`\non the model in order to programmatically supply any missing values. In our case, the\n**required**/**default** value can vary depending on field type in a way that user\ndoes not need to concern with implementing `clean()`.\n\n### String-based fields\nThis covers the following Django field types:\n- CharField\n- SlugField\n- EmailField\n- URLField\n- TextField\n\n| Configuration             | Required     | Default\u003cbr\u003e(If not specified) | Type          | Min length | Comments                                                                                                                                                               |\n|---------------------------|--------------|-------------------------------|---------------|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `null=True, blank=True`   | Optional     | `None`                        | `str \\| None` | `None`     | There's 2 ways to represent \"no data\" in the DB: `null` and `\"\"` (**not recommended**)                                                                                 |\n| `null=True, blank=False`  | **Required** | `PydanticUndefined`           | `str \\| None` | `1`        | • There's 2 ways to represent \"no data\" in the DB: `null` and `\"\"` (**not recommended**)\u003cbr\u003e• However, with **min_length**, we eliminate `\"\"` from being a valid input |\n| `null=False, blank=True`  | Optional     | `\"\"`                          | `str`         | `None`     | **Default** is `\"\"` since `null` is not allowed                                                                                                                        |\n| `null=False, blank=False` | **Required** | `PydanticUndefined`           | `str`         | `1`        |                                                                                                                                                                        |\n\n\n### Non-string-based fields\nThis covers the following Django field types:\n- IntegerField\n- SmallIntegerField\n- IntegerField\n- BigIntegerField\n- PositiveSmallIntegerField\n- PositiveIntegerField\n- PositiveBigIntegerField\n- FloatField\n- DecimalField\n- BinaryField\n- BooleanField\n- DateField\n- DateTimeField\n- DurationField\n- FileField\n- FilePathField\n- GenericIPAddressField\n- ImageField\n- JSONField\n- TimeField\n- UUIDField\n\n**[FieldType]** varies depending on the Django field type\n\n| Configuration             | Required     | Default\u003cbr\u003e(If not specified) | Type                  | Comments                                                                                                                                                |\n|---------------------------|--------------|-------------------------------|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `null=True, blank=True`   | Optional     | `None`                        | `[FieldType] \\| None` |                                                                                                                                                         |\n| `null=True, blank=False`  | **Required** | `PydanticUndefined`           | `[FieldType] \\| None` |                                                                                                                                                         |\n| `null=False, blank=True`  | **Required** | `PydanticUndefined`           | `[FieldType]`         | Unlike string-based fields, without a specified **default** value, there's no valid empty value to be stored in database thus making this **required**  |\n| `null=False, blank=False` | **Required** | `PydanticUndefined`           | `[FieldType]`         |                                                                                                                                                         |\n\n\n### Relational fields\nThis covers the following Django field types:\n- ForeignKey\n- OneToOneField\n- ManyToManyField\n- ManyToOneRel\n- OneToOneRel\n- ManyToManyRel\n\n**[PkType]** varies depending on model's primary key type\n\n#### ForeignKey, OneToOneField\n| Configuration             | Required     | Default\u003cbr\u003e(If not specified) | Type               | Comments                                                                                                                                               |\n|---------------------------|--------------|-------------------------------|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `null=True, blank=True`   | Optional     | `None`                        | `[PkType] \\| None` |                                                                                                                                                        |\n| `null=True, blank=False`  | **Required** | `PydanticUndefined`           | `[PkType] \\| None` |                                                                                                                                                        |\n| `null=False, blank=True`  | **Required** | `PydanticUndefined`           | `[PkType]`         | Unlike string-based fields, without a specified **default** value, there's no valid empty value to be stored in database thus making this **required** |\n| `null=False, blank=False` | **Required** | `PydanticUndefined`           | `[PkType]`         |                                                                                                                                                        |\n\n#### ManyToManyField\n`null` has no effect since there is no way to require a relationship at the database level.\nRef: https://docs.djangoproject.com/en/5.1/ref/models/fields/#manytomanyfield\n\n| Configuration | Required     | Default\u003cbr\u003e(If not specified) | Type                   | Comments |\n|---------------|--------------|-------------------------------|------------------------|----------|\n| `blank=True`  | Optional     | `None`                        | `list[PkType] \\| None` |          |\n| `blank=False` | **Required** | `PydanticUndefined`           | `list[PkType] \\| None` |          |\n\n#### OneToOneRel\nThis field is created as a result of `OneToOneField` and is not directly configurable.\n\n| Required | Default\u003cbr\u003e(If not specified) | Type               | Comments |\n|----------|-------------------------------|--------------------|----------|\n| Optional | `None`                        | `[PkType] \\| None` |          |\n| Optional | `None`                        | `[PkType] \\| None` |          |\n| Optional | `None`                        | `[PkType] \\| None` |          |\n| Optional | `None`                        | `[PkType] \\| None` |          |\n\n\n#### ManyToOneRel, ManyToManyRel\nThese fields are created as a result of `ForeignKey`, `ManyToManyField` and are not directly configurable.\n\n| Required | Default\u003cbr\u003e(If not specified) | Type                   | Comments |\n|----------|-------------------------------|------------------------|----------|\n| Optional | `None`                        | `list[PkType] \\| None` |          |\n| Optional | `None`                        | `list[PkType] \\| None` |          |\n| Optional | `None`                        | `list[PkType] \\| None` |          |\n| Optional | `None`                        | `list[PkType] \\| None` |          |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnextgencontributions%2Fdjango2pydantic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnextgencontributions%2Fdjango2pydantic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnextgencontributions%2Fdjango2pydantic/lists"}