Ejemplo n.º 1
0
def patch_admin() -> None:
    TenantModel = get_tenant_model()

    def get_tenant_field(model: type) -> Optional[Field]:
        for field in model._meta.fields:  # type: ignore
            if getattr(field, 'related_model', None) == TenantModel:
                return field
        return None

    class AutoTenantMixin:
        model: Model

        def get_fields(self,
                       request: HttpRequest,
                       obj: Model = None) -> Sequence[Field]:
            fields = super(AutoTenantMixin,
                           self).get_fields(request, obj=obj)  # type: ignore
            tenant_field = get_tenant_field(self.model)
            if tenant_field and tenant_field.name in fields:
                fields.remove(tenant_field.name)
            return fields

    admin.ModelAdmin.__bases__ = (
        AutoTenantMixin, ) + admin.ModelAdmin.__bases__

    def save_model(self, request: HttpRequest, obj: Model, form: Form,
                   change: bool) -> None:
        if not change:
            tenant_field = get_tenant_field(obj)
            if tenant_field:
                setattr(obj, tenant_field.attname,
                        request.session['active_tenant'])
        obj.save()

    admin.ModelAdmin.save_model = save_model

    if not getattr(LogEntry, 'tenant_id', None):
        # Adding this value is delegated to a postgres trigger - that way it will always
        # be set, without us having to query the database. We still need it as a field,
        # because it's tricky to .annotate() in the place where it's used. Otherwise,
        # we could write a cleaner version that just used default - however we can't do
        # that here because Django will send an explicit NULL, but we would want it not
        # to send it at all.
        LogEntry.add_to_class(
            'tenant_id',
            models.IntegerField(blank=True, null=True),
        )

    get_admin_url = admin.models.LogEntry.get_admin_url

    def get_admin_url_with_tenant(self):
        url = get_admin_url(self)
        if self.tenant_id and url:
            return '{0}?__tenant={1}'.format(url, self.tenant_id)
        return url

    admin.models.LogEntry.get_admin_url = get_admin_url_with_tenant
Ejemplo n.º 2
0
    If we don't patch this, then a ``DatabaseError`` will occur because
    the tables could not be found.
    """
    schema = get_active_schema_name()
    return [
        inline(self.model, self.admin_site) for inline in self.inlines
        if schema or is_shared_model(inline.model)
    ]


admin.ModelAdmin.get_inline_instances = get_inline_instances

if not getattr(LogEntry, 'object_schema', None):
    # We can't use a proper foreign key, as it plays havoc with migrations.
    LogEntry.add_to_class(
        'object_schema_id',
        models.TextField(blank=True, null=True)
    )

    @receiver(models.signals.pre_save, sender=LogEntry)
    def update_object_schema(sender, instance, **kwargs):
        obj = instance.get_edited_object()

        if not is_shared_model(obj):
            instance.object_schema_id = obj._schema

    get_admin_url = LogEntry.get_admin_url

    def get_admin_url_with_schema(self):
        url = get_admin_url(self)

        if self.object_schema_id and url:
Ejemplo n.º 3
0
    If we don't patch this, then a ``DatabaseError`` will occur because
    the tables could not be found.
    """
    schema = get_active_schema_name()
    return [
        inline(self.model, self.admin_site) for inline in self.inlines
        if schema or is_shared_model(inline.model)
    ]


admin.ModelAdmin.get_inline_instances = get_inline_instances

if not getattr(LogEntry, 'object_schema', None):
    # We can't use a proper foreign key, as it plays havoc with migrations.
    LogEntry.add_to_class('object_schema_id',
                          models.TextField(blank=True, null=True))

    @receiver(models.signals.pre_save, sender=LogEntry)
    def update_object_schema(sender, instance, **kwargs):
        obj = instance.get_edited_object()

        if not is_shared_model(obj):
            instance.object_schema_id = obj._schema

    get_admin_url = LogEntry.get_admin_url

    def get_admin_url_with_schema(self):
        url = get_admin_url(self)

        if self.object_schema_id and url:
            return '{0}?__schema={1}'.format(url, self.object_schema_id)