• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

example/H23-Jul-2020-9558

requirements/H03-May-2022-

sortedm2m/H23-Jul-2020-715532

sortedm2m_tests/H23-Jul-2020-551383

test_project/H23-Jul-2020-13389

.coveragercH A D23-Jul-202023 32

.gitignoreH A D23-Jul-2020113 1413

.travis.ymlH A D23-Jul-20201.3 KiB5049

AUTHORS.rstH A D23-Jul-20201.9 KiB5753

CHANGES.rstH A D23-Jul-202010.2 KiB353250

CONTRIBUTING.mdH A D23-Jul-2020308 42

MANIFEST.inH A D23-Jul-2020425 1615

MakefileH A D23-Jul-2020347 107

README.rstH A D23-Jul-20207.2 KiB206147

codecov.ymlH A D23-Jul-2020125 109

pylintrcH A D23-Jul-202014.4 KiB421289

runtests.pyH A D23-Jul-2020863 3320

setup.cfgH A D23-Jul-2020155 129

setup.pyH A D23-Jul-20201.7 KiB6150

tox.iniH A D23-Jul-20201,021 4237

README.rst

1================
2django-sortedm2m
3================
4
5.. image:: https://jazzband.co/static/img/badge.svg
6   :target: https://jazzband.co/
7   :alt: Jazzband
8
9.. image:: https://img.shields.io/pypi/v/django-sortedm2m.svg
10   :target: https://pypi.python.org/pypi/django-sortedm2m
11   :alt: PyPI Release
12
13.. image:: https://travis-ci.org/jazzband/django-sortedm2m.svg?branch=master
14   :target: https://travis-ci.org/jazzband/django-sortedm2m
15   :alt: Build Status
16
17.. image:: https://codecov.io/gh/jazzband/django-sortedm2m/branch/master/graph/badge.svg
18   :target: https://codecov.io/gh/jazzband/django-sortedm2m
19   :alt: Code coverage
20
21``sortedm2m`` is a drop-in replacement for django's own ``ManyToManyField``.
22The provided ``SortedManyToManyField`` behaves like the original one but
23remembers the order of added relations.
24
25Use Cases
26=========
27
28Imagine that you have a gallery model and a photo model. Usually you want a
29relation between these models so you can add multiple photos to one gallery
30but also want to be able to have the same photo on many galleries.
31
32This is where you usually can use many to many relation. The downside is that
33django's default implementation doesn't provide a way to order the photos in
34the gallery. So you only have a random ordering which is not suitable in most
35cases.
36
37You can work around this limitation by using the ``SortedManyToManyField``
38provided by this package as drop in replacement for django's
39``ManyToManyField``.
40
41Requirements
42============
43
44**django-sortedm2m** runs on Python 3.6+ and Django from 2.1 to 3.0.
45
46Usage
47=====
48
49Use ``SortedManyToManyField`` like ``ManyToManyField`` in your models::
50
51    from django.db import models
52    from sortedm2m.fields import SortedManyToManyField
53
54    class Photo(models.Model):
55        name = models.CharField(max_length=50)
56        image = models.ImageField(upload_to='...')
57
58    class Gallery(models.Model):
59        name = models.CharField(max_length=50)
60        photos = SortedManyToManyField(Photo)
61
62If you use the relation in your code like the following, it will remember the
63order in which you have added photos to the gallery. ::
64
65    gallery = Gallery.objects.create(name='Photos ordered by name')
66    for photo in Photo.objects.order_by('name'):
67        gallery.photos.add(photo)
68
69``SortedManyToManyField``
70-------------------------
71
72You can use the following arguments to modify the default behavior:
73
74``sorted``
75~~~~~~~~~~
76
77**Default:** ``True``
78
79You can set the ``sorted`` to ``False`` which will force the
80``SortedManyToManyField`` in behaving like Django's original
81``ManyToManyField``. No ordering will be performed on relation nor will the
82intermediate table have a database field for storing ordering information.
83
84``sort_value_field_name``
85~~~~~~~~~~~~~~~~~~~~~~~~~
86
87**Default:** ``'sort_value'``
88
89Specifies how the field is called in the intermediate database table by which
90the relationship is ordered. You can change its name if you have a legacy
91database that you need to integrate into your application.
92
93``base_class``
94~~~~~~~~~~~~~~
95
96**Default:** ``None``
97
98You can set the ``base_class``, which is the base class of the through model of
99the sortedm2m relationship between models to an abstract base class containing
100a ``__str__`` method to improve the string representations of sortedm2m
101relationships.
102
103.. note::
104
105    You also could use it to add additional fields to the through model. But
106    please beware: These fields will not be created or modified by an
107    automatically created migration. You will need to take care of migrations
108    yourself. In most cases when you want to add another field, consider
109    *not* using sortedm2m but use a ordinary Django ManyToManyField and
110    specify `your own through model`_.
111
112.. _your own through model: https://docs.djangoproject.com/en/1.11/ref/models/fields/#django.db.models.ManyToManyField.through
113
114Migrating a ``ManyToManyField`` to be a ``SortedManyToManyField``
115=================================================================
116
117If you are using Django's migration framework and want to change a
118``ManyToManyField`` to be a ``SortedManyToManyField`` (or the other way
119around), you will find that a migration created by Django's ``makemigrations``
120will not work as expected.
121
122In order to migrate a ``ManyToManyField`` to a ``SortedManyToManyField``, you
123change the field in your models to be a ``SortedManyToManyField`` as
124appropriate and create a new migration with ``manage.py makemigrations``.
125Before applying it, edit the migration file and change in the ``operations``
126list ``migrations.AlterField`` to ``AlterSortedManyToManyField`` (import it
127from ``sortedm2m.operations``).  This operation will take care of changing the
128intermediate tables, add the ordering field and fill in default values.
129
130Admin
131=====
132
133``SortedManyToManyField`` provides a custom widget which can be used to sort
134the selected items. It renders a list of checkboxes that can be sorted by
135drag'n'drop.
136
137To use the widget in the admin you need to add ``sortedm2m`` to your
138INSTALLED_APPS settings, like::
139
140   INSTALLED_APPS = (
141       'django.contrib.auth',
142       'django.contrib.contenttypes',
143       'django.contrib.sessions',
144       'django.contrib.sites',
145       'django.contrib.messages',
146       'django.contrib.staticfiles',
147       'django.contrib.admin',
148
149       'sortedm2m',
150
151       '...',
152   )
153
154Otherwise it will not find the css and js files needed to sort by drag'n'drop.
155
156Finally, make sure *not* to have the model listed in any ``filter_horizontal``
157or ``filter_vertical`` tuples inside of your ``ModelAdmin`` definitions.
158
159If you did it right, you'll wind up with something like this:
160
161.. image:: http://i.imgur.com/HjIW7MI.jpg
162
163It's also possible to use the ``SortedManyToManyField`` with admin's
164``raw_id_fields`` option in the ``ModelAdmin`` definition. Add the name of the
165``SortedManyToManyField`` to this list to get a simple text input field. The
166order in which the ids are entered into the input box is used to sort the
167items of the sorted m2m relation.
168
169Example::
170
171    from django.contrib import admin
172
173    class GalleryAdmin(admin.ModelAdmin):
174        raw_id_fields = ('photos',)
175
176Contribute
177==========
178This is a `Jazzband <https://jazzband.co>`_ project. By contributing you agree to abide by the
179`Contributor Code of Conduct <https://jazzband.co/about/conduct>`_ and follow the
180`guidelines <https://jazzband.co/about/guidelines>`_.
181
182You can find the latest development version on Github_. Get there and fork it, file bugs or send well wishes.
183
184.. _github: http://github.com/jazzband/django-sortedm2m
185
186Running the tests
187-----------------
188
189I recommend to use ``tox`` to run the tests for all relevant python versions
190all at once. Therefore install ``tox`` with ``pip install tox``, then type in
191the root directory of the ``django-sortedm2m`` checkout::
192
193   tox
194
195The tests are run against SQLite, then against PostgreSQL, then against mySQL -
196so you need to install PostgreSQL and mySQL on your dev environment, and should
197have a role/user ``sortedm2m`` set up for both PostgreSQL and mySQL.
198
199Code Quality
200------------
201This project uses `isort <https://github.com/timothycrosley/isort>`_, `pycodestyle <https://github.com/PyCQA/pycodestyle>`_,
202and `pylint <https://www.pylint.org>`_ to manage validate code quality. These validations can be run with the
203following command::
204
205   tox -e quality
206