Merge pull request #44 from BertrandBordage/master
Grappelli support & django-reversion support documentation.fix_request_path_info
commit
cdc9b16aa8
|
|
@ -46,13 +46,18 @@ use the ``base_form`` and ``base_fieldsets`` instead. The ``PolymorphicChildMode
|
||||||
automatically detect the additional fields that the child model has, display those in a separate fieldset.
|
automatically detect the additional fields that the child model has, display those in a separate fieldset.
|
||||||
|
|
||||||
|
|
||||||
|
.. _admin-example:
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
The models are taken from :ref:`advanced-features`.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin
|
from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin
|
||||||
|
from .models import ModelA, ModelB, ModelC
|
||||||
|
|
||||||
|
|
||||||
class ModelAChildAdmin(PolymorphicChildModelAdmin):
|
class ModelAChildAdmin(PolymorphicChildModelAdmin):
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
|
.. _advanced-features:
|
||||||
|
|
||||||
Advanced features
|
Advanced features
|
||||||
=================
|
=================
|
||||||
|
|
||||||
In the examples below, these models are being used::
|
In the examples below, these models are being used::
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
from polymorphic import PolymorphicModel
|
from polymorphic import PolymorphicModel
|
||||||
|
|
||||||
class ModelA(PolymorphicModel):
|
class ModelA(PolymorphicModel):
|
||||||
|
|
@ -99,7 +102,7 @@ model as the root of a polymorphic inheritance tree::
|
||||||
|
|
||||||
from thirdparty import ThirdPartyModel
|
from thirdparty import ThirdPartyModel
|
||||||
|
|
||||||
class MyThirdPartyBaseModel(PolymorhpicModel, ThirdPartyModel):
|
class MyThirdPartyBaseModel(PolymorphicModel, ThirdPartyModel):
|
||||||
pass # or add fields
|
pass # or add fields
|
||||||
|
|
||||||
Or instead integrating the third party model anywhere into an
|
Or instead integrating the third party model anywhere into an
|
||||||
|
|
@ -181,7 +184,7 @@ Using enhanced Q-objects in any Places
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
The queryset enhancements (e.g. ``instance_of``) only work as arguments
|
The queryset enhancements (e.g. ``instance_of``) only work as arguments
|
||||||
to the member functions of a polymorphic queryset. Occationally it may
|
to the member functions of a polymorphic queryset. Occasionally it may
|
||||||
be useful to be able to use Q objects with these enhancements in other places.
|
be useful to be able to use Q objects with these enhancements in other places.
|
||||||
As Django doesn't understand these enhanced Q objects, you need to
|
As Django doesn't understand these enhanced Q objects, you need to
|
||||||
transform them manually into normal Q objects before you can feed them
|
transform them manually into normal Q objects before you can feed them
|
||||||
|
|
|
||||||
|
|
@ -27,17 +27,17 @@ Using vanilla Django, we get the base class objects, which is rarely what we wan
|
||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
|
|
||||||
* Full admin integation.
|
* Full admin integration.
|
||||||
* ORM integration:
|
* ORM integration:
|
||||||
|
|
||||||
* support for ForeignKey, ManyToManyField, OneToOneField descriptors.
|
* Support for ForeignKey, ManyToManyField, OneToOneField descriptors.
|
||||||
* support for proxy models
|
* Support for proxy models.
|
||||||
* Filtering/ordering of inherited models (``ArtProject___artist``).
|
* Filtering/ordering of inherited models (``ArtProject___artist``).
|
||||||
* Filtering model types: ``instance_of(...)`` and ``not_instance_of(...)``
|
* Filtering model types: ``instance_of(...)`` and ``not_instance_of(...)``
|
||||||
* Combining querysets of different models (``qs3 = qs1 | qs2``)
|
* Combining querysets of different models (``qs3 = qs1 | qs2``)
|
||||||
* Support for custom user-defined managers.
|
* Support for custom user-defined managers.
|
||||||
|
|
||||||
* Uses the minumum amount of queries needed to fetch the inherited models.
|
* Uses the minimum amount of queries needed to fetch the inherited models.
|
||||||
* Disabling polymorphic behavior when needed.
|
* Disabling polymorphic behavior when needed.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -59,6 +59,7 @@ Advanced topics
|
||||||
|
|
||||||
advanced
|
advanced
|
||||||
managers
|
managers
|
||||||
|
third-party
|
||||||
changelog
|
changelog
|
||||||
contributing
|
contributing
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
Custom Managers, Querysets & Manager Inheritance
|
Custom Managers, Querysets & Manager Inheritance
|
||||||
================================================
|
================================================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
Third-party applications support
|
||||||
|
================================
|
||||||
|
|
||||||
|
Django-reversion support
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
`Django-reversion <https://github.com/etianen/django-reversion>`_ works as
|
||||||
|
expected with polymorphic models. However, they require more setup than
|
||||||
|
standard models. We have to face these problems:
|
||||||
|
|
||||||
|
* The children models are not registered in the admin site.
|
||||||
|
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>`_.
|
||||||
|
The django-reversion wiki explains
|
||||||
|
`how to deal with this <https://github.com/etianen/django-reversion/wiki/Low-level-API#multi-table-inheritance>`_.
|
||||||
|
|
||||||
|
|
||||||
|
Example
|
||||||
|
.......
|
||||||
|
|
||||||
|
The admin :ref:`admin-example` becomes:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin
|
||||||
|
import reversion
|
||||||
|
from reversion import VersionAdmin
|
||||||
|
from .models import ModelA, ModelB, ModelC
|
||||||
|
|
||||||
|
|
||||||
|
class ModelAChildAdmin(PolymorphicChildModelAdmin):
|
||||||
|
base_model = ModelA
|
||||||
|
base_form = ...
|
||||||
|
base_fieldsets = (
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
|
class ModelBAdmin(VersionAdmin, ModelAChildAdmin):
|
||||||
|
# define custom features here
|
||||||
|
|
||||||
|
class ModelCAdmin(ModelBAdmin):
|
||||||
|
# define custom features here
|
||||||
|
|
||||||
|
|
||||||
|
class ModelAParentAdmin(VersionAdmin, PolymorphicParentModelAdmin):
|
||||||
|
base_model = ModelA
|
||||||
|
child_models = (
|
||||||
|
(ModelB, ModelBAdmin),
|
||||||
|
(ModelC, ModelCAdmin),
|
||||||
|
)
|
||||||
|
|
||||||
|
reversion.register(ModelB, follow=['modela_ptr'])
|
||||||
|
reversion.register(ModelC, follow=['modelb_ptr'])
|
||||||
|
admin.site.register(ModelA, ModelAParentAdmin)
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
{% extends "admin/change_form.html" %}
|
{% extends "admin/change_form.html" %}
|
||||||
{% load i18n polymorphic_admin_tags %}
|
{% load polymorphic_admin_tags %}
|
||||||
|
|
||||||
{# fix breadcrumb #}
|
{% block breadcrumbs %}
|
||||||
{% block breadcrumbs %}{% if not is_popup %}{% breadcrumb_scope base_opts %}
|
{% breadcrumb_scope base_opts %}{{ block.super }}{% endbreadcrumb_scope %}
|
||||||
<div class="breadcrumbs">
|
{% endblock %}
|
||||||
<a href="../../../">{% trans "Home" %}</a> ›
|
|
||||||
<a href="../../">{{ app_label|capfirst|escape }}</a> ›
|
|
||||||
{% if has_change_permission %}<a href="../">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %} ›
|
|
||||||
{% if add %}{% trans "Add" %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endbreadcrumb_scope %}{% endif %}{% endblock %}
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
{% extends "admin/delete_confirmation.html" %}
|
{% extends "admin/delete_confirmation.html" %}
|
||||||
{% load i18n polymorphic_admin_tags %}
|
{% load polymorphic_admin_tags %}
|
||||||
|
|
||||||
{% block breadcrumbs %}{% breadcrumb_scope base_opts %}
|
{% block breadcrumbs %}
|
||||||
<div class="breadcrumbs">
|
{% breadcrumb_scope base_opts %}{{ block.super }}{% endbreadcrumb_scope %}
|
||||||
<a href="../../../../">{% trans "Home" %}</a> ›
|
{% endblock %}
|
||||||
<a href="../../../">{{ app_label|capfirst|escape }}</a> ›
|
|
||||||
<a href="../../">{{ opts.verbose_name_plural|capfirst }}</a> ›
|
|
||||||
<a href="../">{{ object|truncatewords:"18" }}</a> ›
|
|
||||||
{% trans 'Delete' %}
|
|
||||||
</div>
|
|
||||||
{% endbreadcrumb_scope %}{% endblock %}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue