plain.models 0.39.0__tar.gz → 0.39.2__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.
Files changed (131) hide show
  1. {plain_models-0.39.0 → plain_models-0.39.2}/PKG-INFO +29 -1
  2. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/CHANGELOG.md +22 -0
  3. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/README.md +28 -0
  4. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/forms.py +3 -4
  5. {plain_models-0.39.0 → plain_models-0.39.2}/pyproject.toml +1 -1
  6. {plain_models-0.39.0 → plain_models-0.39.2}/.gitignore +0 -0
  7. {plain_models-0.39.0 → plain_models-0.39.2}/LICENSE +0 -0
  8. {plain_models-0.39.0 → plain_models-0.39.2}/README.md +0 -0
  9. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/__init__.py +0 -0
  10. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/aggregates.py +0 -0
  11. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/__init__.py +0 -0
  12. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/base/__init__.py +0 -0
  13. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/base/base.py +0 -0
  14. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/base/client.py +0 -0
  15. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/base/creation.py +0 -0
  16. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/base/features.py +0 -0
  17. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/base/introspection.py +0 -0
  18. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/base/operations.py +0 -0
  19. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/base/schema.py +0 -0
  20. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/base/validation.py +0 -0
  21. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/ddl_references.py +0 -0
  22. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/mysql/__init__.py +0 -0
  23. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/mysql/base.py +0 -0
  24. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/mysql/client.py +0 -0
  25. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/mysql/compiler.py +0 -0
  26. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/mysql/creation.py +0 -0
  27. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/mysql/features.py +0 -0
  28. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/mysql/introspection.py +0 -0
  29. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/mysql/operations.py +0 -0
  30. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/mysql/schema.py +0 -0
  31. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/mysql/validation.py +0 -0
  32. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/postgresql/__init__.py +0 -0
  33. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/postgresql/base.py +0 -0
  34. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/postgresql/client.py +0 -0
  35. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/postgresql/creation.py +0 -0
  36. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/postgresql/features.py +0 -0
  37. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/postgresql/introspection.py +0 -0
  38. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/postgresql/operations.py +0 -0
  39. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/postgresql/schema.py +0 -0
  40. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/sqlite3/__init__.py +0 -0
  41. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/sqlite3/_functions.py +0 -0
  42. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/sqlite3/base.py +0 -0
  43. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/sqlite3/client.py +0 -0
  44. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/sqlite3/creation.py +0 -0
  45. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/sqlite3/features.py +0 -0
  46. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/sqlite3/introspection.py +0 -0
  47. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/sqlite3/operations.py +0 -0
  48. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/sqlite3/schema.py +0 -0
  49. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backends/utils.py +0 -0
  50. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backups/__init__.py +0 -0
  51. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backups/cli.py +0 -0
  52. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backups/clients.py +0 -0
  53. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/backups/core.py +0 -0
  54. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/base.py +0 -0
  55. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/cli.py +0 -0
  56. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/config.py +0 -0
  57. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/connections.py +0 -0
  58. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/constants.py +0 -0
  59. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/constraints.py +0 -0
  60. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/database_url.py +0 -0
  61. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/db.py +0 -0
  62. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/default_settings.py +0 -0
  63. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/deletion.py +0 -0
  64. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/entrypoints.py +0 -0
  65. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/enums.py +0 -0
  66. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/exceptions.py +0 -0
  67. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/expressions.py +0 -0
  68. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/fields/__init__.py +0 -0
  69. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/fields/json.py +0 -0
  70. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/fields/mixins.py +0 -0
  71. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/fields/related.py +0 -0
  72. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/fields/related_descriptors.py +0 -0
  73. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/fields/related_lookups.py +0 -0
  74. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/fields/reverse_related.py +0 -0
  75. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/functions/__init__.py +0 -0
  76. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/functions/comparison.py +0 -0
  77. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/functions/datetime.py +0 -0
  78. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/functions/math.py +0 -0
  79. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/functions/mixins.py +0 -0
  80. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/functions/text.py +0 -0
  81. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/functions/window.py +0 -0
  82. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/indexes.py +0 -0
  83. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/lookups.py +0 -0
  84. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/manager.py +0 -0
  85. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/__init__.py +0 -0
  86. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/autodetector.py +0 -0
  87. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/exceptions.py +0 -0
  88. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/executor.py +0 -0
  89. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/graph.py +0 -0
  90. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/loader.py +0 -0
  91. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/migration.py +0 -0
  92. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/operations/__init__.py +0 -0
  93. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/operations/base.py +0 -0
  94. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/operations/fields.py +0 -0
  95. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/operations/models.py +0 -0
  96. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/operations/special.py +0 -0
  97. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/optimizer.py +0 -0
  98. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/questioner.py +0 -0
  99. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/recorder.py +0 -0
  100. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/serializer.py +0 -0
  101. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/state.py +0 -0
  102. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/utils.py +0 -0
  103. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/migrations/writer.py +0 -0
  104. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/options.py +0 -0
  105. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/otel.py +0 -0
  106. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/preflight.py +0 -0
  107. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/query.py +0 -0
  108. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/query_utils.py +0 -0
  109. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/registry.py +0 -0
  110. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/sql/__init__.py +0 -0
  111. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/sql/compiler.py +0 -0
  112. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/sql/constants.py +0 -0
  113. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/sql/datastructures.py +0 -0
  114. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/sql/query.py +0 -0
  115. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/sql/subqueries.py +0 -0
  116. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/sql/where.py +0 -0
  117. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/test/__init__.py +0 -0
  118. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/test/pytest.py +0 -0
  119. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/test/utils.py +0 -0
  120. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/transaction.py +0 -0
  121. {plain_models-0.39.0 → plain_models-0.39.2}/plain/models/utils.py +0 -0
  122. {plain_models-0.39.0 → plain_models-0.39.2}/tests/app/examples/migrations/0001_initial.py +0 -0
  123. {plain_models-0.39.0 → plain_models-0.39.2}/tests/app/examples/migrations/0002_test_field_removed.py +0 -0
  124. {plain_models-0.39.0 → plain_models-0.39.2}/tests/app/examples/migrations/0003_deleteparent_childsetnull_childsetdefault_and_more.py +0 -0
  125. {plain_models-0.39.0 → plain_models-0.39.2}/tests/app/examples/migrations/__init__.py +0 -0
  126. {plain_models-0.39.0 → plain_models-0.39.2}/tests/app/examples/models.py +0 -0
  127. {plain_models-0.39.0 → plain_models-0.39.2}/tests/app/settings.py +0 -0
  128. {plain_models-0.39.0 → plain_models-0.39.2}/tests/app/urls.py +0 -0
  129. {plain_models-0.39.0 → plain_models-0.39.2}/tests/test_database_url.py +0 -0
  130. {plain_models-0.39.0 → plain_models-0.39.2}/tests/test_delete_behaviors.py +0 -0
  131. {plain_models-0.39.0 → plain_models-0.39.2}/tests/test_models.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain.models
