• Stars
    star
    441
  • Rank 96,534 (Top 2 %)
  • Language
    Python
  • License
    MIT License
  • Created almost 4 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Pydantic model support for Django

Djantic

Pydantic model support for Django

GitHub Workflow Status (Test) PyPi package Supported Python versions Supported Django versions


Documentation: https://jordaneremieff.github.io/djantic/


Djantic is a library that provides a configurable utility class for automatically creating a Pydantic model instance for any Django model class. It is intended to support all of the underlying Pydantic model functionality such as JSON schema generation and introduces custom behaviour for exporting Django model instance data.

Quickstart

Install using pip:

pip install djantic

Create a model schema:

from users.models import User

from djantic import ModelSchema

class UserSchema(ModelSchema):
    class Config:
        model = User
        
print(UserSchema.schema())

Output:

{
        "title": "UserSchema",
        "description": "A user of the application.",
        "type": "object",
        "properties": {
            "profile": {"title": "Profile", "description": "None", "type": "integer"},
            "id": {"title": "Id", "description": "id", "type": "integer"},
            "first_name": {
                "title": "First Name",
                "description": "first_name",
                "maxLength": 50,
                "type": "string",
            },
            "last_name": {
                "title": "Last Name",
                "description": "last_name",
                "maxLength": 50,
                "type": "string",
            },
            "email": {
                "title": "Email",
                "description": "email",
                "maxLength": 254,
                "type": "string",
            },
            "created_at": {
                "title": "Created At",
                "description": "created_at",
                "type": "string",
                "format": "date-time",
            },
            "updated_at": {
                "title": "Updated At",
                "description": "updated_at",
                "type": "string",
                "format": "date-time",
            },
        },
        "required": ["first_name", "email", "created_at", "updated_at"],
    }

See https://pydantic-docs.helpmanual.io/usage/models/ for more.

Loading and exporting model instances

Use the from_orm method on the model schema to load a Django model instance for export:

user = User.objects.create(
    first_name="Jordan", 
    last_name="Eremieff", 
    email="[email protected]"
)

user_schema = UserSchema.from_orm(user)
print(user_schema.json(indent=2))

Output:

{
    "profile": null,
    "id": 1,
    "first_name": "Jordan",
    "last_name": "Eremieff",
    "email": "[email protected]",
    "created_at": "2020-08-15T16:50:30.606345+00:00",
    "updated_at": "2020-08-15T16:50:30.606452+00:00"
}

Using multiple level relations

Djantic supports multiple level relations. This includes foreign keys, many-to-many, and one-to-one relationships.

Consider the following example Django model and Djantic model schema definitions for a number of related database records:

# models.py
from django.db import models

class OrderUser(models.Model):
    email = models.EmailField(unique=True)


class OrderUserProfile(models.Model):
    address = models.CharField(max_length=255)
    user = models.OneToOneField(OrderUser, on_delete=models.CASCADE, related_name='profile')


class Order(models.Model):
    total_price = models.DecimalField(max_digits=8, decimal_places=5, default=0)
    user = models.ForeignKey(
        OrderUser, on_delete=models.CASCADE, related_name="orders"
    )


class OrderItem(models.Model):
    price = models.DecimalField(max_digits=8, decimal_places=5, default=0)
    quantity = models.IntegerField(default=0)
    order = models.ForeignKey(
        Order, on_delete=models.CASCADE, related_name="items"
    )


class OrderItemDetail(models.Model):
    name = models.CharField(max_length=30)
    order_item = models.ForeignKey(
        OrderItem, on_delete=models.CASCADE, related_name="details"
    )
# schemas.py
from djantic import ModelSchema

from orders.models import OrderItemDetail, OrderItem, Order, OrderUserProfile


class OrderItemDetailSchema(ModelSchema):
    class Config:
        model = OrderItemDetail

class OrderItemSchema(ModelSchema):
    details: List[OrderItemDetailSchema]

    class Config:
        model = OrderItem

class OrderSchema(ModelSchema):
    items: List[OrderItemSchema]

    class Config:
        model = Order

class OrderUserProfileSchema(ModelSchema):
    class Config:
        model = OrderUserProfile

class OrderUserSchema(ModelSchema):
    orders: List[OrderSchema]
    profile: OrderUserProfileSchema

Now let's assume you're interested in exporting the order and profile information for a particular user into a JSON format that contains the details accross all of the related item objects:

