Coverage for apis_core/generic/forms/fields.py: 43%
35 statements
« prev ^ index » next coverage.py v7.5.3, created at 2025-06-25 10:00 +0000
« prev ^ index » next coverage.py v7.5.3, created at 2025-06-25 10:00 +0000
1from django.core.exceptions import ValidationError
2from django.forms import ModelChoiceField, MultiValueField, MultiWidget
3from django.utils.translation import gettext as _
5from apis_core.apis_metainfo.utils import create_object_from_uri
8class ModelImportChoiceField(ModelChoiceField):
9 def to_python(self, value):
10 result = None
11 if value:
12 try:
13 result = create_object_from_uri(value, self.queryset.model)
14 except Exception as e:
15 raise ValidationError(
16 _("Could not import %(value)s: %(exception)s"),
17 params={"value": value, "exception": e},
18 )
19 return result or super().to_python(value)
22class RowColumnMultiWidget(MultiWidget):
23 """
24 A custom MultiWidget that is meant to be used with the
25 RowColumnMultiValueField. The widget takes a list of widgets
26 as a parameter and displays those widgets in columns in one row.
27 The `labels` parameter is used to add a separate label to the
28 individual widgets.
29 """
31 template_name = "widgets/row_column_multiwidget.html"
32 use_fieldset = False
34 def __init__(self, widgets, labels=[], attrs=None):
35 self.labels = labels
36 super().__init__(widgets, attrs)
38 def get_context(self, name, value, attrs):
39 ctx = super().get_context(name, value, attrs)
40 for widget in ctx["widget"]["subwidgets"]:
41 if self.labels:
42 widget["label"] = self.labels.pop(0)
43 return ctx
45 def decompress(self, value):
46 if value:
47 return value
48 return []
51class RowColumnMultiValueField(MultiValueField):
52 """
53 This is a custom MultiValueField that simply shows multiple form
54 fields in a row. The form fields are passed to the constructor and
55 the corresponding RowColumnMultiWidget simply iterates through all
56 the fields and shows them in rows.
57 Additionaly it is possible to pass a list of `labels` that are then
58 also passed on to the widget, which uses those to add a separate
59 label to the individual widgets.
60 """
62 def __init__(self, fields, labels=[], *args, **kwargs):
63 kwargs["widget"] = RowColumnMultiWidget(
64 widgets=[f.widget for f in fields], labels=labels
65 )
66 super().__init__(fields, *args, **kwargs)
68 def compress(self, data_list):
69 return data_list