Skip to content

Commit 45d7352

Browse files
authored
Allow default value in field (#34)
* Allow default value in Signed-off-by: Jakub Semik <[email protected]> * run only on push to master and PR to master Signed-off-by: Jakub Semik <[email protected]> * add tests Signed-off-by: Jakub Semik <[email protected]> * run isort Signed-off-by: Jakub Semik <[email protected]>
1 parent 3a3e99d commit 45d7352

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

django_better_admin_arrayfield/forms/fields.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class DynamicArrayField(forms.Field):
1616
def __init__(self, base_field, **kwargs):
1717
self.base_field = base_field
1818
self.max_length = kwargs.pop("max_length", None)
19+
self.default = kwargs.pop("default", None)
1920
kwargs.setdefault("widget", DynamicArrayWidget)
2021
super().__init__(**kwargs)
2122

@@ -36,7 +37,10 @@ def clean(self, value):
3637
)
3738

3839
if not value:
39-
cleaned_data = None
40+
if callable(self.default):
41+
cleaned_data = self.default()
42+
else:
43+
cleaned_data = self.default
4044

4145
if cleaned_data is None and self.initial is not None:
4246
if callable(self.initial):

tests/test_fields.py

+18
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,21 @@ def test_field_required():
2121
field.clean(data)
2222
data = ["12", "13"]
2323
field.clean(data)
24+
25+
26+
def test_default():
27+
default = ["1"]
28+
field = DynamicArrayField(CharField(max_length=10), required=True, default=default)
29+
data = []
30+
cleaned_data = field.clean(data)
31+
assert cleaned_data == default
32+
33+
34+
def test_callable_default():
35+
def default():
36+
return ["1", "2"]
37+
38+
field = DynamicArrayField(CharField(max_length=10), required=True, default=default)
39+
data = []
40+
cleaned_data = field.clean(data)
41+
assert cleaned_data == default()

tests/test_forms.py

+29-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
from typing import Type
22

3-
from django.forms import ModelForm
3+
from django.forms import IntegerField, ModelForm
44

55
import pytest
66

7+
from django_better_admin_arrayfield.forms.fields import DynamicArrayField
78
from tests.testapp.models import DefaultValueNullableModel, DefaultValueRequiredModel, NullableNoDefaultModel
89

910

10-
def form_factory(model) -> Type[ModelForm]:
11+
def form_factory(model, **attrs) -> Type[ModelForm]:
1112
meta = type("Meta", (), {"model": model, "fields": ["array"]})
12-
return type("SampleForm", (ModelForm,), {"Meta": meta})
13+
return type("SampleForm", (ModelForm,), {"Meta": meta, **attrs})
1314

1415

1516
class TestDefaultValue:
@@ -32,3 +33,28 @@ def test_default_list(self, model_class, init_value, expected_value):
3233
form = form_factory(model_class)(data=data)
3334
assert form.is_valid()
3435
assert form.cleaned_data["array"] == expected_value
36+
37+
38+
class TestFormDefaultField:
39+
@pytest.mark.parametrize(
40+
"model_class,init_value,expected_value",
41+
(
42+
(DefaultValueNullableModel, None, [1]),
43+
(NullableNoDefaultModel, None, [1]),
44+
(DefaultValueRequiredModel, None, [1]),
45+
(DefaultValueNullableModel, [2], [2]),
46+
(NullableNoDefaultModel, [2], [2]),
47+
(DefaultValueRequiredModel, [2], [2]),
48+
),
49+
)
50+
def test_default_different_values(self, model_class, init_value, expected_value):
51+
default = [1]
52+
data = {}
53+
if init_value is not None:
54+
data["array"] = init_value
55+
56+
field = DynamicArrayField(IntegerField(), required=True, default=default)
57+
58+
form = form_factory(model_class, array=field)(data=data)
59+
assert form.is_valid()
60+
assert form.cleaned_data["array"] == expected_value

0 commit comments

Comments
 (0)