Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/django/contrib/contenttypes/forms.py: 26%

40 statements  

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

1from django.contrib.contenttypes.models import ContentType 

2from django.db import models 

3from django.forms import ModelForm, modelformset_factory 

4from django.forms.models import BaseModelFormSet 

5 

6 

7class BaseGenericInlineFormSet(BaseModelFormSet): 

8 """ 

9 A formset for generic inline objects to a parent. 

10 """ 

11 

12 def __init__( 

13 self, 

14 data=None, 

15 files=None, 

16 instance=None, 

17 save_as_new=False, 

18 prefix=None, 

19 queryset=None, 

20 **kwargs, 

21 ): 

22 opts = self.model._meta 

23 self.instance = instance 

24 self.rel_name = ( 

25 opts.app_label 

26 + "-" 

27 + opts.model_name 

28 + "-" 

29 + self.ct_field.name 

30 + "-" 

31 + self.ct_fk_field.name 

32 ) 

33 self.save_as_new = save_as_new 

34 if self.instance is None or self.instance.pk is None: 

35 qs = self.model._default_manager.none() 

36 else: 

37 if queryset is None: 

38 queryset = self.model._default_manager 

39 qs = queryset.filter( 

40 **{ 

41 self.ct_field.name: ContentType.objects.get_for_model( 

42 self.instance, for_concrete_model=self.for_concrete_model 

43 ), 

44 self.ct_fk_field.name: self.instance.pk, 

45 } 

46 ) 

47 super().__init__(queryset=qs, data=data, files=files, prefix=prefix, **kwargs) 

48 

49 def initial_form_count(self): 

50 if self.save_as_new: 

51 return 0 

52 return super().initial_form_count() 

53 

54 @classmethod 

55 def get_default_prefix(cls): 

56 opts = cls.model._meta 

57 return ( 

58 opts.app_label 

59 + "-" 

60 + opts.model_name 

61 + "-" 

62 + cls.ct_field.name 

63 + "-" 

64 + cls.ct_fk_field.name 

65 ) 

66 

67 def save_new(self, form, commit=True): 

68 setattr( 

69 form.instance, 

70 self.ct_field.get_attname(), 

71 ContentType.objects.get_for_model(self.instance).pk, 

72 ) 

73 setattr(form.instance, self.ct_fk_field.get_attname(), self.instance.pk) 

74 return form.save(commit=commit) 

75 

76 

77def generic_inlineformset_factory( 

78 model, 

79 form=ModelForm, 

80 formset=BaseGenericInlineFormSet, 

81 ct_field="content_type", 

82 fk_field="object_id", 

83 fields=None, 

84 exclude=None, 

85 extra=3, 

86 can_order=False, 

87 can_delete=True, 

88 max_num=None, 

89 formfield_callback=None, 

90 validate_max=False, 

91 for_concrete_model=True, 

92 min_num=None, 

93 validate_min=False, 

94 absolute_max=None, 

95 can_delete_extra=True, 

96): 

97 """ 

98 Return a ``GenericInlineFormSet`` for the given kwargs. 

99 

100 You must provide ``ct_field`` and ``fk_field`` if they are different from 

101 the defaults ``content_type`` and ``object_id`` respectively. 

102 """ 

103 opts = model._meta 

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

105 ct_field = opts.get_field(ct_field) 

106 if ( 

107 not isinstance(ct_field, models.ForeignKey) 

108 or ct_field.remote_field.model != ContentType 

109 ): 

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

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

112 exclude = [*(exclude or []), ct_field.name, fk_field.name] 

113 FormSet = modelformset_factory( 

114 model, 

115 form=form, 

116 formfield_callback=formfield_callback, 

117 formset=formset, 

118 extra=extra, 

119 can_delete=can_delete, 

120 can_order=can_order, 

121 fields=fields, 

122 exclude=exclude, 

123 max_num=max_num, 

124 validate_max=validate_max, 

125 min_num=min_num, 

126 validate_min=validate_min, 

127 absolute_max=absolute_max, 

128 can_delete_extra=can_delete_extra, 

129 ) 

130 FormSet.ct_field = ct_field 

131 FormSet.ct_fk_field = fk_field 

132 FormSet.for_concrete_model = for_concrete_model 

133 return FormSet