Rename inline/formset classes to avoid more confusion.

AbstractSingletonProxyFactoryBean danger luked here...
Added the Stacked...Inline for clarity too.
fix_request_path_info
Diederik van der Boor 2016-08-09 01:11:05 +02:00
parent 8c42893abd
commit 1f0ddd8436
6 changed files with 157 additions and 143 deletions

View File

@ -14,22 +14,22 @@ from .filters import PolymorphicChildModelFilter
# Inlines # Inlines
from .inlines import ( from .inlines import (
PolymorphicParentInlineModelAdmin, PolymorphicInlineModelAdmin, # base class
PolymorphicChildInlineModelAdmin, StackedPolymorphicInline, # stacked inline
) )
# Helpers for the inlines # Helpers for the inlines
from .helpers import ( from .helpers import (
InlinePolymorphicAdminForm, PolymorphicInlineAdminForm,
InlinePolymorphicAdminFormSet, PolymorphicInlineAdminFormSet,
PolymorphicInlineSupportMixin, # mixin for the regular model admin! PolymorphicInlineSupportMixin, # mixin for the regular model admin!
) )
# Expose generic admin features too. There is no need to split those # Expose generic admin features too. There is no need to split those
# as the admin already relies on contenttypes. # as the admin already relies on contenttypes.
from .generic import ( from .generic import (
PolymorphicParentGenericInlineModelAdmin, GenericPolymorphicInlineModelAdmin, # base class
PolymorphicChildGenericInlineModelAdmin, GenericStackedPolymorphicInline, # stacked inline
) )
__all__ = ( __all__ = (
@ -37,11 +37,10 @@ __all__ = (
'PolymorphicChildModelAdmin', 'PolymorphicChildModelAdmin',
'PolymorphicModelChoiceForm', 'PolymorphicModelChoiceForm',
'PolymorphicChildModelFilter', 'PolymorphicChildModelFilter',
'InlinePolymorphicAdminForm', 'PolymorphicInlineAdminForm',
'InlinePolymorphicAdminFormSet', 'PolymorphicInlineAdminFormSet',
'PolymorphicInlineSupportMixin', 'PolymorphicInlineSupportMixin',
'PolymorphicParentInlineModelAdmin', 'PolymorphicInlineModelAdmin',
'PolymorphicChildInlineModelAdmin', 'GenericPolymorphicInlineModelAdmin',
'PolymorphicParentGenericInlineModelAdmin', 'GenericStackedPolymorphicInline',
'PolymorphicChildGenericInlineModelAdmin',
) )

View File

@ -2,15 +2,15 @@ from django.contrib.contenttypes.admin import GenericInlineModelAdmin
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.utils.functional import cached_property from django.utils.functional import cached_property
from polymorphic.formsets import polymorphic_child_forms_factory, BasePolymorphicGenericInlineFormSet, PolymorphicGenericFormSetChild from polymorphic.formsets import polymorphic_child_forms_factory, BaseGenericPolymorphicInlineFormSet, GenericPolymorphicFormSetChild
from .inlines import PolymorphicParentInlineModelAdmin, PolymorphicChildInlineModelAdmin from .inlines import PolymorphicInlineModelAdmin
class PolymorphicParentGenericInlineModelAdmin(PolymorphicParentInlineModelAdmin, GenericInlineModelAdmin): class GenericPolymorphicInlineModelAdmin(PolymorphicInlineModelAdmin, GenericInlineModelAdmin):
""" """
Variation for inlines based on generic foreign keys. Base class for variation of inlines based on generic foreign keys.
""" """
formset = BasePolymorphicGenericInlineFormSet formset = BaseGenericPolymorphicInlineFormSet
def get_formset(self, request, obj=None, **kwargs): def get_formset(self, request, obj=None, **kwargs):
""" """
@ -26,13 +26,12 @@ class PolymorphicParentGenericInlineModelAdmin(PolymorphicParentInlineModelAdmin
) )
return FormSet return FormSet
class Child(PolymorphicInlineModelAdmin.Child):
class PolymorphicChildGenericInlineModelAdmin(PolymorphicChildInlineModelAdmin):
""" """
Variation for generic inlines. Variation for generic inlines.
""" """
# Make sure that the GFK fields are excluded from the child forms # Make sure that the GFK fields are excluded from the child forms
formset_child = PolymorphicGenericFormSetChild formset_child = GenericPolymorphicFormSetChild
ct_field = "content_type" ct_field = "content_type"
ct_fk_field = "object_id" ct_fk_field = "object_id"
@ -52,4 +51,11 @@ class PolymorphicChildGenericInlineModelAdmin(PolymorphicChildInlineModelAdmin):
"fk_field": self.ct_fk_field, "fk_field": self.ct_fk_field,
} }
defaults.update(kwargs) defaults.update(kwargs)
return super(PolymorphicChildGenericInlineModelAdmin, self).get_formset_child(request, obj=obj, **defaults) return super(GenericPolymorphicInlineModelAdmin.Child, self).get_formset_child(request, obj=obj, **defaults)
class GenericStackedPolymorphicInline(GenericPolymorphicInlineModelAdmin):
"""
The stacked layout for generic inlines.
"""
template = 'admin/polymorphic/edit_inline/stacked.html'

