From 2e5f7addf45e7c116389cd1fba5abff7dee241a8 Mon Sep 17 00:00:00 2001 From: blag Date: Wed, 22 Jul 2020 01:52:57 -0700 Subject: [PATCH 1/6] Update usage docs --- docs/usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.rst b/docs/usage.rst index f636dfb..e0a4497 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -4,7 +4,7 @@ Using Django Admin Sortable 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 # models.py from adminsortable.models import Sortable From 3209998569bcf903f98470791f382947e8809157 Mon Sep 17 00:00:00 2001 From: blag Date: Wed, 22 Jul 2020 01:52:33 -0700 Subject: [PATCH 2/6] Add code-block segments to documentation --- docs/quickstart.rst | 6 ++++++ docs/testing.rst | 2 ++ docs/usage.rst | 20 +++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index da192c8..7b78e43 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -3,6 +3,8 @@ Quickstart To get started using ``django-admin-sortable`` simply install it using ``pip``:: + .. code-block:: bash + $ pip install django-admin-sortable 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``:: + .. code-block:: python + # models.py from adminsortable.models import Sortable @@ -25,6 +29,8 @@ Define your model, inheriting from ``adminsortable.Sortable``:: Wire up your sortable model to Django admin:: + .. code-block:: python + # admin.py from adminsortable.admin import SortableAdmin from .models import MySortableClass diff --git a/docs/testing.rst b/docs/testing.rst index 0ef88cb..db0fe01 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -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: + .. code-block:: bash + $ python manage.py test app diff --git a/docs/usage.rst b/docs/usage.rst index e0a4497..a05baaf 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -6,6 +6,8 @@ Models 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 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. -:: + .. code-block:: python # models.py 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":: + .. code-block:: python + def forwards(self, orm): for index, category in enumerate(orm.Category.objects.all()): category.order = index + 1 @@ -65,6 +69,8 @@ Django Admin To enable sorting in the admin, you need to inherit from ``SortableAdmin``:: + .. code-block:: python + from django.contrib import admin from myapp.models import MySortableClass 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:: + .. code-block:: python + from adminsortable.admin import 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:: + .. code-block:: python + from adminsortable.admin import 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:: + .. code-block:: python + from adminsortable.admin import (SortableGenericTabularInline, SortableGenericStackedInline) """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:: + .. code-block:: python + # add this import to your admin.py 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:: + .. code-block:: python + class Person(Sortable): class Meta(Sortable.Meta): 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:: + .. code-block:: python + change_form_template_extends = 'admin/change_form.html' change_list_template_extends = 'admin/change_list.html' From eb3f18b09e29d0512b29a5124ed1745acc944c0f Mon Sep 17 00:00:00 2001 From: blag Date: Wed, 22 Jul 2020 01:54:14 -0700 Subject: [PATCH 3/6] Use a context manager to read README.rst --- setup.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index ec27483..99eabc9 100644 --- a/setup.py +++ b/setup.py @@ -1,9 +1,7 @@ from setuptools import setup, find_packages -try: - README = open('README.rst').read() -except: - README = None +with open('README.rst') as readme_file: + README = readme_file.read() setup( author='Brandon Taylor', From 616dcdfd7a4d96653c230906dfb647572705b784 Mon Sep 17 00:00:00 2001 From: blag Date: Wed, 22 Jul 2020 01:54:42 -0700 Subject: [PATCH 4/6] Remove incorrect long_description_content_type argument --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index 99eabc9..631b4ee 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,6 @@ setup( install_requires=['django'], license='APL', long_description=README, - long_description_content_type='text/markdown', name='django-admin-sortable', packages=find_packages(exclude=['sample_project']), url='https://github.com/iambrandontaylor/django-admin-sortable', From 7ed44fa84b129271d015ffb9e2ca72462e65f185 Mon Sep 17 00:00:00 2001 From: blag Date: Wed, 22 Jul 2020 01:50:51 -0700 Subject: [PATCH 5/6] Add section title to sortable model with non-sortable parent --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5825ced..d2dddbe 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,8 @@ admin.site.register(Category, 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: ```python From 5e9e0b3564f0942915c98841913ba13adf52a7cf Mon Sep 17 00:00:00 2001 From: blag Date: Wed, 22 Jul 2020 01:51:22 -0700 Subject: [PATCH 6/6] Add section on many-to-many relations --- README.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/README.md b/README.md index d2dddbe..5126b31 100644 --- a/README.md +++ b/README.md @@ -200,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. +#### 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 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.