3
- Version: 0.39.0
3
+ Version: 0.39.2
4
4
  Summary: Database models for Plain.
5
5
  Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
6
6
  License-File: LICENSE
@@ -117,3 +117,31 @@ TODO
117
117
  ## Forms
118
118
 
119
119
  TODO
120
+
121
+ ## Sharing fields across models
122
+
123
+ To share common fields across multiple models, use Python classes as mixins. The final, registered model must inherit directly from `models.Model` and the mixins should not.
124
+
125
+ ```python
126
+ from plain import models
127
+
128
+
129
+ # Regular Python class for shared fields
130
+ class TimestampedMixin:
131
+ created_at = models.DateTimeField(auto_now_add=True)
132
+ updated_at = models.DateTimeField(auto_now=True)
133
+
134
+
135
+ # Models inherit from the mixin AND models.Model
136
+ @models.register_model
137
+ class User(TimestampedMixin, models.Model):
138
+ email = models.EmailField()
139
+ password = PasswordField()
140
+ is_admin = models.BooleanField(default=False)
141
+
142
+
143
+ @models.register_model
144
+ class Note(TimestampedMixin, models.Model):
145
+ content = models.TextField(max_length=1024)
146
+ liked = models.BooleanField(default=False)
147
+ ```
@@ -1,5 +1,26 @@
1
1
  # plain-models changelog
2
2
 
