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

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 

7 

8from apis_core.generic.abc import GenericModel 

9from apis_core.generic.forms.fields import ModelImportChoiceField 

10 

11 

12class GenericImportForm(forms.Form): 

13 class Meta: 

14 fields = [] 

15 

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")) 

29 

30 

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 """ 

38 

39 columns_exclude = [] 

40 

41 def __init__(self, *args, **kwargs): 

42 super().__init__(*args, **kwargs) 

43 

44 self.helper = FormHelper() 

45 self.helper.form_method = "GET" 

46 self.helper.add_input(Submit("submit", "Submit")) 

47 

48 def clean(self): 

49 self.cleaned_data = super().clean() 

50 self.cleaned_data.pop("columns", None) 

51 return self.cleaned_data 

52 

53 

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 """ 

61 

62 class Meta: 

63 fields = "__all__" 

64 

65 def __init__(self, *args, **kwargs): 

66 super().__init__(*args, **kwargs) 

67 self.helper = FormHelper(self) 

68 self.helper.add_input(Submit("submit", "Submit")) 

69 

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 

89 

90 

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() 

109 

110 

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")) 

116 

117 

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 ) 

129 

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"))