Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/polymorphic/formsets/generic.py: 30%

34 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1from django.contrib.contenttypes.forms import ( 

2 BaseGenericInlineFormSet, 

3 generic_inlineformset_factory, 

4) 

5from django.contrib.contenttypes.models import ContentType 

6from django.db import models 

7from django.forms.models import ModelForm 

8 

9from .models import ( 

10 BasePolymorphicModelFormSet, 

11 PolymorphicFormSetChild, 

12 polymorphic_child_forms_factory, 

13) 

14 

15 

16class GenericPolymorphicFormSetChild(PolymorphicFormSetChild): 

17 """ 

18 Formset child for generic inlines 

19 """ 

20 

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

22 self.ct_field = kwargs.pop("ct_field", "content_type") 

23 self.fk_field = kwargs.pop("fk_field", "object_id") 

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

25 

26 def get_form(self, ct_field="content_type", fk_field="object_id", **kwargs): 

27 """ 

28 Construct the form class for the formset child. 

29 """ 

30 exclude = list(self.exclude) 

31 extra_exclude = kwargs.pop("extra_exclude", None) 

32 if extra_exclude: 

33 exclude += list(extra_exclude) 

34 

35 # Make sure the GFK fields are excluded by default 

36 # This is similar to what generic_inlineformset_factory() does 

37 # if there is no field called `ct_field` let the exception propagate 

38 opts = self.model._meta 

39 ct_field = opts.get_field(self.ct_field) 

40 

41 if ( 

42 not isinstance(ct_field, models.ForeignKey) 

43 or ct_field.remote_field.model != ContentType 

44 ): 

45 raise Exception("fk_name '%s' is not a ForeignKey to ContentType" % ct_field) 

46 

47 fk_field = opts.get_field(self.fk_field) # let the exception propagate 

48 exclude.extend([ct_field.name, fk_field.name]) 

49 kwargs["exclude"] = exclude 

50 

51 return super().get_form(**kwargs) 

52 

53 

54class BaseGenericPolymorphicInlineFormSet(BaseGenericInlineFormSet, BasePolymorphicModelFormSet): 

55 """ 

56 Polymorphic formset variation for inline generic formsets 

57 """ 

58 

59 

60def generic_polymorphic_inlineformset_factory( 

61 model, 

62 formset_children, 

63 form=ModelForm, 

64 formset=BaseGenericPolymorphicInlineFormSet, 

65 ct_field="content_type", 

66 fk_field="object_id", 

67 # Base form 

68 # TODO: should these fields be removed in favor of creating 

69 # the base form as a formset child too? 

70 fields=None, 

71 exclude=None, 

72 extra=1, 

73 can_order=False, 

74 can_delete=True, 

75 max_num=None, 

76 formfield_callback=None, 

77 validate_max=False, 

78 for_concrete_model=True, 

79 min_num=None, 

80 validate_min=False, 

81 child_form_kwargs=None, 

82): 

83 """ 

84 Construct the class for a generic inline polymorphic formset. 

85 

86 All arguments are identical to :func:`~django.contrib.contenttypes.forms.generic_inlineformset_factory`, 

87 with the exception of the ``formset_children`` argument. 

88 

89 :param formset_children: A list of all child :class:`PolymorphicFormSetChild` objects 

90 that tell the inline how to render the child model types. 

91 :type formset_children: Iterable[PolymorphicFormSetChild] 

92 :rtype: type 

93 """ 

94 kwargs = { 

95 "model": model, 

96 "form": form, 

97 "formfield_callback": formfield_callback, 

98 "formset": formset, 

99 "ct_field": ct_field, 

100 "fk_field": fk_field, 

101 "extra": extra, 

102 "can_delete": can_delete, 

103 "can_order": can_order, 

104 "fields": fields, 

105 "exclude": exclude, 

106 "min_num": min_num, 

107 "max_num": max_num, 

108 "validate_min": validate_min, 

109 "validate_max": validate_max, 

110 "for_concrete_model": for_concrete_model, 

111 # 'localized_fields': localized_fields, 

112 # 'labels': labels, 

113 # 'help_texts': help_texts, 

114 # 'error_messages': error_messages, 

115 # 'field_classes': field_classes, 

116 } 

117 if child_form_kwargs is None: 

118 child_form_kwargs = {} 

119 

120 child_kwargs = { 

121 # 'exclude': exclude, 

122 "ct_field": ct_field, 

123 "fk_field": fk_field, 

124 } 

125 if child_form_kwargs: 

126 child_kwargs.update(child_form_kwargs) 

127 

128 FormSet = generic_inlineformset_factory(**kwargs) 

129 FormSet.child_forms = polymorphic_child_forms_factory(formset_children, **child_kwargs) 

130 return FormSet