View File

@ -3,19 +3,19 @@ Rendering utils for admin forms;
This makes sure that admin fieldsets/layout settings are exported to the template. This makes sure that admin fieldsets/layout settings are exported to the template.
""" """
from django.contrib.admin.helpers import InlineAdminFormSet, InlineAdminForm import django
from django.contrib.admin.helpers import InlineAdminFormSet, InlineAdminForm, AdminField
from polymorphic.formsets import BasePolymorphicModelFormSet from polymorphic.formsets import BasePolymorphicModelFormSet
class InlinePolymorphicAdminForm(InlineAdminForm): class PolymorphicInlineAdminForm(InlineAdminForm):
""" """
Expose the admin configuration for a form Expose the admin configuration for a form
""" """
pass
class InlinePolymorphicAdminFormSet(InlineAdminFormSet): class PolymorphicInlineAdminFormSet(InlineAdminFormSet):
""" """
Internally used class to expose the formset in the template. Internally used class to expose the formset in the template.
""" """
@ -23,7 +23,7 @@ class InlinePolymorphicAdminFormSet(InlineAdminFormSet):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None) # Assigned later via PolymorphicInlineSupportMixin later. self.request = kwargs.pop('request', None) # Assigned later via PolymorphicInlineSupportMixin later.
self.obj = kwargs.pop('obj', None) self.obj = kwargs.pop('obj', None)
super(InlinePolymorphicAdminFormSet, self).__init__(*args, **kwargs) super(PolymorphicInlineAdminFormSet, self).__init__(*args, **kwargs)
def __iter__(self): def __iter__(self):
""" """
@ -35,7 +35,7 @@ class InlinePolymorphicAdminFormSet(InlineAdminFormSet):
child_inline = self.opts.get_child_inline_instance(model) child_inline = self.opts.get_child_inline_instance(model)
view_on_site_url = self.opts.get_view_on_site_url(original) view_on_site_url = self.opts.get_view_on_site_url(original)
yield InlinePolymorphicAdminForm( yield PolymorphicInlineAdminForm(
formset=self.formset, formset=self.formset,
form=form, form=form,
fieldsets=self.get_child_fieldsets(child_inline), fieldsets=self.get_child_fieldsets(child_inline),
@ -50,7 +50,7 @@ class InlinePolymorphicAdminFormSet(InlineAdminFormSet):
for form in self.formset.extra_forms + self.formset.empty_forms: for form in self.formset.extra_forms + self.formset.empty_forms:
model = form._meta.model model = form._meta.model
child_inline = self.opts.get_child_inline_instance(model) child_inline = self.opts.get_child_inline_instance(model)
yield InlinePolymorphicAdminForm( yield PolymorphicInlineAdminForm(
formset=self.formset, formset=self.formset,
form=form, form=form,
fieldsets=self.get_child_fieldsets(child_inline), fieldsets=self.get_child_fieldsets(child_inline),
@ -81,7 +81,7 @@ class PolymorphicInlineSupportMixin(object):
depending on the polymorphic type of the form instance. depending on the polymorphic type of the form instance.
This is achieved by overwriting :func:`get_inline_formsets` to return This is achieved by overwriting :func:`get_inline_formsets` to return
an :class:`InlinePolymorphicAdminFormSet` instead of a standard Django an :class:`PolymorphicInlineAdminFormSet` instead of a standard Django
:class:`~django.contrib.admin.helpers.InlineAdminFormSet` for the polymorphic formsets. :class:`~django.contrib.admin.helpers.InlineAdminFormSet` for the polymorphic formsets.
""" """
@ -98,7 +98,7 @@ class PolymorphicInlineSupportMixin(object):
if isinstance(admin_formset.formset, BasePolymorphicModelFormSet): if isinstance(admin_formset.formset, BasePolymorphicModelFormSet):
# This is a polymorphic formset, which belongs to our inline. # This is a polymorphic formset, which belongs to our inline.
# Downcast the admin wrapper that generates the form fields. # Downcast the admin wrapper that generates the form fields.
admin_formset.__class__ = InlinePolymorphicAdminFormSet admin_formset.__class__ = PolymorphicInlineAdminFormSet
admin_formset.request = request admin_formset.request = request
admin_formset.obj = obj admin_formset.obj = obj
return inline_admin_formsets return inline_admin_formsets

View File

@ -13,7 +13,7 @@ from polymorphic.formsets import polymorphic_child_forms_factory, BasePolymorphi
from polymorphic.formsets.utils import add_media from polymorphic.formsets.utils import add_media
class PolymorphicParentInlineModelAdmin(InlineModelAdmin): class PolymorphicInlineModelAdmin(InlineModelAdmin):
""" """
A polymorphic inline, where each formset row can be a different form. A polymorphic inline, where each formset row can be a different form.
@ -30,11 +30,11 @@ class PolymorphicParentInlineModelAdmin(InlineModelAdmin):
extra = 0 extra = 0
#: Inlines for all model sub types that can be displayed in this inline. #: Inlines for all model sub types that can be displayed in this inline.
#: Each row is a :class:`PolymorphicChildInlineModelAdmin` #: Each row is a :class:`PolymorphicInlineModelAdmin.Child`
child_inlines = () child_inlines = ()
def __init__(self, parent_model, admin_site): def __init__(self, parent_model, admin_site):
super(PolymorphicParentInlineModelAdmin, self).__init__(parent_model, admin_site) super(PolymorphicInlineModelAdmin, self).__init__(parent_model, admin_site)
# While the inline is created per request, the 'request' object is not known here. # While the inline is created per request, the 'request' object is not known here.
# Hence, creating all child inlines unconditionally, without checking permissions. # Hence, creating all child inlines unconditionally, without checking permissions.
@ -47,7 +47,7 @@ class PolymorphicParentInlineModelAdmin(InlineModelAdmin):
def get_child_inline_instances(self): def get_child_inline_instances(self):
""" """
:rtype List[PolymorphicChildInlineModelAdmin] :rtype List[PolymorphicInlineModelAdmin.Child]
""" """
instances = [] instances = []
for ChildInlineType in self.child_inlines: for ChildInlineType in self.child_inlines:
@ -58,7 +58,7 @@ class PolymorphicParentInlineModelAdmin(InlineModelAdmin):
""" """
Find the child inline for a given model. Find the child inline for a given model.
:rtype: PolymorphicChildInlineModelAdmin :rtype: PolymorphicInlineModelAdmin.Child
""" """
try: try:
return self._child_inlines_lookup[model] return self._child_inlines_lookup[model]
@ -74,7 +74,7 @@ class PolymorphicParentInlineModelAdmin(InlineModelAdmin):
:rtype: type :rtype: type
""" """
# Construct the FormSet class # Construct the FormSet class
FormSet = super(PolymorphicParentInlineModelAdmin, self).get_formset(request, obj=obj, **kwargs) FormSet = super(PolymorphicInlineModelAdmin, self).get_formset(request, obj=obj, **kwargs)
# Instead of completely redefining super().get_formset(), we use # Instead of completely redefining super().get_formset(), we use
# the regular inlineformset_factory(), and amend that with our extra bits. # the regular inlineformset_factory(), and amend that with our extra bits.
@ -115,7 +115,7 @@ class PolymorphicParentInlineModelAdmin(InlineModelAdmin):
# The media of the inline focuses on the admin settings, # The media of the inline focuses on the admin settings,
# whether to expose the scripts for filter_horizontal etc.. # whether to expose the scripts for filter_horizontal etc..
# The admin helper exposes the inline + formset media. # The admin helper exposes the inline + formset media.
base_media = super(PolymorphicParentInlineModelAdmin, self).media base_media = super(PolymorphicInlineModelAdmin, self).media
all_media = Media() all_media = Media()
add_media(all_media, base_media) add_media(all_media, base_media)
@ -127,10 +127,11 @@ class PolymorphicParentInlineModelAdmin(InlineModelAdmin):
if child_media._css != base_media._css and child_media._js != base_media._js: if child_media._css != base_media._css and child_media._js != base_media._js:
add_media(all_media, child_media) add_media(all_media, child_media)
add_media(all_media, self.polymorphic_media)
return all_media return all_media
class Child(InlineModelAdmin):
class PolymorphicChildInlineModelAdmin(InlineModelAdmin):
""" """
The child inline; which allows configuring the admin options The child inline; which allows configuring the admin options
for the child appearance. for the child appearance.
@ -147,7 +148,7 @@ class PolymorphicChildInlineModelAdmin(InlineModelAdmin):
def __init__(self, parent_inline): def __init__(self, parent_inline):
self.parent_inline = parent_inline self.parent_inline = parent_inline
super(PolymorphicChildInlineModelAdmin, self).__init__(parent_inline.parent_model, parent_inline.admin_site) super(PolymorphicInlineModelAdmin.Child, self).__init__(parent_inline.parent_model, parent_inline.admin_site)
def get_formset(self, request, obj=None, **kwargs): def get_formset(self, request, obj=None, **kwargs):
# The child inline is only used to construct the form, # The child inline is only used to construct the form,
@ -211,3 +212,11 @@ class PolymorphicChildInlineModelAdmin(InlineModelAdmin):
# by passing the inline class attributes to modelform_factory() # by passing the inline class attributes to modelform_factory()
FormSetChildClass = self.formset_child FormSetChildClass = self.formset_child
return FormSetChildClass(self.model, **defaults) return FormSetChildClass(self.model, **defaults)
class StackedPolymorphicInline(PolymorphicInlineModelAdmin):
"""
Stacked inline for django-polymorphic models.
Since tabular doesn't make much sense with changed fields, just offer this one.
"""
template = 'admin/polymorphic/edit_inline/stacked.html'

View File

@ -34,18 +34,18 @@ from .models import (
) )
from .generic import ( from .generic import (
# Can import generic here, as polymorphic already depends on the 'contenttypes' app. # Can import generic here, as polymorphic already depends on the 'contenttypes' app.
BasePolymorphicGenericInlineFormSet, BaseGenericPolymorphicInlineFormSet,
PolymorphicGenericFormSetChild, GenericPolymorphicFormSetChild,
polymorphic_generic_inlineformset_factory, generic_polymorphic_inlineformset_factory,
) )
__all__ = ( __all__ = (
'BasePolymorphicModelFormSet', 'BasePolymorphicModelFormSet',
'BasePolymorphicInlineFormSet', 'BasePolymorphicInlineFormSet',
'BasePolymorphicGenericInlineFormSet',
'PolymorphicFormSetChild', 'PolymorphicFormSetChild',
'PolymorphicGenericFormSetChild',
'polymorphic_inlineformset_factory', 'polymorphic_inlineformset_factory',
'polymorphic_generic_inlineformset_factory',
'polymorphic_child_forms_factory', 'polymorphic_child_forms_factory',
'BaseGenericPolymorphicInlineFormSet',
'GenericPolymorphicFormSetChild',
'generic_polymorphic_inlineformset_factory',
) )

View File

@ -7,14 +7,14 @@ from django.forms.models import ModelForm
from .models import BasePolymorphicModelFormSet, polymorphic_child_forms_factory, PolymorphicFormSetChild from .models import BasePolymorphicModelFormSet, polymorphic_child_forms_factory, PolymorphicFormSetChild
class PolymorphicGenericFormSetChild(PolymorphicFormSetChild): class GenericPolymorphicFormSetChild(PolymorphicFormSetChild):
""" """
Formset child for generic inlines Formset child for generic inlines
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.ct_field = kwargs.pop('ct_field', 'content_type') self.ct_field = kwargs.pop('ct_field', 'content_type')
self.fk_field = kwargs.pop('fk_field', 'object_id') self.fk_field = kwargs.pop('fk_field', 'object_id')
super(PolymorphicGenericFormSetChild, self).__init__(*args, **kwargs) super(GenericPolymorphicFormSetChild, self).__init__(*args, **kwargs)
def get_form(self, ct_field="content_type", fk_field="object_id", **kwargs): def get_form(self, ct_field="content_type", fk_field="object_id", **kwargs):
""" """
@ -42,17 +42,17 @@ class PolymorphicGenericFormSetChild(PolymorphicFormSetChild):
exclude.extend([ct_field.name, fk_field.name]) exclude.extend([ct_field.name, fk_field.name])
kwargs['exclude'] = exclude kwargs['exclude'] = exclude
return super(PolymorphicGenericFormSetChild, self).get_form(**kwargs) return super(GenericPolymorphicFormSetChild, self).get_form(**kwargs)
class BasePolymorphicGenericInlineFormSet(BaseGenericInlineFormSet, BasePolymorphicModelFormSet): class BaseGenericPolymorphicInlineFormSet(BaseGenericInlineFormSet, BasePolymorphicModelFormSet):
""" """
Polymorphic formset variation for inline generic formsets Polymorphic formset variation for inline generic formsets
""" """
def polymorphic_generic_inlineformset_factory(model, formset_children, form=ModelForm, def generic_polymorphic_inlineformset_factory(model, formset_children, form=ModelForm,
formset=BasePolymorphicGenericInlineFormSet, formset=BaseGenericPolymorphicInlineFormSet,
ct_field="content_type", fk_field="object_id", ct_field="content_type", fk_field="object_id",
# Base form # Base form
# TODO: should these fields be removed in favor of creating # TODO: should these fields be removed in favor of creating