Update documentation
parent
8bce015199
commit
8b50942292
238
docs/admin.rst
238
docs/admin.rst
|
|
@ -4,68 +4,48 @@ Django admin integration
|
||||||
Off course, it's possible to register individual polymorphic models in the Django admin interface.
|
Off course, it's possible to register individual polymorphic models in the Django admin interface.
|
||||||
However, to use these models in a single cohesive interface, some extra base classes are available.
|
However, to use these models in a single cohesive interface, some extra base classes are available.
|
||||||
|
|
||||||
The polymorphic admin interface works in a simple way:
|
Setup
|
||||||
|
-----
|
||||||
* The add screen gains an additional step where the desired child model is selected.
|
|
||||||
* The edit screen displays the admin interface of the child model.
|
|
||||||
* The list screen still displays all objects of the base class.
|
|
||||||
|
|
||||||
The polymorphic admin is implemented via a parent admin that forwards the *edit* and *delete* views
|
|
||||||
to the ``ModelAdmin`` of the derived child model. The *list* page is still implemented by the parent model admin.
|
|
||||||
|
|
||||||
Both the parent model and child model need to have a ``ModelAdmin`` class.
|
Both the parent model and child model need to have a ``ModelAdmin`` class.
|
||||||
|
|
||||||
The parent model
|
The shared base model should use the :class:`~polymorphic.admin.PolymorphicParentModelAdmin` as base class.
|
||||||
----------------
|
|
||||||
|
|
||||||
The parent model needs to inherit ``PolymorphicParentModelAdmin``, and implement the following:
|
* :attr:`~polymorphic.admin.PolymorphicParentModelAdmin.base_model` should be set
|
||||||
|
* :attr:`~polymorphic.admin.PolymorphicParentModelAdmin.child_models` or
|
||||||
|
:meth:`~polymorphic.admin.PolymorphicParentModelAdmin.get_child_models` should return an iterable of Model classes.
|
||||||
|
|
||||||
* ``base_model`` should be set
|
The admin class for every child model should inherit from :class:`~polymorphic.admin.PolymorphicChildModelAdmin`
|
||||||
* ``child_models`` or ``get_child_models()`` should return an iterable of Model classes.
|
|
||||||
|
|
||||||
The exact implementation can depend on the way your module is structured.
|
* :attr:`~polymorphic.admin.PolymorphicChildModelAdmin.base_model` should be set.
|
||||||
For simple inheritance situations, ``child_models`` is the best solution.
|
|
||||||
For large applications, ``get_child_models()`` can be used to query a plugin registration system.
|
|
||||||
|
|
||||||
By default, the non_polymorphic() method will be called on the queryset, so
|
Although the child models are registered too, they won't be shown in the admin index page.
|
||||||
only the Parent model will be provided to the list template. This is to avoid
|
This only happens when :attr:`~polymorphic.admin.PolymorphicChildModelAdmin.show_in_index` is set to ``True``.
|
||||||
the performance hit of retrieving child models.
|
|
||||||
|
|
||||||
This can be controlled by setting the ``polymorphic_list`` property on the
|
Fieldset configuration
|
||||||
parent admin. Setting it to True will provide child models to the list template.
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If you use other applications such as django-reversion_ or django-mptt_, please check +:ref:`third-party`.
|
The parent admin is only used for the list display of models,
|
||||||
|
and for the edit/delete view of non-subclassed models.
|
||||||
|
|
||||||
Note: If you are using non-integer primary keys in your model, you have to edit ``pk_regex``,
|
All other model types are redirected to the edit/delete/history view of the child model admin.
|
||||||
for example ``pk_regex = '([\w-]+)'`` if you use UUIDs. Otherwise you cannot change model entries.
|
Hence, the fieldset configuration should be placed on the child admin.
|
||||||
|
|
||||||
The child models
|
.. tip::
|
||||||
----------------
|
When the child admin is used as base class for various derived classes, avoid using
|
||||||
|
the standard ``ModelAdmin`` attributes ``form`` and ``fieldsets``.
|
||||||
|
Instead, use the ``base_form`` and ``base_fieldsets`` attributes.
|
||||||
|
This allows the :class:`~polymorphic.admin.PolymorphicChildModelAdmin` class
|
||||||
|
to detect any additional fields in case the child model is overwritten.
|
||||||
|
|
||||||
The admin interface of the derived models should inherit from ``PolymorphicChildModelAdmin``.
|
.. versionchanged:: 1.0
|
||||||
Again, ``base_model`` should be set in this class as well.
|
It's now needed to register the child model classes too.
|
||||||
This class implements the following features:
|
|
||||||
|
|
||||||
* It corrects the breadcrumbs in the admin pages.
|
|
||||||
* It extends the template lookup paths, to look for both the parent model and child model in the ``admin/app/model/change_form.html`` path.
|
|
||||||
* It allows to set ``base_form`` so the derived class will automatically include other fields in the form.
|
|
||||||
* It allows to set ``base_fieldsets`` so the derived class will automatically display any extra fields.
|
|
||||||
* Although it must be registered with admin site, by default it's hidden from admin site index page.
|
|
||||||
This can be overriden by adding ``show_in_index = True`` in admin class.
|
|
||||||
|
|
||||||
The standard ``ModelAdmin`` attributes ``form`` and ``fieldsets`` should rather be avoided at the base class,
|
|
||||||
because it will hide any additional fields which are defined in the derived model. Instead,
|
|
||||||
use the ``base_form`` and ``base_fieldsets`` instead. The ``PolymorphicChildModelAdmin`` will
|
|
||||||
automatically detect the additional fields that the child model has, display those in a separate fieldset.
|
|
||||||
|
|
||||||
|
|
||||||
Using polymorphic models in standard inlines
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
To add a polymorphic child model as an Inline for another model, add a field to the inline's ``readonly_fields`` list
|
|
||||||
formed by the lowercased name of the polymorphic parent model with the string ``_ptr`` appended to it.
|
|
||||||
Otherwise, trying to save that model in the admin will raise an AttributeError with the message "can't set attribute".
|
|
||||||
|
|
||||||
|
In *django-polymorphic* 0.9 and below, the ``child_models`` was a tuple of a ``(Model, ChildModelAdmin)``.
|
||||||
|
The admin classes were registered in an internal class, and kept away from the main admin site.
|
||||||
|
This caused various subtle problems with the ``ManyToManyField`` and related field wrappers,
|
||||||
|
which are fixed by registering the child admin classes too. Note that they are hidden from
|
||||||
|
the main view, unless :attr:`~polymorphic.admin.PolymorphicChildModelAdmin.show_in_index` is set.
|
||||||
|
|
||||||
.. _admin-example:
|
.. _admin-example:
|
||||||
|
|
||||||
|
|
@ -93,17 +73,20 @@ The models are taken from :ref:`advanced-features`.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(ModelB)
|
||||||
class ModelBAdmin(ModelAChildAdmin):
|
class ModelBAdmin(ModelAChildAdmin):
|
||||||
base_model = ModelB
|
base_model = ModelB
|
||||||
# define custom features here
|
# define custom features here
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(ModelC)
|
||||||
class ModelCAdmin(ModelBAdmin):
|
class ModelCAdmin(ModelBAdmin):
|
||||||
base_model = ModelC
|
base_model = ModelC
|
||||||
show_in_index = True # makes child model admin visible in main admin site
|
show_in_index = True # makes child model admin visible in main admin site
|
||||||
# define custom features here
|
# define custom features here
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(ModelA)
|
||||||
class ModelAParentAdmin(PolymorphicParentModelAdmin):
|
class ModelAParentAdmin(PolymorphicParentModelAdmin):
|
||||||
""" The parent model admin """
|
""" The parent model admin """
|
||||||
base_model = ModelA
|
base_model = ModelA
|
||||||
|
|
@ -111,22 +94,6 @@ The models are taken from :ref:`advanced-features`.
|
||||||
list_filter = (PolymorphicChildModelFilter,) # This is optional.
|
list_filter = (PolymorphicChildModelFilter,) # This is optional.
|
||||||
|
|
||||||
|
|
||||||
class ModelBInline(admin.StackedInline):
|
|
||||||
model = ModelB
|
|
||||||
fk_name = 'modelb'
|
|
||||||
readonly_fields = ['modela_ptr']
|
|
||||||
|
|
||||||
|
|
||||||
class StandardModelAdmin(admin.ModelAdmin):
|
|
||||||
inlines = [ModelBInline]
|
|
||||||
|
|
||||||
|
|
||||||
# Only the parent needs to be registered:
|
|
||||||
admin.site.register(ModelA, ModelAParentAdmin)
|
|
||||||
admin.site.register(ModelB, ModelBAdmin)
|
|
||||||
admin.site.register(ModelC, ModelCAdmin)
|
|
||||||
admin.site.register(StandardModel, StandardModelAdmin)
|
|
||||||
|
|
||||||
|
|
||||||
Filtering child types
|
Filtering child types
|
||||||
---------------------
|
---------------------
|
||||||
|
|
@ -134,5 +101,146 @@ Filtering child types
|
||||||
Child model types can be filtered by adding a :class:`~polymorphic.admin.PolymorphicChildModelFilter`
|
Child model types can be filtered by adding a :class:`~polymorphic.admin.PolymorphicChildModelFilter`
|
||||||
to the ``list_filter`` attribute. See the example above.
|
to the ``list_filter`` attribute. See the example above.
|
||||||
|
|
||||||
|
|
||||||
|
Inline models
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. versionadded:: 1.0
|
||||||
|
|
||||||
|
Inline models are handled via a special :class:`~polymorphic.admin.StackedPolymorphicInline` class.
|
||||||
|
|
||||||
|
For models with a generic foreign key, there is a :class:`~polymorphic.admin.GenericStackedPolymorphicInline` class available.
|
||||||
|
|
||||||
|
When the inline is included to a normal :class:`~django.contrib.admin.ModelAdmin`,
|
||||||
|
make sure the :class:`~polymorphic.admin.PolymorphicInlineSupportMixin` is included.
|
||||||
|
This is not needed when the admin inherits from the
|
||||||
|
:class:`~polymorphic.admin.PolymorphicParentModelAdmin` /
|
||||||
|
:class:`~polymorphic.admin.PolymorphicChildModelAdmin` classes.
|
||||||
|
|
||||||
|
In the following example, the ``PaymentInline`` supports several types.
|
||||||
|
These are defined as separate inline classes.
|
||||||
|
The child classes can be nested for clarity, but this is not a requirement.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from polymorphic.admin import PolymorphicInlineSupportMixin, StackedPolymorphicInline
|
||||||
|
from .models import Order, Payment, CreditCardPayment, BankPayment, SepaPayment
|
||||||
|
|
||||||
|
|
||||||
|
class PaymentInline(StackedPolymorphicInline):
|
||||||
|
"""
|
||||||
|
An inline for a polymorphic model.
|
||||||
|
The actual form appearance of each row is determined by
|
||||||
|
the child inline that corresponds with the actual model type.
|
||||||
|
"""
|
||||||
|
class CreditCardPaymentInline(StackedPolymorphicInline.Child):
|
||||||
|
model = CreditCardPayment
|
||||||
|
|
||||||
|
class BankPaymentInline(StackedPolymorphicInline.Child):
|
||||||
|
model = BankPayment
|
||||||
|
|
||||||
|
class SepaPaymentInline(StackedPolymorphicInline.Child):
|
||||||
|
model = SepaPayment
|
||||||
|
|
||||||
|
model = Payment
|
||||||
|
child_inlines = (
|
||||||
|
CreditCardPaymentInline,
|
||||||
|
BankPaymentInline,
|
||||||
|
SepaPaymentInline,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Order)
|
||||||
|
class OrderAdmin(PolymorphicInlineSupportMixin, admin.ModelAdmin):
|
||||||
|
"""
|
||||||
|
Admin for orders.
|
||||||
|
The inline is polymorphic.
|
||||||
|
To make sure the inlines are properly handled,
|
||||||
|
the ``PolymorphicInlineSupportMixin`` is needed to
|
||||||
|
"""
|
||||||
|
inlines = (PaymentInline,)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Using polymorphic models in standard inlines
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
To add a polymorphic child model as an Inline for another model, add a field to the inline's ``readonly_fields`` list
|
||||||
|
formed by the lowercased name of the polymorphic parent model with the string ``_ptr`` appended to it.
|
||||||
|
Otherwise, trying to save that model in the admin will raise an AttributeError with the message "can't set attribute".
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
from .models import StandardModel
|
||||||
|
|
||||||
|
|
||||||
|
class ModelBInline(admin.StackedInline):
|
||||||
|
model = ModelB
|
||||||
|
fk_name = 'modelb'
|
||||||
|
readonly_fields = ['modela_ptr']
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(StandardModel)
|
||||||
|
class StandardModelAdmin(admin.ModelAdmin):
|
||||||
|
inlines = [ModelBInline]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Internal details
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The polymorphic admin interface works in a simple way:
|
||||||
|
|
||||||
|
* The add screen gains an additional step where the desired child model is selected.
|
||||||
|
* The edit screen displays the admin interface of the child model.
|
||||||
|
* The list screen still displays all objects of the base class.
|
||||||
|
|
||||||
|
The polymorphic admin is implemented via a parent admin that redirects the *edit* and *delete* views
|
||||||
|
to the ``ModelAdmin`` of the derived child model. The *list* page is still implemented by the parent model admin.
|
||||||
|
|
||||||
|
The parent model
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The parent model needs to inherit :class:`~polymorphic.admin.PolymorphicParentModelAdmin`, and implement the following:
|
||||||
|
|
||||||
|
* :attr:`~polymorphic.admin.PolymorphicParentModelAdmin.base_model` should be set
|
||||||
|
* :attr:`~polymorphic.admin.PolymorphicParentModelAdmin.child_models` or
|
||||||
|
:meth:`~polymorphic.admin.PolymorphicParentModelAdmin.get_child_models` should return an iterable of Model classes.
|
||||||
|
|
||||||
|
The exact implementation can depend on the way your module is structured.
|
||||||
|
For simple inheritance situations, ``child_models`` is the best solution.
|
||||||
|
For large applications, ``get_child_models()`` can be used to query a plugin registration system.
|
||||||
|
|
||||||
|
By default, the non_polymorphic() method will be called on the queryset, so
|
||||||
|
only the Parent model will be provided to the list template. This is to avoid
|
||||||
|
the performance hit of retrieving child models.
|
||||||
|
|
||||||
|
This can be controlled by setting the ``polymorphic_list`` property on the
|
||||||
|
parent admin. Setting it to True will provide child models to the list template.
|
||||||
|
|
||||||
|
If you use other applications such as django-reversion_ or django-mptt_, please check +:ref:`third-party`.
|
||||||
|
|
||||||
|
Note: If you are using non-integer primary keys in your model, you have to edit ``pk_regex``,
|
||||||
|
for example ``pk_regex = '([\w-]+)'`` if you use UUIDs. Otherwise you cannot change model entries.
|
||||||
|
|
||||||
|
The child models
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The admin interface of the derived models should inherit from :class:`~polymorphic.admin.PolymorphicChildModelAdmin`.
|
||||||
|
Again, :attr:`~polymorphic.admin.PolymorphicChildModelAdmin.base_model` should be set in this class as well.
|
||||||
|
This class implements the following features:
|
||||||
|
|
||||||
|
* It corrects the breadcrumbs in the admin pages.
|
||||||
|
* It extends the template lookup paths, to look for both the parent model and child model in the ``admin/app/model/change_form.html`` path.
|
||||||
|
* It allows to set :attr:`~polymorphic.admin.PolymorphicChildModelAdmin.base_form` so the derived class will automatically include other fields in the form.
|
||||||
|
* It allows to set :attr:`~polymorphic.admin.PolymorphicChildModelAdmin.base_fieldsets` so the derived class will automatically display any extra fields.
|
||||||
|
* Although it must be registered with admin site, by default it's hidden from admin site index page.
|
||||||
|
This can be overriden by adding :attr:`~polymorphic.admin.PolymorphicChildModelAdmin.show_in_index` = ``True`` in admin class.
|
||||||
|
|
||||||
|
|
||||||
.. _django-reversion: https://github.com/etianen/django-reversion
|
.. _django-reversion: https://github.com/etianen/django-reversion
|
||||||
.. _django-mptt: https://github.com/django-mptt/django-mptt
|
.. _django-mptt: https://github.com/django-mptt/django-mptt
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,6 @@ It supports Django 1.1 up till 1.4 and Python 2.4 up till 2.7.
|
||||||
For a detailed list of it's changes, see the :doc:`archived changelog <changelog_archive>`.
|
For a detailed list of it's changes, see the :doc:`archived changelog <changelog_archive>`.
|
||||||
|
|
||||||
.. _Grappelli: http://grappelliproject.com/
|
.. _Grappelli: http://grappelliproject.com/
|
||||||
.. _django-parler: https://github.com/edoburu/django-parler
|
.. _django-parler: https://github.com/django-parler/django-parler
|
||||||
.. _django-reversion: https://github.com/etianen/django-reversion
|
.. _django-reversion: https://github.com/etianen/django-reversion
|
||||||
.. _django-reversion-compare: https://github.com/jedie/django-reversion-compare
|
.. _django-reversion-compare: https://github.com/jedie/django-reversion-compare
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,44 @@
|
||||||
Formsets
|
Formsets
|
||||||
========
|
========
|
||||||
|
|
||||||
|
.. versionadded:: 1.0
|
||||||
|
|
||||||
Polymorphic models can be used in formsets.
|
Polymorphic models can be used in formsets.
|
||||||
|
|
||||||
Use the :func:`polymorphic.formsets.polymorphic_inlineformset_factory` function to generate the formset.
|
The implementation is almost identical to the regular Django formsets.
|
||||||
As extra parameter, the factory needs to know how to display the child models.
|
As extra parameter, the factory needs to know how to display the child models.
|
||||||
Provide a list of :class:`polymorphic.formsets.PolymorphicFormSetChild` objects for this
|
Provide a list of :class:`~polymorphic.formsets.PolymorphicFormSetChild` objects for this.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
from polymorphic.formsets import polymorphic_child_forms_factory
|
from polymorphic.formsets import polymorphic_modelformset_factory, PolymorphicFormSetChild
|
||||||
|
|
||||||
|
ModelAFormSet = polymorphic_modelformset_factory(ModelA, formset_children=(
|
||||||
|
PolymorphicFormSetChild(ModelB),
|
||||||
|
PolymorphicFormSetChild(ModelC),
|
||||||
|
))
|
||||||
|
|
||||||
|
The formset can be used just like all other formsets:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
if request.method == "POST":
|
||||||
|
formset = ModelAFormSet(request.POST, request.FILES, queryset=ModelA.objects.all())
|
||||||
|
if formset.is_valid():
|
||||||
|
formset.save()
|
||||||
|
else:
|
||||||
|
formset = ModelAFormSet(queryset=ModelA.objects.all())
|
||||||
|
|
||||||
|
Like standard Django formsets, there are 3 factory methods available:
|
||||||
|
|
||||||
|
* :func:`~polymorphic.formsets.polymorphic_modelformset_factory` - create a regular model formset.
|
||||||
|
* :func:`~polymorphic.formsets.polymorphic_inlineformset_factory` - create a inline model formset.
|
||||||
|
* :func:`~polymorphic.formsets.generic_polymorphic_inlineformset_factory` - create an inline formset for a generic foreign key.
|
||||||
|
|
||||||
|
Each one uses a different base class:
|
||||||
|
|
||||||
|
* :class:`~polymorphic.formsets.BasePolymorphicModelFormSet`
|
||||||
|
* :class:`~polymorphic.formsets.BasePolymorphicInlineFormSet`
|
||||||
|
* :class:`~polymorphic.formsets.BaseGenericPolymorphicInlineFormSet`
|
||||||
|
|
||||||
|
When needed, the base class can be overwritten and provided to the factory via the ``formset`` parameter.
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,6 @@ Getting started
|
||||||
|
|
||||||
quickstart
|
quickstart
|
||||||
admin
|
admin
|
||||||
formsets
|
|
||||||
performance
|
performance
|
||||||
|
|
||||||
Advanced topics
|
Advanced topics
|
||||||
|
|
@ -64,9 +63,10 @@ Advanced topics
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
|
formsets
|
||||||
migrating
|
migrating
|
||||||
advanced
|
|
||||||
managers
|
managers
|
||||||
|
advanced
|
||||||
third-party
|
third-party
|
||||||
changelog
|
changelog
|
||||||
contributing
|
contributing
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,24 @@
|
||||||
Third-party applications support
|
Third-party applications support
|
||||||
================================
|
================================
|
||||||
|
|
||||||
|
|
||||||
|
django-mptt support
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Combining polymorphic with django-mptt_ is certainly possible, but not straightforward.
|
||||||
|
It involves combining both managers, querysets, models, meta-classes and admin classes
|
||||||
|
using multiple inheritance.
|
||||||
|
|
||||||
|
The django-polymorphic-tree_ package provides this out of the box.
|
||||||
|
|
||||||
|
|
||||||
django-reversion support
|
django-reversion support
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
Support for django-reversion_ works as expected with polymorphic models.
|
Support for django-reversion_ works as expected with polymorphic models.
|
||||||
However, they require more setup than standard models. That's become:
|
However, they require more setup than standard models. That's become:
|
||||||
|
|
||||||
* The children models are not registered in the admin site.
|
* Manually register the child models with django-reversion_, so their ``follow`` parameter can be set.
|
||||||
You will therefore need to manually register them to django-reversion_.
|
|
||||||
* Polymorphic models use `multi-table inheritance <https://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance>`_.
|
* Polymorphic models use `multi-table inheritance <https://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance>`_.
|
||||||
See the `reversion documentation <https://django-reversion.readthedocs.io/en/latest/api.html#multi-table-inheritance>`_
|
See the `reversion documentation <https://django-reversion.readthedocs.io/en/latest/api.html#multi-table-inheritance>`_
|
||||||
how to deal with this by adding a ``follow`` field for the primary key.
|
how to deal with this by adding a ``follow`` field for the primary key.
|
||||||
|
|
@ -87,17 +97,7 @@ This doesn't work, since it needs to look for revisions of the child model. Usin
|
||||||
the view of the actual child model is used, similar to the way the regular change and delete views are redirected.
|
the view of the actual child model is used, similar to the way the regular change and delete views are redirected.
|
||||||
|
|
||||||
|
|
||||||
django-mptt support
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Combining polymorphic with django-mptt_ is certainly possible, but not straightforward.
|
|
||||||
It involves combining both managers, querysets, models, meta-classes and admin classes
|
|
||||||
using multiple inheritance.
|
|
||||||
|
|
||||||
The django-polymorphic-tree_ package provides this out of the box.
|
|
||||||
|
|
||||||
|
|
||||||
.. _django-reversion: https://github.com/etianen/django-reversion
|
.. _django-reversion: https://github.com/etianen/django-reversion
|
||||||
.. _django-reversion-compare: https://github.com/jedie/django-reversion-compare
|
.. _django-reversion-compare: https://github.com/jedie/django-reversion-compare
|
||||||
.. _django-mptt: https://github.com/django-mptt/django-mptt
|
.. _django-mptt: https://github.com/django-mptt/django-mptt
|
||||||
.. _django-polymorphic-tree: https://github.com/edoburu/django-polymorphic-tree
|
.. _django-polymorphic-tree: https://github.com/django-polymorphic/django-polymorphic-tree
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue