File: generic.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 (70 lines) | stat: -rw-r--r-- 2,648 bytes parent folder | download | duplicates (3)
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
from django.contrib.contenttypes.admin import GenericInlineModelAdmin
from django.contrib.contenttypes.models import ContentType
from django.utils.functional import cached_property

from polymorphic.formsets import (
    BaseGenericPolymorphicInlineFormSet,
    GenericPolymorphicFormSetChild,
    polymorphic_child_forms_factory,
)

from .inlines import PolymorphicInlineModelAdmin


class GenericPolymorphicInlineModelAdmin(PolymorphicInlineModelAdmin, GenericInlineModelAdmin):
    """
    Base class for variation of inlines based on generic foreign keys.
    """

    #: The formset class
    formset = BaseGenericPolymorphicInlineFormSet

    def get_formset(self, request, obj=None, **kwargs):
        """
        Construct the generic inline formset class.
        """
        # Construct the FormSet class. This is almost the same as parent version,
        # except that a different super is called so generic_inlineformset_factory() is used.
        # NOTE that generic_inlineformset_factory() also makes sure the GFK fields are excluded in the form.
        FormSet = GenericInlineModelAdmin.get_formset(self, request, obj=obj, **kwargs)

        FormSet.child_forms = polymorphic_child_forms_factory(
            formset_children=self.get_formset_children(request, obj=obj)
        )
        return FormSet

    class Child(PolymorphicInlineModelAdmin.Child):
        """
        Variation for generic inlines.
        """

        # Make sure that the GFK fields are excluded from the child forms
        formset_child = GenericPolymorphicFormSetChild
        ct_field = "content_type"
        ct_fk_field = "object_id"

        @cached_property
        def content_type(self):
            """
            Expose the ContentType that the child relates to.
            This can be used for the ``polymorphic_ctype`` field.
            """
            return ContentType.objects.get_for_model(self.model, for_concrete_model=False)

        def get_formset_child(self, request, obj=None, **kwargs):
            # Similar to GenericInlineModelAdmin.get_formset(),
            # make sure the GFK is automatically excluded from the form
            defaults = {"ct_field": self.ct_field, "fk_field": self.ct_fk_field}
            defaults.update(kwargs)
            return super(GenericPolymorphicInlineModelAdmin.Child, self).get_formset_child(
                request, obj=obj, **defaults
            )


class GenericStackedPolymorphicInline(GenericPolymorphicInlineModelAdmin):
    """
    The stacked layout for generic inlines.
    """

    #: The default template to use.
    template = "admin/polymorphic/edit_inline/stacked.html"