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
« 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
9from .models import (
10 BasePolymorphicModelFormSet,
11 PolymorphicFormSetChild,
12 polymorphic_child_forms_factory,
13)
16class GenericPolymorphicFormSetChild(PolymorphicFormSetChild):
17 """
18 Formset child for generic inlines
19 """
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)
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)
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)
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)
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
51 return super().get_form(**kwargs)
54class BaseGenericPolymorphicInlineFormSet(BaseGenericInlineFormSet, BasePolymorphicModelFormSet):
55 """
56 Polymorphic formset variation for inline generic formsets
57 """
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.
86 All arguments are identical to :func:`~django.contrib.contenttypes.forms.generic_inlineformset_factory`,
87 with the exception of the ``formset_children`` argument.
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 = {}
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)
128 FormSet = generic_inlineformset_factory(**kwargs)
129 FormSet.child_forms = polymorphic_child_forms_factory(formset_children, **child_kwargs)
130 return FormSet