Giter Club home page Giter Club logo

djantic's Introduction

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"
        ]
    }

djantic's People

Contributors

dependabot[bot] avatar jordaneremieff avatar mmcardle avatar phbernardes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

djantic's Issues

Unable to support more than Level 2 relations

class Level1(models.Mode):
name = models.CharField()

class Level2(models.Model):
parent = models.ForeignKey(Level1)
name2 = models.Charge()

class Level3(models.Model):
parent = models.ForeignKey(Level2)
name3 = models.Charge()

class Level3Schema(ModelSchema):
name3: str = Field()

class Level2Schema(ModelSchema):
level3_set:List[Level3Schema] = Field(None)
name2: str = Field(None)

class Level1Schema(ModelSchema):
level2_set :List[Level2Schema] = Field(None)
name1:str = Field(None)

   as following is not work:
 Level1Schema.from_django(level1_instance)

"ValueError: too many values to unpack" with TextChoices

django==3.0.5
pydantic==1.8.2
djantic=0.3.0

Attempting to create a djantic schema for a model that has a django.db.models.TextChoices subclass assigned to a field's choices will result in a ValueError

For example:

from django.db import models
from djantic import ModelSchema


class FoodChoices(models.TextChoices):
    BANANA = 'ba', 'A delicious yellow Banana'
    APPLE = 'ap', 'A delicious red Apple'


class A(models.Model):
    name = models.CharField(max_length=128)
    preferred_food = models.CharField(max_length=2, choices=FoodChoices.choices)


class ASchema(ModelSchema):
    class Config:
        model = A

the above results in:

...
/usr/local/lib/python3.8/site-packages/djantic/main.py in __new__(mcs, name, bases, namespace)
     95 
     96                     else:
---> 97                         python_type, pydantic_field = ModelSchemaField(field)
     98 
     99                     field_values[field_name] = (python_type, pydantic_field)

/usr/local/lib/python3.8/site-packages/djantic/fields.py in ModelSchemaField(field)
     85         if field.choices:
     86             enum_choices = {v: k for k, v in field.choices}
---> 87             python_type = Enum(  # type: ignore
     88                 f"{field.name.title().replace('_', '')}Enum",
     89                 enum_choices,

/usr/local/lib/python3.8/enum.py in __call__(cls, value, names, module, qualname, type, start)
    339             return cls.__new__(cls, value)
    340         # otherwise, functional API: we're creating a new Enum type
--> 341         return cls._create_(
    342                 value,
    343                 names,

/usr/local/lib/python3.8/enum.py in _create_(cls, class_name, names, module, qualname, type, start)
    461                 member_name, member_value = item, names[item]
    462             else:
--> 463                 member_name, member_value = item
    464             classdict[member_name] = member_value
    465         enum_class = metacls.__new__(metacls, class_name, bases, classdict)

ValueError: too many values to unpack (expected 2)

FastAPI + Djantic - OpenAPI spec

HI,

First of all, this is a great project, getting a lot of value from it, so thank you.

Having an issue generating an openapi specification when using it in combination with FastAPI, specifically when using Django model choices.

Django Model

from django.db import models

class SimpleModelWithChoices(models.Model):
    class ChoiceType(models.TextChoices):
        CHOICE1 = "CHOICE1"
        CHOICE2 = "CHOICE2"

    choice = models.CharField("Type", max_length=30, choices=ChoiceType.choices)

Djantic Spec

from djantic import ModelSchema

class Schema1(ModelSchema):
    class Config:
        model = SimpleModelWithChoices


class Schema2(ModelSchema):
    class Config:
        model = SimpleModelWithChoices

FastAPI

from fastapi import APIRouter, FastAPI

router = APIRouter()
application = FastAPI()

@application.get("path1", response_model=Schema1)
def get1(instance: Schema1):
    return instance

@application.get("path2", response_model=Schema2)
def get2(instance: Schema2):
    return instance

application.include_router(router)

assert application.openapi()

Error

.venv\lib\site-packages\fastapi\openapi\utils.py:387: in get_openapi
    definitions = get_model_definitions(

    def get_model_definitions(
        flat_models: Set[Union[Type[BaseModel], Type[Enum]]],
        model_name_map: Dict[Union[Type[BaseModel], Type[Enum]], str],
    ) -> Dict[str, Any]:
        definitions: Dict[str, Dict[str, Any]] = {}
        for model in flat_models:
            m_schema, m_definitions, m_nested_models = model_process_schema(
                model, model_name_map=model_name_map, ref_prefix=REF_PREFIX
            )
            definitions.update(m_definitions)
>           model_name = model_name_map[model]
E           KeyError: <enum 'ChoiceEnum'>

.venv\lib\site-packages\fastapi\utils.py:28: KeyError

I think it is due to the way FastAPI keeps a mapping of classes and uses them internally. I have a workaround in my project

def __fix_enums(new_type):

    for item in new_type.__dict__["__fields__"].values():
        if "enum.EnumMeta" in str(item.type_.__class__):
            enum_values = [(i.value, i.value) for i in item.type_]

            new_enum_type = Enum(f"{new_type.__name__}_{item.name}_Enum", enum_values, module=__name__)
            setattr(item, "type_", new_enum_type)

    return new_type

I would be happy to produce a PR to fix the issue if needed, Maybe adding some sort of uniqueness in the name of the enum class in djantic/fields.py ?

            python_type = Enum(  # type: ignore
                f"{field.name.title().replace('_', '')}Enum",
                enum_choices,
                module=__name__,
            )

Library Versions

djantic = "^0.3.5"
Django = "^3.2.5"
fastapi = "^0.68.0"

Testing djantic for django 3.2

Gave the code a try, went to open a PR for BigAutoField django 3.2 changes, but noticed they were in the main branch already.

Tried install from pypi 0.2.0 and also looked in the tagged zip and didn't see the changes there.

updated my requirements.txt

from

djantic==0.2.0

to:

-e git+https://github.com/jordaneremieff/djantic.git@main#egg=djantic

Was there some other stuff being worked on for django 3.2 support?

Thanks

Abstract class option for ModelSchema subclasses

I am using Djantic in my project, and I would like to base a base class between ModelSchema and my individual model schemata, to implement a to_orm method directly on the ModelSchema, as in my complex case simply doing DjangoModel(**schema) doesn't work because of foreign keys and some other data transformations required. I could just implement it on each of them individually, but then mypy will be very unhappy.

I would like to be able to do the following:

class ModelSchemaToORM(ModelSchema):
    # either this, django model style
    class Meta:
        abstract = True

    # or this
    class Config:
        abstract = True

    async def to_orm(self):
        raise NotImplementedError

Currently the two versions above yield

pydantic.errors.ConfigError: 'Config' (Is `Config` class defined?)

and

pydantic.errors.ConfigError: type object 'Config' has no attribute 'model' (Is `Config.model` a valid Django model class?)

respectively.

Does it make sense to folks here to add an additional condition to ModelSchemaMetaclass to skip Config checks on abstract subclasses? It could either be in Meta or Config, I don't really mind as long as there is a way to put intermediate parents between my ModelSchemata and Djantic's ModelSchema.

Dynamic choice fields

When a type annotation isn't provided for a field with .choices set then an Enum should be generated dynamically, something like:

python_type = Enum(f"{field.name.title()}Enum", {v: k for k, v in field.choices})

Add Support for Django 4.2 which uses psycopg3

It looks like this libaray currently does not support django4.0 or above, yet to say Django4.2. I am happy to pull together a PR to help support Django4.2(which is a major version that uses psycopg3).

Support related include/exclude in configuration

Something like:

class ArticleSchema(PydanticDjangoModel):

    publications: List[PublicationSchema]

    class Config:
        model = Article
        exclude = ["publications__created_at", "publications__updated_at"]

Combine model and schema

The approach in https://github.com/tiangolo/sqlmodel has me interested exploring a combined model for Django and Pydantic. I would consider doing a PR to that project, though it seems too specific to SQLAlchemy and FastAPI for a Django-specific implementation to be a good fit (also don't know if I'll pursue this at all) - not sure.

Something like this for the model definition:

from djantic.models import DjanticModel, Field

class Plant(DjanticModel):
    """A plant."""

    common_name: str
    genus_name: str = Field(
        max_length=100,
        help_text="A generic name for a collective group of plants.",
    )
    specific_epithet: str

    class Meta:
        ordering = ["genus_name"]

    class Config:
        include = ["genus_name", "specific_epithet"]

Then attribute access would (ideally) look like this:

from myapp.models import Plant

# Schema definition from class
schema = Plant.schema()

# Export data from instance
plant = Plant.objects.create(genus_name="Grevillea", specific_epithet="buxifolia")
data = plant.dict()

Maybe.

Support Django querysets

There is a (non-functional) class method from_django_qs based on some things I had done previously, but I think I prefer not to have two methods. Instead there should be a single from_django method that would either automatically determine the query type or allow a parameter to set this explicitly.

Also something like Pydantic.filter() or Pydantic.all for populating a model directly, but probably wouldn't be worth supporting chaining or anything more complex than this.

Rename PydanticDjangoModel

Both Pydantic and Django use the term Model. The current name PydanticDjangoModel is somewhat confusing and could be interpreted in a few different ways at first glance.

I've generally been using *Schema when subclassing the Pydantic model (both in tests and the README):

class UserSchema(PydanticDjangoModel):
    ...

It would probably be better to rename PydanticDjangoModel to something like ModelSchema or DjangoModelSchema and give priority to Django naming convention.

Bugfix custom field MRO lookups

It's possible for a non-field class to exist in the MRO for a custom field, so these should be ignored when searching for the base class.

Error on django ImageField

Error if I add in scheme field avatar

Model:

def get_avatar_upload_path(instance, filename):
    return os.path.join(
        "customer_avatar", str(instance.id), filename)


class Customer(models.Model):
    """
    params: user* avatar shop* balance permissions deleted

    prefetch: -
    """
    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='customers', verbose_name='Пользователь')
    avatar = models.ImageField(upload_to=get_avatar_upload_path, verbose_name='Аватарка', blank=True, null=True)
    retail = models.ForeignKey('retail.Retail', on_delete=models.CASCADE, related_name='customers', verbose_name='Розница')
    balance = models.DecimalField(max_digits=9, decimal_places=2, verbose_name='Баланс', default=0)
    permissions = models.ManyToManyField('retail.Permission', verbose_name='Права доступа', related_name='customers', blank=True)
    deleted = models.BooleanField(default=False, verbose_name='Удален')
    created = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')

Scheme

class CustomerSchema(ModelSchema):
    user: UserSchema

    class Config:
        model = Customer
        include = ['id', 'user', 'avatar', 'retail', 'balance', 'permissions']

Error:

fastapi_1  | Process SpawnProcess-36:
fastapi_1  | Traceback (most recent call last):
fastapi_1  |   File "/usr/local/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
fastapi_1  |     self.run()
fastapi_1  |   File "/usr/local/lib/python3.8/multiprocessing/process.py", line 108, in run
fastapi_1  |     self._target(*self._args, **self._kwargs)
fastapi_1  |   File "/usr/local/lib/python3.8/site-packages/uvicorn/subprocess.py", line 62, in subprocess_started
fastapi_1  |     target(sockets=sockets)
fastapi_1  |   File "/usr/local/lib/python3.8/site-packages/uvicorn/main.py", line 390, in run
fastapi_1  |     loop.run_until_complete(self.serve(sockets=sockets))
fastapi_1  |   File "uvloop/loop.pyx", line 1494, in uvloop.loop.Loop.run_until_complete
fastapi_1  |   File "/usr/local/lib/python3.8/site-packages/uvicorn/main.py", line 397, in serve
fastapi_1  |     config.load()
fastapi_1  |   File "/usr/local/lib/python3.8/site-packages/uvicorn/config.py", line 278, in load
fastapi_1  |     self.loaded_app = import_from_string(self.app)
fastapi_1  |   File "/usr/local/lib/python3.8/site-packages/uvicorn/importer.py", line 20, in import_from_string
fastapi_1  |     module = importlib.import_module(module_str)
fastapi_1  |   File "/usr/local/lib/python3.8/importlib/__init__.py", line 127, in import_module
fastapi_1  |     return _bootstrap._gcd_import(name[level:], package, level)
fastapi_1  |   File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
fastapi_1  |   File "<frozen importlib._bootstrap>", line 991, in _find_and_load
fastapi_1  |   File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
fastapi_1  |   File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
fastapi_1  |   File "<frozen importlib._bootstrap_external>", line 783, in exec_module
fastapi_1  |   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
fastapi_1  |   File "/opt/project/config/asgi.py", line 18, in <module>
fastapi_1  |     from backend.retail.fastapp import app
fastapi_1  |   File "/opt/project/backend/retail/fastapp.py", line 9, in <module>
fastapi_1  |     from backend.retail.routers import router
fastapi_1  |   File "/opt/project/backend/retail/routers.py", line 3, in <module>
fastapi_1  |     from backend.retail.api import auth, postitem, ping, customer
fastapi_1  |   File "/opt/project/backend/retail/api/customer.py", line 8, in <module>
fastapi_1  |     from backend.retail.schemas.customer import CustomerSchema
fastapi_1  |   File "/opt/project/backend/retail/schemas/customer.py", line 7, in <module>
fastapi_1  |     class CustomerSchema(ModelSchema):
fastapi_1  |   File "/usr/local/lib/python3.8/site-packages/djantic/main.py", line 97, in __new__
fastapi_1  |     python_type, pydantic_field = ModelSchemaField(field)
fastapi_1  |   File "/usr/local/lib/python3.8/site-packages/djantic/fields.py", line 135, in ModelSchemaField
fastapi_1  |     python_type,
fastapi_1  | UnboundLocalError: local variable 'python_type' referenced before assignment

JetBrains Code Completion

Is there a way to add support for JetBrains code completion?

class MyDjangoModel(models.Model):
    name = model.CharField(max_lenght=200)

class MyDjangoModelSchema(ModelSchema):
    class Config:
        model = MyDjangoModel

obj = MyDjangoModelSchema.from_orm(MyDjangoModel.objects.first())
obj.name #  PyCharm says "Unresolved attribute reference 'name' for class 'MyDjangoModelSchema' "

Is there a way to overwrite how a field is deserialized?

I have a field in Django models that is an integer, but the value that is returned from an API is a JSON, and I need to grab the value out of it. See example below:

# models.py

class MyModel(models.Model):
    my_field = models.IntegerField(default=0)

# schemas.py
class MySchema(ModelSchema):
    class Config:
        model = MyModel

# API response:
resp = {
    "my_field": {"value": 42}
}

# error happens here
data = MySchema.parse_obj(resp)

Is there a way to overwrite individual field's handling for deserialisation?

Pydantic 2 Support

I was testing out djantic with pydantic 2.4.2 and ran into an error caused by an import that was removed from pydantic.

  File "/usr/local/lib/python3.11/site-packages/djantic/main.py", line 12, in <module>
    from pydantic import BaseModel, ConfigError, create_model
ImportError: cannot import name 'ConfigError' from 'pydantic' (/usr/local/lib/python3.11/site-packages/pydantic/__init__.py)

The root cause of this appears to be that ConfigError was removed from pydantic during the v1 -> v2 transition as mention in the migration guide

Django JSON API view

Either a re-usable CBV or perhaps just some documentation would be good for how to create a basic JSON API view using the model schemas.

Pydantic 2 compatible fork

So I spent a few days making djantic compatible with pydantic 2, since the author of this package seems to be busy with life (I hope they are doing well!)

You can find it on github and install it through pip install djantic2.

ForeignKey show only ID

Django | 3.2.16 (try on 3.2.6)
pydantic | 1.9.1
djantic | 0.7.0 | 0.7.0

# models

class Service(models.Model):
    name = models.CharField(max_length=20)


class ServiceRequest(models.Model):
    name = models.CharField(max_length=50)
    default = models.JSONField(default=dict)
    service = models.ForeignKey(Service, related_name='requests', on_delete=models.CASCADE)

# schemas

from djantic import ModelSchema
from mock_service.models import Service, ServiceRequest


class ServiceSchema(ModelSchema):
    class Config:
        model = Service


class ServiceRequestSchema(ModelSchema):
    class Config:
        model = ServiceRequest

ServiceRequestSchema.from_orm(ServiceRequest.objects.last()).dict() = {'id': 1, 'name': 'test_request', 'default': {'': ''}, 'service': 1}
ServiceSchema.from_orm(Service.objects.last()).dict() = {'requests': [{'id': 1}], 'id': 1, 'name': 'test_service'}

Where I mistake?

Refactor or remove attribute access for Django querysets

Currently the Pydantic model includes the following methods for using the Django queryset:

  • PydanticDjangoModel.objects - Returns the objects manager for the Django model
  • PydanticDjangoModel.get - Queries the objects manager for the provided keyword arguments and returns the Pydantic model populated from the query result.
  • PydanticDjangoModel.create - Calls the create method on the objects manager for the Django model and returns the Pydantic model populated from the new instance.

Alternatively, the Pydantic model could expose only a single attribute, PydanticDjangoModel.objects, and this would support chaining methods and additionally populate the Pydantic model with the results. However, this would require some careful consideration because the Django queryset API can be used to return results that could potentially conflict with the Pydantic model definition.

This feature is a "nice to have" that I initially added as a convenience, and I'm not sure yet if I will do away with the wrapper methods entirely and only support populating the Pydantic model using the from_django_* methods. I don't currently see a tremendous advantage over using the Django ORM directly and loading the results into the models directly, but perhaps I need to think about this more.

String Related Fields

Hello there!

Is there yet a way to use something like DRF's string-related field? That is, for a model field with a relation, set it to a custom field that returns the related model's string representation.

Rename this project?

So I originally called this project "pydantic-django" when I just messing around with model generation and wasn't sure if I'd end up doing much with it beyond my initial exploration, though I'd prefer a different name to make it more distinct and easier to reference without confusing "Pydantic with Django" use-cases that are unrelated to this project.

Since I just did the first 0.1.0 release I think it is early enough that I could rename this and redirect to the new name.

Documentation, docstrings, comments, changelog

I didn't include any docstrings or comments throughout the project because things were changing quite rapidly, but at this point I should go through and add these. Also a mkdocs gh-page and changelog.

Django admin integration for import/export

Create actions for import and export behavior that supports the following formats:

  • JSON
  • CSV

This would probably be implemented using a base admin view class or admin view class mixins.

Custom types for configuring Django fields

Currently there is a custom class for GenericIPAddressField https://github.com/jordaneremieff/pydantic-django/blob/636aa0dfa6fd4fd4c9cd2bd1173d32f03b8c6b9a/pydantic_django/types.py#L30. It isn't being used the way I intended atm (the protocol defaults to both in all cases), but it represents a potential solution to a problem left to solve. I want the options from the deconstructed field to be used here (e.g. protocol would be provided in this case).

Not really sure yet if this is the best approach to this, but definitely a todo.

ValueError: cannot specify both default and default_factory

Hello,

This is a great library. Looking to contribute if you are needing anything done.

Getting this error but I see it looks fixed in your main branch.

  File "\.venv\lib\site-packages\djantic\main.py", line 102, in __new__
    p_model = create_model(
  File "pydantic\main.py", line 990, in pydantic.main.create_model
  File ".venv\lib\site-packages\djantic\main.py", line 34, in __new__
    cls = super().__new__(mcs, name, bases, namespace)
  File "pydantic\main.py", line 299, in pydantic.main.ModelMetaclass.__new__
  File "pydantic\fields.py", line 403, in pydantic.fields.ModelField.infer
  File "pydantic\fields.py", line 388, in pydantic.fields.ModelField._get_field_info
  File "pydantic\fields.py", line 173, in pydantic.fields.FieldInfo._validate
ValueError: cannot specify both default and default_factory
Django==3.2.3
djantic==0.2.0
pydantic==1.8.2

So just posting this for tracking incase anyone else has the same issue.

Do you accept PRs?

Hey,
this project is awesome and I would consider contributing a bit. Do you generally accept PRs?

Best!
Julian

MyPy support

Is MyPy type checking supported at all? Any model property I try to access on a Djantic model is detected as non-existent by mypy. Is this resolvable?

Maybe I can contribute the solution if someone can point me in the right direction. Thank you.

Fix type hints

Currently mypy is commented out in the test script until this is resolved.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.