user = OrderUser.objects.first()
print(OrderUserSchema.from_orm(user).json(ident=4))

Output:

{
    "profile": {
        "id": 1,
        "address": "",
        "user": 1
    },
    "orders": [
        {
            "items": [
                {
                    "details": [
                        {
                            "id": 1,
                            "name": "",
                            "order_item": 1
                        }
                    ],
                    "id": 1,
                    "price": 0.0,
                    "quantity": 0,
                    "order": 1
                }
            ],
            "id": 1,
            "total_price": 0.0,
            "user": 1
        }
    ],
    "id": 1,
    "email": ""
}

The model schema definitions are composable and support customization of the output according to the auto-generated fields and any additional annotations.

Including and excluding fields

The fields exposed in the model instance may be configured using two options: include and exclude. These represent iterables that should contain a list of field name strings. Only one of these options may be set at the same time, and if neither are set then the default behaviour is to include all of the fields from the Django model.

For example, to include all of the fields from a user model except a field named email_address, you would use the exclude option:

class UserSchema(ModelSchema):
    class Config:
        exclude = ["email_address"]

In addition to this, you may also limit the fields to only include annotations from the model schema class by setting the include option to a special string value: "__annotations__".

class ProfileSchema(ModelSchema):
        website: str

        class Config:
            model = Profile
            include = "__annotations__"

    assert ProfileSchema.schema() == {
        "title": "ProfileSchema",
        "description": "A user's profile.",
        "type": "object",
        "properties": {
            "website": {
                "title": "Website",
                "type": "string"
            }
        },
        "required": [
            "website"
        ]
    }

More Repositories

1

mangum

AWS Lambda support for ASGI applications
Python
1,616
star
2

django-fastapi-example

FastAPI + Django experiment
Python
104
star
3

aeroplane

Example project using Django and FastAPI together.
Python
64
star
4

asgi-examples

A collection of example ASGI applications
Python
47
star
5

serverless-mangum-examples

Example ASGI applications and Serverless Framework configurations using Mangum
Python
29
star
6

grevillea

Google Cloud Functions support for ASGI
Python
26
star
7

guitarlette

🎸A songwriting tool for guitarists
HTML
25
star
8

headless-api

Python API service for headless Chromium
Python
19
star
9

asgi-video-streaming

Demonstration of video streaming using an ASGI application
Python
19
star
10

bonnette

ASGI adapter for Azure Functions
Python
13
star
11

mangum-cli

CLI tools for use with Mangum
Python
13
star
12

starlette-graphene-tortoise

An example Starlette app that uses Graphene and Tortoise ORM.
Python
11
star
13

typehint-serialization-experiment

An experiment into API serialization/de-serialization/validation
Python
11
star
14

starlette-svelte-example

Example project using Svelete with Starlette
HTML
9
star
15

mangum-examples

Example ASGI application deployments with AWS Lambda & API Gateway
HTML
9
star
16

django-sphinx-view-example

Python
6
star
17

mangum-chatroom

An example Starlette chatroom application and deployment for AWS Lambda & API Gateway.
Python
6
star
18

charlette

Django app that uses Starlette components with Channels
Python
5
star
19

asgi-s3

(WIP) Static file management tools and ASGI middleware support for Amazon S3
Python
4
star
20

starray

Implementing Pyray 3d rendering using ASGI
Python
3
star
21

asgitools

A collection of tools for developing ASGI applications. Supports both ASGI servers, uvicorn and daphne.
Python
2
star
22

envotate

Settings management using environment variables and type annotations
Python
2
star
23

mangum-template

A template for developing ASGI-compatible apps deployed to AWS Lambda.
Python
2
star
24

python-template

A cookiecutter template for generating Python packages.
Python
1
star
25

starlette-react

An example React app using a Starlette backend
JavaScript
1
star
26

django-rest-slack

Easily handle Slack API events and commands using Django
Python
1
star
27

asgi-tortoise-orm

ASGI middleware that implements Tortoise ORM support. WIP.
Python
1
star
28

aiopaint

WIP: Paint app using ASGI, WebSockets, and the HTML5 Canvas API, work in progress
HTML
1
star
29

starlette-typesystem-databases-example

Example app using Starlette, Typesystem, and Databases
Python
1
star
30

asyncio-http-parser

HTTP parser written using asyncio and Python 3.7, experimental / work in progress.
Python
1
star
31

apistar-react

JavaScript
1
star
32

innate

Small library for implementing command-line interfaces in Python
Python
1
star