﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
6118	Add Ordered MayToMany	toomim@…	nobody	"I'm writing an extremely simple django app to store a database of publications for academics. Each publication has a title and an ordered list of authors. I want the academics in my group to enter their pubs and author lists using the django admin.

Here's the basic model:

{{{
class Author(models.Model):
    name = models.CharField(maxlength=30)

class Pub(models.Model):
    title = models.CharField(maxlength=200)
    authors = models.ManyToManyField(Author)
}}}

However, this list of authors is unordered, and academics care a lot about author order.

Even though ordered lists are common in practice, they turn out to be very tricky to represent in django.You can introduce an intermediary table (http://www.djangoproject.com/documentation/models/m2m_intermediary/) but doing so is a bit too complicated and unintuitive, and I was personally unable to make it work properly with the admin site. (See below & attachment.)

This ticket proposes a new relation akin to ""OrderedManyToManyField"" that works just like ManyToMany, except that the order of elements can be specified and preserved. The code for the above would look something like:

{{{
class Author(models.Model):
    name = models.CharField(maxlength=30)

class Pub(models.Model):
    title = models.CharField(maxlength=200)
    authors = models.OrderedManyToManyField(Author)
}}}

Note that the order must be maintained per publication; you can't just order by an attribute on the author model. Each author can be in multiple differently-ordered lists.

Just for the record, here's my current attempt at implementing an ordered list of items using an intermediary table:

{{{
from django.db import models

class Author(models.Model):
    name = models.CharField(maxlength=30)
    def __str__(self):
        return self.name
    class Admin:
        pass

class Pub(models.Model):
    title = models.CharField(maxlength=200)
    def __str__(self):
        return self.title
    class Admin:
        pass

class PubAuthor(models.Model):
    author = models.OneToOneField(Author, core=True)
    author_number = models.IntegerField(core=True)
    pub = models.ForeignKey(Pub, edit_inline=models.TABULAR, num_in_admin=5, num_extra_on_change=5)
    class Admin:
        pass
    def __str__(self):
        return self.author.__str__() + ' ' + str(self.author_number)
}}}

Besides being more complicated to write, the admin interface for this code does not work right. I'm attaching a screenshot of viewing a pub after it has been created and saved. Note that (1) the admin user has to manually specify the index of each pub rather than have it implicit in the order of the list, and (2) for some reason the authors cannot be changed after the pub has been saved and committed to the database.

(Including links in a separate post to dodge spam filter.)
"		closed	Uncategorized	dev		duplicate	ordered list many-to-many		Unreviewed	0	0	0	0	0	0
