Skip to content

Add ORM protocols Compilable and Resolvable #2551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
adamchainz opened this issue Mar 15, 2025 · 2 comments
Open

Add ORM protocols Compilable and Resolvable #2551

adamchainz opened this issue Mar 15, 2025 · 2 comments

Comments

@adamchainz
Copy link
Contributor

Suggested by @charettes on a Django forum discussion regrading adding types to Django:

from __future__ import annotations

from typing import Protocol

from django.db.models import fields
from django.db.models.sql import compiler, query


class Compilable(Protocol):
    """
    Object that can be compiled to a PEP 249 compliant tuple comprised of
    a SQL string and its associated parameters sequence.

    It can optionally have `as_vendor` methods defined to specialize the
    compilation on different backends (e.g. `as_postgres`).
    """

    def get_source_expressions(self) -> list[Compilable | None]: ...

    def as_sql(
        self, compiler: compiler.SQLCompiler, connection
    ) -> tuple[str, tuple]: ...


class Resolvable(Protocol):
    """
    Object that can resolve any field and transform reference it has in
    the context of a query and return an object ready to be compiled for
    execution.
    """

    output_field: fields.Field

    def get_source_expressions(self) -> list[Resolvable | None]: ...

    def resolve_expression(
        self,
        query: query.Query,
        allow_joins: bool = True,
        reuse: set[str] | None = None,
        summarize: bool = False,
        for_save: bool = False,
    ) -> Compilable: ...

I think we could try adding these in django-stubs and seeing how much simpler and more comprehensible they make things.

@sobolevn
Copy link
Member

I think we could try adding these in django-stubs and seeing how much simpler and more comprehensible they make things.

This will require TYPING_CHECKING only imports, because django-stubs does not have runtime.
If you want them to be user accessible, then we can add them to django-stubs-ext

@adamchainz
Copy link
Contributor Author

Making them user-accessible is probably the way forwards, so we can document them and explain how to use them. But it would need some experimentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants