Coverage for apis_core/generic/forms/__init__.py: 32%
80 statements
« prev ^ index » next coverage.py v7.6.8, created at 2024-12-20 09:24 +0000
« prev ^ index » next coverage.py v7.6.8, created at 2024-12-20 09:24 +0000
1from crispy_forms.helper import FormHelper
2from crispy_forms.layout import Submit
3from dal import autocomplete
4from django import forms
5from django.contrib.contenttypes.models import ContentType
6from django.urls import reverse
8from apis_core.generic.abc import GenericModel
9from apis_core.generic.forms.fields import ModelImportChoiceField
12class GenericImportForm(forms.Form):
13 class Meta:
14 fields = []
16 def __init__(self, *args, **kwargs):
17 super().__init__(*args, **kwargs)
18 self.fields["url"] = ModelImportChoiceField(
19 queryset=self.Meta.model.objects.all()
20 )
21 ct = ContentType.objects.get_for_model(self.Meta.model)
22 url = reverse("apis_core:generic:autocompleteexternalonly", args=[ct])
23 self.fields["url"].widget = autocomplete.ModelSelect2(
24 url, attrs={"data-html": True, "data-tags": 1}
25 )
26 self.fields["url"].widget.choices = self.fields["url"].choices
27 self.helper = FormHelper()
28 self.helper.add_input(Submit("submit", "Submit"))
31class GenericFilterSetForm(forms.Form):
32 """
33 FilterSet form for generic models
34 Adds a submit button using the django crispy form helper
35 Adds a `columns` selector that lists all the fields from
36 the model
37 """
39 columns_exclude = []
41 def __init__(self, *args, **kwargs):
42 super().__init__(*args, **kwargs)
44 self.helper = FormHelper()
45 self.helper.form_method = "GET"
46 self.helper.add_input(Submit("submit", "Submit"))
48 def clean(self):
49 self.cleaned_data = super().clean()
50 self.cleaned_data.pop("columns", None)
51 return self.cleaned_data
54class GenericModelForm(forms.ModelForm):
55 """
56 Model form for generic models
57 Adds a submit button using the django crispy form helper
58 and sets the ModelChoiceFields and ModelMultipleChoiceFields
59 to use autocomplete replacement fields
60 """
62 class Meta:
63 fields = "__all__"
65 def __init__(self, *args, **kwargs):
66 super().__init__(*args, **kwargs)
67 self.helper = FormHelper(self)
68 self.helper.add_input(Submit("submit", "Submit"))
70 # override the fields pointing to other models,
71 # to make them use the autocomplete widgets
72 override_fieldtypes = {
73 "ModelMultipleChoiceField": autocomplete.ModelSelect2Multiple,
74 "ModelChoiceField": autocomplete.ModelSelect2,
75 "ModelImportChoiceField": autocomplete.ModelSelect2,
76 }
77 for field in self.fields:
78 clsname = self.fields[field].__class__.__name__
79 if clsname in override_fieldtypes.keys():
80 ct = ContentType.objects.get_for_model(
81 self.fields[field]._queryset.model
82 )
83 if issubclass(ct.model_class(), GenericModel):
84 url = reverse("apis_core:generic:autocomplete", args=[ct])
85 self.fields[field].widget = override_fieldtypes[clsname](
86 url, attrs={"data-html": True}
87 )
88 self.fields[field].widget.choices = self.fields[field].choices
91class GenericSelectMergeOrEnrichForm(forms.Form):
92 def __init__(self, *args, **kwargs):
93 if "instance" in kwargs:
94 instance = kwargs.pop("instance")
95 super().__init__(*args, **kwargs)
96 ct = ContentType.objects.get_for_model(instance)
97 self.fields["uri"] = forms.ModelChoiceField(
98 queryset=ct.model_class().objects.all()
99 )
100 uri = reverse("apis_core:generic:autocomplete", args=[ct])
101 attrs = {"data-html": True, "data-tags": 1}
102 self.fields["uri"].widget = autocomplete.ModelSelect2(uri, attrs=attrs)
103 self.fields["uri"].widget.choices = self.fields["uri"].choices
104 self.fields["uri"].label = "Select or paste URI"
105 self.helper = FormHelper()
106 self.helper.form_method = "GET"
107 self.helper.add_input(Submit("submit", "Submit"))
108 self.helper.form_action = instance.get_enrich_url()
111class GenericMergeWithForm(forms.Form):
112 def __init__(self, *args, **kwargs):
113 super().__init__(*args, **kwargs)
114 self.helper = FormHelper()
115 self.helper.add_input(Submit("submit", "Merge"))
118class GenericEnrichForm(forms.Form):
119 def __init__(self, *args, **kwargs):
120 data = kwargs.pop("data", {})
121 instance = kwargs.pop("instance", None)
122 super().__init__(*args, **kwargs)
123 for key, value in data.items():
124 update_key = f"update_{key}"
125 self.fields[update_key] = forms.BooleanField(
126 required=False,
127 label=f"Update {key} from {getattr(instance, key)} to {value}",
128 )
130 self.fields[key] = forms.CharField(initial=value, required=False)
131 self.fields[key].widget = self.fields[key].hidden_widget()
132 self.helper = FormHelper()
133 self.helper.add_input(Submit("submit", "Submit"))