3
+ ## [0.39.2](https://github.com/dropseed/plain/releases/plain-models@0.39.2) (2025-07-25)
4
+
5
+ ### What's changed
6
+
7
+ - Fixed remaining `to_field_name` attribute usage in `ModelMultipleChoiceField` validation to use `id` directly ([26c80356d3](https://github.com/dropseed/plain/commit/26c80356d3))
8
+
9
+ ### Upgrade instructions
10
+
11
+ - No changes required
12
+
13
+ ## [0.39.1](https://github.com/dropseed/plain/releases/plain-models@0.39.1) (2025-07-22)
14
+
15
+ ### What's changed
16
+
17
+ - Added documentation for sharing fields across models using Python class mixins ([cad3af01d2](https://github.com/dropseed/plain/commit/cad3af01d2))
18
+ - Added note about `PrimaryKeyField()` replacement requirement for migrations ([70ea931660](https://github.com/dropseed/plain/commit/70ea931660))
19
+
20
+ ### Upgrade instructions
21
+
22
+ - No changes required
23
+
3
24
  ## [0.39.0](https://github.com/dropseed/plain/releases/plain-models@0.39.0) (2025-07-22)
4
25
 
5
26
  ### What's changed
@@ -18,6 +39,7 @@
18
39
  - Remove any `to_field` arguments from ForeignKey definitions - they are no longer supported
19
40
  - Remove any `parent_link=True` arguments from ForeignKey definitions - they are no longer supported
20
41
  - Replace any usage of `InlineForeignKeyField` in forms with standard form fields
42
+ - `models.BigAutoField(auto_created=True, primary_key=True)` need to be replaced with `models.PrimaryKeyField()` in migrations
21
43
 
22
44
  ## [0.38.0](https://github.com/dropseed/plain/releases/plain-models@0.38.0) (2025-07-21)
23
45
 
@@ -106,3 +106,31 @@ TODO
106
106
  ## Forms
107
107
 
108
108
  TODO
109
+
110
+ ## Sharing fields across models
111
+
112
+ To share common fields across multiple models, use Python classes as mixins. The final, registered model must inherit directly from `models.Model` and the mixins should not.
113
+
114
+ ```python
115
+ from plain import models
116
+
117
+
118
+ # Regular Python class for shared fields
119
+ class TimestampedMixin:
120
+ created_at = models.DateTimeField(auto_now_add=True)
121
+ updated_at = models.DateTimeField(auto_now=True)
122
+
123
+
124
+ # Models inherit from the mixin AND models.Model
125
+ @models.register_model
126
+ class User(TimestampedMixin, models.Model):
127
+ email = models.EmailField()
128
+ password = PasswordField()
129
+ is_admin = models.BooleanField(default=False)
130
+
131
+
132
+ @models.register_model
133
+ class Note(TimestampedMixin, models.Model):
134
+ content = models.TextField(max_length=1024)
135
+ liked = models.BooleanField(default=False)
136
+ ```
@@ -573,7 +573,6 @@ class ModelMultipleChoiceField(ModelChoiceField):
573
573
  corresponding objects. Raise a ValidationError if a given value is
574
574
  invalid (not a valid PK, not in the queryset, etc.)
575
575
  """
576
- key = self.to_field_name or "id"
577
576
  # deduplicate given values to avoid creating many querysets or
578
577
  # requiring the database backend deduplicate efficiently.
579
578
  try:
@@ -586,15 +585,15 @@ class ModelMultipleChoiceField(ModelChoiceField):
586
585
  )
587
586
  for id_val in value:
588
587
  try:
589
- self.queryset.filter(**{key: id_val})
588
+ self.queryset.filter(id=id_val)
590
589
  except (ValueError, TypeError):
591
590
  raise ValidationError(
592
591
  self.error_messages["invalid_id_value"],
593
592
  code="invalid_id_value",
594
593
  params={"id": id_val},
595
594
  )
596
- qs = self.queryset.filter(**{f"{key}__in": value})
597
- ids = {str(getattr(o, key)) for o in qs}
595
+ qs = self.queryset.filter(id__in=value)
596
+ ids = {str(o.id) for o in qs}
598
597
  for val in value:
599
598
  if str(val) not in ids:
600
599
  raise ValidationError(
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "plain.models"
3
- version = "0.39.0"
3
+ version = "0.39.2"
4
4
  description = "Database models for Plain."
5
5
  authors = [{name = "Dave Gaeddert", email = "dave.gaeddert@dropseed.dev"}]
6
6
  readme = "README.md"
File without changes
File without changes
File without changes