{
"info": {
"author": "Shenggao Zhu",
"author_email": "zshgao@gmail.com",
"bugtrack_url": null,
"classifiers": [
"Development Status :: 4 - Beta",
"Environment :: Web Environment",
"Framework :: Django",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content"
],
"description": "=====================\ndjango-sortedone2many\n=====================\n\n.. image:: https://img.shields.io/pypi/l/django-sortedone2many.svg\n :target: ./LICENSE\n :alt: License\n\n.. image:: https://img.shields.io/pypi/v/django-sortedone2many.svg\n :target: https://pypi.python.org/pypi/django-sortedone2many\n :alt: PyPI Release\n\n.. image:: https://img.shields.io/pypi/pyversions/django-sortedone2many.svg\n :target: https://pypi.python.org/pypi/django-sortedone2many\n :alt: Supported Python versions\n\n.. .. image:: https://img.shields.io/pypi/dm/django-sortedone2many.svg\n :alt: PyPI Downloads\n :target: https://pypi.python.org/pypi/django-sortedone2many\n\n.. image:: https://travis-ci.org/ShenggaoZhu/django-sortedone2many.svg?branch=master\n :target: https://travis-ci.org/ShenggaoZhu/django-sortedone2many\n :alt: Travis Build Status\n\n\n``sortedone2many`` provides a ``SortedOneToManyField`` for django Model that establishes a\none-to-many relationship (which can also remember the order of related objects).\n\nDepends on ``SortedManyToManyField`` from the great library django-sortedm2m_ (check it out!).\n\n.. _django-sortedm2m: https://github.com/gregmuellegger/django-sortedm2m\n\n\nInstallation\n============\n\n``pip install django-sortedone2many``\n\nPyPI repository: https://pypi.python.org/pypi/django-sortedone2many\n\n\nUsecases\n========\n\nSorted ``OneToMany`` relationship\n---------------------------------\n\nThe ``OneToMany`` relationship has been long missing from django ORM.\nA similar relationship, ``ManyToOne``, is provided via a ``ForeignKey``,\nwhich is always declared on the \"many\" side of the relationship.\nIn the following example (using ``related_name`` on a ``ForeignKey``):\n\n.. code-block:: python\n\n class Category(models.Model):\n name = models.CharField(max_length=50)\n\n class Item(models.Model):\n category = ForeignKey(Category, related_name=\"items\")\n\n``item.category`` is a ``ManyToOne`` relationship, while\n``category.items`` is a ``OneToMany`` relationship.\nHowever, it is not easy to\nmanage the order of the list of ``items`` in a ``category``.\n\nTo address this need, simply add a ``SortedOneToManyField`` (from this package) to\nthe model on the \"one\" side of the relationship:\n\n.. code-block:: python\n\n class Category(models.Model):\n name = models.CharField(max_length=50)\n items = SortedOneToManyField(Item, sorted=True, blank=True)\n\n``SortedOneToManyField`` uses an intermediary model with an extra\n``sort_value`` field to manage the orders of the related objects.\nIt is very useful to represent **an ordered list of items**\n(according to their added order or user-specified order).\n\nAlso, ``OneToMany`` relationship offers better **semantics** and **readability** than ``ForeignKey``,\nespecially for scenarios like ``master-detail`` or ``category-item``\n(where each item only belongs to one category).\n`This blog explains it nicely `_.\n\nAdding ``OneToMany`` to existing models\n---------------------------------------\n\nSince ``OneToMany`` relationship uses an intermediary model,\nit can work without altering already-existing models/tables,\nthus providing better **extensibility** than ``ForeignKey``\n(which requires adding a ``ForeignKey`` field to the model/table).\nThis is a big advantage when the existing models can't be changed\n(e.g., models in a third-party library, or shared among several applications).\n\nThis package provides a shortcut function ``add_sorted_one2many_relation``\nto inject ``OneToMany`` relationship to existing models without editing the\nmodel source code or subclassing the models.\n\n\nUsage\n=====\n\nAdd the ``SortedOneToManyField`` to the model on the \"one\" side of the\nrelationship (as opposed to ``ForeignKey`` on the \"many\" side):\n\n.. code-block:: python\n\n from django.db import models\n from sortedone2many.fields import SortedOneToManyField\n\n class Item(models.Model):\n name = models.CharField(max_length=50)\n\n class Category(models.Model):\n name = models.CharField(max_length=50)\n items = SortedOneToManyField(Item, sorted=True, blank=True)\n\nHere, ``category.items`` is the manager for related ``Item`` objects (the same as\nthe normal ``ManyToManyField``); use it like ``category.items.add(new_item)``,\n``category.items.all()``. By default, the list of ``items`` (e.g., ``category.items.all()``)\nis sorted according to the order that each ``item`` is added.\n\nOn the other side, ``item.category`` is an *instance* (not manager) of ``Category`` (similar\nto a ``OneToOneField``); use it like ``item.category.pk``, ``item.category = new_category``.\n\nStrictly speaking, ``item.category`` is an instance of\n``sortedone2many.fields.OneToManyRelatedObjectDescriptor``\n(a type of `python descriptor `_),\nwhich directly exposes the *single* related object (i.e., the ``category`` instance).\nThis is different from the ``ManyRelatedObjectsDescriptor`` (as in the normal ``ManyToManyField``)\nwhich exposes the ``manager`` of the *potentially multiple* related objects\n(which is not as convenient to use in the ``OneToMany`` relationship).\n\n``SortedOneToManyField``\n------------------------\nSimilar to ``SortedManyToManyField``,\nit uses an intermediary model that holds a ForeignKey field pointed at\nthe model on the \"one\" side of the relationship, a OneToOneField field\npointed at the model on the \"many\" side (to ensure the unique relationship\nto the \"one\" side), and another field storing the\nsort value (to remember to orders of the objects on the \"many\" side).\n\n``SortedOneToManyField`` accepts a boolean ``sorted`` attribute which specifies if relationship is\nordered or not. Default is set to ``True``.\n\nRefer to django-sortedm2m_ for more details.\n\nAdmin\n_____\n\nFirst, add ``\"sortedm2m\"`` to your ``INSTALLED_APPS`` settings,\nwhich provides the static ``js`` and ``css`` files to render\nthe related objects in a ``SortedOneToManyField`` as a list of\ncheckboxes that can be sorted by drag'n'drop.\n(That is similar to the behavior of a ``SortedManyToManyField``).\n\nBy default, a ``SortedOneToManyField`` is translated into a form field\n``sortedone2many.forms.SortedMultipleChoiceWithDisabledField`` for rendering.\nThis form field also adds a special function to the widget:\ndisables those checkboxes that should not be directly selected\nin the current admin view (to ensure the unique ``OneToMany`` relationship).\n\nE.g., in the image below, in the admin view for ``category 1``,\n``item1.category`` is ``category 2``, so the checkbox for ``item1`` is disabled\nbecause ``category 2`` has to remove ``item1`` from its ``items`` list before\n``category 1`` can select ``item1`` in the admin view.\n\n.. image:: https://raw.githubusercontent.com/ShenggaoZhu/django-sortedone2many/master/docs/category.jpg\n\nIn the admin site, to display a related object on the reverse side of\na ``SortedOneToManyField`` (e.g., to display ``item1.category`` in the\nadmin view of ``item1``), simply use ``sortedone2many.admin.One2ManyModelAdmin``\nas the ``admin class`` to register your model:\n\n.. code-block:: python\n\n from django.contrib import admin\n from sortedone2many.admin import One2ManyModelAdmin\n admin.site.register(MyItemModel, One2ManyModelAdmin)\n\nOr, use the shortcut function ``sortedone2many.admin.register``:\n\n.. code-block:: python\n\n from sortedone2many.admin import register\n register(MyItemModel)\n\nThe related object will be rendered as a dropdown