# Path: shared_schema_tenants_custom_data/mixins.py
# class TenantSpecificFieldsModelMixin(models.Model):
#     objects = TenantSpecificFieldsModelManager()
# 
#     def __init__(self, *args, **kwargs):
#         table_id = kwargs.get('table_id', getattr(kwargs.get('table'), 'id', None))
#         definitions = self.get_definitions(table_id=table_id)
#         for definition in definitions:
#             if definition.name in kwargs.keys():
#                 setattr(self, definition.name, kwargs.pop(definition.name))
#         super(TenantSpecificFieldsModelMixin, self).__init__(*args, **kwargs)
# 
#     def get_definitions(self, table_id=-1, force_hit_db=False):
#         from shared_schema_tenants_custom_data.models import TenantSpecificFieldDefinition, TenantSpecificTable
#         if not hasattr(self, 'definitions') or force_hit_db:
#             if type(self).__name__ == 'TenantSpecificTableRow':
#                 self.definitions = TenantSpecificFieldDefinition.objects.filter(
#                     table_content_type=ContentType.objects.get_for_model(TenantSpecificTable),
#                     table_id=table_id)
#             else:
#                 self.definitions = TenantSpecificFieldDefinition.objects.filter(
#                     table_content_type=ContentType.objects.get_for_model(type(self)))
#         return self.definitions
# 
#     def create_tenant_specific_fields(self, tenant_specific_fields_data):
#         definitions = self.get_definitions()
#         definitions_by_name = {d.name: d for d in definitions}
# 
#         with transaction.atomic():
#             for field_name, definition in definitions_by_name.items():
#                 field_value = tenant_specific_fields_data.get(
#                     field_name, getattr(self, field_name, None))
#                 PivotTableClass = _get_pivot_table_class_for_data_type(definition.data_type)
#                 PivotTableClass.objects.create(
#                     definition=definition, row_id=self.id,
#                     row_content_type=ContentType.objects.get_for_model(self.__class__),
#                     value=field_value)
# 
#     def update_tenant_specific_fields(self, tenant_specific_fields_data):
#         old = self.__class__.objects.get(pk=self.pk)
#         definitions = self.get_definitions()
#         definitions_by_name = {d.name: d for d in definitions}
# 
#         with transaction.atomic():
#             for field_name, definition in definitions_by_name.items():
#                 new_value = tenant_specific_fields_data.get(field_name, None)
#                 old_value = getattr(old, field_name, None)
#                 PivotTableClass = _get_pivot_table_class_for_data_type(definition.data_type)
#                 if new_value != old_value:
#                     PivotTableClass.objects.filter(
#                         definition__id=definition.id, row_id=self.id,
#                         row_content_type=ContentType.objects.get_for_model(self.__class__)
#                     ).update(value=new_value)
# 
#     def save(self, *args, **kwargs):
#         table_id = getattr(self, 'table_id', getattr(getattr(self, 'table', object()), 'id', None))
# 
#         force_hit_db = False
#         if hasattr(self, 'definitions') and not self.definitions.exists():
#             force_hit_db = True
# 
#         definitions = self.get_definitions(table_id=table_id, force_hit_db=force_hit_db)
#         tenant_specific_fields_data = {}
#         for definition in definitions:
#             if hasattr(self, definition.name):
#                 tenant_specific_fields_data[definition.name] = getattr(self, definition.name)
#                 delattr(self, definition.name)
#             else:
#                 tenant_specific_fields_data[definition.name] = definition.default_value
# 
#         if not self.pk:
#             if not hasattr(self, 'tenant'):
#                 self.tenant = get_current_tenant()
#             super(TenantSpecificFieldsModelMixin, self).save(*args, **kwargs)
#             self.create_tenant_specific_fields(tenant_specific_fields_data)
#         else:
#             super(TenantSpecificFieldsModelMixin, self).save(*args, **kwargs)
#             self.update_tenant_specific_fields(tenant_specific_fields_data)
# 
#         self.tenant_specific_fields_data = {}
# 
#     @property
#     def fields_definitions(self):
#         return self.get_definitions()
# 
#     class Meta:
#         abstract = True


from django.db import models
from django.conf import settings
from shared_schema_tenants_custom_data.mixins import TenantSpecificFieldsModelMixin


class Lecture(TenantSpecificFieldsModelMixin):
    subject = models.CharField(max_length=100)
    description = models.TextField()

