django-cte 2.0.1.dev20251006193645__tar.gz → 2.0.1.dev20251120124810__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.dev20251120124810}/PKG-INFO +1 -1
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/__init__.py +1 -1
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/cte.py +33 -12
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/LICENSE +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/README.md +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/_deprecated.py +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/jitmixin.py +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/join.py +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/meta.py +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/query.py +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/raw.py +0 -0
- {django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/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):
|
|
@@ -105,7 +115,12 @@ class CTE:
|
|
|
105
115
|
q_object = Q(*filter_q, **filter_kw)
|
|
106
116
|
map = query.alias_map
|
|
107
117
|
existing_inner = set(a for a in map if map[a].join_type == INNER)
|
|
108
|
-
|
|
118
|
+
if django.VERSION >= (5, 2):
|
|
119
|
+
on_clause, _ = query._add_q(
|
|
120
|
+
q_object, query.used_aliases, update_join_types=(join_type == INNER)
|
|
121
|
+
)
|
|
122
|
+
else:
|
|
123
|
+
on_clause, _ = query._add_q(q_object, query.used_aliases)
|
|
109
124
|
query.demote_joins(existing_inner)
|
|
110
125
|
|
|
111
126
|
parent = query.get_initial_alias()
|
|
@@ -124,24 +139,30 @@ class CTE:
|
|
|
124
139
|
"""
|
|
125
140
|
cte_query = self.query
|
|
126
141
|
qs = cte_query.model._default_manager.get_queryset()
|
|
142
|
+
qs._iterable_class = self._iterable_class
|
|
143
|
+
qs._fields = () # Allow any field names to be used in further annotations
|
|
127
144
|
|
|
128
145
|
query = jit_mixin(sql.Query(cte_query.model), CTEQuery)
|
|
129
146
|
query.join(BaseTable(self.name, None))
|
|
130
147
|
query.default_cols = cte_query.default_cols
|
|
131
148
|
query.deferred_loading = cte_query.deferred_loading
|
|
132
|
-
|
|
149
|
+
|
|
150
|
+
if django.VERSION < (5, 2) and cte_query.values_select:
|
|
133
151
|
query.set_values(cte_query.values_select)
|
|
134
|
-
|
|
152
|
+
|
|
135
153
|
if cte_query.annotations:
|
|
136
154
|
for alias, value in cte_query.annotations.items():
|
|
137
155
|
col = CTEColumnRef(alias, self.name, value.output_field)
|
|
138
156
|
query.add_annotation(col, alias)
|
|
139
157
|
query.annotation_select_mask = cte_query.annotation_select_mask
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
158
|
+
|
|
159
|
+
if selected := getattr(cte_query, "selected", None):
|
|
160
|
+
for alias in selected:
|
|
161
|
+
if alias not in cte_query.annotations:
|
|
162
|
+
output_field = cte_query.resolve_ref(alias).output_field
|
|
163
|
+
col = CTEColumnRef(alias, self.name, output_field)
|
|
164
|
+
query.add_annotation(col, alias)
|
|
165
|
+
query.selected = {alias: alias for alias in selected}
|
|
145
166
|
|
|
146
167
|
qs.query = query
|
|
147
168
|
return qs
|
|
File without changes
|
|
File without changes
|
{django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/_deprecated.py
RENAMED
|
File without changes
|
{django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/jitmixin.py
RENAMED
|
File without changes
|
{django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/join.py
RENAMED
|
File without changes
|
{django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/meta.py
RENAMED
|
File without changes
|
{django_cte-2.0.1.dev20251006193645 → django_cte-2.0.1.dev20251120124810}/django_cte/query.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|