|
2 | 2 | from django.forms import modelform_factory
|
3 | 3 | from django.utils.translation import override
|
4 | 4 |
|
| 5 | +from testapp.custom_fields import CustomPathTextField |
5 | 6 | from testapp.field_types_models import CustomFieldModel
|
6 | 7 |
|
7 | 8 |
|
@@ -134,3 +135,110 @@ def test_custom_field_valid_options(option):
|
134 | 135 | model.save()
|
135 | 136 | assert model.custom_choices_en == option
|
136 | 137 | assert model.custom_choices_de == option
|
| 138 | + |
| 139 | + |
| 140 | +@pytest.mark.django_db |
| 141 | +def test_custom_path_field_type_preserved(): |
| 142 | + """ |
| 143 | + Test that custom field classes are preserved even when the path is overridden. |
| 144 | +
|
| 145 | + This test passes unexpectedly. It seems TranslatedField actually does preserve |
| 146 | + the field class, which is good! The path from deconstruct() is used only for |
| 147 | + migrations, but the actual field instance in the model is of the correct type. |
| 148 | +
|
| 149 | + This shows that TranslatedField doesn't use the path from deconstruct() when |
| 150 | + creating the field instances, but rather the original class. |
| 151 | + """ |
| 152 | + # Get the field instances |
| 153 | + custom_en = CustomFieldModel._meta.get_field("custom_path_text_en") |
| 154 | + custom_de = CustomFieldModel._meta.get_field("custom_path_text_de") |
| 155 | + |
| 156 | + # Check that the field instances are of the custom field type |
| 157 | + assert isinstance(custom_en, CustomPathTextField) |
| 158 | + assert isinstance(custom_de, CustomPathTextField) |
| 159 | + |
| 160 | + # Get the deconstruct values |
| 161 | + name_en, path_en, args_en, kwargs_en = custom_en.deconstruct() |
| 162 | + name_de, path_de, args_de, kwargs_de = custom_de.deconstruct() |
| 163 | + |
| 164 | + # Confirm that deconstruct returns the base TextField path |
| 165 | + assert path_en == "django.db.models.TextField" |
| 166 | + assert path_de == "django.db.models.TextField" |
| 167 | + |
| 168 | + # Confirm we're using the right class despite the wrong path |
| 169 | + assert type(custom_en) is CustomPathTextField |
| 170 | + assert type(custom_de) is CustomPathTextField |
| 171 | + |
| 172 | + |
| 173 | +@pytest.mark.django_db |
| 174 | +def test_custom_path_field_form_generation(): |
| 175 | + """ |
| 176 | + Test form field generation for custom fields. |
| 177 | +
|
| 178 | + This test shows that while the model field instance is correctly preserved as CustomPathTextField, |
| 179 | + when forms are generated, Django uses the field's formfield() method which returns a standard |
| 180 | + form field type. This is expected behavior and not a bug in TranslatedField. |
| 181 | + """ |
| 182 | + form_class = modelform_factory( |
| 183 | + CustomFieldModel, fields=["custom_path_text_en", "custom_path_text_de"] |
| 184 | + ) |
| 185 | + form = form_class() |
| 186 | + |
| 187 | + # Get the form fields |
| 188 | + field_en = form.fields["custom_path_text_en"] |
| 189 | + field_de = form.fields["custom_path_text_de"] |
| 190 | + |
| 191 | + # Get the model fields for comparison |
| 192 | + model_field_en = CustomFieldModel._meta.get_field("custom_path_text_en") |
| 193 | + model_field_de = CustomFieldModel._meta.get_field("custom_path_text_de") |
| 194 | + |
| 195 | + # Check that the model field is our custom type |
| 196 | + assert isinstance(model_field_en, CustomPathTextField) |
| 197 | + assert isinstance(model_field_de, CustomPathTextField) |
| 198 | + |
| 199 | + # Model field class is correctly preserved |
| 200 | + assert type(model_field_en).__name__ == "CustomPathTextField" |
| 201 | + assert type(model_field_de).__name__ == "CustomPathTextField" |
| 202 | + |
| 203 | + # Form field is based on standard Django form fields - these assertions should pass |
| 204 | + # Django maps TextField to Textarea widget by default |
| 205 | + from django.forms import CharField |
| 206 | + |
| 207 | + assert isinstance(field_en, CharField) |
| 208 | + assert field_en.widget.__class__.__name__ == "Textarea" |
| 209 | + |
| 210 | + # This is Django's standard behavior - model field's formfield() method determines |
| 211 | + # what form field type is used, not TranslatedField's behavior |
| 212 | + assert field_en.__class__.__name__ == "CharField" |
| 213 | + assert field_de.__class__.__name__ == "CharField" |
| 214 | + |
| 215 | + |
| 216 | +@pytest.mark.django_db |
| 217 | +def test_custom_path_field_model_usage(): |
| 218 | + """ |
| 219 | + Test using the custom path text field with a model instance. |
| 220 | +
|
| 221 | + This test verifies that the basic functionality of the model works properly |
| 222 | + with the CustomPathTextField when its path is overridden in deconstruct(). |
| 223 | + """ |
| 224 | + # Create a model instance with values for the custom path text field |
| 225 | + text_en = "English text content" |
| 226 | + text_de = "Deutscher Textinhalt" |
| 227 | + |
| 228 | + model = CustomFieldModel.objects.create( |
| 229 | + custom_choices_en="a", |
| 230 | + custom_choices_de="a", |
| 231 | + custom_path_text_en=text_en, |
| 232 | + custom_path_text_de=text_de, |
| 233 | + ) |
| 234 | + |
| 235 | + # Check that the values are correctly stored |
| 236 | + assert model.custom_path_text_en == text_en |
| 237 | + assert model.custom_path_text_de == text_de |
| 238 | + |
| 239 | + # Check that the translated descriptor works |
| 240 | + with override("en"): |
| 241 | + assert model.custom_path_text == text_en |
| 242 | + |
| 243 | + with override("de"): |
| 244 | + assert model.custom_path_text == text_de |
0 commit comments