Thursday, March 16, 2017

Sequence in ManyToMany fields

Up till now I had designed the database with Paper being a class that had a ManyToMany field connected to the Author class. So essentially a paper will have multiple authors and an author will have several papers. The concept works except for one problem. Defining a ManyToMany relationship in the Paper class in the following manner:

paper_authors = models.ManyToManyField(Author)

Allows you to add multiple Author objects to objects of the class Paper. However, adding authors in a particular sequence does not guarantee that sequence will be maintained. If a query is performed:

paper.paper_authors.all()

The Author objects in the object paper will be extracted randomly from the database. The only way to solve this as I could see from the answer to a question I posted on Stack Overflow is:

http://stackoverflow.com/questions/42741591/order-of-manytomany-field-in-model-changed-when-one-object-is-replaced

What was suggested is that I define a membership class and use the "through" attribute (click view raw at the bottom to see code in a new window).



Now the ManyToMany field has the following definition:

paper_authors = models.ManyToManyField(Author, through = 'Contributor')

It uses a membership class using the "through" attribute to define additional details about how Author is related to Paper. From the above code, now the Contributor class has a "position" defined which designates the author's position in the paper. Also, before, authors could be added by using the add function as:

paper_Y.paper_authors.add(X)

However, now the membership object has to be defined as:

xy = Contributor(paper=paper_Y, author=X,position=1)
xy.save()

With this change made, the functions in views.py have been changed and now a paper can be edited to change the authors without losing the sequence.

Now that a basic database has been created, I'll tinker around a little to make sure I haven't missed anything and then I'll create a better set of web pages to make it easier to navigate this application.

No comments:

Post a Comment