@@ -63,19 +63,17 @@ Key Concepts
63
63
- **Configuration Model **: A `Pydantic <https://docs.pydantic.dev/ >`_ model defining the structure and validation rules for your configuration.
64
64
- **Configuration Step **: A class that implements the actual configuration logic using the validated configuration model.
65
65
66
- Getting Started
67
- ---------------
68
66
69
67
Define a Configuration Model
70
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
68
+ ----------------------------
71
69
72
70
.. code-block :: python
73
71
74
72
from pydantic import Field
75
73
from django_setup_configuration import ConfigurationModel, DjangoModelRef
76
74
77
75
class UserConfigurationModel (ConfigurationModel ):
78
- # Use Pydantic's validation features
76
+ # A regular Pydantic field
79
77
add_to_groups: list[str ] = Field(
80
78
default_factory = list ,
81
79
description = " Groups to add the user to"
@@ -95,8 +93,58 @@ Define a Configuration Model
95
93
User: [" password" ]
96
94
}
97
95
96
+
97
+ Field Defaults
98
+ ^^^^^^^^^^^^^^
99
+
100
+ For regular Pydantic fields, you must explicitly configure defaults using `Field
101
+ (default=...) ` or `Field(default_factory=lambda: ...) ` as specified in the `Pydantic
102
+ documentation <https://docs.pydantic.dev/2.10/concepts/fields/#default-values> `_.
103
+
104
+ **NOTE: ** Marking a field as ``Optional `` or using ``... | None `` does *not * automatically
105
+ set the field's default to `None `. You must set this explicitly if you want the field to
106
+ be optional:
107
+
108
+ .. code-block :: python
109
+
110
+ from pydantic import Field
111
+
112
+ class ConfigModel (ConfigurationModel ):
113
+ optional_field: int | None = DjangoModelRef(SomeModel, " some_field" , default = None )
114
+
115
+ For ``DjangoModelRef ``, the default value handling follows these rules:
116
+
117
+ You can provide explicit defaults using the ``default `` or ``default_factory `` kwargs,
118
+ similar to regular Pydantic fields:
119
+
120
+ .. code-block :: python
121
+
122
+ class ConfigModel (ConfigurationModel ):
123
+ # Explicit string default
124
+ field_with_explicit_default = DjangoModelRef(SomeModel, " some_field" , default = " foobar" )
125
+
126
+ # Explicit default factory for a list
127
+ field_with_explicit_default_factory: list[str ] = DjangoModelRef(
128
+ SomeModel, " some_other_field" , default_factory = list
129
+ )
130
+
131
+ When no explicit default is provided, the default is derived from the referenced Django field:
132
+
133
+ 1. If the Django field has an explicit default, that default will be used.
134
+
135
+ 2. If no explicit default is set but the field has ``null=True `` set:
136
+
137
+ a. The default will be set to ``None ``
138
+ b. The field will be optional
139
+
140
+ 3. If no explicit default is provided and the field is not nullable, but has ``blank=True `` **and ** it is a string-type field:
141
+
142
+ a. The default will be an empty string
143
+ b. The field will be optional
144
+
145
+
98
146
Create a Configuration Step
99
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^
147
+ ---------------------------
100
148
101
149
.. code-block :: python
102
150
@@ -130,8 +178,8 @@ Create a Configuration Step
130
178
group = Group.objects.get(name = group_name)
131
179
group.user_set.add(user)
132
180
133
- Configuration File
134
- ^^^^^^^^^^^^^^^^^^
181
+ Configuration Source
182
+ --------------------
135
183
136
184
Create a YAML configuration file with your settings:
137
185
@@ -155,7 +203,7 @@ keys are exclusively used for the steps' ``enable_setting`` key, and the ``names
155
203
key which encapsulates the configuration model's attributes.
156
204
157
205
Step Registration
158
- ^^^^^^^^^^^^^^^^^
206
+ -----------------
159
207
160
208
Register your configuration steps in Django settings:
161
209
@@ -258,7 +306,7 @@ Using Test Helpers
258
306
# Add assertions
259
307
260
308
Best Practices
261
- --------------
309
+ ==============
262
310
263
311
- **Idempotency **: Design steps that can be run multiple times without unintended side effects.
264
312
- **Validation **: You can use the full range of Pydantic's validation capabilities.
0 commit comments