plain.models 0.40.1__tar.gz → 0.41.1__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.
- {plain_models-0.40.1 → plain_models-0.41.1}/PKG-INFO +2 -2
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/CHANGELOG.md +24 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/operations/models.py +0 -1
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/options.py +0 -2
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/otel.py +62 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/query.py +2 -57
- {plain_models-0.40.1 → plain_models-0.41.1}/pyproject.toml +2 -2
- {plain_models-0.40.1 → plain_models-0.41.1}/.gitignore +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/LICENSE +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/README.md +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/AGENTS.md +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/README.md +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/aggregates.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/base/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/base/base.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/base/client.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/base/creation.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/base/features.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/base/introspection.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/base/operations.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/base/schema.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/base/validation.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/ddl_references.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/mysql/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/mysql/base.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/mysql/client.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/mysql/compiler.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/mysql/creation.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/mysql/features.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/mysql/introspection.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/mysql/operations.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/mysql/schema.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/mysql/validation.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/postgresql/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/postgresql/base.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/postgresql/client.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/postgresql/creation.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/postgresql/features.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/postgresql/introspection.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/postgresql/operations.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/postgresql/schema.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/sqlite3/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/sqlite3/_functions.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/sqlite3/base.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/sqlite3/client.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/sqlite3/creation.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/sqlite3/features.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/sqlite3/introspection.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/sqlite3/operations.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/sqlite3/schema.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/utils.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backups/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backups/cli.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backups/clients.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backups/core.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/base.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/cli.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/config.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/connections.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/constants.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/constraints.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/database_url.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/db.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/default_settings.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/deletion.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/entrypoints.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/enums.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/exceptions.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/expressions.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/fields/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/fields/json.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/fields/mixins.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/fields/related.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/fields/related_descriptors.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/fields/related_lookups.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/fields/reverse_related.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/forms.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/functions/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/functions/comparison.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/functions/datetime.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/functions/math.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/functions/mixins.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/functions/text.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/functions/window.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/indexes.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/lookups.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/manager.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/autodetector.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/exceptions.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/executor.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/graph.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/loader.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/migration.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/operations/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/operations/base.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/operations/fields.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/operations/special.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/optimizer.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/questioner.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/recorder.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/serializer.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/state.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/utils.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/migrations/writer.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/preflight.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/query_utils.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/registry.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/sql/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/sql/compiler.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/sql/constants.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/sql/datastructures.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/sql/query.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/sql/subqueries.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/sql/where.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/test/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/test/pytest.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/test/utils.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/transaction.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/plain/models/utils.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/tests/app/examples/migrations/0001_initial.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/tests/app/examples/migrations/0002_test_field_removed.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/tests/app/examples/migrations/0003_deleteparent_childsetnull_childsetdefault_and_more.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/tests/app/examples/migrations/__init__.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/tests/app/examples/models.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/tests/app/settings.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/tests/app/urls.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/tests/test_database_url.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/tests/test_delete_behaviors.py +0 -0
- {plain_models-0.40.1 → plain_models-0.41.1}/tests/test_models.py +0 -0
@@ -1,10 +1,10 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: plain.models
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.41.1
|
4
4
|
Summary: Model your data and store it in a database.
|
5
5
|
Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
|
6
6
|
License-File: LICENSE
|
7
|
-
Requires-Python: >=3.
|
7
|
+
Requires-Python: >=3.13
|
8
8
|
Requires-Dist: plain<1.0.0
|
9
9
|
Requires-Dist: sqlparse>=0.3.1
|
10
10
|
Description-Content-Type: text/markdown
|
@@ -1,5 +1,29 @@
|
|
1
1
|
# plain-models changelog
|
2
2
|
|
3
|
+
## [0.41.1](https://github.com/dropseed/plain/releases/plain-models@0.41.1) (2025-09-09)
|
4
|
+
|
5
|
+
### What's changed
|
6
|
+
|
7
|
+
- Improved stack trace filtering in OpenTelemetry spans to exclude internal plain/models frames, making debugging traces cleaner and more focused on user code ([5771dd5](https://github.com/dropseed/plain/commit/5771dd5))
|
8
|
+
|
9
|
+
### Upgrade instructions
|
10
|
+
|
11
|
+
- No changes required
|
12
|
+
|
13
|
+
## [0.41.0](https://github.com/dropseed/plain/releases/plain-models@0.41.0) (2025-09-09)
|
14
|
+
|
15
|
+
### What's changed
|
16
|
+
|
17
|
+
- Python 3.13 is now the minimum required version ([d86e307](https://github.com/dropseed/plain/commit/d86e307))
|
18
|
+
- Removed the `earliest()`, `latest()`, and `get_latest_by` model meta option - use `order_by().first()` and `order_by().last()` instead ([b6093a8](https://github.com/dropseed/plain/commit/b6093a8))
|
19
|
+
- Removed automatic ordering in `first()` and `last()` queryset methods - they now respect the existing queryset ordering without adding default ordering ([adc19a6](https://github.com/dropseed/plain/commit/adc19a6))
|
20
|
+
- Added code location attributes to database operation tracing, showing the source file, line number, and function where the query originated ([da36a17](https://github.com/dropseed/plain/commit/da36a17))
|
21
|
+
|
22
|
+
### Upgrade instructions
|
23
|
+
|
24
|
+
- Replace usage of `earliest()`, `latest()`, and model `Meta` `get_latest_by` queryset methods with equivalent `order_by().first()` or `order_by().last()` calls
|
25
|
+
- The `first()` and `last()` methods no longer automatically add ordering by `id` - explicitly add `.order_by()` to your querysets or `ordering` to your models `Meta` class if needed
|
26
|
+
|
3
27
|
## [0.40.1](https://github.com/dropseed/plain/releases/plain-models@0.40.1) (2025-09-03)
|
4
28
|
|
5
29
|
### What's changed
|
@@ -25,7 +25,6 @@ DEFAULT_NAMES = (
|
|
25
25
|
"db_table",
|
26
26
|
"db_table_comment",
|
27
27
|
"ordering",
|
28
|
-
"get_latest_by",
|
29
28
|
"package_label",
|
30
29
|
"models_registry",
|
31
30
|
"default_related_name",
|
@@ -74,7 +73,6 @@ class Options:
|
|
74
73
|
self.constraints = []
|
75
74
|
self.object_name = None
|
76
75
|
self.package_label = package_label
|
77
|
-
self.get_latest_by = None
|
78
76
|
self.required_db_features = []
|
79
77
|
self.required_db_vendor = None
|
80
78
|
self.meta = meta
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import re
|
2
|
+
import traceback
|
2
3
|
from contextlib import contextmanager
|
3
4
|
from typing import Any
|
4
5
|
|
@@ -8,6 +9,13 @@ from opentelemetry.semconv._incubating.attributes.db_attributes import (
|
|
8
9
|
DB_QUERY_PARAMETER_TEMPLATE,
|
9
10
|
DB_USER,
|
10
11
|
)
|
12
|
+
from opentelemetry.semconv.attributes.code_attributes import (
|
13
|
+
CODE_COLUMN_NUMBER,
|
14
|
+
CODE_FILE_PATH,
|
15
|
+
CODE_FUNCTION_NAME,
|
16
|
+
CODE_LINE_NUMBER,
|
17
|
+
CODE_STACKTRACE,
|
18
|
+
)
|
11
19
|
from opentelemetry.semconv.attributes.db_attributes import (
|
12
20
|
DB_COLLECTION_NAME,
|
13
21
|
DB_NAMESPACE,
|
@@ -126,6 +134,8 @@ def db_span(db, sql: Any, *, many: bool = False, params=None):
|
|
126
134
|
DB_OPERATION_NAME: operation,
|
127
135
|
}
|
128
136
|
|
137
|
+
attrs.update(_get_code_attributes())
|
138
|
+
|
129
139
|
# Add collection name if detected
|
130
140
|
if collection_name:
|
131
141
|
attrs[DB_COLLECTION_NAME] = collection_name
|
@@ -173,3 +183,55 @@ def suppress_db_tracing():
|
|
173
183
|
yield
|
174
184
|
finally:
|
175
185
|
otel_context.detach(token)
|
186
|
+
|
187
|
+
|
188
|
+
def _get_code_attributes():
|
189
|
+
"""Extract code context attributes for the current database query.
|
190
|
+
|
191
|
+
Returns a dict of OpenTelemetry code attributes.
|
192
|
+
"""
|
193
|
+
stack = traceback.extract_stack()
|
194
|
+
|
195
|
+
# Find the user code frame
|
196
|
+
for frame in reversed(stack):
|
197
|
+
filepath = frame.filename
|
198
|
+
if not filepath:
|
199
|
+
continue
|
200
|
+
|
201
|
+
if "/plain/models/" in filepath:
|
202
|
+
continue
|
203
|
+
|
204
|
+
if filepath.endswith("contextlib.py"):
|
205
|
+
continue
|
206
|
+
|
207
|
+
# Found user code - build attributes dict
|
208
|
+
attrs = {}
|
209
|
+
|
210
|
+
if filepath:
|
211
|
+
attrs[CODE_FILE_PATH] = filepath
|
212
|
+
if frame.lineno:
|
213
|
+
attrs[CODE_LINE_NUMBER] = frame.lineno
|
214
|
+
if frame.name:
|
215
|
+
attrs[CODE_FUNCTION_NAME] = frame.name
|
216
|
+
if frame.colno:
|
217
|
+
attrs[CODE_COLUMN_NUMBER] = frame.colno
|
218
|
+
|
219
|
+
# Add full stack trace only in DEBUG mode (expensive)
|
220
|
+
if settings.DEBUG:
|
221
|
+
# Filter out internal frames from the stack trace
|
222
|
+
filtered_stack = []
|
223
|
+
for frame in stack:
|
224
|
+
filepath = frame.filename
|
225
|
+
if not filepath:
|
226
|
+
continue
|
227
|
+
if "/plain/models/" in filepath:
|
228
|
+
continue
|
229
|
+
if filepath.endswith("contextlib.py"):
|
230
|
+
continue
|
231
|
+
filtered_stack.append(frame)
|
232
|
+
|
233
|
+
attrs[CODE_STACKTRACE] = "".join(traceback.format_list(filtered_stack))
|
234
|
+
|
235
|
+
return attrs
|
236
|
+
|
237
|
+
return {}
|
@@ -873,59 +873,14 @@ class QuerySet:
|
|
873
873
|
)
|
874
874
|
return params
|
875
875
|
|
876
|
-
def _earliest(self, *fields):
|
877
|
-
"""
|
878
|
-
Return the earliest object according to fields (if given) or by the
|
879
|
-
model's Meta.get_latest_by.
|
880
|
-
"""
|
881
|
-
if fields:
|
882
|
-
order_by = fields
|
883
|
-
else:
|
884
|
-
order_by = getattr(self.model._meta, "get_latest_by")
|
885
|
-
if order_by and not isinstance(order_by, tuple | list):
|
886
|
-
order_by = (order_by,)
|
887
|
-
if order_by is None:
|
888
|
-
raise ValueError(
|
889
|
-
"earliest() and latest() require either fields as positional "
|
890
|
-
"arguments or 'get_latest_by' in the model's Meta."
|
891
|
-
)
|
892
|
-
obj = self._chain()
|
893
|
-
obj.query.set_limits(high=1)
|
894
|
-
obj.query.clear_ordering(force=True)
|
895
|
-
obj.query.add_ordering(*order_by)
|
896
|
-
return obj.get()
|
897
|
-
|
898
|
-
def earliest(self, *fields):
|
899
|
-
if self.query.is_sliced:
|
900
|
-
raise TypeError("Cannot change a query once a slice has been taken.")
|
901
|
-
return self._earliest(*fields)
|
902
|
-
|
903
|
-
def latest(self, *fields):
|
904
|
-
"""
|
905
|
-
Return the latest object according to fields (if given) or by the
|
906
|
-
model's Meta.get_latest_by.
|
907
|
-
"""
|
908
|
-
if self.query.is_sliced:
|
909
|
-
raise TypeError("Cannot change a query once a slice has been taken.")
|
910
|
-
return self.reverse()._earliest(*fields)
|
911
|
-
|
912
876
|
def first(self):
|
913
877
|
"""Return the first object of a query or None if no match is found."""
|
914
|
-
|
915
|
-
queryset = self
|
916
|
-
else:
|
917
|
-
self._check_ordering_first_last_queryset_aggregation(method="first")
|
918
|
-
queryset = self.order_by("id")
|
919
|
-
for obj in queryset[:1]:
|
878
|
+
for obj in self[:1]:
|
920
879
|
return obj
|
921
880
|
|
922
881
|
def last(self):
|
923
882
|
"""Return the last object of a query or None if no match is found."""
|
924
|
-
|
925
|
-
queryset = self.reverse()
|
926
|
-
else:
|
927
|
-
self._check_ordering_first_last_queryset_aggregation(method="last")
|
928
|
-
queryset = self.order_by("-id")
|
883
|
+
queryset = self.reverse()
|
929
884
|
for obj in queryset[:1]:
|
930
885
|
return obj
|
931
886
|
|
@@ -1763,16 +1718,6 @@ class QuerySet:
|
|
1763
1718
|
if self.query.combinator or other.query.combinator:
|
1764
1719
|
raise TypeError(f"Cannot use {operator_} operator with combined queryset.")
|
1765
1720
|
|
1766
|
-
def _check_ordering_first_last_queryset_aggregation(self, method):
|
1767
|
-
if isinstance(self.query.group_by, tuple) and not any(
|
1768
|
-
col.output_field is self.model._meta.get_field("id")
|
1769
|
-
for col in self.query.group_by
|
1770
|
-
):
|
1771
|
-
raise TypeError(
|
1772
|
-
f"Cannot use QuerySet.{method}() on an unordered queryset performing "
|
1773
|
-
f"aggregation. Add an ordering with order_by()."
|
1774
|
-
)
|
1775
|
-
|
1776
1721
|
|
1777
1722
|
class InstanceCheckMeta(type):
|
1778
1723
|
def __instancecheck__(self, instance):
|
@@ -1,10 +1,10 @@
|
|
1
1
|
[project]
|
2
2
|
name = "plain.models"
|
3
|
-
version = "0.
|
3
|
+
version = "0.41.1"
|
4
4
|
description = "Model your data and store it in a database."
|
5
5
|
authors = [{name = "Dave Gaeddert", email = "dave.gaeddert@dropseed.dev"}]
|
6
6
|
readme = "README.md"
|
7
|
-
requires-python = ">=3.
|
7
|
+
requires-python = ">=3.13"
|
8
8
|
dependencies = [
|
9
9
|
"plain<1.0.0",
|
10
10
|
"sqlparse>=0.3.1",
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{plain_models-0.40.1 → plain_models-0.41.1}/plain/models/backends/postgresql/introspection.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{plain_models-0.40.1 → plain_models-0.41.1}/tests/app/examples/migrations/0002_test_field_removed.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|