From 551e93c47c09b013ba16c3b11d3626db960a6388 Mon Sep 17 00:00:00 2001 From: Diederik van der Boor Date: Sun, 8 Oct 2017 22:21:44 +0200 Subject: [PATCH] Fix support for proxy models in formsets and admin inlines (cherry picked from commit c2768f810157e61e50f4d4c6a3fc6d2835290f92) --- polymorphic/admin/generic.py | 2 +- polymorphic/admin/helpers.py | 2 +- polymorphic/formsets/models.py | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/polymorphic/admin/generic.py b/polymorphic/admin/generic.py index bd3453f..91fc082 100644 --- a/polymorphic/admin/generic.py +++ b/polymorphic/admin/generic.py @@ -42,7 +42,7 @@ class GenericPolymorphicInlineModelAdmin(PolymorphicInlineModelAdmin, GenericInl 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) + 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(), diff --git a/polymorphic/admin/helpers.py b/polymorphic/admin/helpers.py index d7fdef6..52d70ab 100644 --- a/polymorphic/admin/helpers.py +++ b/polymorphic/admin/helpers.py @@ -42,7 +42,7 @@ class PolymorphicInlineAdminFormSet(InlineAdminFormSet): """ for form, original in zip(self.formset.initial_forms, self.formset.get_queryset()): # Output the form - model = original.get_real_concrete_instance_class() + model = original.get_real_instance_class() child_inline = self.opts.get_child_inline_instance(model) view_on_site_url = self.opts.get_view_on_site_url(original) diff --git a/polymorphic/formsets/models.py b/polymorphic/formsets/models.py index 9bac2b1..9c193bd 100644 --- a/polymorphic/formsets/models.py +++ b/polymorphic/formsets/models.py @@ -15,7 +15,6 @@ class UnsupportedChildType(LookupError): pass - class PolymorphicFormSetChild(object): """ Metadata to define the inline of a polymorphic child. @@ -47,7 +46,7 @@ class PolymorphicFormSetChild(object): 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) + return ContentType.objects.get_for_model(self.model, for_concrete_model=False) def get_form(self, **kwargs): """ @@ -162,7 +161,7 @@ class BasePolymorphicModelFormSet(BaseModelFormSet): if self.is_bound: if 'instance' in defaults: # Object is already bound to a model, won't change the content type - model = defaults['instance'].get_real_concrete_instance_class() # respect proxy models + model = defaults['instance'].get_real_instance_class() # allow proxy models else: # Extra or empty form, use the provided type. # Note this completely tru @@ -178,7 +177,7 @@ class BasePolymorphicModelFormSet(BaseModelFormSet): raise UnsupportedChildType("Child model type {0} is not part of the formset".format(model)) else: if 'instance' in defaults: - model = defaults['instance'].get_real_concrete_instance_class() # respect proxy models + model = defaults['instance'].get_real_instance_class() # allow proxy models elif 'polymorphic_ctype' in defaults.get('initial', {}): model = defaults['initial']['polymorphic_ctype'].model_class() elif i < len(self.queryset_data): @@ -197,7 +196,7 @@ class BasePolymorphicModelFormSet(BaseModelFormSet): def add_fields(self, form, index): """Add a hidden field for the content type.""" - ct = ContentType.objects.get_for_model(form._meta.model) + ct = ContentType.objects.get_for_model(form._meta.model, for_concrete_model=False) choices = [(ct.pk, ct)] # Single choice, existing forms can't change the value. form.fields['polymorphic_ctype'] = forms.ChoiceField(choices=choices, initial=ct.pk, required=False, widget=forms.HiddenInput) super(BasePolymorphicModelFormSet, self).add_fields(form, index)