# Path: shared_schema_tenants_custom_data/mixins.py
# class TenantSpecificFieldsModelMixin(models.Model):
#     objects = TenantSpecificFieldsModelManager()
# 
#     def __init__(self, *args, **kwargs):
#         table_id = kwargs.get('table_id', getattr(kwargs.get('table'), 'id', None))
#         definitions = self.get_definitions(table_id=table_id)
#         for definition in definitions:
#             if definition.name in kwargs.keys():
#                 setattr(self, definition.name, kwargs.pop(definition.name))
#         super(TenantSpecificFieldsModelMixin, self).__init__(*args, **kwargs)
# 
#     def get_definitions(self, table_id=-1, force_hit_db=False):
#         from shared_schema_tenants_custom_data.models import TenantSpecificFieldDefinition, TenantSpecificTable
#         if not hasattr(self, 'definitions') or force_hit_db:
#             if type(self).__name__ == 'TenantSpecificTableRow':
#                 self.definitions = TenantSpecificFieldDefinition.objects.filter(
#                     table_content_type=ContentType.objects.get_for_model(TenantSpecificTable),
#                     table_id=table_id)
#             else:
#                 self.definitions = TenantSpecificFieldDefinition.objects.filter(
#                     table_content_type=ContentType.objects.get_for_model(type(self)))
#         return self.definitions
# 
#     def create_tenant_specific_fields(self, tenant_specific_fields_data):
#         definitions = self.get_definitions()
#         definitions_by_name = {d.name: d for d in definitions}
# 
#         with transaction.atomic():
#             for field_name, definition in definitions_by_name.items():
#                 field_value = tenant_specific_fields_data.get(
#                     field_name, getattr(self, field_name, None))
#                 PivotTableClass = _get_pivot_table_class_for_data_type(definition.data_type)
#                 PivotTableClass.objects.create(
#                     definition=definition, row_id=self.id,
#                     row_content_type=ContentType.objects.get_for_model(self.__class__),
#                     value=field_value)
# 
#     def update_tenant_specific_fields(self, tenant_specific_fields_data):
#         old = self.__class__.objects.get(pk=self.pk)
#         definitions = self.get_definitions()
#         definitions_by_name = {d.name: d for d in definitions}
# 
#         with transaction.atomic():
#             for field_name, definition in definitions_by_name.items():
#                 new_value = tenant_specific_fields_data.get(field_name, None)
#                 old_value = getattr(old, field_name, None)
#                 PivotTableClass = _get_pivot_table_class_for_data_type(definition.data_type)
#                 if new_value != old_value:
#                     PivotTableClass.objects.filter(
#                         definition__id=definition.id, row_id=self.id,
#                         row_content_type=ContentType.objects.get_for_model(self.__class__)
#                     ).update(value=new_value)
# 
#     def save(self, *args, **kwargs):
#         table_id = getattr(self, 'table_id', getattr(getattr(self, 'table', object()), 'id', None))
# 
#         force_hit_db = False
#         if hasattr(self, 'definitions') and not self.definitions.exists():
#             force_hit_db = True
# 
#         definitions = self.get_definitions(table_id=table_id, force_hit_db=force_hit_db)
#         tenant_specific_fields_data = {}
#         for definition in definitions:
#             if hasattr(self, definition.name):
#                 tenant_specific_fields_data[definition.name] = getattr(self, definition.name)
#                 delattr(self, definition.name)
#             else:
#                 tenant_specific_fields_data[definition.name] = definition.default_value
# 
#         if not self.pk:
#             if not hasattr(self, 'tenant'):
#                 self.tenant = get_current_tenant()
#             super(TenantSpecificFieldsModelMixin, self).save(*args, **kwargs)
#             self.create_tenant_specific_fields(tenant_specific_fields_data)
#         else:
#             super(TenantSpecificFieldsModelMixin, self).save(*args, **kwargs)
#             self.update_tenant_specific_fields(tenant_specific_fields_data)
# 
#         self.tenant_specific_fields_data = {}
# 
#     @property
#     def fields_definitions(self):
#         return self.get_definitions()
# 
#     class Meta:
#         abstract = True


# Path: exampleproject/lectures/models.py
from django.db import models
from django.conf import settings
from shared_schema_tenants_custom_data.mixins import TenantSpecificFieldsModelMixin



class Lecture(TenantSpecificFieldsModelMixin):
    subject = models.CharField(max_length=100)
    description = models.TextField()

    speaker = models.ForeignKey(settings.AUTH_USER_MODEL)