commit
757deb302d
56
README.md
56
README.md
|
|
@ -155,6 +155,8 @@ admin.site.register(Category, SortableAdmin)
|
||||||
admin.site.register(Project, SortableAdmin)
|
admin.site.register(Project, SortableAdmin)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Sortable Model With Non-Sortable Parent
|
||||||
|
|
||||||
Sometimes you might have a parent model that is not sortable, but has child models that are. In that case define your models and admin options as such:
|
Sometimes you might have a parent model that is not sortable, but has child models that are. In that case define your models and admin options as such:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
@ -198,6 +200,60 @@ admin.site.register(Category, CategoryAdmin)
|
||||||
|
|
||||||
The `NonSortableParentAdmin` class is necessary to wire up the additional URL patterns and JavaScript that Django Admin Sortable needs to make your models sortable. The child model does not have to be an inline model, it can be wired directly to Django admin and the objects will be grouped by the non-sortable foreign key when sorting.
|
The `NonSortableParentAdmin` class is necessary to wire up the additional URL patterns and JavaScript that Django Admin Sortable needs to make your models sortable. The child model does not have to be an inline model, it can be wired directly to Django admin and the objects will be grouped by the non-sortable foreign key when sorting.
|
||||||
|
|
||||||
|
#### Sortable Many-to-Many Model
|
||||||
|
|
||||||
|
It is also possible to make many-to-many relations sortable, but it requires an explicit many-to-many model.
|
||||||
|
|
||||||
|
`models.py`:
|
||||||
|
```python
|
||||||
|
from django.db import models
|
||||||
|
from adminsortable.models import SortableMixin
|
||||||
|
from adminsortable.fields import SortableForeignKey
|
||||||
|
|
||||||
|
class Image(models.Model):
|
||||||
|
...
|
||||||
|
|
||||||
|
class Gallery(models.Model):
|
||||||
|
class Meta:
|
||||||
|
verbose_name_plural = 'Galleries'
|
||||||
|
...
|
||||||
|
images = models.ManyToManyField(
|
||||||
|
Image,
|
||||||
|
through_fields=('gallery', 'image'),
|
||||||
|
through='GalleryImageRelation',
|
||||||
|
verbose_name=_('Images')
|
||||||
|
)
|
||||||
|
|
||||||
|
class GalleryImageRelation(SortableMixin):
|
||||||
|
"""Many to many relation that allows users to sort images in galleries"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['image_order']
|
||||||
|
|
||||||
|
gallery = models.ForeignKey(Gallery, verbose_name=_("Gallery"))
|
||||||
|
image = SortableForeignKey(Image, verbose_name=_("Image"))
|
||||||
|
image_order = models.PositiveIntegerField(default=0, editable=False, db_index=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
`admin.py`:
|
||||||
|
```python
|
||||||
|
from django.contrib import admin
|
||||||
|
from adminsortable.admin import (SortableAdmin, SortableTabularInline)
|
||||||
|
from .models import (Image, Gallery, GalleryImageRelation)
|
||||||
|
|
||||||
|
class GalleryImageRelationInlineAdmin(SortableTabularInline):
|
||||||
|
model = GalleryImageRelation
|
||||||
|
extra = 1
|
||||||
|
|
||||||
|
class GalleryAdmin(NonSortableParentAdmin):
|
||||||
|
inlines = (GalleryImageRelationInlineAdmin,)
|
||||||
|
|
||||||
|
admin.site.register(Image, admin.ModelAdmin)
|
||||||
|
admin.site.register(Gallery, GalleryAdmin)
|
||||||
|
```
|
||||||
|
|
||||||
|
Any non-editable space in each rendered inline will let you drag and drop them into order.
|
||||||
|
|
||||||
|
|
||||||
### Backwards Compatibility
|
### Backwards Compatibility
|
||||||
If you previously used Django Admin Sortable, **DON'T PANIC** - everything will still work exactly as before ***without any changes to your code***. Going forward, it is recommended that you use the new `SortableMixin` on your models, as pre-2.0 compatibility might not be a permanent thing.
|
If you previously used Django Admin Sortable, **DON'T PANIC** - everything will still work exactly as before ***without any changes to your code***. Going forward, it is recommended that you use the new `SortableMixin` on your models, as pre-2.0 compatibility might not be a permanent thing.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ Quickstart
|
||||||
|
|
||||||
To get started using ``django-admin-sortable`` simply install it using ``pip``::
|
To get started using ``django-admin-sortable`` simply install it using ``pip``::
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
$ pip install django-admin-sortable
|
$ pip install django-admin-sortable
|
||||||
|
|
||||||
Add ``adminsortable`` to your project's ``INSTALLED_APPS`` setting.
|
Add ``adminsortable`` to your project's ``INSTALLED_APPS`` setting.
|
||||||
|
|
@ -11,6 +13,8 @@ Ensure ``django.core.context_processors.static`` is in your ``TEMPLATE_CONTEXT_P
|
||||||
|
|
||||||
Define your model, inheriting from ``adminsortable.Sortable``::
|
Define your model, inheriting from ``adminsortable.Sortable``::
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
# models.py
|
# models.py
|
||||||
from adminsortable.models import Sortable
|
from adminsortable.models import Sortable
|
||||||
|
|
||||||
|
|
@ -25,6 +29,8 @@ Define your model, inheriting from ``adminsortable.Sortable``::
|
||||||
|
|
||||||
Wire up your sortable model to Django admin::
|
Wire up your sortable model to Django admin::
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
# admin.py
|
# admin.py
|
||||||
from adminsortable.admin import SortableAdmin
|
from adminsortable.admin import SortableAdmin
|
||||||
from .models import MySortableClass
|
from .models import MySortableClass
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,6 @@ Inlines may be drag-and-dropped into any order directly from the change form.
|
||||||
|
|
||||||
Unit and functional tests may be found in the ``app/tests.py`` file and run via:
|
Unit and functional tests may be found in the ``app/tests.py`` file and run via:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
$ python manage.py test app
|
$ python manage.py test app
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ Using Django Admin Sortable
|
||||||
Models
|
Models
|
||||||
------
|
------
|
||||||
|
|
||||||
To add sorting to a model, your model needs to inherit from ``Sortable`` and have an inner ``Meta`` class that inherits from ``Sortable.Meta``::
|
To add sorting to a model, your model needs to inherit from ``SortableMixin`` and at minimum, define an inner ``Meta.ordering`` value
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
# models.py
|
# models.py
|
||||||
from adminsortable.models import Sortable
|
from adminsortable.models import Sortable
|
||||||
|
|
@ -22,7 +24,7 @@ It is also possible to order objects relative to another object that is a Foreig
|
||||||
|
|
||||||
.. note:: A small caveat here is that ``Category`` must also either inherit from ``Sortable`` or include an ``order`` property which is a ``PositiveSmallInteger`` field. This is due to the way Django admin instantiates classes.
|
.. note:: A small caveat here is that ``Category`` must also either inherit from ``Sortable`` or include an ``order`` property which is a ``PositiveSmallInteger`` field. This is due to the way Django admin instantiates classes.
|
||||||
|
|
||||||
::
|
.. code-block:: python
|
||||||
|
|
||||||
# models.py
|
# models.py
|
||||||
from adminsortable.fields import SortableForeignKey
|
from adminsortable.fields import SortableForeignKey
|
||||||
|
|
@ -53,6 +55,8 @@ If you're adding Sorting to an existing model, it is recommended that you use `d
|
||||||
|
|
||||||
Example assuming a model named "Category"::
|
Example assuming a model named "Category"::
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
def forwards(self, orm):
|
def forwards(self, orm):
|
||||||
for index, category in enumerate(orm.Category.objects.all()):
|
for index, category in enumerate(orm.Category.objects.all()):
|
||||||
category.order = index + 1
|
category.order = index + 1
|
||||||
|
|
@ -65,6 +69,8 @@ Django Admin
|
||||||
|
|
||||||
To enable sorting in the admin, you need to inherit from ``SortableAdmin``::
|
To enable sorting in the admin, you need to inherit from ``SortableAdmin``::
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from myapp.models import MySortableClass
|
from myapp.models import MySortableClass
|
||||||
from adminsortable.admin import SortableAdmin
|
from adminsortable.admin import SortableAdmin
|
||||||
|
|
@ -76,6 +82,8 @@ To enable sorting in the admin, you need to inherit from ``SortableAdmin``::
|
||||||
|
|
||||||
To enable sorting on TabularInline models, you need to inherit from SortableTabularInline::
|
To enable sorting on TabularInline models, you need to inherit from SortableTabularInline::
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
from adminsortable.admin import SortableTabularInline
|
from adminsortable.admin import SortableTabularInline
|
||||||
|
|
||||||
class MySortableTabularInline(SortableTabularInline):
|
class MySortableTabularInline(SortableTabularInline):
|
||||||
|
|
@ -83,6 +91,8 @@ To enable sorting on TabularInline models, you need to inherit from SortableTabu
|
||||||
|
|
||||||
To enable sorting on StackedInline models, you need to inherit from SortableStackedInline::
|
To enable sorting on StackedInline models, you need to inherit from SortableStackedInline::
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
from adminsortable.admin import SortableStackedInline
|
from adminsortable.admin import SortableStackedInline
|
||||||
|
|
||||||
class MySortableStackedInline(SortableStackedInline):
|
class MySortableStackedInline(SortableStackedInline):
|
||||||
|
|
@ -90,6 +100,8 @@ To enable sorting on StackedInline models, you need to inherit from SortableStac
|
||||||
|
|
||||||
There are also generic equivalents that you can inherit from::
|
There are also generic equivalents that you can inherit from::
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
from adminsortable.admin import (SortableGenericTabularInline,
|
from adminsortable.admin import (SortableGenericTabularInline,
|
||||||
SortableGenericStackedInline)
|
SortableGenericStackedInline)
|
||||||
"""Your generic inline options go here"""
|
"""Your generic inline options go here"""
|
||||||
|
|
@ -108,6 +120,8 @@ Overriding ``queryset()`` for an inline model
|
||||||
|
|
||||||
This is a special case, which requires a few lines of extra code to properly determine the sortability of your model. Example::
|
This is a special case, which requires a few lines of extra code to properly determine the sortability of your model. Example::
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
# add this import to your admin.py
|
# add this import to your admin.py
|
||||||
from adminsortable.utils import get_is_sortable
|
from adminsortable.utils import get_is_sortable
|
||||||
|
|
||||||
|
|
@ -137,6 +151,8 @@ It is also possible to sort a subset of objects in your model by adding a ``sort
|
||||||
|
|
||||||
An example of sorting subsets would be a "Board of Directors". In this use case, you have a list of "People" objects. Some of these people are on the Board of Directors and some not, and you need to sort them independently::
|
An example of sorting subsets would be a "Board of Directors". In this use case, you have a list of "People" objects. Some of these people are on the Board of Directors and some not, and you need to sort them independently::
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
class Person(Sortable):
|
class Person(Sortable):
|
||||||
class Meta(Sortable.Meta):
|
class Meta(Sortable.Meta):
|
||||||
verbose_name_plural = 'People'
|
verbose_name_plural = 'People'
|
||||||
|
|
@ -170,6 +186,8 @@ By default, adminsortable's change form and change list views inherit from Djang
|
||||||
|
|
||||||
These attributes have default values of::
|
These attributes have default values of::
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
change_form_template_extends = 'admin/change_form.html'
|
change_form_template_extends = 'admin/change_form.html'
|
||||||
change_list_template_extends = 'admin/change_list.html'
|
change_list_template_extends = 'admin/change_list.html'
|
||||||
|
|
||||||
|
|
|
||||||
7
setup.py
7
setup.py
|
|
@ -1,9 +1,7 @@
|
||||||
from setuptools import setup, find_packages
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
try:
|
with open('README.rst') as readme_file:
|
||||||
README = open('README.rst').read()
|
README = readme_file.read()
|
||||||
except:
|
|
||||||
README = None
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
author='Brandon Taylor',
|
author='Brandon Taylor',
|
||||||
|
|
@ -22,7 +20,6 @@ setup(
|
||||||
install_requires=['django'],
|
install_requires=['django'],
|
||||||
license='APL',
|
license='APL',
|
||||||
long_description=README,
|
long_description=README,
|
||||||
long_description_content_type='text/markdown',
|
|
||||||
name='django-admin-sortable',
|
name='django-admin-sortable',
|
||||||
packages=find_packages(exclude=['sample_project']),
|
packages=find_packages(exclude=['sample_project']),
|
||||||
url='https://github.com/iambrandontaylor/django-admin-sortable',
|
url='https://github.com/iambrandontaylor/django-admin-sortable',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue