Manipulate queryset object before it is compiled

I was wondering if anyone knows any way to manipulate queryset before it is compiled? Similar to that of sqlalchemy [1].

My goal is to get information from a tenant connected to the system, but overwriting the get_queryset method in Manager class is not enough.

My solution so far is creating a customizable lookup.

@Field.register_lookup
class CurrentTenant(models.Lookup):
    lookup_name = "ct"

    def as_sql(self, compiler, connection):
        lhs, lhs_params = self.process_lhs(compiler, connection)
        tenant = get_current_tenant()
        params = lhs_params

        return "%s = '%s'" % (lhs, tenant.id), params


class TenantManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(tenant__id__ct=FAKE_FILTER)

[1] - ORM Events — SQLAlchemy 1.4 Documentation

Django’s orm is significantly different from SQL Alchemy.

If you could be more specific - provide more details about what you’re trying to accomplish as the end result - we might be able to offer a more Django-centric solution.

I made this app for my system. Basically customer data is obtained through a “global filter”, this prevents me from writing filter.(tenant=tenant) in all my queries.

Why don’t I override the get_queryset method?
In many places the queries are not lazy, forms, CBV, etc.
I think that manipulating queryset before sql is compiled is a solution.

This is an example with another ORM.

That’s where a custom manager can come into play. See https://docs.djangoproject.com/en/3.1/topics/db/managers. You can define any operation on the manager that will apply to all uses of that manager.

Using a customized manager is a solution, but I don’t know how to adapt it to my problem.
Using Django ModelForm, the related fields get_queryset will be called at server start (runserver). My custom manager needs to work after middleware is called.

No, that’s not an accurate statement. The instance of your ModelForm is created when the form is created within the view. The get_queryset is called at that time.

The instance is created inside the view, but the related fields are created when declaring the Meta class and thus calling the manager’s get_queryset

At a minimum, you’re confusing two different objects.

A Model ForeignKey field is different from a Form ForeignKey field - yes, it’s easy to get the two confused, but they are different objects. Your first reference is to the Form, the second is to the Model. They are instantiated at two different times for two different purposes.

I was able to manipulate the sql before compilation using a custom expression.