Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/hnarayanan/django-extensible-models

A rough experiment before sketching out a more general Django package for this exact feature
https://github.com/hnarayanan/django-extensible-models

Last synced: 29 days ago
JSON representation

A rough experiment before sketching out a more general Django package for this exact feature

Awesome Lists containing this project

README

        

* Django Extensible Models
** What is it?

Django Extensible Models is a robust framework for dynamically
extending Django models at runtime. It uses JSONFields for flexible
data storage, with JSONSchema validation ensuring data integrity. It
seamlessly integrates with Django's ORM while enabling multi-tenant
schema variations.

** Why is it?

Django offers a really robust model system that functions as a great
interface to store and retrieve data related to your app. Models in
Django are backed by tables in a relational database. While this is
really good for correctness, it is quite rigid in terms of the shape
of data that is stored. Sometimes, you run into use-cases that demand
a bit more dynamism during the running of your Django app.

Let's take a concrete example. You have an existing Django SaaS app
that's launched to many happy customers. They are happy, but each
customer feels that if they could store /just a little bit more custom
data/ as part of their usage of your app, their workflows would be
much smoother. So they ask you to add what they want. The trouble is,
each customer is interested in augmenting their data in different
ways. You diligently add the first customer's fields. And then
another's. And then even more. And before you know it, things get
really messy.

Solving this problem is the point of this project. Instead of
individually catering to each of their requests, /Django Extensible
Models/ offers you a general extension mechanism that allows your models
to grow with your customers' needs.

* Features
** DONE It's easy to incrementally add this to your app

With a relatively small change to your existing model code (see
[[#installation][Installation]] and [[#usage][Usage]]), you now have a Django model that retains all
its Django goodness, and can be extended on the fly with additional
fields at runtime.

** DONE Formal schema for extended fields

We don't just stuff the extra data for these additional fields into a
~JSONField~ and call it a day,[fn::What sort of operation do you think
this is?] we allow you to define a proper schema for this data (using
[[https://jsonschema.net][JSON Schema]]).

** DONE Different extended schema for different groups of objects

It wouldn't make much sense to apply the same extension schema to all
objects of your model,[fn::You could just update the Python model code
of your app instead!] so Django Extensible Models allows you to define
different extended fields for different sets of objects.

We also allow you to extended individual objects in unique ways if
that is what you need.

** DONE Strong validation of data for these extended fields

With a good schema defined, it is easy to validate that incoming data
for your extended fields match your expectations before storing it in
the database.

** TODO Ability to query these fields using an ORM-friendly syntax

The data for your extended fields is not simply stored in a messy,
impenetrable blob. It is stored in a structured [[https://docs.djangoproject.com/en/dev/ref/models/fields/#jsonfield][JSONField]] that can be
queried in a systematic way using standard Django syntax.

** TODO Dynamically generated forms for these extended fields in the Django Admin interface
** TODO Dynamic extensions for these fields in Django Model Forms (and Crispy Forms)
** TODO Dynamic extensions for these fields in for Django Rest Framework
** TODO Dynamic extensions for these fields in Django (Rest Framework) Filters
** TODO Migrations between versions of your extended schema!

Taken together, you should be able to use your extended fields much
like how you use your native Django model fields. And this is just
cool.

* Installation
:PROPERTIES:
:CUSTOM_ID: installation
:END:
#+BEGIN_SRC shell
pip install django-extensible-models
#+END_SRC

#+BEGIN_SRC python
# settings.py
INSTALLED_APPS = [
# ...
"extensible_models",
# ...
]

EXTENSIBLE_MODELS_TENANT_MODEL = "your_app.YourTenantModel"
EXTENSIBLE_MODELS_TENANT_FIELD = "your_tenant_field_name"
#+END_SRC
* Usage
:PROPERTIES:
:CUSTOM_ID: usage
:END:

#+BEGIN_SRC python
# models.py
from django.db import models
from extensible_models.models import ExtensibleModelMixin

class ExampleModel(ExtensibleModelMixin, models.Model):

...
#+END_SRC

#+BEGIN_SRC python
# admin.py
from django.contrib import admin

from extensible_models.admin import ExtensibleModelAdminMixin

class ExampleModelAdmin(ExtensibleModelAdminMixin, admin.ModelAdmin):

# Leave all your existing configuration as is!
#+END_SRC
* Copyright and License

Copyright (c) 2022-2024 [[https://harishnarayanan.org][Harish Narayanan]]

This code is licenced under the MIT Licence. See [[https://github.com/hnarayanan/django-extensible-models-experiment/blob/main/LICENSE][LICENSE]] for the full
text of this licence.