|
88 | 88 | from iommi.from_model import ( |
89 | 89 | member_from_model, |
90 | 90 | ) |
| 91 | +from iommi.member import reify_conf |
91 | 92 | from iommi.page import ( |
92 | 93 | Page, |
93 | 94 | ) |
@@ -1061,12 +1062,12 @@ def test_choice_not_required(): |
1061 | 1062 | class MyForm(Form): |
1062 | 1063 | foo = Field.choice(required=False, choices=['bar']) |
1063 | 1064 |
|
1064 | | - assert do_post(MyForm()).fields.foo.value is None |
1065 | | - assert do_post(MyForm(), foo='bar').fields.foo.value == 'bar' |
1066 | | - form = do_post(MyForm(), do_post_key_validation=False, baz='bar') |
| 1065 | + assert do_post(MyForm.create()).fields.foo.value is None |
| 1066 | + assert do_post(MyForm.create(), foo='bar').fields.foo.value == 'bar' |
| 1067 | + form = do_post(MyForm.create(), do_post_key_validation=False, baz='bar') |
1067 | 1068 | assert form.fields.foo.value is None |
1068 | 1069 |
|
1069 | | - form = do_post(MyForm(), foo='baz') |
| 1070 | + form = do_post(MyForm.create(), foo='baz') |
1070 | 1071 | assert form.fields.foo.value is None |
1071 | 1072 | assert form.get_errors() == {'fields': {'foo': {'baz not in available choices'}}} |
1072 | 1073 |
|
@@ -1400,6 +1401,10 @@ class FooModel(Model): |
1400 | 1401 | assert not Field.from_model(FooModel, 'c').refine_done().required |
1401 | 1402 | assert Field.from_model(FooModel, 'd').refine_done().required |
1402 | 1403 |
|
| 1404 | + # Conf overrides default |
| 1405 | + assert Field.from_model(FooModel, 'a', required=True).refine_done().required |
| 1406 | + assert not Field.from_model(FooModel, 'd', required=False).refine_done().required |
| 1407 | + |
1403 | 1408 |
|
1404 | 1409 | @pytest.mark.django |
1405 | 1410 | @pytest.mark.filterwarnings("ignore:Model 'tests.foomodel' was already registered") |
@@ -1549,13 +1554,15 @@ def test_overriding_parse_empty_string_as_none_in_shortcut(): |
1549 | 1554 | parse_empty_string_as_none='foo', |
1550 | 1555 | ) |
1551 | 1556 | # test overriding parse_empty_string_as_none |
1552 | | - x = member_from_model( |
1553 | | - cls=Field, |
1554 | | - model=Foo, |
1555 | | - model_field=CharField(blank=True), |
1556 | | - factory_lookup={CharField: s}, |
1557 | | - factory_lookup_register_function=register_field_factory, |
1558 | | - defaults_factory=field_defaults_factory, |
| 1557 | + x = reify_conf( |
| 1558 | + member_from_model( |
| 1559 | + cls=Field, |
| 1560 | + model=Foo, |
| 1561 | + model_field=CharField(blank=True), |
| 1562 | + factory_lookup={CharField: s}, |
| 1563 | + factory_lookup_register_function=register_field_factory, |
| 1564 | + defaults_factory=field_defaults_factory, |
| 1565 | + ) |
1559 | 1566 | ).refine_done() |
1560 | 1567 |
|
1561 | 1568 | assert 'foo' == x.parse_empty_string_as_none |
@@ -1643,9 +1650,23 @@ def test_field_from_model_many_to_one_foreign_key(): |
1643 | 1650 | def test_register_field_factory(): |
1644 | 1651 | from tests.models import FooField, RegisterFieldFactoryTest |
1645 | 1652 |
|
| 1653 | + f = Field() |
| 1654 | + |
| 1655 | + register_field_factory(FooField, factory=lambda **kwargs: f) |
| 1656 | + |
| 1657 | + assert Field.from_model(RegisterFieldFactoryTest, 'foo') is f |
| 1658 | + |
| 1659 | + |
| 1660 | +@pytest.mark.django |
| 1661 | +def test_register_field_factory_disallow_non_dict_non_field(): |
| 1662 | + from tests.models import FooField, RegisterFieldFactoryTest |
| 1663 | + |
1646 | 1664 | register_field_factory(FooField, factory=lambda **kwargs: 7) |
1647 | 1665 |
|
1648 | | - assert Field.from_model(RegisterFieldFactoryTest, 'foo') == 7 |
| 1666 | + with pytest.raises(AssertionError) as e: |
| 1667 | + assert Field.from_model(RegisterFieldFactoryTest, 'foo') |
| 1668 | + |
| 1669 | + assert str(e.value) == 'Factories must return a configuration dict or an instance of Field. Got int: "7"' |
1649 | 1670 |
|
1650 | 1671 |
|
1651 | 1672 | def shortcut_test(shortcut, raw_and_parsed_data_tuples, normalizing=None, is_list=False): |
@@ -2670,7 +2691,7 @@ class Meta: |
2670 | 2691 | def test_shortcut_to_subclass(): |
2671 | 2692 | class MyField(Field): |
2672 | 2693 | @classmethod |
2673 | | - @with_defaults() |
| 2694 | + @with_defaults |
2674 | 2695 | def my_shortcut(cls, **kwargs): |
2675 | 2696 | return cls(**kwargs) # pragma: no cover: we aren't testing that this shortcut is implemented correctly |
2676 | 2697 |
|
@@ -3526,12 +3547,14 @@ def test_initial_is_set_to_default_of_model(): |
3526 | 3547 |
|
3527 | 3548 |
|
3528 | 3549 | def test_shoot_config_into_auto_dunder_field(): |
3529 | | - Form( |
| 3550 | + other_display_name = 'something else' |
| 3551 | + form = Form( |
3530 | 3552 | auto__model=FieldFromModelOneToOneTest, |
3531 | 3553 | # attr `foo_one_to_one__foo` creates a field named `foo_one_to_one_foo`. Note that the `__` is collapsed to one `_`! |
3532 | 3554 | auto__include=['foo_one_to_one__foo'], |
3533 | | - fields__foo_one_to_one_foo__display_name='bar', |
| 3555 | + fields__foo_one_to_one_foo__display_name=other_display_name, |
3534 | 3556 | ).bind(request=req('get')) |
| 3557 | + assert form.fields.foo_one_to_one_foo.display_name == other_display_name |
3535 | 3558 |
|
3536 | 3559 |
|
3537 | 3560 | @pytest.mark.django_db |
@@ -3747,7 +3770,7 @@ def test_action_callbacks_should_be_lazy(): |
3747 | 3770 | def test_form_template_override_bug(): |
3748 | 3771 | class MyForm(Form): |
3749 | 3772 | @classmethod |
3750 | | - @with_defaults() |
| 3773 | + @with_defaults |
3751 | 3774 | def case1(cls, **kwargs): |
3752 | 3775 | kwargs['template'] = 'case1' |
3753 | 3776 | return cls(**kwargs) |
@@ -4090,3 +4113,42 @@ def test_parsed_data_does_not_crash_on_non_editable(): |
4090 | 4113 | parsed_data=lambda **_: 1, |
4091 | 4114 | ) |
4092 | 4115 | ).bind(request=req('POST', **{'-submit': ''})) |
| 4116 | + |
| 4117 | + |
| 4118 | +def test_call_target__attribute(): |
| 4119 | + class FooForm(Form): |
| 4120 | + class Meta: |
| 4121 | + auto__model = Foo |
| 4122 | + auto__include = ['foo'] |
| 4123 | + fields__foo__call_target__attribute = 'hardcoded' |
| 4124 | + fields__foo__parsed_data = 123 |
| 4125 | + |
| 4126 | + form = FooForm().bind(request=req('post', foo='456')) |
| 4127 | + assert form.fields.foo.value == 123 |
| 4128 | + |
| 4129 | + |
| 4130 | +def test_call_target__attribute_override_to_radio_button(): |
| 4131 | + class FooForm(Form): |
| 4132 | + class Meta: |
| 4133 | + auto__model = ChoicesModel |
| 4134 | + fields__color__call_target__attribute = 'radio' |
| 4135 | + |
| 4136 | + form = FooForm().bind(request=req('get')) |
| 4137 | + assert form.fields.color.iommi_shortcut_stack == [ |
| 4138 | + 'radio', |
| 4139 | + 'choice', |
| 4140 | + ] |
| 4141 | + |
| 4142 | + |
| 4143 | +def test_shoot_config_into_related_field(): |
| 4144 | + class FooForm(Form): |
| 4145 | + class Meta: |
| 4146 | + auto__model = Bar |
| 4147 | + auto__include = ['foo__foo'] |
| 4148 | + fields__foo_foo__call_target__attribute = 'hardcoded' |
| 4149 | + fields__foo_foo__parsed_data = 123 |
| 4150 | + |
| 4151 | + form = do_post(FooForm.create(), do_post_key_validation=False, foo='456') |
| 4152 | + assert form.fields.foo_foo.iommi_shortcut_stack == ['hardcoded'] |
| 4153 | + assert form.fields.foo_foo.parsed_data == 123 |
| 4154 | + assert form.fields.foo_foo.value == 123 |
0 commit comments