mirror of
https://github.com/jazzband/django-constance.git
synced 2026-03-16 22:40:24 +00:00
Added missing logic to reset multi select (#659)
Some checks failed
Docs / docs (push) Has been cancelled
Test / ruff-format (push) Has been cancelled
Test / ruff-lint (push) Has been cancelled
Test / build (3.10) (push) Has been cancelled
Test / build (3.11) (push) Has been cancelled
Test / build (3.12) (push) Has been cancelled
Test / build (3.13) (push) Has been cancelled
Test / build (3.14) (push) Has been cancelled
Test / build (3.8) (push) Has been cancelled
Test / build (3.9) (push) Has been cancelled
Some checks failed
Docs / docs (push) Has been cancelled
Test / ruff-format (push) Has been cancelled
Test / ruff-lint (push) Has been cancelled
Test / build (3.10) (push) Has been cancelled
Test / build (3.11) (push) Has been cancelled
Test / build (3.12) (push) Has been cancelled
Test / build (3.13) (push) Has been cancelled
Test / build (3.14) (push) Has been cancelled
Test / build (3.8) (push) Has been cancelled
Test / build (3.9) (push) Has been cancelled
This commit is contained in:
parent
7e75db3ebc
commit
c908b05740
4 changed files with 75 additions and 0 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
import json
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
@ -62,8 +63,13 @@ class ConstanceAdmin(admin.ModelAdmin):
|
||||||
"is_date": isinstance(default, date),
|
"is_date": isinstance(default, date),
|
||||||
"is_datetime": isinstance(default, datetime),
|
"is_datetime": isinstance(default, datetime),
|
||||||
"is_checkbox": isinstance(form_field.field.widget, forms.CheckboxInput),
|
"is_checkbox": isinstance(form_field.field.widget, forms.CheckboxInput),
|
||||||
|
"is_multi_select": isinstance(
|
||||||
|
form_field.field.widget, (forms.SelectMultiple, forms.CheckboxSelectMultiple)
|
||||||
|
),
|
||||||
"is_file": isinstance(form_field.field.widget, forms.FileInput),
|
"is_file": isinstance(form_field.field.widget, forms.FileInput),
|
||||||
}
|
}
|
||||||
|
if config_value["is_multi_select"]:
|
||||||
|
config_value["json_default"] = json.dumps(default if isinstance(default, list) else [default])
|
||||||
if field_type and field_type in settings.ADDITIONAL_FIELDS:
|
if field_type and field_type in settings.ADDITIONAL_FIELDS:
|
||||||
serialized_default = form[name].field.prepare_value(default)
|
serialized_default = form[name].field.prepare_value(default)
|
||||||
config_value["default"] = serialized_default
|
config_value["default"] = serialized_default
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,17 @@
|
||||||
|
|
||||||
if (fieldType === 'checkbox') {
|
if (fieldType === 'checkbox') {
|
||||||
field.prop('checked', this.dataset.default === 'true');
|
field.prop('checked', this.dataset.default === 'true');
|
||||||
|
} else if (fieldType === 'multi-select') {
|
||||||
|
const defaults = JSON.parse(this.dataset.default);
|
||||||
|
const stringDefaults = defaults.map(function(v) { return String(v); });
|
||||||
|
// CheckboxSelectMultiple: individual checkboxes inside a wrapper
|
||||||
|
field.find('input[type="checkbox"]').each(function() {
|
||||||
|
$(this).prop('checked', stringDefaults.indexOf($(this).val()) !== -1);
|
||||||
|
});
|
||||||
|
// SelectMultiple: <select multiple> element
|
||||||
|
field.find('option').each(function() {
|
||||||
|
$(this).prop('selected', stringDefaults.indexOf($(this).val()) !== -1);
|
||||||
|
});
|
||||||
} else if (fieldType === 'date') {
|
} else if (fieldType === 'date') {
|
||||||
const defaultDate = new Date(this.dataset.default * 1000);
|
const defaultDate = new Date(this.dataset.default * 1000);
|
||||||
$('#' + this.dataset.fieldId).val(defaultDate.strftime(get_format('DATE_INPUT_FORMATS')[0]));
|
$('#' + this.dataset.fieldId).val(defaultDate.strftime(get_format('DATE_INPUT_FORMATS')[0]));
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,14 @@
|
||||||
data-field-id="{{ item.form_field.auto_id }}"
|
data-field-id="{{ item.form_field.auto_id }}"
|
||||||
data-field-type="{% spaceless %}
|
data-field-type="{% spaceless %}
|
||||||
{% if item.is_checkbox %}checkbox
|
{% if item.is_checkbox %}checkbox
|
||||||
|
{% elif item.is_multi_select %}multi-select
|
||||||
{% elif item.is_datetime %}datetime
|
{% elif item.is_datetime %}datetime
|
||||||
{% elif item.is_date %}date
|
{% elif item.is_date %}date
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endspaceless %}"
|
{% endspaceless %}"
|
||||||
data-default="{% spaceless %}
|
data-default="{% spaceless %}
|
||||||
{% if item.is_checkbox %}{% if item.raw_default %} true {% else %} false {% endif %}
|
{% if item.is_checkbox %}{% if item.raw_default %} true {% else %} false {% endif %}
|
||||||
|
{% elif item.is_multi_select %}{{ item.json_default }}
|
||||||
{% elif item.is_date %}{{ item.raw_default|date:"U" }}
|
{% elif item.is_date %}{{ item.raw_default|date:"U" }}
|
||||||
{% elif item.is_datetime %}{{ item.raw_default|date:"U" }}
|
{% elif item.is_datetime %}{{ item.raw_default|date:"U" }}
|
||||||
{% else %}{{ item.default }}
|
{% else %}{{ item.default }}
|
||||||
|
|
|
||||||
|
|
@ -266,6 +266,62 @@ class TestAdmin(TestCase):
|
||||||
content_str = response.content.decode()
|
content_str = response.content.decode()
|
||||||
self.assertGreater(content_str.find("STRING_VALUE"), content_str.find("INT_VALUE"))
|
self.assertGreater(content_str.find("STRING_VALUE"), content_str.find("INT_VALUE"))
|
||||||
|
|
||||||
|
@mock.patch(
|
||||||
|
"constance.settings.ADDITIONAL_FIELDS",
|
||||||
|
{
|
||||||
|
"language_select": [
|
||||||
|
"django.forms.fields.TypedMultipleChoiceField",
|
||||||
|
{
|
||||||
|
"widget": "django.forms.CheckboxSelectMultiple",
|
||||||
|
"choices": (("en", "English"), ("de", "German"), ("fr", "French")),
|
||||||
|
"coerce": str,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
@mock.patch(
|
||||||
|
"constance.settings.CONFIG",
|
||||||
|
{
|
||||||
|
"LANGUAGES": (["en", "de"], "Supported languages", "language_select"),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
def test_reset_to_default_multi_select(self):
|
||||||
|
"""
|
||||||
|
Test that multi-select config values render with data-field-type='multi-select'
|
||||||
|
and a JSON-encoded data-default attribute.
|
||||||
|
"""
|
||||||
|
# Re-parse additional fields so the mock is picked up by the form
|
||||||
|
from constance.forms import FIELDS
|
||||||
|
from constance.forms import parse_additional_fields
|
||||||
|
|
||||||
|
FIELDS.update(
|
||||||
|
parse_additional_fields(
|
||||||
|
{
|
||||||
|
"language_select": [
|
||||||
|
"django.forms.fields.TypedMultipleChoiceField",
|
||||||
|
{
|
||||||
|
"widget": "django.forms.CheckboxSelectMultiple",
|
||||||
|
"choices": (("en", "English"), ("de", "German"), ("fr", "French")),
|
||||||
|
"coerce": str,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
self.client.login(username="admin", password="nimda")
|
||||||
|
request = self.rf.get("/admin/constance/config/")
|
||||||
|
request.user = self.superuser
|
||||||
|
response = self.options.changelist_view(request, {})
|
||||||
|
response.render()
|
||||||
|
content = response.content.decode()
|
||||||
|
|
||||||
|
self.assertIn('data-field-type="multi-select"', content)
|
||||||
|
self.assertIn('data-default="["en", "de"]"', content)
|
||||||
|
finally:
|
||||||
|
# Clean up FIELDS to avoid leaking into other tests
|
||||||
|
FIELDS.pop("language_select", None)
|
||||||
|
|
||||||
def test_labels(self):
|
def test_labels(self):
|
||||||
self.assertEqual(type(self.model._meta.label), str)
|
self.assertEqual(type(self.model._meta.label), str)
|
||||||
self.assertEqual(type(self.model._meta.label_lower), str)
|
self.assertEqual(type(self.model._meta.label_lower), str)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue