django-polymorphic/polymorphic/admin/generic.py

56 lines
2.3 KiB
Python

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 polymorphic_child_forms_factory, BasePolymorphicGenericInlineFormSet, PolymorphicGenericFormSetChild
from .inlines import PolymorphicParentInlineModelAdmin, PolymorphicChildInlineModelAdmin
class PolymorphicParentGenericInlineModelAdmin(PolymorphicParentInlineModelAdmin, GenericInlineModelAdmin):
"""
Variation for inlines based on generic foreign keys.
"""
formset = BasePolymorphicGenericInlineFormSet
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 PolymorphicChildGenericInlineModelAdmin(PolymorphicChildInlineModelAdmin):
"""
Variation for generic inlines.
"""
# Make sure that the GFK fields are excluded from the child forms
formset_child = PolymorphicGenericFormSetChild
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)
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(PolymorphicChildGenericInlineModelAdmin, self).get_formset_child(request, obj=obj, **defaults)