django-cte 2.0.1.dev20251006193645__tar.gz → 2.0.1.dev20251027172651__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/PKG-INFO +1 -1
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/__init__.py +1 -1
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/cte.py +27 -11
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/LICENSE +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/README.md +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/_deprecated.py +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/jitmixin.py +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/join.py +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/meta.py +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/query.py +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/raw.py +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/pyproject.toml +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from copy import copy
|
|
2
2
|
|
|
3
|
+
import django
|
|
3
4
|
from django.db.models import Manager, sql
|
|
4
5
|
from django.db.models.expressions import Ref
|
|
5
6
|
from django.db.models.query import Q, QuerySet, ValuesIterable
|
|
@@ -45,21 +46,30 @@ class CTE:
|
|
|
45
46
|
"""
|
|
46
47
|
|
|
47
48
|
def __init__(self, queryset, name="cte", materialized=False):
|
|
48
|
-
self.
|
|
49
|
+
self._set_queryset(queryset)
|
|
49
50
|
self.name = name
|
|
50
51
|
self.col = CTEColumns(self)
|
|
51
52
|
self.materialized = materialized
|
|
52
53
|
|
|
53
54
|
def __getstate__(self):
|
|
54
|
-
return (self.query, self.name, self.materialized)
|
|
55
|
+
return (self.query, self.name, self.materialized, self._iterable_class)
|
|
55
56
|
|
|
56
57
|
def __setstate__(self, state):
|
|
57
|
-
|
|
58
|
+
if len(state) == 3:
|
|
59
|
+
# Keep compatibility with the previous serialization method
|
|
60
|
+
self.query, self.name, self.materialized = state
|
|
61
|
+
self._iterable_class = ValuesIterable
|
|
62
|
+
else:
|
|
63
|
+
self.query, self.name, self.materialized, self._iterable_class = state
|
|
58
64
|
self.col = CTEColumns(self)
|
|
59
65
|
|
|
60
66
|
def __repr__(self):
|
|
61
67
|
return f"<{type(self).__name__} {self.name}>"
|
|
62
68
|
|
|
69
|
+
def _set_queryset(self, queryset):
|
|
70
|
+
self.query = None if queryset is None else queryset.query
|
|
71
|
+
self._iterable_class = getattr(queryset, "_iterable_class", ValuesIterable)
|
|
72
|
+
|
|
63
73
|
@classmethod
|
|
64
74
|
def recursive(cls, make_cte_queryset, name="cte", materialized=False):
|
|
65
75
|
"""Recursive Common Table Expression
|
|
@@ -73,7 +83,7 @@ class CTE:
|
|
|
73
83
|
:returns: The fully constructed recursive cte object.
|
|
74
84
|
"""
|
|
75
85
|
cte = cls(None, name, materialized)
|
|
76
|
-
cte.
|
|
86
|
+
cte._set_queryset(make_cte_queryset(cte))
|
|
77
87
|
return cte
|
|
78
88
|
|
|
79
89
|
def join(self, model_or_queryset, *filter_q, **filter_kw):
|
|
@@ -124,24 +134,30 @@ class CTE:
|
|
|
124
134
|
"""
|
|
125
135
|
cte_query = self.query
|
|
126
136
|
qs = cte_query.model._default_manager.get_queryset()
|
|
137
|
+
qs._iterable_class = self._iterable_class
|
|
138
|
+
qs._fields = () # Allow any field names to be used in further annotations
|
|
127
139
|
|
|
128
140
|
query = jit_mixin(sql.Query(cte_query.model), CTEQuery)
|
|
129
141
|
query.join(BaseTable(self.name, None))
|
|
130
142
|
query.default_cols = cte_query.default_cols
|
|
131
143
|
query.deferred_loading = cte_query.deferred_loading
|
|
132
|
-
|
|
144
|
+
|
|
145
|
+
if django.VERSION < (5, 2) and cte_query.values_select:
|
|
133
146
|
query.set_values(cte_query.values_select)
|
|
134
|
-
|
|
147
|
+
|
|
135
148
|
if cte_query.annotations:
|
|
136
149
|
for alias, value in cte_query.annotations.items():
|
|
137
150
|
col = CTEColumnRef(alias, self.name, value.output_field)
|
|
138
151
|
query.add_annotation(col, alias)
|
|
139
152
|
query.annotation_select_mask = cte_query.annotation_select_mask
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
153
|
+
|
|
154
|
+
if selected := getattr(cte_query, "selected", None):
|
|
155
|
+
for alias in selected:
|
|
156
|
+
if alias not in cte_query.annotations:
|
|
157
|
+
output_field = cte_query.resolve_ref(alias).output_field
|
|
158
|
+
col = CTEColumnRef(alias, self.name, output_field)
|
|
159
|
+
query.add_annotation(col, alias)
|
|
160
|
+
query.selected = {alias: alias for alias in selected}
|
|
145
161
|
|
|
146
162
|
qs.query = query
|
|
147
163
|
return qs
|
|
File without changes
|
|
File without changes
|
{django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/_deprecated.py
RENAMED
|
File without changes
|
{django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/jitmixin.py
RENAMED
|
File without changes
|
{django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/join.py
RENAMED
|
File without changes
|
{django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/meta.py
RENAMED
|
File without changes
|
{django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251027172651}/django_cte/query.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|