django-cattrs-fields, your data modeling toolkit

hi :waving_hand:
today i published the result of my experiments with django and cattrs
django-cattrs-fields is a data modeling library that helps you model and validate your data bringing the power of attrs based data classes and cattrs toolkit to django.

important uses:

  • creating API endpoints
  • handling html forms
  • handling multipart data
  • use with http clients
  • modeling data for any other use

you can now install it from pypi using pip install django-cattrs-fields

it is intentionally small, it’s meant to fit into your setup, so you can shape it anyway you like and model your data in a fast, type safe way.

with this package you can create rest API endpoints, de/serializing your data from and to json or any other format, it has built-in support for a lot of different serialization libraries, and it’s very easy to add more.
and this is done in your simple django views, no need to write a seprate view for API endpoints (ofc, you can if you want to).

or maybe you want to write a client that connects to an API, you can use this package to send and receive the data while keeping the data django friendly (validation, etc…)

or maybe you just want to some data around, we can help with that as well.

and, if you are ok with writing some code, you can use one attrs based data model to handle html forms and REST request, so you no longer have to write separate django forms and DRF serializers
it can all be done with one class, and one view.

for example when working with users you can write something like this:

from attrs import define

from django_cattrs_fields import CharField, EmailField


@define
class User:
    username: CharField
    email: EmailField
    password: CharField

and it can be use like this:

from django_cattrs_fields.converters import converter
from django_cattrs_fields.converters.json import serializer


def get_data(request):
    if request.method == "POST":
        if request.content_type in {"application/x-www-form-urlencoded", "multipart/form-data"}:
            structured_data = converter.structure({**request.POST.dict(), **request.FILES.dict()}, User)  # handle html forms, and multipart data
        else:
            structured_data = serializer.loads(request.body, User)  # handle json (or anything else)

        data: dict[str, Any] = converter.unstructure(structured_data)  # a dictionary of all the POST data

        UserModel.objects.create_user(**data)

        return HttpResponse("done")

i would note that this is a first release and not suited for production.

i also have the idea of a full fledged REST library based on this project, which will eliminate a lot of boilerplate, but it will be in a separate package,
as i mentioned this is intentionally small and is meant to help you model your data, not a full REST workflow.

if you have any kind of feedback, please let me know :folded_hands:

1 Like

Hey @amirreza8002 — This looks cool. :heart: cattrs :grinning_face:

Your general approach is very much in line with how I do things. Good to see others picking that up. (I’m working on getting my take ready to show now.)

For the REST bit, I think the key is getting JSONSchema from the attrs classes. At that point, most of the bits in the ecosystem for OpenAPI docs are already in place (or easily enough made so). There are some breadcrumbs in the environment:

It’s on my list to dig into that, but I didn’t get to it yet.

I think if we could get that step in place we should be able to adapt drf-spectacular for the rest of the OpenAPI bits we’d need. (I’ve spoken with Thorsten there over a couple of DjangoCon Europes, and it looks feasible.)

TL;dr: Exciting! And this is where it’s at, from my POV. :partying_face:

1 Like

hi :waving_hand:
thanks :raising_hands: this was reassuring

cattrs gets me more interested by day, excited to see your take on it

and thanks for the openAPI links, I’ve been meaning to start researching that, haven’t done any work in that area before.

i think there’s a lot of locked potential in cattrs for us, hopefully it’ll be very beneficial to Django community, one way or another :heart:

1 Like