File: extra_views.py

package info (click to toggle)
django-polymorphic 4.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 892 kB
  • sloc: python: 6,784; javascript: 263; makefile: 137
file content (137 lines) | stat: -rw-r--r-- 4,061 bytes parent folder | download | duplicates (2)
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