1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
"""
The ``extra_views.formsets`` provides a simple way to handle formsets.
The ``extra_views.advanced`` provides a method to combine that with a create/update form.
This package provides classes that support both options for polymorphic formsets.
"""
import extra_views
from django.core.exceptions import ImproperlyConfigured
from polymorphic.formsets import (
BasePolymorphicInlineFormSet,
BasePolymorphicModelFormSet,
polymorphic_child_forms_factory,
)
__all__ = (
"PolymorphicFormSetView",
"PolymorphicInlineFormSetView",
"PolymorphicInlineFormSet",
)
class PolymorphicFormSetMixin:
"""
Internal Mixin, that provides polymorphic integration with the ``extra_views`` package.
"""
formset_class = BasePolymorphicModelFormSet
#: Default 0 extra forms
factory_kwargs = {"extra": 0}
#: Define the children
# :type: list[PolymorphicFormSetChild]
formset_children = None
def get_formset_children(self):
"""
:rtype: list[PolymorphicFormSetChild]
"""
if not self.formset_children:
raise ImproperlyConfigured(
"Define 'formset_children' as list of `PolymorphicFormSetChild`"
)
return self.formset_children
def get_formset_child_kwargs(self):
return {}
def get_formset(self):
"""
Returns the formset class from the inline formset factory
"""
# Implementation detail:
# Since `polymorphic_modelformset_factory` and `polymorphic_inlineformset_factory` mainly
# reuse the standard factories, and then add `child_forms`, the same can be done here.
# This makes sure the base class construction is completely honored.
FormSet = super().get_formset()
FormSet.child_forms = polymorphic_child_forms_factory(
self.get_formset_children(), **self.get_formset_child_kwargs()
)
return FormSet
class PolymorphicFormSetView(PolymorphicFormSetMixin, extra_views.ModelFormSetView):
"""
A view that displays a single polymorphic formset.
.. code-block:: python
from polymorphic.formsets import PolymorphicFormSetChild
class ItemsView(PolymorphicFormSetView):
model = Item
formset_children = [
PolymorphicFormSetChild(ItemSubclass1),
PolymorphicFormSetChild(ItemSubclass2),
]
"""
formset_class = BasePolymorphicModelFormSet
class PolymorphicInlineFormSetView(PolymorphicFormSetMixin, extra_views.InlineFormSetView):
"""
A view that displays a single polymorphic formset - with one parent object.
This is a variation of the :mod:`extra_views` package classes for django-polymorphic.
.. code-block:: python
from polymorphic.formsets import PolymorphicFormSetChild
class OrderItemsView(PolymorphicInlineFormSetView):
model = Order
inline_model = Item
formset_children = [
PolymorphicFormSetChild(ItemSubclass1),
PolymorphicFormSetChild(ItemSubclass2),
]
"""
formset_class = BasePolymorphicInlineFormSet
class PolymorphicInlineFormSet(PolymorphicFormSetMixin, extra_views.InlineFormSetFactory):
"""
An inline to add to the ``inlines`` of
the :class:`~extra_views.advanced.CreateWithInlinesView`
and :class:`~extra_views.advanced.UpdateWithInlinesView` class.
.. code-block:: python
from polymorphic.formsets import PolymorphicFormSetChild
class ItemsInline(PolymorphicInlineFormSet):
model = Item
formset_children = [
PolymorphicFormSetChild(ItemSubclass1),
PolymorphicFormSetChild(ItemSubclass2),
]
class OrderCreateView(CreateWithInlinesView):
model = Order
inlines = [ItemsInline]
def get_success_url(self):
return self.object.get_absolute_url()
"""
formset_class = BasePolymorphicInlineFormSet
|